From 93bdeb5e953c2e35600a721007cd373dc11a379d Mon Sep 17 00:00:00 2001 From: wehub-resource-sync Date: Mon, 13 Jul 2026 12:08:36 +0800 Subject: [PATCH] chore: import upstream snapshot with attribution --- .cargo/config.toml | 8 + .devcontainer/devcontainer.json | 10 + .dockerignore | 9 + .gitattributes | 9 + .github/ISSUE_TEMPLATE/bug_report.md | 29 + .github/ISSUE_TEMPLATE/config.yml | 11 + .github/ISSUE_TEMPLATE/feature_request.md | 24 + .github/PULL_REQUEST_TEMPLATE.md | 1 + .github/dependabot.yml | 52 + .github/workflows/ci.yml | 119 + .github/workflows/release.yml | 378 + .gitignore | 14 + .rustfmt.toml | 4 + .taplo.toml | 13 + CHANGELOG.md | 416 + CONTRIBUTING.md | 47 + Cargo.lock | 7956 +++++++++++++++++ Cargo.toml | 146 + LICENSE | 201 + Makefile | 84 + README.md | 61 + README.wehub.md | 7 + _typos.toml | 17 + defaults/dark-theme.toml | 210 + defaults/icon-theme.toml | 153 + defaults/keymaps-common.toml | 737 ++ defaults/keymaps-macos.toml | 305 + defaults/keymaps-nonmacos.toml | 310 + defaults/light-theme.toml | 216 + defaults/run.toml | 30 + defaults/settings.toml | 105 + deny.toml | 15 + docker-bake.hcl | 244 + docs/building-from-source.md | 50 + docs/installing-with-package-manager.md | 20 + docs/new-release.md | 8 + docs/why-lapce.md | 23 + extra/entitlements.plist | 14 + extra/fonts/DejaVu/DejaVuSans.ttf | Bin 0 -> 757076 bytes extra/fonts/DejaVu/DejaVuSansMono.ttf | Bin 0 -> 340712 bytes extra/fonts/DejaVu/LICENSE | 187 + .../images/linux/code-file-with-highlight.png | Bin 0 -> 198184 bytes extra/images/logo.png | Bin 0 -> 242292 bytes extra/images/logo.svg | 8 + extra/images/logo_app.svg | 22 + extra/images/logo_app_light.svg | 17 + extra/images/logo_color.svg | 13 + extra/images/screenshot.png | Bin 0 -> 966575 bytes extra/images/volt.png | Bin 0 -> 7371 bytes extra/linux/dev.lapce.lapce.desktop | 20 + extra/linux/dev.lapce.lapce.metainfo.xml | 63 + extra/linux/docker/alpine/Dockerfile | 123 + extra/linux/docker/debian/Dockerfile | 186 + extra/linux/docker/fedora/Dockerfile | 190 + extra/linux/docker/ubuntu/Dockerfile | 213 + extra/macos/Lapce.app/Contents/Info.plist | 58 + .../Lapce.app/Contents/Resources/lapce.icns | Bin 0 -> 368832 bytes extra/proxy.ps1 | 47 + extra/proxy.sh | 104 + extra/schemas/color-theme.json | 202 + extra/schemas/icon-theme.json | 60 + extra/schemas/settings.json | 353 + extra/windows/lapce.ico | Bin 0 -> 410598 bytes extra/windows/wix/lapce.wxs | 64 + extra/windows/wix/license.rtf | 53 + icons/codicons/LICENSE | 395 + icons/codicons/README.md | 3 + icons/codicons/add.svg | 1 + icons/codicons/arrow-both.svg | 1 + icons/codicons/arrow-down.svg | 1 + icons/codicons/arrow-left.svg | 1 + icons/codicons/arrow-right.svg | 1 + icons/codicons/arrow-swap.svg | 1 + icons/codicons/arrow-up.svg | 1 + icons/codicons/blank.svg | 1 + icons/codicons/case-sensitive.svg | 1 + icons/codicons/chevron-down.svg | 1 + icons/codicons/chevron-left.svg | 1 + icons/codicons/chevron-right.svg | 1 + icons/codicons/chevron-up.svg | 1 + icons/codicons/chrome-close.svg | 1 + icons/codicons/chrome-maximize.svg | 1 + icons/codicons/chrome-minimize.svg | 1 + icons/codicons/chrome-restore.svg | 1 + icons/codicons/circle-filled.svg | 1 + icons/codicons/close.svg | 1 + icons/codicons/combine.svg | 1 + icons/codicons/debug-alt-small.svg | 1 + icons/codicons/debug-alt.svg | 1 + icons/codicons/debug-console.svg | 1 + icons/codicons/debug-continue.svg | 1 + icons/codicons/debug-disconnect.svg | 1 + icons/codicons/debug-pause.svg | 1 + icons/codicons/debug-restart.svg | 1 + icons/codicons/debug-start.svg | 1 + icons/codicons/debug-step-into.svg | 1 + icons/codicons/debug-step-out.svg | 1 + icons/codicons/debug-step-over.svg | 1 + icons/codicons/debug-stop.svg | 1 + icons/codicons/debug.svg | 1 + icons/codicons/diff-added.svg | 1 + icons/codicons/diff-ignored.svg | 1 + icons/codicons/diff-modified.svg | 1 + icons/codicons/diff-removed.svg | 1 + icons/codicons/diff-renamed.svg | 1 + icons/codicons/diff.svg | 1 + icons/codicons/discard.svg | 1 + icons/codicons/edit.svg | 1 + icons/codicons/error.svg | 1 + icons/codicons/extensions.svg | 1 + icons/codicons/file-binary.svg | 1 + icons/codicons/file-code.svg | 1 + icons/codicons/file-media.svg | 1 + icons/codicons/file-pdf.svg | 1 + icons/codicons/file-submodule.svg | 1 + icons/codicons/file-symlink-directory.svg | 1 + icons/codicons/file-symlink-file.svg | 1 + icons/codicons/file-zip.svg | 1 + icons/codicons/file.svg | 1 + icons/codicons/files.svg | 1 + icons/codicons/fold-down.svg | 1 + icons/codicons/fold-up.svg | 1 + icons/codicons/fold.svg | 1 + icons/codicons/folder-active.svg | 1 + icons/codicons/folder-library.svg | 1 + icons/codicons/folder-opened.svg | 1 + icons/codicons/folder.svg | 1 + icons/codicons/gear.svg | 1 + icons/codicons/git-commit.svg | 1 + icons/codicons/git-compare.svg | 1 + icons/codicons/git-merge.svg | 1 + icons/codicons/go-to-file.svg | 1 + icons/codicons/group-by-ref-type.svg | 1 + icons/codicons/history.svg | 1 + icons/codicons/info.svg | 1 + icons/codicons/inspect.svg | 1 + icons/codicons/issues.svg | 1 + icons/codicons/json.svg | 1 + icons/codicons/key.svg | 1 + icons/codicons/keyboard.svg | 1 + icons/codicons/layout-activitybar-left.svg | 1 + icons/codicons/layout-activitybar-right.svg | 1 + icons/codicons/layout-centered.svg | 1 + icons/codicons/layout-menubar.svg | 1 + icons/codicons/layout-panel-center.svg | 1 + icons/codicons/layout-panel-justify.svg | 1 + icons/codicons/layout-panel-left.svg | 1 + icons/codicons/layout-panel-off.svg | 1 + icons/codicons/layout-panel-right.svg | 1 + icons/codicons/layout-panel.svg | 1 + icons/codicons/layout-sidebar-left-off.svg | 1 + icons/codicons/layout-sidebar-left.svg | 1 + icons/codicons/layout-sidebar-right-off.svg | 1 + icons/codicons/layout-sidebar-right.svg | 1 + icons/codicons/layout-statusbar.svg | 1 + icons/codicons/layout.svg | 1 + icons/codicons/lightbulb-autofix.svg | 1 + icons/codicons/lightbulb.svg | 1 + icons/codicons/link-external.svg | 1 + icons/codicons/link.svg | 1 + icons/codicons/menu.svg | 1 + icons/codicons/merge.svg | 1 + icons/codicons/multiple-windows.svg | 1 + icons/codicons/new-file.svg | 1 + icons/codicons/new-folder.svg | 1 + icons/codicons/open-preview.svg | 1 + icons/codicons/plugin-icon.svg | 1 + icons/codicons/references.svg | 1 + icons/codicons/refresh.svg | 1 + icons/codicons/regex.svg | 1 + icons/codicons/remote-explorer.svg | 1 + icons/codicons/remote.svg | 1 + icons/codicons/remove.svg | 1 + icons/codicons/replace-all.svg | 1 + icons/codicons/replace.svg | 1 + icons/codicons/repo-clone.svg | 1 + icons/codicons/repo-force-push.svg | 1 + icons/codicons/repo-forked.svg | 1 + icons/codicons/repo-pull.svg | 1 + icons/codicons/repo-push.svg | 1 + icons/codicons/repo.svg | 1 + icons/codicons/root-folder-opened.svg | 1 + icons/codicons/root-folder.svg | 1 + icons/codicons/run-errors.svg | 1 + icons/codicons/screen-full.svg | 1 + icons/codicons/screen-normal.svg | 1 + icons/codicons/search-stop.svg | 1 + icons/codicons/search.svg | 1 + icons/codicons/settings-gear.svg | 1 + icons/codicons/settings.svg | 1 + icons/codicons/source-control.svg | 1 + icons/codicons/split-horizontal.svg | 1 + icons/codicons/split-vertical.svg | 1 + icons/codicons/symbol-array.svg | 1 + icons/codicons/symbol-boolean.svg | 1 + icons/codicons/symbol-class.svg | 1 + icons/codicons/symbol-color.svg | 1 + icons/codicons/symbol-constant.svg | 1 + icons/codicons/symbol-enum-member.svg | 1 + icons/codicons/symbol-enum.svg | 1 + icons/codicons/symbol-event.svg | 1 + icons/codicons/symbol-field.svg | 1 + icons/codicons/symbol-file.svg | 1 + icons/codicons/symbol-interface.svg | 1 + icons/codicons/symbol-key.svg | 1 + icons/codicons/symbol-keyword.svg | 1 + icons/codicons/symbol-method.svg | 1 + icons/codicons/symbol-misc.svg | 1 + icons/codicons/symbol-namespace.svg | 1 + icons/codicons/symbol-numeric.svg | 1 + icons/codicons/symbol-operator.svg | 1 + icons/codicons/symbol-parameter.svg | 1 + icons/codicons/symbol-property.svg | 1 + icons/codicons/symbol-ruler.svg | 1 + icons/codicons/symbol-snippet.svg | 1 + icons/codicons/symbol-string.svg | 1 + icons/codicons/symbol-structure.svg | 1 + icons/codicons/symbol-variable.svg | 1 + icons/codicons/terminal.svg | 1 + icons/codicons/type-hierarchy.svg | 1 + icons/codicons/unsaved.svg | 3 + icons/codicons/warning.svg | 1 + icons/codicons/whole-word.svg | 1 + icons/lapce/lapce_logo.svg | 8 + icons/lapce/lapce_remote.svg | 28 + lapce-app/Cargo.toml | 85 + lapce-app/benches/visual_line.rs | 278 + lapce-app/src/about.rs | 213 + lapce-app/src/alert.rs | 174 + lapce-app/src/app.rs | 4321 +++++++++ lapce-app/src/app/grammars.rs | 141 + lapce-app/src/app/logging.rs | 153 + lapce-app/src/bin/lapce.rs | 7 + lapce-app/src/code_action.rs | 233 + lapce-app/src/code_lens.rs | 100 + lapce-app/src/command.rs | 818 ++ lapce-app/src/completion.rs | 417 + lapce-app/src/config.rs | 1020 +++ lapce-app/src/config/color.rs | 182 + lapce-app/src/config/color_theme.rs | 263 + lapce-app/src/config/core.rs | 25 + lapce-app/src/config/editor.rs | 306 + lapce-app/src/config/icon.rs | 171 + lapce-app/src/config/icon_theme.rs | 243 + lapce-app/src/config/svg.rs | 65 + lapce-app/src/config/terminal.rs | 101 + lapce-app/src/config/ui.rs | 144 + lapce-app/src/config/watcher.rs | 55 + lapce-app/src/db.rs | 452 + lapce-app/src/debug.rs | 640 ++ lapce-app/src/doc.rs | 2239 +++++ lapce-app/src/editor.rs | 3926 ++++++++ lapce-app/src/editor/diff.rs | 552 ++ lapce-app/src/editor/gutter.rs | 402 + lapce-app/src/editor/location.rs | 34 + lapce-app/src/editor/view.rs | 2667 ++++++ lapce-app/src/editor_tab.rs | 484 + lapce-app/src/file_explorer/data.rs | 681 ++ lapce-app/src/file_explorer/mod.rs | 3 + lapce-app/src/file_explorer/node.rs | 38 + lapce-app/src/file_explorer/view.rs | 620 ++ lapce-app/src/find.rs | 545 ++ lapce-app/src/focus_text.rs | 287 + lapce-app/src/global_search.rs | 200 + lapce-app/src/history.rs | 26 + lapce-app/src/hover.rs | 28 + lapce-app/src/id.rs | 11 + lapce-app/src/inline_completion.rs | 288 + lapce-app/src/keymap.rs | 562 ++ lapce-app/src/keypress.rs | 701 ++ lapce-app/src/keypress/condition.rs | 162 + lapce-app/src/keypress/key.rs | 74 + lapce-app/src/keypress/keymap.rs | 707 ++ lapce-app/src/keypress/loader.rs | 253 + lapce-app/src/keypress/press.rs | 18 + lapce-app/src/lib.rs | 50 + lapce-app/src/listener.rs | 65 + lapce-app/src/lsp.rs | 92 + lapce-app/src/main_split.rs | 3105 +++++++ lapce-app/src/markdown.rs | 344 + lapce-app/src/palette.rs | 1700 ++++ lapce-app/src/palette/item.rs | 87 + lapce-app/src/palette/kind.rs | 162 + lapce-app/src/panel/call_hierarchy_view.rs | 251 + lapce-app/src/panel/data.rs | 464 + lapce-app/src/panel/debug_view.rs | 758 ++ lapce-app/src/panel/document_symbol.rs | 321 + lapce-app/src/panel/global_search_view.rs | 309 + lapce-app/src/panel/implementation_view.rs | 384 + lapce-app/src/panel/kind.rs | 66 + lapce-app/src/panel/mod.rs | 15 + lapce-app/src/panel/plugin_view.rs | 407 + lapce-app/src/panel/position.rs | 74 + lapce-app/src/panel/problem_view.rs | 399 + lapce-app/src/panel/references_view.rs | 18 + lapce-app/src/panel/source_control_view.rs | 364 + lapce-app/src/panel/style.rs | 8 + lapce-app/src/panel/terminal_view.rs | 387 + lapce-app/src/panel/view.rs | 655 ++ lapce-app/src/plugin.rs | 1023 +++ lapce-app/src/proxy.rs | 171 + lapce-app/src/proxy/remote.rs | 497 + lapce-app/src/proxy/ssh.rs | 67 + lapce-app/src/proxy/wsl.rs | 33 + lapce-app/src/rename.rs | 154 + lapce-app/src/settings.rs | 1400 +++ lapce-app/src/snippet.rs | 859 ++ lapce-app/src/source_control.rs | 104 + lapce-app/src/status.rs | 473 + lapce-app/src/terminal/data.rs | 861 ++ lapce-app/src/terminal/event.rs | 77 + lapce-app/src/terminal/mod.rs | 6 + lapce-app/src/terminal/panel.rs | 820 ++ lapce-app/src/terminal/raw.rs | 149 + lapce-app/src/terminal/tab.rs | 68 + lapce-app/src/terminal/view.rs | 799 ++ lapce-app/src/text_area.rs | 121 + lapce-app/src/text_input.rs | 801 ++ lapce-app/src/title.rs | 533 ++ lapce-app/src/tracing.rs | 4 + lapce-app/src/update.rs | 233 + lapce-app/src/wave.rs | 59 + lapce-app/src/web_link.rs | 24 + lapce-app/src/window.rs | 394 + lapce-app/src/window_tab.rs | 2989 +++++++ lapce-app/src/workspace.rs | 159 + lapce-core/Cargo.toml | 43 + lapce-core/build.rs | 114 + lapce-core/src/directory.rs | 192 + lapce-core/src/encoding.rs | 163 + lapce-core/src/language.rs | 2075 +++++ lapce-core/src/lens.rs | 388 + lapce-core/src/lib.rs | 13 + lapce-core/src/meta.rs | 8 + lapce-core/src/rope_text_pos.rs | 40 + lapce-core/src/style.rs | 75 + lapce-core/src/syntax/edit.rs | 119 + lapce-core/src/syntax/highlight.rs | 831 ++ lapce-core/src/syntax/mod.rs | 1280 +++ lapce-core/src/syntax/util.rs | 27 + lapce-proxy/Cargo.toml | 69 + lapce-proxy/src/bin/lapce-proxy.rs | 5 + lapce-proxy/src/buffer.rs | 351 + lapce-proxy/src/cli.rs | 219 + lapce-proxy/src/dispatch.rs | 1761 ++++ lapce-proxy/src/lib.rs | 215 + lapce-proxy/src/plugin/catalog.rs | 756 ++ lapce-proxy/src/plugin/dap.rs | 824 ++ lapce-proxy/src/plugin/lsp.rs | 557 ++ lapce-proxy/src/plugin/mod.rs | 1797 ++++ lapce-proxy/src/plugin/psp.rs | 1440 +++ lapce-proxy/src/plugin/wasi.rs | 629 ++ .../src/plugin/wasi/plugins/smiley.png | Bin 0 -> 41750 bytes .../some_author.test-plugin-one/Dark.svg | 50 + .../some_author.test-plugin-one/Dark.toml | 0 .../some_author.test-plugin-one/Light.svg | 50 + .../some_author.test-plugin-one/Light.toml | 0 .../some_author.test-plugin-one/lapce.wasm | 0 .../some_author.test-plugin-one/volt.toml | 16 + .../some_author.test-plugin-three/volt.toml | 16 + .../some_author.test-plugin-two/Light.svg | 50 + .../some_author.test-plugin-two/Light.toml | 0 .../some_author.test-plugin-two/lapce.wasm | 0 .../some_author.test-plugin-two/volt.toml | 16 + lapce-proxy/src/plugin/wasi/tests.rs | 237 + lapce-proxy/src/terminal.rs | 384 + lapce-proxy/src/watcher.rs | 275 + lapce-rpc/Cargo.toml | 25 + lapce-rpc/src/buffer.rs | 24 + lapce-rpc/src/core.rs | 433 + lapce-rpc/src/counter.rs | 19 + lapce-rpc/src/dap_types.rs | 876 ++ lapce-rpc/src/file.rs | 591 ++ lapce-rpc/src/file_line.rs | 11 + lapce-rpc/src/lib.rs | 33 + lapce-rpc/src/parse.rs | 76 + lapce-rpc/src/plugin.rs | 237 + lapce-rpc/src/proxy.rs | 1220 +++ lapce-rpc/src/source_control.rs | 47 + lapce-rpc/src/stdio.rs | 142 + lapce-rpc/src/style.rs | 25 + lapce-rpc/src/terminal.rs | 26 + lapce.spec | 40 + 383 files changed, 83019 insertions(+) create mode 100644 .cargo/config.toml create mode 100644 .devcontainer/devcontainer.json create mode 100644 .dockerignore create mode 100644 .gitattributes create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release.yml create mode 100644 .gitignore create mode 100644 .rustfmt.toml create mode 100644 .taplo.toml create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 README.wehub.md create mode 100644 _typos.toml create mode 100644 defaults/dark-theme.toml create mode 100644 defaults/icon-theme.toml create mode 100644 defaults/keymaps-common.toml create mode 100644 defaults/keymaps-macos.toml create mode 100644 defaults/keymaps-nonmacos.toml create mode 100644 defaults/light-theme.toml create mode 100644 defaults/run.toml create mode 100644 defaults/settings.toml create mode 100644 deny.toml create mode 100644 docker-bake.hcl create mode 100644 docs/building-from-source.md create mode 100644 docs/installing-with-package-manager.md create mode 100644 docs/new-release.md create mode 100644 docs/why-lapce.md create mode 100644 extra/entitlements.plist create mode 100644 extra/fonts/DejaVu/DejaVuSans.ttf create mode 100644 extra/fonts/DejaVu/DejaVuSansMono.ttf create mode 100644 extra/fonts/DejaVu/LICENSE create mode 100644 extra/images/linux/code-file-with-highlight.png create mode 100644 extra/images/logo.png create mode 100644 extra/images/logo.svg create mode 100644 extra/images/logo_app.svg create mode 100644 extra/images/logo_app_light.svg create mode 100644 extra/images/logo_color.svg create mode 100644 extra/images/screenshot.png create mode 100644 extra/images/volt.png create mode 100644 extra/linux/dev.lapce.lapce.desktop create mode 100644 extra/linux/dev.lapce.lapce.metainfo.xml create mode 100644 extra/linux/docker/alpine/Dockerfile create mode 100644 extra/linux/docker/debian/Dockerfile create mode 100644 extra/linux/docker/fedora/Dockerfile create mode 100644 extra/linux/docker/ubuntu/Dockerfile create mode 100644 extra/macos/Lapce.app/Contents/Info.plist create mode 100644 extra/macos/Lapce.app/Contents/Resources/lapce.icns create mode 100644 extra/proxy.ps1 create mode 100644 extra/proxy.sh create mode 100644 extra/schemas/color-theme.json create mode 100644 extra/schemas/icon-theme.json create mode 100644 extra/schemas/settings.json create mode 100644 extra/windows/lapce.ico create mode 100644 extra/windows/wix/lapce.wxs create mode 100644 extra/windows/wix/license.rtf create mode 100644 icons/codicons/LICENSE create mode 100644 icons/codicons/README.md create mode 100644 icons/codicons/add.svg create mode 100644 icons/codicons/arrow-both.svg create mode 100644 icons/codicons/arrow-down.svg create mode 100644 icons/codicons/arrow-left.svg create mode 100644 icons/codicons/arrow-right.svg create mode 100644 icons/codicons/arrow-swap.svg create mode 100644 icons/codicons/arrow-up.svg create mode 100644 icons/codicons/blank.svg create mode 100644 icons/codicons/case-sensitive.svg create mode 100644 icons/codicons/chevron-down.svg create mode 100644 icons/codicons/chevron-left.svg create mode 100644 icons/codicons/chevron-right.svg create mode 100644 icons/codicons/chevron-up.svg create mode 100644 icons/codicons/chrome-close.svg create mode 100644 icons/codicons/chrome-maximize.svg create mode 100644 icons/codicons/chrome-minimize.svg create mode 100644 icons/codicons/chrome-restore.svg create mode 100644 icons/codicons/circle-filled.svg create mode 100644 icons/codicons/close.svg create mode 100644 icons/codicons/combine.svg create mode 100644 icons/codicons/debug-alt-small.svg create mode 100644 icons/codicons/debug-alt.svg create mode 100644 icons/codicons/debug-console.svg create mode 100644 icons/codicons/debug-continue.svg create mode 100644 icons/codicons/debug-disconnect.svg create mode 100644 icons/codicons/debug-pause.svg create mode 100644 icons/codicons/debug-restart.svg create mode 100644 icons/codicons/debug-start.svg create mode 100644 icons/codicons/debug-step-into.svg create mode 100644 icons/codicons/debug-step-out.svg create mode 100644 icons/codicons/debug-step-over.svg create mode 100644 icons/codicons/debug-stop.svg create mode 100644 icons/codicons/debug.svg create mode 100644 icons/codicons/diff-added.svg create mode 100644 icons/codicons/diff-ignored.svg create mode 100644 icons/codicons/diff-modified.svg create mode 100644 icons/codicons/diff-removed.svg create mode 100644 icons/codicons/diff-renamed.svg create mode 100644 icons/codicons/diff.svg create mode 100644 icons/codicons/discard.svg create mode 100644 icons/codicons/edit.svg create mode 100644 icons/codicons/error.svg create mode 100644 icons/codicons/extensions.svg create mode 100644 icons/codicons/file-binary.svg create mode 100644 icons/codicons/file-code.svg create mode 100644 icons/codicons/file-media.svg create mode 100644 icons/codicons/file-pdf.svg create mode 100644 icons/codicons/file-submodule.svg create mode 100644 icons/codicons/file-symlink-directory.svg create mode 100644 icons/codicons/file-symlink-file.svg create mode 100644 icons/codicons/file-zip.svg create mode 100644 icons/codicons/file.svg create mode 100644 icons/codicons/files.svg create mode 100644 icons/codicons/fold-down.svg create mode 100644 icons/codicons/fold-up.svg create mode 100644 icons/codicons/fold.svg create mode 100644 icons/codicons/folder-active.svg create mode 100644 icons/codicons/folder-library.svg create mode 100644 icons/codicons/folder-opened.svg create mode 100644 icons/codicons/folder.svg create mode 100644 icons/codicons/gear.svg create mode 100644 icons/codicons/git-commit.svg create mode 100644 icons/codicons/git-compare.svg create mode 100644 icons/codicons/git-merge.svg create mode 100644 icons/codicons/go-to-file.svg create mode 100644 icons/codicons/group-by-ref-type.svg create mode 100644 icons/codicons/history.svg create mode 100644 icons/codicons/info.svg create mode 100644 icons/codicons/inspect.svg create mode 100644 icons/codicons/issues.svg create mode 100644 icons/codicons/json.svg create mode 100644 icons/codicons/key.svg create mode 100644 icons/codicons/keyboard.svg create mode 100644 icons/codicons/layout-activitybar-left.svg create mode 100644 icons/codicons/layout-activitybar-right.svg create mode 100644 icons/codicons/layout-centered.svg create mode 100644 icons/codicons/layout-menubar.svg create mode 100644 icons/codicons/layout-panel-center.svg create mode 100644 icons/codicons/layout-panel-justify.svg create mode 100644 icons/codicons/layout-panel-left.svg create mode 100644 icons/codicons/layout-panel-off.svg create mode 100644 icons/codicons/layout-panel-right.svg create mode 100644 icons/codicons/layout-panel.svg create mode 100644 icons/codicons/layout-sidebar-left-off.svg create mode 100644 icons/codicons/layout-sidebar-left.svg create mode 100644 icons/codicons/layout-sidebar-right-off.svg create mode 100644 icons/codicons/layout-sidebar-right.svg create mode 100644 icons/codicons/layout-statusbar.svg create mode 100644 icons/codicons/layout.svg create mode 100644 icons/codicons/lightbulb-autofix.svg create mode 100644 icons/codicons/lightbulb.svg create mode 100644 icons/codicons/link-external.svg create mode 100644 icons/codicons/link.svg create mode 100644 icons/codicons/menu.svg create mode 100644 icons/codicons/merge.svg create mode 100644 icons/codicons/multiple-windows.svg create mode 100644 icons/codicons/new-file.svg create mode 100644 icons/codicons/new-folder.svg create mode 100644 icons/codicons/open-preview.svg create mode 100644 icons/codicons/plugin-icon.svg create mode 100644 icons/codicons/references.svg create mode 100644 icons/codicons/refresh.svg create mode 100644 icons/codicons/regex.svg create mode 100644 icons/codicons/remote-explorer.svg create mode 100644 icons/codicons/remote.svg create mode 100644 icons/codicons/remove.svg create mode 100644 icons/codicons/replace-all.svg create mode 100644 icons/codicons/replace.svg create mode 100644 icons/codicons/repo-clone.svg create mode 100644 icons/codicons/repo-force-push.svg create mode 100644 icons/codicons/repo-forked.svg create mode 100644 icons/codicons/repo-pull.svg create mode 100644 icons/codicons/repo-push.svg create mode 100644 icons/codicons/repo.svg create mode 100644 icons/codicons/root-folder-opened.svg create mode 100644 icons/codicons/root-folder.svg create mode 100644 icons/codicons/run-errors.svg create mode 100644 icons/codicons/screen-full.svg create mode 100644 icons/codicons/screen-normal.svg create mode 100644 icons/codicons/search-stop.svg create mode 100644 icons/codicons/search.svg create mode 100644 icons/codicons/settings-gear.svg create mode 100644 icons/codicons/settings.svg create mode 100644 icons/codicons/source-control.svg create mode 100644 icons/codicons/split-horizontal.svg create mode 100644 icons/codicons/split-vertical.svg create mode 100644 icons/codicons/symbol-array.svg create mode 100644 icons/codicons/symbol-boolean.svg create mode 100644 icons/codicons/symbol-class.svg create mode 100644 icons/codicons/symbol-color.svg create mode 100644 icons/codicons/symbol-constant.svg create mode 100644 icons/codicons/symbol-enum-member.svg create mode 100644 icons/codicons/symbol-enum.svg create mode 100644 icons/codicons/symbol-event.svg create mode 100644 icons/codicons/symbol-field.svg create mode 100644 icons/codicons/symbol-file.svg create mode 100644 icons/codicons/symbol-interface.svg create mode 100644 icons/codicons/symbol-key.svg create mode 100644 icons/codicons/symbol-keyword.svg create mode 100644 icons/codicons/symbol-method.svg create mode 100644 icons/codicons/symbol-misc.svg create mode 100644 icons/codicons/symbol-namespace.svg create mode 100644 icons/codicons/symbol-numeric.svg create mode 100644 icons/codicons/symbol-operator.svg create mode 100644 icons/codicons/symbol-parameter.svg create mode 100644 icons/codicons/symbol-property.svg create mode 100644 icons/codicons/symbol-ruler.svg create mode 100644 icons/codicons/symbol-snippet.svg create mode 100644 icons/codicons/symbol-string.svg create mode 100644 icons/codicons/symbol-structure.svg create mode 100644 icons/codicons/symbol-variable.svg create mode 100644 icons/codicons/terminal.svg create mode 100644 icons/codicons/type-hierarchy.svg create mode 100644 icons/codicons/unsaved.svg create mode 100644 icons/codicons/warning.svg create mode 100644 icons/codicons/whole-word.svg create mode 100644 icons/lapce/lapce_logo.svg create mode 100644 icons/lapce/lapce_remote.svg create mode 100644 lapce-app/Cargo.toml create mode 100644 lapce-app/benches/visual_line.rs create mode 100644 lapce-app/src/about.rs create mode 100644 lapce-app/src/alert.rs create mode 100644 lapce-app/src/app.rs create mode 100644 lapce-app/src/app/grammars.rs create mode 100644 lapce-app/src/app/logging.rs create mode 100644 lapce-app/src/bin/lapce.rs create mode 100644 lapce-app/src/code_action.rs create mode 100644 lapce-app/src/code_lens.rs create mode 100644 lapce-app/src/command.rs create mode 100644 lapce-app/src/completion.rs create mode 100644 lapce-app/src/config.rs create mode 100644 lapce-app/src/config/color.rs create mode 100644 lapce-app/src/config/color_theme.rs create mode 100644 lapce-app/src/config/core.rs create mode 100644 lapce-app/src/config/editor.rs create mode 100644 lapce-app/src/config/icon.rs create mode 100644 lapce-app/src/config/icon_theme.rs create mode 100644 lapce-app/src/config/svg.rs create mode 100644 lapce-app/src/config/terminal.rs create mode 100644 lapce-app/src/config/ui.rs create mode 100644 lapce-app/src/config/watcher.rs create mode 100644 lapce-app/src/db.rs create mode 100644 lapce-app/src/debug.rs create mode 100644 lapce-app/src/doc.rs create mode 100644 lapce-app/src/editor.rs create mode 100644 lapce-app/src/editor/diff.rs create mode 100644 lapce-app/src/editor/gutter.rs create mode 100644 lapce-app/src/editor/location.rs create mode 100644 lapce-app/src/editor/view.rs create mode 100644 lapce-app/src/editor_tab.rs create mode 100644 lapce-app/src/file_explorer/data.rs create mode 100644 lapce-app/src/file_explorer/mod.rs create mode 100644 lapce-app/src/file_explorer/node.rs create mode 100644 lapce-app/src/file_explorer/view.rs create mode 100644 lapce-app/src/find.rs create mode 100644 lapce-app/src/focus_text.rs create mode 100644 lapce-app/src/global_search.rs create mode 100644 lapce-app/src/history.rs create mode 100644 lapce-app/src/hover.rs create mode 100644 lapce-app/src/id.rs create mode 100644 lapce-app/src/inline_completion.rs create mode 100644 lapce-app/src/keymap.rs create mode 100644 lapce-app/src/keypress.rs create mode 100644 lapce-app/src/keypress/condition.rs create mode 100644 lapce-app/src/keypress/key.rs create mode 100644 lapce-app/src/keypress/keymap.rs create mode 100644 lapce-app/src/keypress/loader.rs create mode 100644 lapce-app/src/keypress/press.rs create mode 100644 lapce-app/src/lib.rs create mode 100644 lapce-app/src/listener.rs create mode 100644 lapce-app/src/lsp.rs create mode 100644 lapce-app/src/main_split.rs create mode 100644 lapce-app/src/markdown.rs create mode 100644 lapce-app/src/palette.rs create mode 100644 lapce-app/src/palette/item.rs create mode 100644 lapce-app/src/palette/kind.rs create mode 100644 lapce-app/src/panel/call_hierarchy_view.rs create mode 100644 lapce-app/src/panel/data.rs create mode 100644 lapce-app/src/panel/debug_view.rs create mode 100644 lapce-app/src/panel/document_symbol.rs create mode 100644 lapce-app/src/panel/global_search_view.rs create mode 100644 lapce-app/src/panel/implementation_view.rs create mode 100644 lapce-app/src/panel/kind.rs create mode 100644 lapce-app/src/panel/mod.rs create mode 100644 lapce-app/src/panel/plugin_view.rs create mode 100644 lapce-app/src/panel/position.rs create mode 100644 lapce-app/src/panel/problem_view.rs create mode 100644 lapce-app/src/panel/references_view.rs create mode 100644 lapce-app/src/panel/source_control_view.rs create mode 100644 lapce-app/src/panel/style.rs create mode 100644 lapce-app/src/panel/terminal_view.rs create mode 100644 lapce-app/src/panel/view.rs create mode 100644 lapce-app/src/plugin.rs create mode 100644 lapce-app/src/proxy.rs create mode 100644 lapce-app/src/proxy/remote.rs create mode 100644 lapce-app/src/proxy/ssh.rs create mode 100644 lapce-app/src/proxy/wsl.rs create mode 100644 lapce-app/src/rename.rs create mode 100644 lapce-app/src/settings.rs create mode 100644 lapce-app/src/snippet.rs create mode 100644 lapce-app/src/source_control.rs create mode 100644 lapce-app/src/status.rs create mode 100644 lapce-app/src/terminal/data.rs create mode 100644 lapce-app/src/terminal/event.rs create mode 100644 lapce-app/src/terminal/mod.rs create mode 100644 lapce-app/src/terminal/panel.rs create mode 100644 lapce-app/src/terminal/raw.rs create mode 100644 lapce-app/src/terminal/tab.rs create mode 100644 lapce-app/src/terminal/view.rs create mode 100644 lapce-app/src/text_area.rs create mode 100644 lapce-app/src/text_input.rs create mode 100644 lapce-app/src/title.rs create mode 100644 lapce-app/src/tracing.rs create mode 100644 lapce-app/src/update.rs create mode 100644 lapce-app/src/wave.rs create mode 100644 lapce-app/src/web_link.rs create mode 100644 lapce-app/src/window.rs create mode 100644 lapce-app/src/window_tab.rs create mode 100644 lapce-app/src/workspace.rs create mode 100644 lapce-core/Cargo.toml create mode 100644 lapce-core/build.rs create mode 100644 lapce-core/src/directory.rs create mode 100644 lapce-core/src/encoding.rs create mode 100644 lapce-core/src/language.rs create mode 100644 lapce-core/src/lens.rs create mode 100644 lapce-core/src/lib.rs create mode 100644 lapce-core/src/meta.rs create mode 100644 lapce-core/src/rope_text_pos.rs create mode 100644 lapce-core/src/style.rs create mode 100644 lapce-core/src/syntax/edit.rs create mode 100644 lapce-core/src/syntax/highlight.rs create mode 100644 lapce-core/src/syntax/mod.rs create mode 100644 lapce-core/src/syntax/util.rs create mode 100644 lapce-proxy/Cargo.toml create mode 100644 lapce-proxy/src/bin/lapce-proxy.rs create mode 100644 lapce-proxy/src/buffer.rs create mode 100644 lapce-proxy/src/cli.rs create mode 100644 lapce-proxy/src/dispatch.rs create mode 100644 lapce-proxy/src/lib.rs create mode 100644 lapce-proxy/src/plugin/catalog.rs create mode 100644 lapce-proxy/src/plugin/dap.rs create mode 100644 lapce-proxy/src/plugin/lsp.rs create mode 100644 lapce-proxy/src/plugin/mod.rs create mode 100644 lapce-proxy/src/plugin/psp.rs create mode 100644 lapce-proxy/src/plugin/wasi.rs create mode 100644 lapce-proxy/src/plugin/wasi/plugins/smiley.png create mode 100644 lapce-proxy/src/plugin/wasi/plugins/some_author.test-plugin-one/Dark.svg create mode 100644 lapce-proxy/src/plugin/wasi/plugins/some_author.test-plugin-one/Dark.toml create mode 100644 lapce-proxy/src/plugin/wasi/plugins/some_author.test-plugin-one/Light.svg create mode 100644 lapce-proxy/src/plugin/wasi/plugins/some_author.test-plugin-one/Light.toml create mode 100644 lapce-proxy/src/plugin/wasi/plugins/some_author.test-plugin-one/lapce.wasm create mode 100644 lapce-proxy/src/plugin/wasi/plugins/some_author.test-plugin-one/volt.toml create mode 100644 lapce-proxy/src/plugin/wasi/plugins/some_author.test-plugin-three/volt.toml create mode 100644 lapce-proxy/src/plugin/wasi/plugins/some_author.test-plugin-two/Light.svg create mode 100644 lapce-proxy/src/plugin/wasi/plugins/some_author.test-plugin-two/Light.toml create mode 100644 lapce-proxy/src/plugin/wasi/plugins/some_author.test-plugin-two/lapce.wasm create mode 100644 lapce-proxy/src/plugin/wasi/plugins/some_author.test-plugin-two/volt.toml create mode 100644 lapce-proxy/src/plugin/wasi/tests.rs create mode 100644 lapce-proxy/src/terminal.rs create mode 100644 lapce-proxy/src/watcher.rs create mode 100644 lapce-rpc/Cargo.toml create mode 100644 lapce-rpc/src/buffer.rs create mode 100644 lapce-rpc/src/core.rs create mode 100644 lapce-rpc/src/counter.rs create mode 100644 lapce-rpc/src/dap_types.rs create mode 100644 lapce-rpc/src/file.rs create mode 100644 lapce-rpc/src/file_line.rs create mode 100644 lapce-rpc/src/lib.rs create mode 100644 lapce-rpc/src/parse.rs create mode 100644 lapce-rpc/src/plugin.rs create mode 100644 lapce-rpc/src/proxy.rs create mode 100644 lapce-rpc/src/source_control.rs create mode 100644 lapce-rpc/src/stdio.rs create mode 100644 lapce-rpc/src/style.rs create mode 100644 lapce-rpc/src/terminal.rs create mode 100644 lapce.spec diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..829d53f --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,8 @@ +# Link runtime statically so Visual C++ Redist is not required +[target.'cfg(all(windows, target_env = "msvc"))'] +rustflags = ["-C", "target-feature=+crt-static"] + +[profile.ci] +inherits = "dev" +opt-level = 0 +debug = false diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..55ee7ab --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,10 @@ +{ + "image": "ghcr.io/lapce/lapdev-devcontainer-lapce", + "forwardPorts": [6080], + "portsAttributes": { + "6080": { + "label": "VNC", + } + } +} + diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..1f1fcb5 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,9 @@ +.github +.vscode +.lapce +docs +extra/linux/docker +extra/macos +extra/windows +target +lapce.spec diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..96b3553 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,9 @@ +# Auto detect text files and perform normalization +* text=auto eol=lf + +*.rs text diff=rust eol=lf +*.toml text diff=toml eol=lf +Cargo.lock text eol=lf + +*.sh text eol=lf +*.ps1 text eol=crlf diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..2dad458 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,29 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: 'C-bug' +assignees: '' + +--- + +## Lapce Version + +The Lapce version you are using, which can be found in "About Lapce" at the top right settings icon. + +## System information + +the operating system used, including its version, e.g. Windows 10, Ubuntu 18.04 + +## Describe the bug +A clear and concise description of what the bug is. + +## Additional information + +Other information that can be used to further reproduce or isolate the problem. +This commonly includes: + +- screenshots +- logs +- theories about what might be going wrong +- workarounds that you used diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..aac61aa --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,11 @@ +blank_issues_enabled: false +contact_links: + - name: Lapce community on Discord + url: https://discord.gg/n8tGJ6Rn6D + about: Please ask and answer questions here. + - name: Lapce community on Matrix + url: https://matrix.to/#/#lapce-editor:matrix.org + about: Please ask and answer questions here. + - name: Lapce documentation + url: https://docs.lapce.dev/ + about: Documentation for Lapce diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..2464024 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,24 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: 'C-feature' +assignees: '' + +--- + +## Is your feature request related to a problem? Please describe. + +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +## Describe the solution you'd like + +A clear and concise description of what you want to happen. + +## Describe alternatives you've considered + +A clear and concise description of any alternative solutions or features you've considered. + +## Additional context + +Add any other context or screenshots about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..e3e1d64 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1 @@ +- [ ] Added an entry to `CHANGELOG.md` if this change could be valuable to users \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..f1d5314 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,52 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + groups: + all-dependencies: + patterns: + - "*" + - package-ecosystem: "cargo" + directory: "/" + open-pull-requests-limit: 10 + schedule: + interval: "monthly" + groups: + all-dependencies: + patterns: + - "*" + exclude-patterns: + - "wasmtime*" + - "wasi-common" + - "wasi-experimental-http-wasmtime" + - "tracing*" + - "strum*" + - "tree-sitter" + - "floem*" + wasmtime: + patterns: + - "wasmtime*" + - "wasi-common" + - "wasi-experimental-http-wasmtime" + toml: + patterns: + - "toml" + - "toml_edit" + strum: + patterns: + - "strum" + - "strum_macros" + tracing: + patterns: + - "tracing*" + floem: + patterns: + - "floem*" + tree-sitter: + patterns: + - "tree-sitter" + windows: + patterns: + - "windows*" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..8a168ff --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,119 @@ +on: + push: + branches: + - master + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + paths: + - Cargo.toml + - Cargo.lock + - lapce-** + - .github/workflows/ci.yml + workflow_dispatch: + +name: CI + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +env: + CARGO_TERM_COLOR: always + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse + +permissions: {} + +jobs: + build: + name: Rust on ${{ matrix.os }} + if: github.event.pull_request.draft == false + needs: [fmt, clippy] + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.os }} + permissions: + contents: read + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + + - name: Install dependencies on Ubuntu + if: startsWith(matrix.os, 'ubuntu') + run: sudo make ubuntu-deps + + - name: Update toolchain + run: | + rustup update --no-self-update + + - name: Cache Rust dependencies + uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 + + - name: Fetch dependencies + run: cargo fetch --locked + + - name: Build + run: cargo build --profile ci --frozen + + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f + with: + name: lapce-${{ matrix.os }} + path: | + target/ci/lapce* + retention-days: 1 + + - name: Build as portable + if: startsWith(matrix.os, 'windows') + run: cargo build --profile ci --frozen --features lapce-app/portable + + - name: Free space on Windows + if: startsWith(matrix.os, 'windows') + run: cargo clean + + - name: Run doc tests + run: cargo test --profile ci --doc --workspace + + fmt: + name: Formatting and spellchecking + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + + - name: Update toolchain & add rustfmt + run: | + rustup update + rustup component add rustfmt + + - name: Run rustfmt + run: cargo fmt --all --check + + - name: Spell Check Repo + uses: crate-ci/typos@02ea592e44b3a53c302f697cddca7641cd051c3d + + clippy: + name: Clippy on ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + + - name: Update toolchain & add clippy + run: | + rustup update --no-self-update + rustup component add clippy + + - name: Install dependencies on Ubuntu + if: startsWith(matrix.os, 'ubuntu') + run: sudo make ubuntu-deps + + - name: Cache Rust dependencies + uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 + + - name: Fetch dependencies + run: cargo fetch --locked + + - name: Run clippy + run: cargo clippy --profile ci diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..438d5a6 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,378 @@ +name: Release + +on: + schedule: + - cron: 0 0 * * * + workflow_dispatch: + inputs: + tag_name: + description: "Tag name for release" + required: false + default: nightly + push: + tags: ["v[0-9]+.[0-9]+.[0-9]+*"] + pull_request: + paths: + # trigger release workflow only if this file changed + - .github/workflows/release.yml + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CARGO_TERM_COLOR: always + +permissions: {} + +jobs: + tagname: + runs-on: ubuntu-latest + outputs: + tag_name: ${{ steps.tag.outputs.tag }} + steps: + - id: vars + shell: bash + run: echo "sha_short=${GITHUB_SHA::7}" | tee -a $GITHUB_OUTPUT + + - if: github.event_name == 'workflow_dispatch' + run: echo "TAG_NAME=${{ github.event.inputs.tag_name }}" | tee -a $GITHUB_ENV + + - if: github.event_name == 'schedule' || github.event_name == 'pull_request' + run: echo 'TAG_NAME=nightly-${{ steps.vars.outputs.sha_short }}' | tee -a $GITHUB_ENV + + - if: github.event_name == 'push' + run: | + TAG_NAME=${{ github.ref }} + echo "TAG_NAME=${TAG_NAME#refs/tags/}" | tee -a $GITHUB_ENV + + - id: tag + run: echo "tag=$TAG_NAME" | tee -a $GITHUB_OUTPUT + + windows: + runs-on: windows-latest + needs: tagname + env: + RELEASE_TAG_NAME: ${{ needs.tagname.outputs.tag_name }} + defaults: + run: + shell: bash + permissions: + contents: read + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + + - name: Update rust + run: rustup update --no-self-update + + - name: Fetch dependencies + run: cargo fetch --locked + + - name: Build + run: cargo build --frozen --profile release-lto + + - name: Crate msi installer + run: | + candle.exe -arch "x64" -ext WixUIExtension -ext WixUtilExtension \ + -out "./lapce.wixobj" "extra/windows/wix/lapce.wxs" + + light.exe -ext WixUIExtension -ext WixUtilExtension \ + -out "./Lapce-windows.msi" -sice:ICE61 -sice:ICE91 \ + "./lapce.wixobj" + + - name: Create portable + shell: pwsh + run: | + cargo build --profile release-lto --features lapce-app/portable + Compress-Archive ./target/release-lto/lapce.exe ./Lapce-windows-portable.zip + + - name: Create lapce-proxy archive + shell: pwsh + run: | + $file = [System.IO.File]::Open((Join-Path $PWD '.\target\release-lto\lapce-proxy.exe'), [System.IO.FileMode]::Open) + $archive = [System.IO.File]::Create((Join-Path $PWD '.\lapce-proxy-windows-x86_64.gz')) + $compressor = [System.IO.Compression.GZipStream]::new($archive, [System.IO.Compression.CompressionMode]::Compress) + $file.CopyTo($compressor) + Start-Sleep -Seconds 10 + $compressor.close() + + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f + with: + name: lapce-windows + path: | + ./lapce-proxy-windows-*.gz + ./Lapce-windows-portable.zip + ./Lapce-windows.msi + retention-days: 1 + + linux: + runs-on: ubuntu-latest + needs: tagname + env: + RELEASE_TAG_NAME: ${{ needs.tagname.outputs.tag_name }} + permissions: + contents: read + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + - name: Build deb packages + run: | + docker buildx create --driver=docker-container --use + docker buildx bake --pull ubuntu-focal-binary + + - name: Gzip + run: | + mkdir Lapce + cp ./target/linux_amd64/lapce Lapce/ + tar -zcvf ./lapce-linux-amd64.tar.gz Lapce + + rm -rf Lapce + + mkdir Lapce + cp ./target/linux_arm64/lapce Lapce/ + tar -zcvf ./lapce-linux-arm64.tar.gz Lapce + + - name: Fetch dependencies + run: cargo fetch --locked + + - name: Vendor dependencies + run: | + cargo vendor --frozen > ./vendor-config.toml + mv ./vendor-config.toml ./vendor/ + tar -zcf vendor.tar.gz ./vendor/ + + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f + with: + name: lapce-linux + path: | + ./lapce-linux-*.tar.gz + ./vendor.tar.gz + retention-days: 1 + + deb: + runs-on: ubuntu-latest + needs: tagname + env: + RELEASE_TAG_NAME: ${{ needs.tagname.outputs.tag_name }} + permissions: + contents: read + strategy: + fail-fast: false + matrix: + include: + - os-name: debian + os-version: bookworm + - os-name: debian + os-version: bullseye + - os-name: ubuntu + os-version: jammy + - os-name: ubuntu + os-version: noble + - os-name: ubuntu + os-version: plucky + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + + - name: Build deb packages + run: | + docker buildx create --driver=docker-container --use + docker buildx bake --pull ${{ matrix.os-name }}-${{ matrix.os-version }}-package + + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f + with: + name: lapce-${{ matrix.os-name }}-${{ matrix.os-version }} + path: | + ./target/linux_*/* + retention-days: 1 + + rpm: + runs-on: ubuntu-latest + needs: tagname + env: + RELEASE_TAG_NAME: ${{ needs.tagname.outputs.tag_name }} + permissions: + contents: read + strategy: + fail-fast: false + matrix: + include: + - os-name: fedora + os-version: 42 + - os-name: fedora + os-version: 43 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + + - name: Build rpm packages + run: | + docker buildx create --driver=docker-container --use + docker buildx bake --pull ${{ matrix.os-name }}-${{ matrix.os-version }}-package + + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f + with: + name: lapce-${{ matrix.os-name }}-${{ matrix.os-version }} + path: | + ./target/* + retention-days: 1 + + lapce-proxy: + runs-on: ubuntu-latest + needs: tagname + env: + RELEASE_TAG_NAME: ${{ needs.tagname.outputs.tag_name }} + permissions: + contents: read + strategy: + fail-fast: false + matrix: + include: + - os-name: alpine + os-version: "" # uses latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + + - name: Set up QEMU + uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a + + - name: Build lapce-proxy binary + run: | + docker buildx create --driver=docker-container --use + docker buildx bake --pull ${{ matrix.os-name }}-${{ matrix.os-version }} + + - name: Gzip + run: | + gzip -c ./target/linux_amd64/lapce-proxy > ./lapce-proxy-linux-x86_64.gz + gzip -c ./target/linux_arm64/lapce-proxy > ./lapce-proxy-linux-aarch64.gz + + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f + with: + name: lapce-proxy-linux + path: | + ./lapce-proxy-linux-*.gz + retention-days: 1 + + macos: + runs-on: macos-15 + needs: tagname + env: + RELEASE_TAG_NAME: ${{ needs.tagname.outputs.tag_name }} + + NOTARIZE_USERNAME: ${{ secrets.NOTARIZE_USERNAME }} + NOTARIZE_PASSWORD: ${{ secrets.NOTARIZE_PASSWORD }} + permissions: + contents: read + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + + - name: Install ARM target + run: rustup update && rustup target add x86_64-apple-darwin + + - name: Import Certificate + uses: Apple-Actions/import-codesign-certs@b610f78488812c1e56b20e6df63ec42d833f2d14 + with: + p12-file-base64: ${{ secrets.MACOS_CERTIFICATE }} + p12-password: ${{ secrets.MACOS_CERTIFICATE_PWD }} + + - name: Fetch dependencies + run: cargo fetch --locked + + - name: Make DMG + run: make dmg-universal + + - name: Rename + run: | + cp ./target/release-lto/macos/Lapce.dmg ./target/release-lto/macos/Lapce-macos.dmg + + - name: Gzip lapce-proxy + run: | + gzip -c ./target/x86_64-apple-darwin/release-lto/lapce-proxy > ./target/release-lto/macos/lapce-proxy-darwin-x86_64.gz + gzip -c ./target/aarch64-apple-darwin/release-lto/lapce-proxy > ./target/release-lto/macos/lapce-proxy-darwin-aarch64.gz + + - name: Notarize Release Build + uses: lando/notarize-action@b5c3ef16cf2fbcf2af26dc58c90255ec242abeed + with: + product-path: "./target/release-lto/macos/Lapce-macos.dmg" + appstore-connect-username: ${{ secrets.NOTARIZE_USERNAME }} + appstore-connect-password: ${{ secrets.NOTARIZE_PASSWORD }} + appstore-connect-team-id: CYSGAZFR8D + primary-bundle-id: "io.lapce" + verbose: true + + - name: "Staple Release Build" + uses: lapce/xcode-staple@062485d6eeafe841c18a412f012e80f49e23c517 + with: + product-path: "./target/release-lto/macos/Lapce-macos.dmg" + + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f + with: + name: lapce-macos + path: | + ./target/release-lto/macos/lapce-proxy-darwin-*.gz + ./target/release-lto/macos/Lapce-macos.dmg + retention-days: 3 + + publish: + needs: + - linux + - lapce-proxy + - deb + - rpm + - windows + - macos + runs-on: ubuntu-latest + env: + GH_REPO: ${{ github.repository }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + permissions: + contents: write + steps: + # Must perform checkout first, since it deletes the target directory + # before running, and would therefore delete the downloaded artifacts + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c + + - if: github.event_name == 'workflow_dispatch' + run: echo "TAG_NAME=${{ github.event.inputs.tag_name }}" | tee -a $GITHUB_ENV + + - if: github.event_name == 'schedule' + run: echo 'TAG_NAME=nightly' | tee -a $GITHUB_ENV + + - if: github.event_name == 'push' + run: | + TAG_NAME=${{ github.ref }} + echo "TAG_NAME=${TAG_NAME#refs/tags/}" | tee -a $GITHUB_ENV + + - if: env.TAG_NAME == 'nightly' + run: | + { + echo 'SUBJECT=Lapce development build' + echo 'PRERELEASE=--prerelease' + } | tee -a $GITHUB_ENV + + - if: env.TAG_NAME == 'nightly' && github.event_name != 'pull_request' + name: Re-Tag nightly + run: | + gh release delete nightly --yes || true + git push origin :nightly || true + + - if: env.TAG_NAME != 'nightly' + run: | + { + echo 'SUBJECT=Lapce release build' + echo 'PRERELEASE=' + } | tee -a $GITHUB_ENV + + - name: Publish release + if: github.event_name != 'pull_request' + env: + DEBUG: api + run: | + gh release create $TAG_NAME $PRERELEASE --title "$TAG_NAME" --target $GITHUB_SHA \ + lapce-macos/* \ + lapce-linux/* \ + lapce-debian*/*/* \ + lapce-ubuntu*/*/* \ + lapce-fedora*/* \ + lapce-proxy-linux/* \ + lapce-windows/* diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fc7a859 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +.vscode +.lapce +.idea +.fleet +shell.nix +lib/ +target/ +core/languages/ +vendor/ + +.DS_Store +*.patch +*.tar +*.gz diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index 0000000..06900d0 --- /dev/null +++ b/.rustfmt.toml @@ -0,0 +1,4 @@ +max_width = 85 +# below requires nightly +# imports_granularity = "Crate" +# group_imports = "StdExternalCrate" diff --git a/.taplo.toml b/.taplo.toml new file mode 100644 index 0000000..ee911f0 --- /dev/null +++ b/.taplo.toml @@ -0,0 +1,13 @@ +include = ["**/*.toml"] +exclude = ["lapce-proxy/src/**"] + +[[rule]] +include = ["**/Cargo.toml", ".taplo.toml", "Cargo.toml"] + +[rule.formatting] +align_entries = true +align_comments = true +array_trailing_comma = true +trailing_newline = true +column_width = 100 +inline_table_expand = false diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..f885a95 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,416 @@ +# Changelog + +## Unreleased + +### Features/Changes + +### Bug Fixes + +## 0.4.6 + +### Features/Changes + +- Add `.har` file extension as recognised JSON language () +- Remove builds for Ubuntu Oracular, add Ubuntu Plucky () + +### Bug Fixes + +- Fix mouse wheel scrolling when viewing diff () +- Fix editor tabs not selectable while appearing selectable () +- Fix flickering when reordering editor tabs () +- Fix diff viewer to scroll using mouse () +- Fix updating window scale when it changes via settings tab () +- Fix vendor tarball not being included in GitHub release +- Fix cursor style inconsistencies () + +## 0.4.5 + +### Bug Fixes + +- Fix missing/incorrect metadata for Linux packages using AppStream metainfo +- Fix incorrect version in macOS/Windows package metadata +- Fix rendering issues when using custom scale display () + +## 0.4.4 + +### Features/Changes + +- Update Fedora releases to use 41/42 +- Update Alpine to latest (used for building portable lapce-proxy) +- Remove Ubuntu Focal (20.04) + +### Bug Fixes + +- Fix dropdown menu disappearing after releasing mouse button () +- Fix issue with cargo vendoring due to duplicate `dpi` crate + +## 0.4.3 + +### Features/Changes + +- Add Ubuntu 24.04 LTS (noble) build +- Use Diff syntax for files with .diff/.patch extensions by default. +- Update titles of file dialogs for better clarity +- Bump to Rust 2024 Edition +- Implement "Find References" panel +- Implement "Go To Implementation" panel + +### Bug Fixes + +- Fix pointer event not working on plugin panel +- Fix rename/new file editor in file explorer is too small + +## 0.4.2 + +### Features/Changes + +- Implement "Run in terminal" +- Implement document symbols in a panel +- Implement "Go To Location" functionality in the Diff editor. +- Implement on screen find which is similar to `f` in vim but for the whole screen. +- Make file explorer horizontal scrollable +- Implement "Reveal in system file explorer" + +### Bug Fixes + +- Fix markdown syntax highlighting +- Fix click issue on window error message + +## 0.4.1 + +### Features/Changes + +- Add fedora builds +- Finish tree sitter dynamic library support by downloading from https://github.com/lapce/tree-sitter-grammars +- Saves scale configuration in settings to restore at startup +- text in ui can be selected and copied +- add right click context menu for editor tab +- terminal: added support for Alt+ some character input +- Terminal: right-click to add "clear all" function +- terminal: double-click to maximize bottom +- initial lsp code lens support for rust-analyzer +- Context menu for "reveal file in explorer" +- support rust-analyzer's notification "experimental/serverStatus" +- jump to definition support in Inlay Hints +- "Show Call Hierarchy" support +- Add proxy support and retry to all HTTPS GET requests. +- Implement the drag-and-drop to open file/folder + +### Bug Fixes + +- [#3203](https://github.com/lapce/lapce/pull/3203): Fallback to default theme is theme key is not found +- use windows subsystem to prevent console running +- reimplement gotodefinition on cmd/ctrl+click +- fix crash on tinyskia renderer +- show file status for scratch documents +- fix crash due to locale_config + +## 0.4.0 + +### Features/Changes + +- [#2723](https://github.com/lapce/lapce/pull/2723): Line wrapping based on width (no column-based yet) +- [#1277](https://github.com/lapce/lapce/pull/1277): Error message prompted on missing git user.email and/or user.name +- [#2910](https://github.com/lapce/lapce/pull/2910): Files can be compared in the diff editor +- [#2918](https://github.com/lapce/lapce/pull/2918): Allow searching the shortcuts overview by shortcut (e.g. "Ctrl+P") or when condition (e.g. "list_focus") +- [#2955](https://github.com/lapce/lapce/pull/2955): Using glob patterns to hide files or directories in explorer +- [#3026](https://github.com/lapce/lapce/pull/3026): Add missing file explorer context menu entries +- [#3047](https://github.com/lapce/lapce/pull/3047): Add support for different CrLf/Lf line endings per-file +- [#3053](https://github.com/lapce/lapce/pull/3053): Add tooltips to various places +- [#3069](https://github.com/lapce/lapce/pull/3069): Allow color variables for themes +- [#3086](https://github.com/lapce/lapce/pull/3086): Add folding to panels +- [#3095](https://github.com/lapce/lapce/pull/3095): Add option to hide the Open Editors section in the explorer +- [#3096](https://github.com/lapce/lapce/pull/3096): Add source control status coloring to file explorer +- [#2989](https://github.com/lapce/lapce/pull/2989): Add building packages for linux distros +- [#3123](https://github.com/lapce/lapce/pull/3123): Swap sled to plain text file for db + +### Bug Fixes + +- [#2779](https://github.com/lapce/lapce/pull/2779): Fix files detection on fresh git/VCS repository +- [#3031](https://github.com/lapce/lapce/pull/3031): Fix find not receiving inputs when clicked +- [#3142](https://github.com/lapce/lapce/pull/3142): Fix terminal default profile saving incorrectly +- [#3158](https://github.com/lapce/lapce/pull/3158): Fix ShowHover command for showing hover with keybind +- [#3119](https://github.com/lapce/lapce/pull/3119): Fix non US keyboard layout + +## 0.3.1 + +### Features/Changes + +### Bug Fixes + +- [#2754](https://github.com/lapce/lapce/pull/2754): Don't mark nonexistent files as read only (fix saving new files) +- [#2819](https://github.com/lapce/lapce/issues/2819): `Save Without Formatting` doesn't save the file + +## 0.3.0 + +### Features/Changes + +- [#2190](https://github.com/lapce/lapce/pull/2190): Rewrite with Floem UI +- [#2425](https://github.com/lapce/lapce/pull/2425): Reimplement completion lens +- [#2498](https://github.com/lapce/lapce/pull/2498): Show Lapce as an option when doing "Open With..." on Linux +- [#2549](https://github.com/lapce/lapce/pull/2549): Implement multi-line vim-motion yank and delete (`3dd`, `2yy`, etc.) +- [#2553](https://github.com/lapce/lapce/pull/2553): Implement search and replace +- [#1809](https://github.com/lapce/lapce/pull/1809): Implement debug adapter protocol + +### Bug Fixes + +- [#2650](https://github.com/lapce/lapce/pull/2650): Inform language servers that Lapce supports LSP diagnostics + +## 0.2.8 + +### Features/Changes + +- [#1964](https://github.com/lapce/lapce/pull/1964): Add option to open files at line/column +- [#2403](https://github.com/lapce/lapce/pull/2403): Add basic Vim marks feature + +### Bug Fixes + +## 0.2.7 + +### Features/Changes + +### Bug Fixes + +- [#2209](https://github.com/lapce/lapce/pull/2209): Fix macOS crashes +- [#2228](https://github.com/lapce/lapce/pull/2228): Fix `.desktop` entry to properly associate with Lapce on Wayland + +## 0.2.6 + +### Breaking changes + +- [#1820](https://github.com/lapce/lapce/pull/1820): Add remote svg icon colour to theme, disable plugin settings when none are available +- [#1988](https://github.com/lapce/lapce/pull/1987): Replace modal status background with background/foreground theme keys + +### Features/Changes + +- [#1899](https://github.com/lapce/lapce/pull/1899): Improve sorting files with numbers +- [#1831](https://github.com/lapce/lapce/pull/1831): Plugin settings shown on right click +- [#1830](https://github.com/lapce/lapce/pull/1830): Adds Clojure language support +- [#1835](https://github.com/lapce/lapce/pull/1835): Add mouse keybinds +- [#1856](https://github.com/lapce/lapce/pull/1856): Highlight git/VCS modified files in explorer, palette, and buffer tabs +- [#1574](https://github.com/lapce/lapce/pull/1574): Panel sections can be expanded/collapsed +- [#1938](https://github.com/lapce/lapce/pull/1938): Use dropdown for theme selection in settings +- [#1960](https://github.com/lapce/lapce/pull/1960): Add sticky headers and code lens for PHP +- [#1968](https://github.com/lapce/lapce/pull/1968): Completion lens (disabled by default) + - ![image](https://user-images.githubusercontent.com/13157904/211959283-c3229cfc-28d7-4676-a50d-aec7d47cde9f.png) +- [#1972](https://github.com/lapce/lapce/pull/1972): Add file duplication option in fs tree context menu +- [#1991](https://github.com/lapce/lapce/pull/1991): Implement rendering of images in markdown views +- [#2004](https://github.com/lapce/lapce/pull/2004): Add ToggleHistory command +- [#2033](https://github.com/lapce/lapce/pull/2033): Add setting for double click delay (Currently only works for opening file from the explorer) +- [#2045](https://github.com/lapce/lapce/pull/2045): Add 'Rename Symbol' option on right-click +- [#2071](https://github.com/lapce/lapce/pull/2071): Add command and keybinds to delete line +- [#2073](https://github.com/lapce/lapce/pull/2073): Add Ctrl+{a,e,k} keybinds on macOS +- [#2128](https://github.com/lapce/lapce/pull/2128): Add Lapce app icon to logo collection +- [#2127](https://github.com/lapce/lapce/pull/2127): Extended double-click options with file-only and file + folders mode +- [#1944](https://github.com/lapce/lapce/pull/1944): Add filter input in git branch selection + - ![image](https://user-images.githubusercontent.com/4404609/211232461-293e3b31-4e17-457e-825c-3018699a6fc2.png) + +### Bug Fixes + +- [#1911](https://github.com/lapce/lapce/pull/1911): Fix movement on selections with left/right arrow keys +- [#1939](https://github.com/lapce/lapce/pull/1939): Fix saving/editing newly saved-as files +- [#1971](https://github.com/lapce/lapce/pull/1971): Fix up/down movement on first/last line +- [#2036](https://github.com/lapce/lapce/pull/2036): Fix movement on selections with up/down arrow keys +- [#2056](https://github.com/lapce/lapce/pull/2056): Fix default directory of remote session file picker +- [#2072](https://github.com/lapce/lapce/pull/2072): Fix connection issues from Windows to lapce proxy +- [#2069](https://github.com/lapce/lapce/pull/2045): Fix not finding git repositories in parent path +- [#2131](https://github.com/lapce/lapce/pull/2131): Fix overwriting symlink +- [#2188](https://github.com/lapce/lapce/pull/2188): Fix auto closing matching pairs in inappropriate inputs + +## 0.2.5 + +### Breaking changes + +- [#1726](https://github.com/lapce/lapce/pull/1726): Add more panel theme keys, apply hover first, then current item colour + +### Features/Changes + +- [#1791](https://github.com/lapce/lapce/pull/1791): Add highlighting for scope lines +- [#1767](https://github.com/lapce/lapce/pull/1767): Added CMake tree-sitter syntax highlighting +- [#1759](https://github.com/lapce/lapce/pull/1759): Update C tree-sitter and highlight queries +- [#1758](https://github.com/lapce/lapce/pull/1758): Replaced dlang syntax highlighting +- [#1713](https://github.com/lapce/lapce/pull/1713): Add protobuf syntax and highlighting +- [#1720](https://github.com/lapce/lapce/pull/1720): Display signature/parameter information from LSP +- [#1723](https://github.com/lapce/lapce/pull/1723): In the palette, display the keybind for a command adjacent to it +- [#1722](https://github.com/lapce/lapce/pull/1722): Add 'Save without Formatting'; Add option to disable formatting on autosave +- [#1741](https://github.com/lapce/lapce/pull/1741): Add syntax highlighting for glsl +- [#1756](https://github.com/lapce/lapce/pull/1756): Add support for ssh port with `[user@]host[:port]` +- [#1760](https://github.com/lapce/lapce/pull/1760): Add vim motions `cw`, `ce`, `cc`, `S`, and QOL modal bind `gf` +- [#1770](https://github.com/lapce/lapce/pull/1770): Add support for terminal tabs + +### Bug Fixes + +- [#1771](https://github.com/lapce/lapce/pull/1771): Update tree-sitter-bash +- [#1737](https://github.com/lapce/lapce/pull/1726): Fix an issue that plugins can't be upgraded +- [#1724](https://github.com/lapce/lapce/pull/1724): Files and hidden folders no longer will be considered when trying to open a plugin base folder +- [#1753](https://github.com/lapce/lapce/pull/1753): Limit proxy search response size in order to avoid issues with absurdly long lines +- [#1805](https://github.com/lapce/lapce/pull/1805): Fix some LSP bugs causing code actions to not show up correctly + +## 0.2.4 + +### Features/Changes + +- [#1700](https://github.com/lapce/lapce/pull/1700): Add prisma syntax and highlighting +- [#1702](https://github.com/lapce/lapce/pull/1702): Improved svelte treesitter queries +- [#1690](https://github.com/lapce/lapce/pull/1690): Add codelens and sticky headers for Dart +- [#1711](https://github.com/lapce/lapce/pull/1711): Add zstd support for plugin +- [#1715](https://github.com/lapce/lapce/pull/1715): Add support for requests from plugins + +### Bug Fixes + +- [#1710](https://github.com/lapce/lapce/pull/1710): Fix autosave trying to save scratch files +- [#1709](https://github.com/lapce/lapce/pull/1709): Fix search result ordering +- [#1708](https://github.com/lapce/lapce/pull/1708): Fix visual issue when search panel is placed to either side panel + +## 0.2.3 + +### Features/Changes + +- [#1655](https://github.com/lapce/lapce/pull/1655): Add status foreground theme key, use author colour for plugin version +- [#1646](https://github.com/lapce/lapce/pull/1646): Fork the process when started from terminal +- [#1653](https://github.com/lapce/lapce/pull/1653): Paint plugin icons +- [#1644](https://github.com/lapce/lapce/pull/1644): Added "Reveal in File Tree" action to the editor tabs context menu +- [#1645](https://github.com/lapce/lapce/pull/1645): Add plugin search + +### Bug Fixes + +- [#1651](https://github.com/lapce/lapce/pull/1651): Fixed an issue where new windows would never be created after closing all windows on macOS. +- [#1637](https://github.com/lapce/lapce/issues/1637): Fix python using 7 spaces instead of 4 spaces to indent +- [#1669](https://github.com/lapce/lapce/issues/1669): It will now remember panel states when open a new project +- [#1706](https://github.com/lapce/lapce/issues/1706): Fix the issue that color can't be changed in theme settings + +## 0.2.2 + +### Features/Changes + +- [#1643](https://github.com/lapce/lapce/pull/1643): Use https://plugins.lapce.dev/ as the plugin registry +- [#1620](https://github.com/lapce/lapce/pull/1620): Added "Show Hover" keybinding that will trigger the hover at the cursor location +- [#1619](https://github.com/lapce/lapce/pull/1619): + - Add active/inactive tab colours + - Add primary button colour + - Add hover effect in source control panel + - Add colour preview in settings +- [#1617](https://github.com/lapce/lapce/pull/1617): Fixed a stack overflow that would crash lapce when attempting to sort a large number of PaletteItems +- [#1609](https://github.com/lapce/lapce/pull/1609): Add syntax highlighting for erlang +- [#1590](https://github.com/lapce/lapce/pull/1590): Added ability to open file and file diff from source control context menu +- [#1570](https://github.com/lapce/lapce/pull/1570): Added a basic tab context menu with common close actions +- [#1560](https://github.com/lapce/lapce/pull/1560): Added ability to copy active editor remote file path to clipboard +- [#1510](https://github.com/lapce/lapce/pull/1510): Added support to discard changes to a file +- [#1459](https://github.com/lapce/lapce/pull/1459): Implement icon theme system + - **This is a breaking change for colour themes!** + - Colour themes should now use `[color-theme]` table format in theme TOML + - `volt.toml` now use `color-themes` and `icon-themes` keys. `themes` key is not used anymore. +- [#1554](https://github.com/lapce/lapce/pull/1554): Added XML language support +- [#1472](https://github.com/lapce/lapce/pull/1472): Added SQL language support +- [#1531](https://github.com/lapce/lapce/pull/1531): Improved Ctrl+Left command on spaces at the beginning of a line +- [#1491](https://github.com/lapce/lapce/pull/1491): Added Vim shift+c to delete remainder of line +- [#1508](https://github.com/lapce/lapce/pull/1508): Show in progress when Lapce is self updating +- [#1475](https://github.com/lapce/lapce/pull/1475): Add editor setting: "Cursor Surrounding Lines" which sets minimum number of lines above and below cursor +- [#1525](https://github.com/lapce/lapce/pull/1525): Add editor indent guide +- [#1521](https://github.com/lapce/lapce/pull/1521): Show unique paths to disambiguate same file names +- [#1452](https://github.com/lapce/lapce/pull/1452): Wrap selected text with brackets/quotes +- [#1421](https://github.com/lapce/lapce/pull/1421): Add matching bracket highlighting +- [#1541](https://github.com/lapce/lapce/pull/1541): Order palette items according to last execute time + +### Bug Fixes + +- [#1566](https://github.com/lapce/lapce/pull/1565)|[#1568](https://github.com/lapce/lapce/pull/1568): Use separate colour for drag and drop background +- [#1459](https://github.com/lapce/lapce/pull/1459): Fix opening currently used logfile +- [#1505](https://github.com/lapce/lapce/pull/1505): Fix proxy download for hosts with curl without -Z flag +- [#1483](https://github.com/lapce/lapce/pull/1483): Fix showing the close icon for the first tab when opening multiple tab +- [#1477](https://github.com/lapce/lapce/pull/1477): Now use `esc` to close searchbar regardless of the current focus +- [#1507](https://github.com/lapce/lapce/pull/1507): Fixed a crash when scratch buffer is closed +- [#1547](https://github.com/lapce/lapce/pull/1547): Fix infinite cycle in workspace symbol search +- [#1628](https://github.com/lapce/lapce/pull/1541): Fix kts files not being recognized + +## 0.2.1 + +### Features/Changes + +- [#1050](https://github.com/lapce/lapce/pull/1050): Collapse groups of problems in the problem list panel +- [#1165](https://github.com/lapce/lapce/pull/1165): Command to reveal item in system file explorer +- [#1196](https://github.com/lapce/lapce/pull/1196): Always show close button on focused editor tabs +- [#1208](https://github.com/lapce/lapce/pull/1208): Sticky header breadcrumbs + - This provides a header at the top which tells you information about the current scope! Especially useful for long blocks of code + - ![image](https://user-images.githubusercontent.com/13157904/195404556-2c329ebb-f721-4d55-aa22-56a54f8e8454.png) + - As well, you can see that there is now a breadcrumb path to the current file. + - A language with syntax highlighting can have this added, even without an LSP. Take a look at `language.rs` if your language isn't supported! +- [#1198](https://github.com/lapce/lapce/pull/1198): Focus current theme/language in palette +- [#1244](https://github.com/lapce/lapce/pull/1244); Prettier plugin panel +- [#1238](https://github.com/lapce/lapce/pull/1238): Improved multicursor selection +- [#1291](https://github.com/lapce/lapce/pull/1291): Use link colour for empty editor buttons +- [#1234](https://github.com/lapce/lapce/commit/07390f0c90c0700d1f69409bf48723d15090c474): Automatic line height +- [#1262](https://github.com/lapce/lapce/pull/1262): Add absolute/relative copy path to file explorer +- [#1284](https://github.com/lapce/lapce/pull/1284): Render whitespace (default: none) + - ![image](https://user-images.githubusercontent.com/13157904/195410868-f27db85f-d7d2-4197-84f0-12d6c44e2053.png) +- [#1308](https://github.com/lapce/lapce/pull/1308): Handle LSP ResourceOp +- [#1251](https://github.com/lapce/lapce/pull/1251): Add vim's paste-before `P` command +- [#1319](https://github.com/lapce/lapce/pull/1319): Add information page for plugins +- [#1344](https://github.com/lapce/lapce/pull/1344): Replace the branch-selector menu with a scrollable list +- [#1352](https://github.com/lapce/lapce/pull/1352): Add duplicate line up/down commands +- [#1281](https://github.com/lapce/lapce/pull/1281): Implement logic for displaying plugin installation status +- [#1353](https://github.com/lapce/lapce/pull/1353): Implement syntax aware selection +- [#1358](https://github.com/lapce/lapce/pull/1358): Add autosave implementation +- [#1381](https://github.com/lapce/lapce/pull/1381): Show multiple hover items in the hover box +- [#1040](https://github.com/lapce/lapce/pull/1040): Add keybindings for `Shift-Del`, `Shift-Ins`, and `Ctrl-Ins` +- [#1401](https://github.com/lapce/lapce/pull/1401): Merge semantic and tree-sitter syntax highlighting +- [#1426](https://github.com/lapce/lapce/pull/1426): Add cursor position/current selection in status bar + - ![image](https://user-images.githubusercontent.com/13157904/195414557-dbf6cff1-3ab2-49ec-ba9d-c7507b2fc83a.png) +- [#1420](https://github.com/lapce/lapce/pull/1420): Add LSP `codeAction/resolve` support +- [#1440](https://github.com/lapce/lapce/pull/1440): IME support +- [#1449](https://github.com/lapce/lapce/pull/1449): Plugin settings in the editor support. Though this still needs some work from plugins to expose them all nicely! +- [#1441](https://github.com/lapce/lapce/pull/1441): Button for Case-Sensitive search +- [#1471](https://github.com/lapce/lapce/pull/1471): Add command to (un)install Lapce from/to PATH +- [#1419](https://github.com/lapce/lapce/pull/1419): Add atomic soft tabs: now you can move your cursor over four spaces as if it was a single block + +### Syntax / Extensions + +- [#957](https://github.com/lapce/lapce/pull/957): Replace existing tree-sitter syntax highlighting code with part of Helix's better implementation + - This means that syntax highlighting for more languages! Such as fixing markdown support, and making so that languages embedded in others (like JavaScript in HTML) work. + - Note that not all themes have updated themselves to include the extra scopes/colors. +- [#1036](https://github.com/lapce/lapce/pull/1036): Recognize ESM/CJS extensions for JavaScript/TypeScript +- [#1007](https://github.com/lapce/lapce/pull/1007): Add ability to bind a key shortcut for quitting the editor +- [#1104](https://github.com/lapce/lapce/pull/1104): Add syntax highlighting for Dockerfile, C#, and Nix +- [#1118](https://github.com/lapce/lapce/pull/1118): Recognize `pyi, pyc, pyd, pyw` extensions for Python +- [#1122](https://github.com/lapce/lapce/pull/1122): Recognize extensions for DLang +- [#1335](https://github.com/lapce/lapce/pull/1335): Highlighting for DLang +- [#1153](https://github.com/lapce/lapce/pull/1050): Recognize and add highlighting for Dart +- [#1161](https://github.com/lapce/lapce/pull/1161): Recognize and add highlighting for Svelte and LaTeX files +- [#1299](https://github.com/lapce/lapce/pull/1299): Recognize and add highlighting for Kotlin +- [#1326](https://github.com/lapce/lapce/pull/1326): Recognize and add highlighting for Vue +- [#1370](https://github.com/lapce/lapce/pull/1370): Recognize and add highlighting for R +- [#1416](https://github.com/lapce/lapce/pull/1416): Recognize and add highlighting for Scheme +- [#1145](https://github.com/lapce/lapce/pull/1145): Adds/Fixes highlighting for C/C++/TypeScript/JavaScript/Zig/Bash +- [#1272](https://github.com/lapce/lapce/pull/1272): Adds/Fixes highlighting for Elm/JSX/TSX +- [#1450](https://github.com/lapce/lapce/pull/1450): Add `tf` extension for HCL + +### Bug Fixes + +- [#1030](https://github.com/lapce/lapce/pull/1030): Don't try to open an font file with an empty name if there is no font family set +- [9f0120d](https://github.com/lapce/lapce/commit/9f0120df85e3aaaef7fbb43385bb15d88443260a): Fix excessive CPU usage in part of the code +- [bf5a98a](https://github.com/lapce/lapce/commit/bf5a98a6d432f9d2abdc1737da2d075e204771fb): Fix issue where sometimes Lapce can't open +- [#1084](https://github.com/lapce/lapce/pull/1084): Use host shell in terminal when running inside Flatpak +- [#1120](https://github.com/lapce/lapce/pull/1120): Make Alt+Backspace work in the terminal properly +- [#1127](https://github.com/lapce/lapce/pull/1127): Improve Julia highlighting +- [#1179](https://github.com/lapce/lapce/pull/1179): Various improvements/fixes to window-tab functionality +- [#1210](https://github.com/lapce/lapce/pull/1210): Fixed closing modified file when closing split +- [#1219](https://github.com/lapce/lapce/pull/1219): Fix append command behavior +- [#1250](https://github.com/lapce/lapce/pull/1250): Fix too long socket path for proxy +- [#1252](https://github.com/lapce/lapce/pull/1252): Check whether the active editor tab index actually exists, avoiding a potential crash +- [#1294](https://github.com/lapce/lapce/pull/1294): Backward word deletion should respect whitespace better +- [#1301](https://github.com/lapce/lapce/pull/1301): Fix incorrect path when going from Url -> PathBuf (such as from an LSP) +- [#1368](https://github.com/lapce/lapce/pull/1368): Fix tabstop for postfix completions +- [#1388](https://github.com/lapce/lapce/pull/1388): Fix regex search within the terminal +- [#1423](https://github.com/lapce/lapce/pull/1423): Fix multiple cursor offset after inserting opening pair +- [#1434](https://github.com/lapce/lapce/pull/1434): Join PATH with correct platform separator +- [#1443](https://github.com/lapce/lapce/pull/1443): Correct terminal font sizing +- [#1453](https://github.com/lapce/lapce/pull/1453): Trim whitespace from search results +- [#1461](https://github.com/lapce/lapce/pull/1461): Load shell environment when launching from GUI +- Many more fixes! + +### Other + +- [#1191](https://github.com/lapce/lapce/pull/1191): Tone down default inlay hint background color in Lapce dark theme +- [#1227](https://github.com/lapce/lapce/pull/1227): Don't restore cursor mode on undo +- [#1413](https://github.com/lapce/lapce/pull/1413): Disable format-on-save by default. Remember to re-enable this if you want it! +- [#1404](https://github.com/lapce/lapce/pull/1404): Log panics with full backtrace as error diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..6fd0e72 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,47 @@ +# How to contribute +Thank you for your interest in contributing to Lapce! No contribution is too small and we consider _all_ contributions to the project. There are many ways to contribute (a few are listed here) but if you think of something else, join us on [Discord](https://discord.gg/n8tGJ6Rn6D) or let us know via an [issue](https://github.com/lapce/lapce/issues). + +## Questions + +We're always around hanging on our [Discord](https://discord.gg/n8tGJ6Rn6D) server but if you're only participating on GitHub, you can open a [Discussion](https://github.com/lapce/lapce/discussions) + +## Feature Requests + +A feature request is _editor behaviour that you want to have included in Lapce_. We track feature requests on GitHub via [issues](https://github.com/lapce/lapce/issues). There are generally few kinds of features: + +### Core features + +A feature more suited to the core development of Lapce. If this is the case please make a suggestion in an [issue](https://github.com/lapce/lapce/issues). + +### Programming language support (autocompletion/intellisense/formatting) + +A feature that relates to specific programming language or development tool that provides intellisense, or various editor commands. +We do not track plugins development here, each plugin should have own issue tracker with eventual issues linked/referenced to main Lapce issue tracker. + +### Syntax highlighting + +There is main issue for tracking syntax highlighting grammars support at https://github.com/lapce/lapce/issues/272. + +--- + +To reduce the number of duplicate requests, please search through the issues to see if something has already been suggested. If a feature you want has been suggested, then comment on that issue to let us know it's popular. You can use emoji-reactions to show us just how popular. + +## Bug Reports + +Bugs should also be reported on GitHub via [issues](https://github.com/lapce/lapce/issues). This allows us to track them and see how prevalent they are. + +If you encounter a bug when using Lapce, check the issues to see if anyone else has encountered it. If it already exists, you can use emoji reactions so we can see community interest in specific issues and how important they are. + +Please follow the rule of [NoPlusOne](https://github.com/golang/go/wiki/NoPlusOne) + +## Pull Requests + +If you want to write some code, develop the documentation, or otherwise work on a certain feature or bug, let us know by replying to or creating an [issue](https://github.com/lapce/lapce/issues). + +Run `cargo fmt --all` and `cargo clippy` on your code before submitting pull requests and fix any issues; this makes sure that the CI runs only fail on genuine build errors and not formatting/Clippy lints. + +We are currently in the process of improving the documentation for new developers/code contributors. Feel free to get started, or post a message on [Discord](https://discord.gg/n8tGJ6Rn6D) to see what can be done. + +## Contact + +As always, if you have any questions or are just not sure where to start, post a message into the [Discord](https://discord.gg/n8tGJ6Rn6D) server. We suggest you start here as it is the most popular way for Lapce's contributors and users to communicate. diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..ecaecb6 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7956 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "ab_glyph" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5110f1c78cf582855d895ecd0746b653db010cec6d9f5575293f27934d980a39" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "getrandom 0.2.7", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "alacritty_terminal" +version = "0.24.1-dev" +source = "git+https://github.com/alacritty/alacritty?rev=cacdb5bb3b72bad2c729227537979d95af75978f#cacdb5bb3b72bad2c729227537979d95af75978f" +dependencies = [ + "base64 0.22.0", + "bitflags 2.9.1", + "home", + "libc", + "log", + "miow", + "parking_lot", + "piper", + "polling", + "regex-automata", + "rustix-openpty", + "serde", + "signal-hook", + "unicode-width", + "vte", + "windows-sys 0.52.0", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + +[[package]] +name = "ambient-authority" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9d4ee0d472d1cd2e28c97dfa124b3d8d992e10eb0a035f33f5d12e3a177ba3b" + +[[package]] +name = "android-activity" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" +dependencies = [ + "android-properties", + "bitflags 2.9.1", + "cc", + "cesu8", + "jni", + "jni-sys", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys 0.6.0+11769913", + "num_enum", + "thiserror 1.0.69", +] + +[[package]] +name = "android-properties" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "anstyle" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" + +[[package]] +name = "anyhow" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" + +[[package]] +name = "arbitrary" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2e1373abdaa212b704512ec2bd8b26bd0b7d5c3f70117411a5d9a451383c859" + +[[package]] +name = "arc-swap" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "as-raw-xcb-connection" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d5f312b0a56c5cdf967c0aeb67f6289603354951683bc97ddc595ab974ba9aa" + +[[package]] +name = "ash" +version = "0.38.0+1.3.281" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" +dependencies = [ + "libloading", +] + +[[package]] +name = "ashpd" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cbdf310d77fd3aaee6ea2093db7011dc2d35d2eb3481e5607f1f8d942ed99df" +dependencies = [ + "async-fs", + "async-net", + "enumflags2", + "futures-channel", + "futures-util", + "rand 0.9.1", + "raw-window-handle", + "serde", + "serde_repr", + "url", + "wayland-backend", + "wayland-client", + "wayland-protocols 0.32.10", + "zbus", +] + +[[package]] +name = "async-broadcast" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "258b52a1aa741b9f09783b2d86cf0aeeb617bbf847f6933340a39644227acbdb" +dependencies = [ + "event-listener 5.4.0", + "event-listener-strategy 0.5.0", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-channel" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" +dependencies = [ + "concurrent-queue", + "event-listener 5.4.0", + "event-listener-strategy 0.5.0", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb812ffb58524bdd10860d7d974e2f01cc0950c2438a74ee5ec2e2280c6c4ffa" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "pin-project-lite", + "slab", +] + +[[package]] +name = "async-fs" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc19683171f287921f2405677dd2ed2549c3b3bda697a563ebc3a121ace2aba1" +dependencies = [ + "async-lock 3.3.0", + "blocking", + "futures-lite", +] + +[[package]] +name = "async-io" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" +dependencies = [ + "async-lock 3.3.0", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix 0.38.32", + "slab", + "tracing 0.1.41", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener 2.5.3", +] + +[[package]] +name = "async-lock" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +dependencies = [ + "event-listener 4.0.3", + "event-listener-strategy 0.4.0", + "pin-project-lite", +] + +[[package]] +name = "async-net" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" +dependencies = [ + "async-io", + "blocking", + "futures-lite", +] + +[[package]] +name = "async-process" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" +dependencies = [ + "async-channel", + "async-io", + "async-lock 3.3.0", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener 5.4.0", + "futures-lite", + "rustix 0.38.32", + "tracing 0.1.41", +] + +[[package]] +name = "async-recursion" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "async-signal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" +dependencies = [ + "async-io", + "async-lock 2.8.0", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix 0.38.32", + "signal-hook-registry", + "slab", + "windows-sys 0.48.0", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +dependencies = [ + "serde", +] + +[[package]] +name = "bitmaps" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" +dependencies = [ + "typenum", +] + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +dependencies = [ + "objc2 0.5.2", +] + +[[package]] +name = "block2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "340d2f0bdb2a43c1d3cd40513185b2bd7def0aa1052f956455114bc98f82dcf2" +dependencies = [ + "objc2 0.6.3", +] + +[[package]] +name = "blocking" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +dependencies = [ + "async-channel", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + +[[package]] +name = "borsh" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2506947f73ad44e344215ccd6403ac2ae18cd8e046e581a441bf8d199f257f03" +dependencies = [ + "cfg_aliases", +] + +[[package]] +name = "bstr" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c79ad7fb2dd38f3dabd76b09c6a5a20c038fc0213ef1e9afd30eb777f120f019" +dependencies = [ + "memchr", + "regex-automata", + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "bytecount" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" + +[[package]] +name = "bytemuck" +version = "1.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "calloop" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b50b5a44d59a98c55a9eeb518f39bf7499ba19fd98ee7d22618687f3f10adbf" +dependencies = [ + "bitflags 2.9.1", + "log", + "polling", + "rustix 0.38.32", + "slab", + "thiserror 1.0.69", +] + +[[package]] +name = "calloop" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" +dependencies = [ + "bitflags 2.9.1", + "log", + "polling", + "rustix 0.38.32", + "slab", + "thiserror 1.0.69", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02" +dependencies = [ + "calloop 0.12.3", + "rustix 0.38.32", + "wayland-backend", + "wayland-client", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" +dependencies = [ + "calloop 0.13.0", + "rustix 0.38.32", + "wayland-backend", + "wayland-client", +] + +[[package]] +name = "cap-fs-ext" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b779b2d0a001c125b4584ad586268fb4b92d957bff8d26d7fe0dd78283faa814" +dependencies = [ + "cap-primitives", + "cap-std", + "io-lifetimes", + "windows-sys 0.48.0", +] + +[[package]] +name = "cap-net-ext" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ffc30dee200c20b4dcb80572226f42658e1d9c4b668656d7cc59c33d50e396e" +dependencies = [ + "cap-primitives", + "cap-std", + "rustix 0.38.32", + "smallvec", +] + +[[package]] +name = "cap-primitives" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf30c373a3bee22c292b1b6a7a26736a38376840f1af3d2d806455edf8c3899" +dependencies = [ + "ambient-authority", + "fs-set-times", + "io-extras", + "io-lifetimes", + "ipnet", + "maybe-owned", + "rustix 0.38.32", + "windows-sys 0.48.0", + "winx", +] + +[[package]] +name = "cap-rand" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "577de6cff7c2a47d6b13efe5dd28bf116bd7f8f7db164ea95b7cc2640711f522" +dependencies = [ + "ambient-authority", + "rand 0.8.5", +] + +[[package]] +name = "cap-std" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84bade423fa6403efeebeafe568fdb230e8c590a275fba2ba978dd112efcf6e9" +dependencies = [ + "cap-primitives", + "io-extras", + "io-lifetimes", + "rustix 0.38.32", +] + +[[package]] +name = "cap-time-ext" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8f52b3c8f4abfe3252fd0a071f3004aaa3b18936ec97bdbd8763ce03aff6247" +dependencies = [ + "cap-primitives", + "once_cell", + "rustix 0.38.32", + "winx", +] + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cc" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" +dependencies = [ + "jobserver", + "libc", + "once_cell", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.6", +] + +[[package]] +name = "ciborium" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" + +[[package]] +name = "ciborium-ll" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "clap" +version = "4.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb" +dependencies = [ + "anstyle", + "clap_lex", +] + +[[package]] +name = "clap_derive" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + +[[package]] +name = "clipboard-win" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fdf5e01086b6be750428ba4a40619f847eb2e95756eee84b18e06e5f0b50342" +dependencies = [ + "lazy-bytes-cast", + "winapi", +] + +[[package]] +name = "cocoa" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c" +dependencies = [ + "bitflags 1.3.2", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics", + "foreign-types 0.5.0", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" +dependencies = [ + "bitflags 1.3.2", + "block", + "core-foundation", + "core-graphics-types", + "foreign-types 0.3.2", + "libc", + "objc", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "color" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18ef4657441fb193b65f34dc39b3781f0dfec23d3bd94d0eeb4e88cde421edb" +dependencies = [ + "serde", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "config" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23738e11972c7643e4ec947840fc463b6a571afcd3e735bdfce7d03c7a784aca" +dependencies = [ + "async-trait", + "lazy_static", + "nom", + "pathdiff", + "serde", + "toml 0.5.9", +] + +[[package]] +name = "copypasta" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deb85422867ca93da58b7f95fb5c0c10f6183ed6e1ef8841568968a896d3a858" +dependencies = [ + "clipboard-win", + "objc", + "objc-foundation", + "objc_id", + "smithay-clipboard", + "x11-clipboard", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "core-graphics" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "970a29baf4110c26fedbc7f82107d42c23f7e88e404c4577ed73fe99ff85a212" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types 0.5.0", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + +[[package]] +name = "core_maths" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b02505ccb8c50b0aa21ace0fc08c3e53adebd4e58caa18a36152803c7709a3" +dependencies = [ + "libm", +] + +[[package]] +name = "cosmic-text" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da46a9d5a8905cc538a4a5bceb6a4510de7a51049c5588c0114efce102bcbbe8" +dependencies = [ + "bitflags 2.9.1", + "fontdb 0.16.2", + "log", + "rangemap", + "rustc-hash 1.1.0", + "rustybuzz 0.14.1", + "self_cell", + "smol_str 0.2.2", + "swash", + "sys-locale", + "ttf-parser 0.21.1", + "unicode-bidi", + "unicode-linebreak", + "unicode-script", + "unicode-segmentation", +] + +[[package]] +name = "cpp_demangle" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eeaa953eaad386a53111e47172c2fedba671e5684c8dd601a5f474f4f118710f" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "cpufeatures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +dependencies = [ + "libc", +] + +[[package]] +name = "cranelift-bforest" +version = "0.101.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b5bb9245ec7dcc04d03110e538d31f0969d301c9d673145f4b4d5c3478539a3" +dependencies = [ + "cranelift-entity", +] + +[[package]] +name = "cranelift-codegen" +version = "0.101.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebb18d10e5ddac43ba4ca8fd4e310938569c3e484cc01b6372b27dc5bb4dfd28" +dependencies = [ + "bumpalo", + "cranelift-bforest", + "cranelift-codegen-meta", + "cranelift-codegen-shared", + "cranelift-control", + "cranelift-entity", + "cranelift-isle", + "gimli", + "hashbrown 0.14.5", + "log", + "regalloc2", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-codegen-meta" +version = "0.101.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a3ce6d22982c1b9b6b012654258bab1a13947bb12703518bef06b1a4867c3d6" +dependencies = [ + "cranelift-codegen-shared", +] + +[[package]] +name = "cranelift-codegen-shared" +version = "0.101.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47220fd4f9a0ce23541652b6f16f83868d282602c600d14934b2a4c166b4bd80" + +[[package]] +name = "cranelift-control" +version = "0.101.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5a4c42672aea9b6e820046b52e47a1c05d3394a6cdf4cb3c3c4b702f954bd2" +dependencies = [ + "arbitrary", +] + +[[package]] +name = "cranelift-entity" +version = "0.101.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b4e9a3296fc827f9d35135dc2c0c8dd8d8359eb1ef904bae2d55d5bcb0c9f94" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "cranelift-frontend" +version = "0.101.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aaadf1e7cf28886bbf046eaf7ef538997bc8a7e020e578ea4957b39da87d5a1" +dependencies = [ + "cranelift-codegen", + "log", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-isle" +version = "0.101.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45bab6d69919d210a50331d35cc6ce111567bc040aebac63a8ae130d0400a075" + +[[package]] +name = "cranelift-native" +version = "0.101.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76fb52ba71be98312f35e798d9e98e45ab2586f27584231bf7c644fa9501e8af" +dependencies = [ + "cranelift-codegen", + "libc", + "target-lexicon", +] + +[[package]] +name = "cranelift-wasm" +version = "0.101.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1b2f48857ec7c051af938c72b5fdf370a5eec255c8a2be87633241af3c05772" +dependencies = [ + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "itertools 0.10.5", + "log", + "smallvec", + "wasmparser", + "wasmtime-types", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "criterion" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" +dependencies = [ + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "is-terminal", + "itertools 0.10.5", + "num-traits", + "once_cell", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools 0.10.5", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "ctor" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e366bff8cd32dd8754b0991fb66b279dc48f598c3a18914852a6673deef583" +dependencies = [ + "quote", + "syn 2.0.94", +] + +[[package]] +name = "cursor-icon" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" +dependencies = [ + "serde", +] + +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "data-url" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a" + +[[package]] +name = "debugid" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" +dependencies = [ + "uuid", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "directories" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "directories-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dispatch2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +dependencies = [ + "bitflags 2.9.1", + "block2 0.6.1", + "libc", + "objc2 0.6.3", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +dependencies = [ + "libloading", +] + +[[package]] +name = "dmg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abc28c350337837f23b4750f774371f63db232338c9f89bdb9eb48523a7c4722" +dependencies = [ + "log", + "plist", +] + +[[package]] +name = "document-features" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" +dependencies = [ + "litrs", +] + +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + +[[package]] +name = "dpi" +version = "0.1.1" +source = "git+https://github.com/rust-windowing/winit?rev=ee245c569d65fdeacf705ee5eedb564508d10ebe#ee245c569d65fdeacf705ee5eedb564508d10ebe" +dependencies = [ + "serde", +] + +[[package]] +name = "drm" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0f8a69e60d75ae7dab4ef26a59ca99f2a89d4c142089b537775ae0c198bdcde" +dependencies = [ + "bitflags 2.9.1", + "bytemuck", + "drm-ffi", + "drm-fourcc", + "rustix 0.38.32", +] + +[[package]] +name = "drm-ffi" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41334f8405792483e32ad05fbb9c5680ff4e84491883d2947a4757dc54cb2ac6" +dependencies = [ + "drm-sys", + "rustix 0.38.32", +] + +[[package]] +name = "drm-fourcc" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4" + +[[package]] +name = "drm-sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d09ff881f92f118b11105ba5e34ff8f4adf27b30dae8f12e28c193af1c83176" +dependencies = [ + "libc", + "linux-raw-sys 0.6.4", +] + +[[package]] +name = "dyn-clone" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" + +[[package]] +name = "educe" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "either" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" + +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "encoding_rs_io" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cc3c5651fb62ab8aa3103998dade57efdd028544bd300516baa31840c252a83" +dependencies = [ + "encoding_rs", +] + +[[package]] +name = "endi" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" + +[[package]] +name = "enum-ordinalize" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5" +dependencies = [ + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "enumflags2" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "euclid" +version = "0.22.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad9cdb4b747e485a12abb0e6566612956c7a1bafa3bdb8d682c5b6d403589e48" +dependencies = [ + "num-traits", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +dependencies = [ + "event-listener 4.0.3", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291" +dependencies = [ + "event-listener 5.4.0", + "pin-project-lite", +] + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fd-lock" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b0377f1edc77dbd1118507bc7a66e4ab64d2b90c66f90726dc801e73a8c68f9" +dependencies = [ + "cfg-if", + "rustix 0.38.32", + "windows-sys 0.48.0", +] + +[[package]] +name = "fdeflate" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "filetime" +version = "0.2.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" +dependencies = [ + "cfg-if", + "libc", + "libredox", + "windows-sys 0.60.2", +] + +[[package]] +name = "flate2" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" + +[[package]] +name = "floem" +version = "0.2.0" +source = "git+https://github.com/lapce/floem?rev=31fa8f444c37f4c314f47d88c23ffdbc25f2ab53#31fa8f444c37f4c314f47d88c23ffdbc25f2ab53" +dependencies = [ + "bitflags 2.9.1", + "clipboard-win", + "copypasta", + "educe", + "floem-editor-core", + "floem_reactive", + "floem_renderer", + "floem_tiny_skia_renderer", + "floem_vger_renderer", + "im", + "im-rc", + "image", + "indexmap", + "lapce-xi-rope", + "muda", + "objc2 0.6.3", + "objc2-app-kit 0.3.2", + "objc2-foundation 0.3.2", + "parking_lot", + "peniko", + "raw-window-handle", + "rfd", + "rustc-hash 2.1.1", + "serde", + "sha2", + "slotmap", + "smallvec", + "strum 0.27.2", + "strum_macros 0.27.2", + "taffy", + "unicode-segmentation", + "wasm-bindgen-futures", + "web-time", + "wgpu", + "winit", +] + +[[package]] +name = "floem-editor-core" +version = "0.2.0" +source = "git+https://github.com/lapce/floem?rev=31fa8f444c37f4c314f47d88c23ffdbc25f2ab53#31fa8f444c37f4c314f47d88c23ffdbc25f2ab53" +dependencies = [ + "bitflags 2.9.1", + "itertools 0.14.0", + "lapce-xi-rope", + "memchr", + "serde", + "strum 0.27.2", + "strum_macros 0.27.2", +] + +[[package]] +name = "floem-vger" +version = "0.3.1" +source = "git+https://github.com/lapce/vger-rs.git?rev=3206d47ec1e30b645ddcb0687036ba3e1f0d98ec#3206d47ec1e30b645ddcb0687036ba3e1f0d98ec" +dependencies = [ + "cosmic-text", + "euclid", + "fontdue", + "rect_packer", + "wgpu", +] + +[[package]] +name = "floem_reactive" +version = "0.2.0" +source = "git+https://github.com/lapce/floem?rev=31fa8f444c37f4c314f47d88c23ffdbc25f2ab53#31fa8f444c37f4c314f47d88c23ffdbc25f2ab53" +dependencies = [ + "smallvec", +] + +[[package]] +name = "floem_renderer" +version = "0.2.0" +source = "git+https://github.com/lapce/floem?rev=31fa8f444c37f4c314f47d88c23ffdbc25f2ab53#31fa8f444c37f4c314f47d88c23ffdbc25f2ab53" +dependencies = [ + "cosmic-text", + "futures", + "parking_lot", + "peniko", + "resvg", + "swash", + "wasm-bindgen-futures", + "wgpu", + "winit", +] + +[[package]] +name = "floem_tiny_skia_renderer" +version = "0.2.0" +source = "git+https://github.com/lapce/floem?rev=31fa8f444c37f4c314f47d88c23ffdbc25f2ab53#31fa8f444c37f4c314f47d88c23ffdbc25f2ab53" +dependencies = [ + "anyhow", + "floem_renderer", + "peniko", + "raw-window-handle", + "resvg", + "softbuffer", +] + +[[package]] +name = "floem_vger_renderer" +version = "0.2.0" +source = "git+https://github.com/lapce/floem?rev=31fa8f444c37f4c314f47d88c23ffdbc25f2ab53#31fa8f444c37f4c314f47d88c23ffdbc25f2ab53" +dependencies = [ + "anyhow", + "floem-vger", + "floem_renderer", + "image", + "peniko", + "resvg", + "wgpu", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "font-types" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02a596f5713680923a2080d86de50fe472fb290693cf0f701187a1c8b36996b7" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "fontconfig-parser" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a595cb550439a117696039dfc69830492058211b771a2a165379f2a1a53d84d" +dependencies = [ + "roxmltree 0.19.0", +] + +[[package]] +name = "fontdb" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0299020c3ef3f60f526a4f64ab4a3d4ce116b1acbf24cdd22da0068e5d81dc3" +dependencies = [ + "fontconfig-parser", + "log", + "memmap2", + "slotmap", + "tinyvec", + "ttf-parser 0.20.0", +] + +[[package]] +name = "fontdb" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "457e789b3d1202543297a350643cf459f836cade38934e7a4cf6a39e7cde2905" +dependencies = [ + "fontconfig-parser", + "log", + "memmap2", + "slotmap", + "tinyvec", + "ttf-parser 0.25.1", +] + +[[package]] +name = "fontdue" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e57e16b3fe8ff4364c0661fdaac543fb38b29ea9bc9c2f45612d90adf931d2b" +dependencies = [ + "hashbrown 0.15.4", + "ttf-parser 0.21.1", +] + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared 0.1.1", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared 0.3.1", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fs-set-times" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd738b84894214045e8414eaded76359b4a5773f0a0a56b16575110739cdcf39" +dependencies = [ + "io-lifetimes", + "rustix 0.38.32", + "windows-sys 0.48.0", +] + +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "fsevent-sys" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" +dependencies = [ + "libc", +] + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-lite" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "fxprof-processed-profile" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27d12c0aed7f1e24276a241aadc4cb8ea9f83000f34bc062b7cc2d51e3b0fabd" +dependencies = [ + "bitflags 2.9.1", + "debugid", + "fxhash", + "serde", + "serde_json", +] + +[[package]] +name = "generic-array" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "gethostname" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +dependencies = [ + "libc", + "windows-targets 0.48.5", +] + +[[package]] +name = "getopts" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "getrandom" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", +] + +[[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +dependencies = [ + "fallible-iterator", + "indexmap", + "stable_deref_trait", +] + +[[package]] +name = "git2" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2deb07a133b1520dc1a5690e9bd08950108873d7ed5de38dcc74d3b5ebffa110" +dependencies = [ + "bitflags 2.9.1", + "libc", + "libgit2-sys", + "log", + "openssl-probe", + "openssl-sys", + "url", +] + +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + +[[package]] +name = "globset" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "glow" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e5ea60d70410161c8bf5da3fdfeaa1c72ed2c15f8bbb9d19fe3a4fad085f08" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a4e1951bbd9434a81aa496fe59ccc2235af3820d27b85f9314e279609211e2c" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "gpu-alloc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" +dependencies = [ + "bitflags 2.9.1", + "gpu-alloc-types", +] + +[[package]] +name = "gpu-alloc-types" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" +dependencies = [ + "bitflags 2.9.1", +] + +[[package]] +name = "gpu-allocator" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c151a2a5ef800297b4e79efa4f4bec035c5f51d5ae587287c9b952bdf734cacd" +dependencies = [ + "log", + "presser", + "thiserror 1.0.69", + "windows 0.58.0", +] + +[[package]] +name = "gpu-descriptor" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" +dependencies = [ + "bitflags 2.9.1", + "gpu-descriptor-types", + "hashbrown 0.15.4", +] + +[[package]] +name = "gpu-descriptor-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" +dependencies = [ + "bitflags 2.9.1", +] + +[[package]] +name = "grep-matcher" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47a3141a10a43acfedc7c98a60a834d7ba00dfe7bec9071cbfc19b55b292ac02" +dependencies = [ + "memchr", +] + +[[package]] +name = "grep-regex" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f748bb135ca835da5cbc67ca0e6955f968db9c5df74ca4f56b18e1ddbc68230d" +dependencies = [ + "bstr", + "grep-matcher", + "log", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "grep-searcher" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba536ae4f69bec62d8839584dd3153d3028ef31bb229f04e09fb5a9e5a193c54" +dependencies = [ + "bstr", + "encoding_rs", + "encoding_rs_io", + "grep-matcher", + "log", + "memchr", + "memmap2", +] + +[[package]] +name = "grid" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71b01d27060ad58be4663b9e4ac9e2d4806918e8876af8912afbddd1a91d5eaa" + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing 0.1.41", +] + +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashbrown" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hexf-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "http" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "human-sort" +version = "0.2.2" +source = "git+https://github.com/dragazo/human-sort?rev=1e74db1e09e8194ba88ad983723cf6f8b0c365da#1e74db1e09e8194ba88ad983723cf6f8b0c365da" + +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing 0.1.41", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd911b35d940d2bd0bea0f9100068e5b97b51a1cbe13d13382f132e0365257a0" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "icu_collections" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" + +[[package]] +name = "icu_properties" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2549ca8c7241c82f59c80ba2a6f415d931c5b58d24fb8412caa1a1f02c49139a" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "potential_utf", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8197e866e47b68f8f7d95249e172903bec06004b18b2937f1095d40a0c57de04" + +[[package]] +name = "icu_provider" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +dependencies = [ + "displaydoc", + "icu_locale_core", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "id-arena" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "ignore" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492" +dependencies = [ + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + +[[package]] +name = "im" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" +dependencies = [ + "bitmaps", + "rand_core 0.6.4", + "rand_xoshiro", + "serde", + "sized-chunks", + "typenum", + "version_check", +] + +[[package]] +name = "im-rc" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1955a75fa080c677d3972822ec4bad316169ab1cfc6c257a942c2265dbe5fe" +dependencies = [ + "bitmaps", + "rand_core 0.6.4", + "rand_xoshiro", + "sized-chunks", + "typenum", + "version_check", +] + +[[package]] +name = "image" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11" +dependencies = [ + "bytemuck", + "byteorder", + "image-webp 0.1.3", + "num-traits", + "png", + "zune-core", + "zune-jpeg", +] + +[[package]] +name = "image-webp" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f79afb8cbee2ef20f59ccd477a218c12a93943d075b492015ecb1bb81f8ee904" +dependencies = [ + "byteorder-lite", + "quick-error", +] + +[[package]] +name = "image-webp" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6970fe7a5300b4b42e62c52efa0187540a5bef546c60edaf554ef595d2e6f0b" +dependencies = [ + "byteorder-lite", + "quick-error", +] + +[[package]] +name = "imagesize" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edcd27d72f2f071c64249075f42e205ff93c9a4c5f6c6da53e79ed9f9832c285" + +[[package]] +name = "include_dir" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd" +dependencies = [ + "include_dir_macros", +] + +[[package]] +name = "include_dir_macros" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "indexmap" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +dependencies = [ + "equivalent", + "hashbrown 0.15.4", + "serde", +] + +[[package]] +name = "inotify" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" +dependencies = [ + "bitflags 1.3.2", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + +[[package]] +name = "interprocess" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81f2533f3be42fffe3b5e63b71aeca416c1c3bc33e4e27be018521e76b1f38fb" +dependencies = [ + "blocking", + "cfg-if", + "futures-core", + "futures-io", + "intmap", + "libc", + "once_cell", + "rustc_version", + "spinning", + "thiserror 1.0.69", + "to_method", + "winapi", +] + +[[package]] +name = "intmap" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae52f28f45ac2bc96edb7714de995cffc174a395fb0abf5bff453587c980d7b9" + +[[package]] +name = "io-extras" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d3c230ee517ee76b1cc593b52939ff68deda3fae9e41eca426c6b4993df51c4" +dependencies = [ + "io-lifetimes", + "windows-sys 0.48.0", +] + +[[package]] +name = "io-lifetimes" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bffb4def18c48926ccac55c1223e02865ce1a821751a95920448662696e7472c" + +[[package]] +name = "ipnet" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" + +[[package]] +name = "is-docker" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" +dependencies = [ + "once_cell", +] + +[[package]] +name = "is-terminal" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "is-wsl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" +dependencies = [ + "is-docker", + "once_cell", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" + +[[package]] +name = "ittapi" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25a5c0b993601cad796222ea076565c5d9f337d35592f8622c753724f06d7271" +dependencies = [ + "anyhow", + "ittapi-sys", + "log", +] + +[[package]] +name = "ittapi-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7b5e473765060536a660eed127f758cf1a810c73e49063264959c60d1727d9" +dependencies = [ + "cc", +] + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "jsonrpc-lite" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb4128aba82294c14af2998831c4df3c843940e92b5cfc41bac1229d1e63b88c" +dependencies = [ + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "keyboard-types" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" +dependencies = [ + "bitflags 2.9.1", + "serde", + "unicode-segmentation", +] + +[[package]] +name = "khronos-egl" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" +dependencies = [ + "libc", + "libloading", + "pkg-config", +] + +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + +[[package]] +name = "kqueue" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d6112e8f37b59803ac47a42d14f1f3a59bbf72fc6857ffc5be455e28a691f8e" +dependencies = [ + "kqueue-sys", + "libc", +] + +[[package]] +name = "kqueue-sys" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8367585489f01bc55dd27404dcf56b95e6da061a256a666ab23be9ba96a2e587" +dependencies = [ + "bitflags 1.3.2", + "libc", +] + +[[package]] +name = "kurbo" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1077d333efea6170d9ccb96d3c3026f300ca0773da4938cc4c811daa6df68b0c" +dependencies = [ + "arrayvec", + "serde", + "smallvec", +] + +[[package]] +name = "lapce" +version = "0.4.6" +dependencies = [ + "lapce-app", + "lapce-proxy", +] + +[[package]] +name = "lapce-app" +version = "0.4.6" +dependencies = [ + "Inflector", + "alacritty_terminal", + "anyhow", + "backtrace", + "base64 0.21.7", + "bytemuck", + "chrono", + "clap", + "config", + "criterion", + "crossbeam-channel", + "dmg", + "flate2", + "floem", + "fs_extra", + "globset", + "im", + "include_dir", + "indexmap", + "interprocess", + "itertools 0.12.1", + "lapce-core", + "lapce-proxy", + "lapce-rpc", + "lapce-xi-rope", + "lsp-types", + "notify", + "nucleo", + "once_cell", + "open", + "parking_lot", + "percent-encoding", + "pulldown-cmark", + "rayon", + "regex", + "reqwest", + "semver", + "serde", + "serde_json", + "sha2", + "smallvec", + "structdesc", + "strum 0.27.2", + "strum_macros 0.27.2", + "tar", + "tempfile", + "thiserror 1.0.69", + "toml 0.8.2", + "toml_edit 0.20.2", + "tracing 0.2.0", + "tracing-appender", + "tracing-log", + "tracing-subscriber", + "unicode-width", + "url", + "windows-sys 0.60.2", + "zip", + "zstd", +] + +[[package]] +name = "lapce-core" +version = "0.4.6" +dependencies = [ + "ahash", + "anyhow", + "arc-swap", + "directories", + "floem-editor-core", + "git2", + "hashbrown 0.14.5", + "include_dir", + "itertools 0.12.1", + "lapce-rpc", + "lapce-xi-rope", + "libloading", + "lsp-types", + "once_cell", + "regex", + "remain", + "slotmap", + "strum 0.27.2", + "strum_macros 0.27.2", + "thiserror 1.0.69", + "tracing 0.2.0", + "tree-sitter", +] + +[[package]] +name = "lapce-proxy" +version = "0.4.6" +dependencies = [ + "alacritty_terminal", + "anyhow", + "clap", + "crossbeam-channel", + "directories", + "dyn-clone", + "flate2", + "floem-editor-core", + "git2", + "globset", + "grep-matcher", + "grep-regex", + "grep-searcher", + "ignore", + "indexmap", + "interprocess", + "jsonrpc-lite", + "lapce-core", + "lapce-rpc", + "lapce-xi-rope", + "libc", + "locale_config", + "lsp-types", + "notify", + "parking_lot", + "polling", + "psp-types", + "regex", + "reqwest", + "serde", + "serde_json", + "tar", + "toml 0.8.2", + "tracing 0.2.0", + "tracing-log", + "trash", + "url", + "walkdir", + "wasi-common", + "wasi-experimental-http-wasmtime", + "wasmtime", + "wasmtime-wasi", + "zstd", +] + +[[package]] +name = "lapce-rpc" +version = "0.4.6" +dependencies = [ + "anyhow", + "crossbeam-channel", + "human-sort", + "indexmap", + "lapce-xi-rope", + "lsp-types", + "parking_lot", + "serde", + "serde_json", + "tracing 0.2.0", + "url", +] + +[[package]] +name = "lapce-xi-rope" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6516aaa99c5059dc1a1bc02ed782d5e524699c1b4330028a6bed8259f9d9ff0a" +dependencies = [ + "bytecount", + "memchr", + "regex", + "serde", + "unicode-segmentation", +] + +[[package]] +name = "lazy-bytes-cast" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10257499f089cd156ad82d0a9cd57d9501fa2c989068992a97eb3c27836f206b" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "libc" +version = "0.2.180" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" + +[[package]] +name = "libgit2-sys" +version = "0.18.1+1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1dcb20f84ffcdd825c7a311ae347cce604a6f084a767dec4a4929829645290e" +dependencies = [ + "cc", + "libc", + "libssh2-sys", + "libz-sys", + "openssl-sys", + "pkg-config", +] + +[[package]] +name = "libloading" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "libm" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.9.1", + "libc", + "redox_syscall 0.5.8", +] + +[[package]] +name = "libssh2-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee" +dependencies = [ + "cc", + "libc", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libz-sys" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "line-wrap" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd1bc4d24ad230d21fb898d1116b1801d7adfc449d42026475862ab48b11e70e" + +[[package]] +name = "linebender_resource_handle" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a5ff6bcca6c4867b1c4fd4ef63e4db7436ef363e0ad7531d1558856bae64f4" +dependencies = [ + "serde", + "serde_bytes", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "linux-raw-sys" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0b5399f6804fbab912acbd8878ed3532d506b7c951b8f9f164ef90fef39e3f4" + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "litemap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" + +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + +[[package]] +name = "locale_config" +version = "0.3.1-alpha.0" +source = "git+https://github.com/lapce/locale_config.git?branch=lapce#54c9fe6a247c3618c224ec57e6c3a747bc3a96e4" +dependencies = [ + "lazy_static", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "regex", + "winapi", +] + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "lsp-types" +version = "0.95.1" +source = "git+https://github.com/lapce/lsp-types?rev=feaa1e2ec80975c9dadd400a238ceacf071058e6#feaa1e2ec80975c9dadd400a238ceacf071058e6" +dependencies = [ + "bitflags 1.3.2", + "serde", + "serde_json", + "serde_repr", + "url", +] + +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "maybe-owned" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4facc753ae494aeb6e3c22f839b158aebd4f9270f55cd3c79906c45476c47ab4" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "memfd" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" +dependencies = [ + "rustix 0.38.32", +] + +[[package]] +name = "memmap2" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deaba38d7abf1d4cca21cc89e932e542ba2b9258664d2a9ef0e61512039c9375" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "metal" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f569fb946490b5743ad69813cb19629130ce9374034abe31614a36402d18f99e" +dependencies = [ + "bitflags 2.9.1", + "block", + "core-graphics-types", + "foreign-types 0.5.0", + "log", + "objc", + "paste", +] + +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.48.0", +] + +[[package]] +name = "miow" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "359f76430b20a79f9e20e115b3428614e654f04fab314482fc0fda0ebd3c6044" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "muda" +version = "0.16.1" +source = "git+https://github.com/tauri-apps/muda?rev=8e986af3cea96a729413abc75c3702dec3990bd2#8e986af3cea96a729413abc75c3702dec3990bd2" +dependencies = [ + "crossbeam-channel", + "dpi", + "keyboard-types", + "objc2 0.6.3", + "objc2-app-kit 0.3.2", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "once_cell", + "png", + "thiserror 2.0.12", + "windows-sys 0.59.0", +] + +[[package]] +name = "naga" +version = "24.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e380993072e52eef724eddfcde0ed013b0c023c3f0417336ed041aa9f076994e" +dependencies = [ + "arrayvec", + "bit-set", + "bitflags 2.9.1", + "cfg_aliases", + "codespan-reporting", + "hexf-parse", + "indexmap", + "log", + "rustc-hash 1.1.0", + "spirv", + "strum 0.26.3", + "termcolor", + "thiserror 2.0.12", + "unicode-xid", +] + +[[package]] +name = "native-tls" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.9.1", + "jni-sys", + "log", + "ndk-sys 0.6.0+11769913", + "num_enum", + "raw-window-handle", + "thiserror 1.0.69", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.5.0+25.2.9519653" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "nix" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +dependencies = [ + "bitflags 2.9.1", + "cfg-if", + "cfg_aliases", + "libc", + "memoffset", +] + +[[package]] +name = "nom" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "notify" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "729f63e1ca555a43fe3efa4f3efdf4801c479da85b432242a7b726f353c88486" +dependencies = [ + "bitflags 1.3.2", + "crossbeam-channel", + "filetime", + "fsevent-sys", + "inotify", + "kqueue", + "libc", + "mio", + "serde", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "nucleo" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5262af4c94921c2646c5ac6ff7900c2af9cbb08dc26a797e18130a7019c039d4" +dependencies = [ + "nucleo-matcher", + "parking_lot", + "rayon", +] + +[[package]] +name = "nucleo-matcher" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf33f538733d1a5a3494b836ba913207f14d9d4a1d3cd67030c5061bdd2cac85" +dependencies = [ + "memchr", + "unicode-segmentation", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70bf6736f74634d299d00086f02986875b3c2d924781a6a2cb6c201e73da0ceb" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ea360eafe1022f7cc56cd7b869ed57330fb2453d0c7831d99b74c65d2f5597" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" +dependencies = [ + "objc2-encode", +] + +[[package]] +name = "objc2-app-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +dependencies = [ + "bitflags 2.9.1", + "block2 0.5.1", + "libc", + "objc2 0.5.2", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation 0.2.2", + "objc2-quartz-core", +] + +[[package]] +name = "objc2-app-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" +dependencies = [ + "bitflags 2.9.1", + "block2 0.6.1", + "objc2 0.6.3", + "objc2-core-foundation", + "objc2-foundation 0.3.2", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +dependencies = [ + "bitflags 2.9.1", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-core-location", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-contacts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +dependencies = [ + "bitflags 2.9.1", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags 2.9.1", + "dispatch2", + "objc2 0.6.3", +] + +[[package]] +name = "objc2-core-image" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "objc2-metal", +] + +[[package]] +name = "objc2-core-location" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-contacts", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.9.1", + "block2 0.5.1", + "dispatch", + "libc", + "objc2 0.5.2", +] + +[[package]] +name = "objc2-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" +dependencies = [ + "bitflags 2.9.1", + "objc2 0.6.3", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.9.1", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.9.1", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "objc2-metal", +] + +[[package]] +name = "objc2-symbols" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +dependencies = [ + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.9.1", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation 0.2.2", + "objc2-link-presentation", + "objc2-quartz-core", + "objc2-symbols", + "objc2-uniform-type-identifiers", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-uniform-type-identifiers" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.9.1", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-core-location", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "crc32fast", + "hashbrown 0.14.5", + "indexmap", + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + +[[package]] +name = "open" +version = "5.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5ca541f22b1c46d4bb9801014f234758ab4297e7870b904b6a8415b980a7388" +dependencies = [ + "is-wsl", + "libc", + "pathdiff", +] + +[[package]] +name = "openssl" +version = "0.10.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" +dependencies = [ + "bitflags 2.9.1", + "cfg-if", + "foreign-types 0.3.2", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-src" +version = "300.2.3+3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cff92b6f71555b61bb9315f7c64da3ca43d87531622120fea0195fc761b4843" +dependencies = [ + "cc", +] + +[[package]] +name = "openssl-sys" +version = "0.9.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" +dependencies = [ + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "orbclient" +version = "0.3.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba0b26cec2e24f08ed8bb31519a9333140a6599b867dac464bb150bdb796fd43" +dependencies = [ + "libredox", +] + +[[package]] +name = "ordered-float" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" +dependencies = [ + "num-traits", +] + +[[package]] +name = "ordered-stream" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "owned_ttf_parser" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "706de7e2214113d63a8238d1910463cfce781129a6f263d13fdb09ff64355ba4" +dependencies = [ + "ttf-parser 0.19.1", +] + +[[package]] +name = "parking" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.5.8", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "paste" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" + +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + +[[package]] +name = "peniko" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b44f9ddd2f480176b34278eb653ec1c8062f3b143a4e16eeff5ffac3334e288" +dependencies = [ + "color", + "kurbo", + "linebender_resource_handle", + "serde", + "smallvec", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + +[[package]] +name = "pin-project" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "piper" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[package]] +name = "pkg-config" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" + +[[package]] +name = "plist" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9d34169e64b3c7a80c8621a48adaf44e0cf62c78a9b25dd9dd35f1881a17cf9" +dependencies = [ + "base64 0.21.7", + "indexmap", + "line-wrap", + "quick-xml 0.31.0", + "time", +] + +[[package]] +name = "plotters" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" + +[[package]] +name = "plotters-svg" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "png" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "polling" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0c976a60b2d7e99d6f229e414670a9b85d13ac305cc6d1e9c134de58c5aaaf6" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix 0.38.32", + "tracing 0.1.41", + "windows-sys 0.52.0", +] + +[[package]] +name = "pollster" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" + +[[package]] +name = "potential_utf" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "presser" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +dependencies = [ + "toml_edit 0.23.5", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "profiling" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45f10e75d83c7aec79a6aa46f897075890e156b105eebe51cfa0abce51af025f" + +[[package]] +name = "psm" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +dependencies = [ + "cc", +] + +[[package]] +name = "psp-types" +version = "0.1.0" +source = "git+https://github.com/lapce/psp-types?rev=f7fea28f59e7b2d6faa1034a21679ad49b3524ad#f7fea28f59e7b2d6faa1034a21679ad49b3524ad" +dependencies = [ + "lsp-types", + "serde", + "serde_json", +] + +[[package]] +name = "pulldown-cmark" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8746739f11d39ce5ad5c2520a9b75285310dbfe78c541ccf832d38615765aec0" +dependencies = [ + "bitflags 2.9.1", + "getopts", + "memchr", + "pulldown-cmark-escape", + "unicase", +] + +[[package]] +name = "pulldown-cmark-escape" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae" + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quick-xml" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +dependencies = [ + "memchr", +] + +[[package]] +name = "quick-xml" +version = "0.38.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c" +dependencies = [ + "memchr", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.7", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.3", +] + +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "range-alloc" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8a99fddc9f0ba0a85884b8d14e3592853e787d581ca1816c91349b10e4eeab" + +[[package]] +name = "rangemap" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60fcc7d6849342eff22c4350c8b9a989ee8ceabc4b481253e8946b9fe83d684" + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "read-fonts" +version = "0.29.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04ca636dac446b5664bd16c069c00a9621806895b8bb02c2dc68542b23b8f25d" +dependencies = [ + "bytemuck", + "font-types", +] + +[[package]] +name = "rect_packer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8ffb4dfda4b01cc420847665dc480760d596ce186f2772a66ed32fe9acb1c45" + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +dependencies = [ + "bitflags 2.9.1", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom 0.2.7", + "redox_syscall 0.2.16", + "thiserror 1.0.69", +] + +[[package]] +name = "regalloc2" +version = "0.9.3" +source = "git+https://github.com/bytecodealliance/regalloc2?rev=5d79e12d0a93b10fc181f4da409b4671dd365228#5d79e12d0a93b10fc181f4da409b4671dd365228" +dependencies = [ + "hashbrown 0.14.5", + "log", + "rustc-hash 1.1.0", + "slice-group-by", + "smallvec", +] + +[[package]] +name = "regex" +version = "1.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "remain" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46aef80f842736de545ada6ec65b81ee91504efd6853f4b96de7414c42ae7443" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "renderdoc-sys" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" + +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-socks", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "resvg" +version = "0.45.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8928798c0a55e03c9ca6c4c6846f76377427d2c1e1f7e6de3c06ae57942df43" +dependencies = [ + "gif", + "image-webp 0.2.3", + "log", + "pico-args", + "rgb", + "svgtypes", + "tiny-skia", + "usvg", + "zune-jpeg", +] + +[[package]] +name = "rfd" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2bee61e6cffa4635c72d7d81a84294e28f0930db0ddcb0f66d10244674ebed" +dependencies = [ + "ashpd", + "block2 0.6.1", + "dispatch2", + "js-sys", + "log", + "objc2 0.6.3", + "objc2-app-kit 0.3.2", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "pollster", + "raw-window-handle", + "urlencoding", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-sys 0.59.0", +] + +[[package]] +name = "rgb" +version = "0.8.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20ec2d3e3fc7a92ced357df9cebd5a10b6fb2aa1ee797bf7e9ce2f17dffc8f59" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "roxmltree" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f" + +[[package]] +name = "roxmltree" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" + +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +dependencies = [ + "bitflags 2.9.1", + "errno", + "itoa", + "libc", + "linux-raw-sys 0.4.13", + "once_cell", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustix" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +dependencies = [ + "bitflags 2.9.1", + "errno", + "libc", + "linux-raw-sys 0.11.0", + "windows-sys 0.60.2", +] + +[[package]] +name = "rustix-openpty" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a25c3aad9fc1424eb82c88087789a7d938e1829724f3e4043163baf0d13cfc12" +dependencies = [ + "errno", + "libc", + "rustix 0.38.32", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "rustybuzz" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfb9cf8877777222e4a3bc7eb247e398b56baba500c38c1c46842431adc8b55c" +dependencies = [ + "bitflags 2.9.1", + "bytemuck", + "libm", + "smallvec", + "ttf-parser 0.21.1", + "unicode-bidi-mirroring 0.2.0", + "unicode-ccc 0.2.0", + "unicode-properties", + "unicode-script", +] + +[[package]] +name = "rustybuzz" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3c7c96f8a08ee34eff8857b11b49b07d71d1c3f4e88f8a88d4c9e9f90b1702" +dependencies = [ + "bitflags 2.9.1", + "bytemuck", + "core_maths", + "log", + "smallvec", + "ttf-parser 0.25.1", + "unicode-bidi-mirroring 0.4.0", + "unicode-ccc 0.4.0", + "unicode-properties", + "unicode-script", +] + +[[package]] +name = "ryu" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "sctk-adwaita" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" +dependencies = [ + "ab_glyph", + "log", + "memmap2", + "smithay-client-toolkit 0.19.2", + "tiny-skia", +] + +[[package]] +name = "security-framework" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "self_cell" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a" + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "serde_json" +version = "1.0.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "serde_spanned" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shellexpand" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ccc8076840c4da029af4f87e4e8daeb0fca6b87bbb02e10cb60b791450e11e4" +dependencies = [ + "dirs", +] + +[[package]] +name = "signal-hook" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "simplecss" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a11be7c62927d9427e9f40f3444d5499d868648e2edbc4e2116de69e7ec0e89d" +dependencies = [ + "log", +] + +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + +[[package]] +name = "sized-chunks" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" +dependencies = [ + "bitmaps", + "typenum", +] + +[[package]] +name = "skrifa" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbeb4ca4399663735553a09dd17ce7e49a0a0203f03b706b39628c4d913a8607" +dependencies = [ + "bytemuck", + "read-fonts", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slice-group-by" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03b634d87b960ab1a38c4fe143b508576f075e7c978bfad18217645ebfdfa2ec" + +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +dependencies = [ + "serde", +] + +[[package]] +name = "smithay-client-toolkit" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60e3d9941fa3bacf7c2bf4b065304faa14164151254cd16ce1b1bc8fc381600f" +dependencies = [ + "bitflags 2.9.1", + "calloop 0.12.3", + "calloop-wayland-source 0.2.0", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix 0.38.32", + "thiserror 1.0.69", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols 0.31.0", + "wayland-protocols-wlr 0.2.0", + "wayland-scanner", + "xkeysym", +] + +[[package]] +name = "smithay-client-toolkit" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" +dependencies = [ + "bitflags 2.9.1", + "calloop 0.13.0", + "calloop-wayland-source 0.3.0", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix 0.38.32", + "thiserror 1.0.69", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols 0.32.10", + "wayland-protocols-wlr 0.3.5", + "wayland-scanner", + "xkeysym", +] + +[[package]] +name = "smithay-clipboard" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb62b280ce5a5cba847669933a0948d00904cf83845c944eae96a4738cea1a6" +dependencies = [ + "libc", + "smithay-client-toolkit 0.18.0", + "wayland-backend", +] + +[[package]] +name = "smol_str" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" + +[[package]] +name = "smol_str" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9676b89cd56310a87b93dec47b11af744f34d5fc9f367b829474eec0a891350d" +dependencies = [ + "borsh", + "serde", +] + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "softbuffer" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61d5d17f23326fe0d9b0af282f73f3af666699420fd5f42629efd9c6e7dc166f" +dependencies = [ + "as-raw-xcb-connection", + "bytemuck", + "cfg_aliases", + "cocoa", + "core-graphics", + "drm", + "fastrand", + "foreign-types 0.5.0", + "js-sys", + "log", + "memmap2", + "objc", + "raw-window-handle", + "redox_syscall 0.5.8", + "rustix 0.38.32", + "tiny-xlib", + "wasm-bindgen", + "wayland-backend", + "wayland-client", + "wayland-sys", + "web-sys", + "windows-sys 0.52.0", + "x11rb", +] + +[[package]] +name = "spinning" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d4f0e86297cad2658d92a707320d87bf4e6ae1050287f51d19b67ef3f153a7b" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spirv" +version = "0.3.0+sdk-1.3.268.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" +dependencies = [ + "bitflags 2.9.1", +] + +[[package]] +name = "sptr" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strict-num" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" +dependencies = [ + "float-cmp", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "structdesc" +version = "0.1.0" +source = "git+https://github.com/lapce/structdesc?rev=bb56969f22fdb2c2d6c03f158fd4a2bdc983b659#bb56969f22fdb2c2d6c03f158fd4a2bdc983b659" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros 0.26.4", +] + +[[package]] +name = "strum" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" +dependencies = [ + "strum_macros 0.27.2", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.94", +] + +[[package]] +name = "strum_macros" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "svgtypes" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68c7541fff44b35860c1a7a47a7cadf3e4a304c457b58f9870d9706ece028afc" +dependencies = [ + "kurbo", + "siphasher", +] + +[[package]] +name = "swash" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f745de914febc7c9ab4388dfaf94bbc87e69f57bb41133a9b0c84d4be49856f3" +dependencies = [ + "skrifa", + "yazi", + "zeno", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "987bc0be1cdea8b10216bd06e2ca407d40b9543468fafd3ddfb02f36e77f71f3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "sys-locale" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e801cf239ecd6ccd71f03d270d67dd53d13e90aab208bf4b8fe4ad957ea949b0" +dependencies = [ + "libc", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "system-interface" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27ce32341b2c0b70c144bbf35627fdc1ef18c76ced5e5e7b3ee8b5ba6b2ab6a0" +dependencies = [ + "bitflags 2.9.1", + "cap-fs-ext", + "cap-std", + "fd-lock", + "io-lifetimes", + "rustix 0.38.32", + "windows-sys 0.48.0", + "winx", +] + +[[package]] +name = "taffy" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aaef0ac998e6527d6d0d5582f7e43953bb17221ac75bb8eb2fcc2db3396db1c" +dependencies = [ + "arrayvec", + "grid", + "serde", + "slotmap", +] + +[[package]] +name = "tar" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "target-lexicon" +version = "0.12.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix 0.38.32", + "windows-sys 0.52.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl 2.0.12", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "thread_local" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +dependencies = [ + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tiny-skia" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" +dependencies = [ + "arrayref", + "arrayvec", + "bytemuck", + "cfg-if", + "log", + "png", + "tiny-skia-path", +] + +[[package]] +name = "tiny-skia-path" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" +dependencies = [ + "arrayref", + "bytemuck", + "strict-num", +] + +[[package]] +name = "tiny-xlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4098d49269baa034a8d1eae9bd63e9fa532148d772121dace3bcd6a6c98eb6d" +dependencies = [ + "as-raw-xcb-connection", + "ctor", + "libloading", + "tracing 0.1.41", +] + +[[package]] +name = "tinystr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "to_method" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c4ceeeca15c8384bbc3e011dbd8fccb7f068a440b752b7d9b32ceb0ca0e2e8" + +[[package]] +name = "tokio" +version = "1.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-socks" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51165dfa029d2a65969413a6cc96f354b86b464498702f174a4efa13608fd8c0" +dependencies = [ + "either", + "futures-util", + "thiserror 1.0.69", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing 0.1.41", +] + +[[package]] +name = "toml" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +dependencies = [ + "serde", +] + +[[package]] +name = "toml" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime 0.6.3", + "toml_edit 0.20.2", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap", + "toml_datetime 0.6.3", + "winnow 0.5.10", +] + +[[package]] +name = "toml_edit" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime 0.6.3", + "winnow 0.5.10", +] + +[[package]] +name = "toml_edit" +version = "0.23.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2ad0b7ae9cfeef5605163839cb9221f453399f15cfb5c10be9885fcf56611f9" +dependencies = [ + "indexmap", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "winnow 0.7.14", +] + +[[package]] +name = "toml_parser" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +dependencies = [ + "winnow 0.7.14", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes 0.1.28", + "tracing-core 0.1.33", +] + +[[package]] +name = "tracing" +version = "0.2.0" +source = "git+https://github.com/tokio-rs/tracing?rev=908cc432a5994f6e17c8f36e13c217dc40085704#908cc432a5994f6e17c8f36e13c217dc40085704" +dependencies = [ + "pin-project-lite", + "tracing-attributes 0.2.0", + "tracing-core 0.2.0", +] + +[[package]] +name = "tracing-appender" +version = "0.2.0" +source = "git+https://github.com/tokio-rs/tracing?rev=908cc432a5994f6e17c8f36e13c217dc40085704#908cc432a5994f6e17c8f36e13c217dc40085704" +dependencies = [ + "crossbeam-channel", + "thiserror 1.0.69", + "time", + "tracing-subscriber", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "tracing-attributes" +version = "0.2.0" +source = "git+https://github.com/tokio-rs/tracing?rev=908cc432a5994f6e17c8f36e13c217dc40085704#908cc432a5994f6e17c8f36e13c217dc40085704" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tracing-core" +version = "0.2.0" +source = "git+https://github.com/tokio-rs/tracing?rev=908cc432a5994f6e17c8f36e13c217dc40085704#908cc432a5994f6e17c8f36e13c217dc40085704" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "git+https://github.com/tokio-rs/tracing?rev=908cc432a5994f6e17c8f36e13c217dc40085704#908cc432a5994f6e17c8f36e13c217dc40085704" +dependencies = [ + "log", + "once_cell", + "tracing-core 0.2.0", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.0" +source = "git+https://github.com/tokio-rs/tracing?rev=908cc432a5994f6e17c8f36e13c217dc40085704#908cc432a5994f6e17c8f36e13c217dc40085704" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core 0.2.0", + "tracing-log", +] + +[[package]] +name = "trash" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af3663fb8f476d674b9c61d1d2796acec725bef6bec4b41402a904252a25971e" +dependencies = [ + "chrono", + "libc", + "log", + "objc", + "once_cell", + "scopeguard", + "url", + "windows 0.44.0", +] + +[[package]] +name = "tree-sitter" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df7cc499ceadd4dcdf7ec6d4cbc34ece92c3fa07821e287aedecd4416c516dca" +dependencies = [ + "cc", + "regex", +] + +[[package]] +name = "try-lock" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + +[[package]] +name = "ttf-parser" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a464a4b34948a5f67fddd2b823c62d9d92e44be75058b99939eae6c5b6960b33" + +[[package]] +name = "ttf-parser" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4" + +[[package]] +name = "ttf-parser" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" + +[[package]] +name = "ttf-parser" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" +dependencies = [ + "core_maths", +] + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "uds_windows" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" +dependencies = [ + "memoffset", + "tempfile", + "winapi", +] + +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-bidi-mirroring" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cb788ffebc92c5948d0e997106233eeb1d8b9512f93f41651f52b6c5f5af86" + +[[package]] +name = "unicode-bidi-mirroring" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfa6e8c60bb66d49db113e0125ee8711b7647b5579dc7f5f19c42357ed039fe" + +[[package]] +name = "unicode-ccc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656" + +[[package]] +name = "unicode-ccc" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce61d488bcdc9bc8b5d1772c404828b17fc481c0a582b5581e95fb233aef503e" + +[[package]] +name = "unicode-ident" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + +[[package]] +name = "unicode-properties" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" + +[[package]] +name = "unicode-script" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d817255e1bed6dfd4ca47258685d14d2bdcfbc64fdc9e3819bd5848057b8ecc" + +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "unicode-vo" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94" + +[[package]] +name = "unicode-width" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "usvg" +version = "0.45.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80be9b06fbae3b8b303400ab20778c80bbaf338f563afe567cf3c9eea17b47ef" +dependencies = [ + "base64 0.22.0", + "data-url", + "flate2", + "fontdb 0.23.0", + "imagesize", + "kurbo", + "log", + "pico-args", + "roxmltree 0.20.0", + "rustybuzz 0.20.1", + "simplecss", + "siphasher", + "strict-num", + "svgtypes", + "tiny-skia-path", + "unicode-bidi", + "unicode-script", + "unicode-vo", + "xmlwriter", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "vte" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40eb22ae96f050e0c0d6f7ce43feeae26c348fc4dea56928ca81537cfaa6188b" +dependencies = [ + "bitflags 2.9.1", + "cursor-icon", + "log", + "serde", + "utf8parse", + "vte_generate_state_changes", +] + +[[package]] +name = "vte_generate_state_changes" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "wasi-cap-std-sync" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5837041da0e6ec454a819bc20ab0f8a70b2c44bf4d33287aea9fdb16bc4d597" +dependencies = [ + "anyhow", + "async-trait", + "cap-fs-ext", + "cap-rand", + "cap-std", + "cap-time-ext", + "fs-set-times", + "io-extras", + "io-lifetimes", + "once_cell", + "rustix 0.38.32", + "system-interface", + "tracing 0.1.41", + "wasi-common", + "windows-sys 0.48.0", +] + +[[package]] +name = "wasi-common" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6efb2e9d72c6a070d62cf7b698acebab6faca9aacf26412bdecb9fabab79fd09" +dependencies = [ + "anyhow", + "bitflags 2.9.1", + "cap-rand", + "cap-std", + "io-extras", + "log", + "rustix 0.38.32", + "thiserror 1.0.69", + "tracing 0.1.41", + "wasmtime", + "wiggle", + "windows-sys 0.48.0", +] + +[[package]] +name = "wasi-experimental-http-wasmtime" +version = "0.10.0" +source = "git+https://github.com/lapce/wasi-experimental-http#21419eb785cb583ead180f25a9685fa16de7f326" +dependencies = [ + "anyhow", + "bytes", + "futures", + "http", + "reqwest", + "thiserror 1.0.69", + "tokio", + "tracing 0.1.41", + "url", + "wasi-common", + "wasmtime", + "wasmtime-wasi", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" +dependencies = [ + "cfg-if", + "futures-util", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.94", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-encoder" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca90ba1b5b0a70d3d49473c5579951f3bddc78d47b59256d2f9d4922b150aca" +dependencies = [ + "leb128", +] + +[[package]] +name = "wasmparser" +version = "0.115.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e06c0641a4add879ba71ccb3a1e4278fd546f76f1eafb21d8f7b07733b547cd5" +dependencies = [ + "indexmap", + "semver", +] + +[[package]] +name = "wasmprinter" +version = "0.2.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e74458a9bc5cc9c7108abfa0fe4dc88d5abf1f3baf194df3264985f17d559b5e" +dependencies = [ + "anyhow", + "wasmparser", +] + +[[package]] +name = "wasmtime" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76e45ad44701a658aa3eb138a5bb63a10a35fa8874419b5e6047cfa54b2eb2cd" +dependencies = [ + "anyhow", + "async-trait", + "bincode", + "bumpalo", + "cfg-if", + "encoding_rs", + "fxprof-processed-profile", + "indexmap", + "libc", + "log", + "object", + "once_cell", + "paste", + "psm", + "rayon", + "serde", + "serde_derive", + "serde_json", + "target-lexicon", + "wasm-encoder", + "wasmparser", + "wasmtime-cache", + "wasmtime-component-macro", + "wasmtime-component-util", + "wasmtime-cranelift", + "wasmtime-environ", + "wasmtime-fiber", + "wasmtime-jit", + "wasmtime-runtime", + "wasmtime-winch", + "wat", + "windows-sys 0.48.0", +] + +[[package]] +name = "wasmtime-asm-macros" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a5944c8415853471b6ddff1f38b09d58fe5ac3c5dad27ee6bc03ca29e65cca" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "wasmtime-cache" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c16f85353656b301a4472ad649e9b17cc47400cee50a94bd9b24e7886a8130f" +dependencies = [ + "anyhow", + "base64 0.21.7", + "bincode", + "directories-next", + "log", + "rustix 0.38.32", + "serde", + "serde_derive", + "sha2", + "toml 0.5.9", + "windows-sys 0.48.0", + "zstd", +] + +[[package]] +name = "wasmtime-component-macro" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b174f64cd4b189396dde1bbe137f349d3c98525b8564b539f94ce978c571173d" +dependencies = [ + "anyhow", + "proc-macro2", + "quote", + "syn 2.0.94", + "wasmtime-component-util", + "wasmtime-wit-bindgen", + "wit-parser", +] + +[[package]] +name = "wasmtime-component-util" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b18ff6d21a0ef69de7fd4db023646b386982e78b7e5c06e6455d98cf44774954" + +[[package]] +name = "wasmtime-cranelift" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7dbb50f43a7eb897f222fb427b3ba50620014eb43673b5bfa50cfd5b2681e37" +dependencies = [ + "anyhow", + "cfg-if", + "cranelift-codegen", + "cranelift-control", + "cranelift-entity", + "cranelift-frontend", + "cranelift-native", + "cranelift-wasm", + "gimli", + "log", + "object", + "target-lexicon", + "thiserror 1.0.69", + "wasmparser", + "wasmtime-cranelift-shared", + "wasmtime-environ", + "wasmtime-versioned-export-macros", +] + +[[package]] +name = "wasmtime-cranelift-shared" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc154520d9c910f02ce90735691186f90b220f532f9b0725543b054bf0d8381" +dependencies = [ + "anyhow", + "cranelift-codegen", + "cranelift-control", + "cranelift-native", + "gimli", + "object", + "target-lexicon", + "wasmtime-environ", +] + +[[package]] +name = "wasmtime-environ" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d72b405647d5378ed3ff7889586d26d79825641f477f288bc72ab416136ad4da" +dependencies = [ + "anyhow", + "cranelift-entity", + "gimli", + "indexmap", + "log", + "object", + "serde", + "serde_derive", + "target-lexicon", + "thiserror 1.0.69", + "wasm-encoder", + "wasmparser", + "wasmprinter", + "wasmtime-component-util", + "wasmtime-types", +] + +[[package]] +name = "wasmtime-fiber" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8702d1efdf73df040a586e239fffc6883d88edf60ac6f593b41392cc1f97c754" +dependencies = [ + "cc", + "cfg-if", + "rustix 0.38.32", + "wasmtime-asm-macros", + "wasmtime-versioned-export-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "wasmtime-jit" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c7462341d96d44b30776c7aec411c0cc11b15fde44b58efcbf269d21570bd7a" +dependencies = [ + "addr2line", + "anyhow", + "bincode", + "cfg-if", + "cpp_demangle", + "gimli", + "ittapi", + "log", + "object", + "rustc-demangle", + "rustix 0.38.32", + "serde", + "serde_derive", + "target-lexicon", + "wasmtime-environ", + "wasmtime-jit-debug", + "wasmtime-jit-icache-coherence", + "wasmtime-runtime", + "windows-sys 0.48.0", +] + +[[package]] +name = "wasmtime-jit-debug" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa128cdc680b5982087ea64eb73b63e96570b338fd6438b704b313eb854fd94" +dependencies = [ + "object", + "once_cell", + "rustix 0.38.32", + "wasmtime-versioned-export-macros", +] + +[[package]] +name = "wasmtime-jit-icache-coherence" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0980a96b16abbdaf829858d2389697b1d6cfc6a903873fd74b7e47a6b1045584" +dependencies = [ + "cfg-if", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "wasmtime-runtime" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de31031471f04c0bad4f5e29b0e632db318488dd030cdb794ef15f91a52f2338" +dependencies = [ + "anyhow", + "cc", + "cfg-if", + "encoding_rs", + "indexmap", + "libc", + "log", + "mach", + "memfd", + "memoffset", + "paste", + "rand 0.8.5", + "rustix 0.38.32", + "sptr", + "wasm-encoder", + "wasmtime-asm-macros", + "wasmtime-environ", + "wasmtime-fiber", + "wasmtime-jit-debug", + "wasmtime-versioned-export-macros", + "wasmtime-wmemcheck", + "windows-sys 0.48.0", +] + +[[package]] +name = "wasmtime-types" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e98a2c09807eee3207991bf05b6271aa3817c548224ded6b7bac61374ef9221" +dependencies = [ + "cranelift-entity", + "serde", + "serde_derive", + "thiserror 1.0.69", + "wasmparser", +] + +[[package]] +name = "wasmtime-versioned-export-macros" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73190422af3b408daa3c791f97f50c62509746c09de934d69dae602c65809663" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "wasmtime-wasi" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1022616613f6279243392b00990ac81135f0c46018eba620538392342fc93df9" +dependencies = [ + "anyhow", + "async-trait", + "bitflags 2.9.1", + "bytes", + "cap-fs-ext", + "cap-net-ext", + "cap-rand", + "cap-std", + "cap-time-ext", + "fs-set-times", + "futures", + "io-extras", + "io-lifetimes", + "libc", + "log", + "once_cell", + "rustix 0.38.32", + "system-interface", + "thiserror 1.0.69", + "tokio", + "tracing 0.1.41", + "url", + "wasi-cap-std-sync", + "wasi-common", + "wasmtime", + "wiggle", + "windows-sys 0.48.0", +] + +[[package]] +name = "wasmtime-winch" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff589e9b8f701ea4d66472115d23145fe58b62d1289c51f4a2e36c5dccf6053" +dependencies = [ + "anyhow", + "cranelift-codegen", + "gimli", + "object", + "target-lexicon", + "wasmparser", + "wasmtime-cranelift-shared", + "wasmtime-environ", + "winch-codegen", +] + +[[package]] +name = "wasmtime-wit-bindgen" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f672060c021afd9a3ab72f4e319d1f7bb1f4e973d5e24130bb0bb11eba356f5e" +dependencies = [ + "anyhow", + "heck 0.4.1", + "indexmap", + "wit-parser", +] + +[[package]] +name = "wasmtime-wmemcheck" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d40e574507de689ee8ad428b5ddfc6bc81b5eff3c8d493e0b8ec1ebf7e4eadf" + +[[package]] +name = "wast" +version = "35.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ef140f1b49946586078353a453a1d28ba90adfc54dde75710bc1931de204d68" +dependencies = [ + "leb128", +] + +[[package]] +name = "wast" +version = "66.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93cb43b0ac6dd156f2c375735ccfd72b012a7c0a6e6d09503499b8d3cb6e6072" +dependencies = [ + "leb128", + "memchr", + "unicode-width", + "wasm-encoder", +] + +[[package]] +name = "wat" +version = "1.0.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e367582095d2903caeeea9acbb140e1db9c7677001efa4347c3687fd34fe7072" +dependencies = [ + "wast 66.0.2", +] + +[[package]] +name = "wayland-backend" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fee64194ccd96bf648f42a65a7e589547096dfa702f7cadef84347b66ad164f9" +dependencies = [ + "cc", + "downcast-rs", + "rustix 1.1.3", + "scoped-tls", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-client" +version = "0.31.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e6faa537fbb6c186cb9f1d41f2f811a4120d1b57ec61f50da451a0c5122bec" +dependencies = [ + "bitflags 2.9.1", + "rustix 1.1.3", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-csd-frame" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" +dependencies = [ + "bitflags 2.9.1", + "cursor-icon", + "wayland-backend", +] + +[[package]] +name = "wayland-cursor" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a206e8b2b53b1d3fcb9428fec72bc278ce539e2fa81fe2bfc1ab27703d5187b9" +dependencies = [ + "rustix 0.38.32", + "wayland-client", + "xcursor", +] + +[[package]] +name = "wayland-protocols" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e253d7107ba913923dc253967f35e8561a3c65f914543e46843c88ddd729e21c" +dependencies = [ + "bitflags 2.9.1", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols" +version = "0.32.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baeda9ffbcfc8cd6ddaade385eaf2393bd2115a69523c735f12242353c3df4f3" +dependencies = [ + "bitflags 2.9.1", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-plasma" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa98634619300a535a9a97f338aed9a5ff1e01a461943e8346ff4ae26007306b" +dependencies = [ + "bitflags 2.9.1", + "wayland-backend", + "wayland-client", + "wayland-protocols 0.32.10", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" +dependencies = [ + "bitflags 2.9.1", + "wayland-backend", + "wayland-client", + "wayland-protocols 0.31.0", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "782e12f6cd923c3c316130d56205ebab53f55d6666b7faddfad36cecaeeb4022" +dependencies = [ + "bitflags 2.9.1", + "wayland-backend", + "wayland-client", + "wayland-protocols 0.32.10", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5423e94b6a63e68e439803a3e153a9252d5ead12fd853334e2ad33997e3889e3" +dependencies = [ + "proc-macro2", + "quick-xml 0.38.4", + "quote", +] + +[[package]] +name = "wayland-sys" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6dbfc3ac5ef974c92a2235805cc0114033018ae1290a72e474aa8b28cbbdfd" +dependencies = [ + "dlib", + "log", + "once_cell", + "pkg-config", +] + +[[package]] +name = "web-sys" +version = "0.3.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + +[[package]] +name = "wgpu" +version = "24.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b0b3436f0729f6cdf2e6e9201f3d39dc95813fad61d826c1ed07918b4539353" +dependencies = [ + "arrayvec", + "bitflags 2.9.1", + "cfg_aliases", + "document-features", + "js-sys", + "log", + "naga", + "parking_lot", + "profiling", + "raw-window-handle", + "smallvec", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-core" +version = "24.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f0aa306497a238d169b9dc70659105b4a096859a34894544ca81719242e1499" +dependencies = [ + "arrayvec", + "bit-vec", + "bitflags 2.9.1", + "cfg_aliases", + "document-features", + "indexmap", + "log", + "naga", + "once_cell", + "parking_lot", + "profiling", + "raw-window-handle", + "rustc-hash 1.1.0", + "smallvec", + "thiserror 2.0.12", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-hal" +version = "24.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f112f464674ca69f3533248508ee30cb84c67cf06c25ff6800685f5e0294e259" +dependencies = [ + "android_system_properties", + "arrayvec", + "ash", + "bit-set", + "bitflags 2.9.1", + "block", + "bytemuck", + "cfg_aliases", + "core-graphics-types", + "glow", + "glutin_wgl_sys", + "gpu-alloc", + "gpu-allocator", + "gpu-descriptor", + "js-sys", + "khronos-egl", + "libc", + "libloading", + "log", + "metal", + "naga", + "ndk-sys 0.5.0+25.2.9519653", + "objc", + "once_cell", + "ordered-float", + "parking_lot", + "profiling", + "range-alloc", + "raw-window-handle", + "renderdoc-sys", + "rustc-hash 1.1.0", + "smallvec", + "thiserror 2.0.12", + "wasm-bindgen", + "web-sys", + "wgpu-types", + "windows 0.58.0", + "windows-core", +] + +[[package]] +name = "wgpu-types" +version = "24.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50ac044c0e76c03a0378e7786ac505d010a873665e2d51383dcff8dd227dc69c" +dependencies = [ + "bitflags 2.9.1", + "js-sys", + "log", + "web-sys", +] + +[[package]] +name = "wiggle" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "334709283558d9ebb0206cd1842c4fa619ff467d68c71eff982376d9c999d636" +dependencies = [ + "anyhow", + "async-trait", + "bitflags 2.9.1", + "thiserror 1.0.69", + "tracing 0.1.41", + "wasmtime", + "wiggle-macro", +] + +[[package]] +name = "wiggle-generate" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4143cb3a8c65efceba6fc3bf49769b7b5d60090f1226e708365044c1136584ee" +dependencies = [ + "anyhow", + "heck 0.4.1", + "proc-macro2", + "quote", + "shellexpand", + "syn 2.0.94", + "witx", +] + +[[package]] +name = "wiggle-macro" +version = "14.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56981968f26952a527f78cf3aeb5ac436db82d3be1682a217a1835754fa50f51" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", + "wiggle-generate", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22" +dependencies = [ + "windows-sys 0.60.2", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "winch-codegen" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2942fc0530ed88259df32f09f52a4222583e1ec7c3fa3f4a911905bbf70c3b0" +dependencies = [ + "anyhow", + "cranelift-codegen", + "gimli", + "regalloc2", + "smallvec", + "target-lexicon", + "wasmparser", + "wasmtime-environ", +] + +[[package]] +name = "windows" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.3", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "winit" +version = "0.30.7" +source = "git+https://github.com/rust-windowing/winit?rev=ee245c569d65fdeacf705ee5eedb564508d10ebe#ee245c569d65fdeacf705ee5eedb564508d10ebe" +dependencies = [ + "ahash", + "android-activity", + "atomic-waker", + "bitflags 2.9.1", + "block2 0.5.1", + "bytemuck", + "calloop 0.13.0", + "cfg_aliases", + "concurrent-queue", + "core-foundation", + "core-graphics", + "cursor-icon", + "dpi", + "js-sys", + "libc", + "memmap2", + "ndk", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", + "objc2-ui-kit", + "orbclient", + "percent-encoding", + "pin-project", + "raw-window-handle", + "redox_syscall 0.5.8", + "rustix 0.38.32", + "sctk-adwaita", + "serde", + "smithay-client-toolkit 0.19.2", + "smol_str 0.3.2", + "tracing 0.1.41", + "unicode-segmentation", + "wasm-bindgen", + "wasm-bindgen-futures", + "wayland-backend", + "wayland-client", + "wayland-protocols 0.32.10", + "wayland-protocols-plasma", + "web-sys", + "web-time", + "windows-sys 0.52.0", + "x11-dl", + "x11rb", + "xkbcommon-dl", +] + +[[package]] +name = "winnow" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5504cc7644f4b593cbc05c4a55bf9bd4e94b867c3c0bd440934174d50482427d" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "winx" +version = "0.36.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357bb8e2932df531f83b052264b050b81ba0df90ee5a59b2d1d3949f344f81e5" +dependencies = [ + "bitflags 2.9.1", + "windows-sys 0.48.0", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.9.1", +] + +[[package]] +name = "wit-parser" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ace9943d89bbf3dbbc71b966da0e7302057b311f36a4ac3d65ddfef17b52cf" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", +] + +[[package]] +name = "witx" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e366f27a5cabcddb2706a78296a40b8fcc451e1a6aba2fc1d94b4a01bdaaef4b" +dependencies = [ + "anyhow", + "log", + "thiserror 1.0.69", + "wast 35.0.2", +] + +[[package]] +name = "writeable" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" + +[[package]] +name = "x11-clipboard" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98785a09322d7446e28a13203d2cae1059a0dd3dfb32cb06d0a225f023d8286" +dependencies = [ + "libc", + "x11rb", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "x11rb" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8f25ead8c7e4cba123243a6367da5d3990e0d3affa708ea19dce96356bd9f1a" +dependencies = [ + "as-raw-xcb-connection", + "gethostname", + "libc", + "libloading", + "once_cell", + "rustix 0.38.32", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e63e71c4b8bd9ffec2c963173a4dc4cbde9ee96961d4fcb4429db9929b606c34" + +[[package]] +name = "xattr" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +dependencies = [ + "libc", + "linux-raw-sys 0.4.13", + "rustix 0.38.32", +] + +[[package]] +name = "xcursor" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7" +dependencies = [ + "nom", +] + +[[package]] +name = "xkbcommon-dl" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" +dependencies = [ + "bitflags 2.9.1", + "dlib", + "log", + "once_cell", + "xkeysym", +] + +[[package]] +name = "xkeysym" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054a8e68b76250b253f671d1268cb7f1ae089ec35e195b2efb2a4e9a836d0621" + +[[package]] +name = "xml-rs" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" + +[[package]] +name = "xmlwriter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" + +[[package]] +name = "yazi" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5" + +[[package]] +name = "yoke" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", + "synstructure", +] + +[[package]] +name = "zbus" +version = "5.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3a7c7cee313d044fca3f48fa782cb750c79e4ca76ba7bc7718cd4024cdf6f68" +dependencies = [ + "async-broadcast", + "async-executor", + "async-io", + "async-lock 3.3.0", + "async-process", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "enumflags2", + "event-listener 5.4.0", + "futures-core", + "futures-lite", + "hex", + "nix", + "ordered-stream", + "serde", + "serde_repr", + "tracing 0.1.41", + "uds_windows", + "windows-sys 0.59.0", + "winnow 0.7.14", + "zbus_macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "5.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17e7e5eec1550f747e71a058df81a9a83813ba0f6a95f39c4e218bdc7ba366a" +dependencies = [ + "proc-macro-crate 3.4.0", + "proc-macro2", + "quote", + "syn 2.0.94", + "zbus_names", + "zvariant", + "zvariant_utils", +] + +[[package]] +name = "zbus_names" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97" +dependencies = [ + "serde", + "static_assertions", + "winnow 0.7.14", + "zvariant", +] + +[[package]] +name = "zeno" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", + "synstructure", +] + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "byteorder", + "crc32fast", + "crossbeam-utils", + "flate2", +] + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.1+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fd07cbbc53846d9145dbffdf6dd09a7a0aa52be46741825f5c97bdd4f73f12b" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "zune-core" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" + +[[package]] +name = "zune-jpeg" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec866b44a2a1fd6133d363f073ca1b179f438f99e7e5bfb1e33f7181facfe448" +dependencies = [ + "zune-core", +] + +[[package]] +name = "zvariant" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d30786f75e393ee63a21de4f9074d4c038d52c5b1bb4471f955db249f9dffb1" +dependencies = [ + "endi", + "enumflags2", + "serde", + "url", + "winnow 0.7.14", + "zvariant_derive", + "zvariant_utils", +] + +[[package]] +name = "zvariant_derive" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75fda702cd42d735ccd48117b1630432219c0e9616bf6cb0f8350844ee4d9580" +dependencies = [ + "proc-macro-crate 3.4.0", + "proc-macro2", + "quote", + "syn 2.0.94", + "zvariant_utils", +] + +[[package]] +name = "zvariant_utils" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16edfee43e5d7b553b77872d99bc36afdda75c223ca7ad5e3fbecd82ca5fc34" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "static_assertions", + "syn 2.0.94", + "winnow 0.7.14", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..5b91afe --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,146 @@ +[package] +name = "lapce" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +license = { workspace = true } +rust-version = { workspace = true } +default-run = "lapce" + +[dependencies] +lapce-app = { path = "./lapce-app" } +lapce-proxy = { path = "./lapce-proxy" } + +[[bin]] +name = "lapce" +path = "lapce-app/src/bin/lapce.rs" + +[[bin]] +name = "lapce-proxy" +path = "lapce-proxy/src/bin/lapce-proxy.rs" + +[workspace] +members = ["lapce-app", "lapce-proxy", "lapce-rpc", "lapce-core"] + +[workspace.package] +version = "0.4.6" +edition = "2024" +rust-version = "1.87.0" +license = "Apache-2.0" +homepage = "https://lapce.dev" +authors = ["Dongdong Zhou "] + +[workspace.dependencies] +anyhow = { version = "1.0" } +backtrace = { version = "0.3" } +chrono = { version = "0.4" } +clap = { version = "4.5.0", default-features = false, features = ["std", "help", "usage", "derive"] } +crossbeam-channel = { version = "0.5.12" } +directories = { version = "4.0.1" } +flate2 = { version = "1.0" } +git2 = { version = "0.20.0", features = ["vendored-openssl"] } +globset = { version = "0.4.14" } +hashbrown = { version = "0.14.5", features = ["serde"] } +im = { version = "15.0.0", features = ["serde"] } +include_dir = { version = "0.7" } +indexmap = { version = "2.0", features = ["serde"] } +interprocess = { version = "1.2.1" } +itertools = { version = "0.12.1" } +notify = { version = "5.2.0", features = ["serde"] } +once_cell = { version = "1.19" } +parking_lot = { version = "0.12.3" } +rayon = { version = "1.10.0" } +regex = { version = "1.10.5" } +remain = { version = "0.2" } +semver = { version = "1.0" } +reqwest = { version = "0.11", features = ["blocking", "json", "socks"] } +serde = { version = "1.0" } +serde_json = { version = "1.0" } +smallvec = { version = "1.15.1" } +strum = { version = "0.27.1" } +strum_macros = { version = "0.27.1" } +tar = { version = "0.4" } +tempfile = { version = "3.10.1" } +thiserror = { version = "1.0" } +toml = { version = "*" } +toml_edit = { version = "0.20.2", features = ["serde"] } +url = { version = "2.5.0" } +zstd = { version = "0.11.2" } # follow same version wasmtime-cache in lockfile + +lsp-types = { version = "0.95.1", features = ["proposed"] } # not following semver, so should be locked to patch version updates only +psp-types = { git = "https://github.com/lapce/psp-types", rev = "f7fea28f59e7b2d6faa1034a21679ad49b3524ad" } + +lapce-xi-rope = { version = "0.3.2", features = ["serde"] } + +lapce-core = { path = "./lapce-core" } +lapce-rpc = { path = "./lapce-rpc" } +lapce-proxy = { path = "./lapce-proxy" } + +[workspace.dependencies.floem] +# path = "../floem" +git = "https://github.com/lapce/floem" +rev = "31fa8f444c37f4c314f47d88c23ffdbc25f2ab53" +features = ["editor", "serde", "default-image-formats", "rfd-async-std"] + +[workspace.dependencies.floem-editor-core] +# path = "../floem/editor-core/" +git = "https://github.com/lapce/floem" +rev = "31fa8f444c37f4c314f47d88c23ffdbc25f2ab53" +features = ["serde"] + +[patch.crates-io] +# Temporarily patch lsp-types with a version that adds message-type debug +lsp-types = { git = "https://github.com/lapce/lsp-types", rev = "feaa1e2ec80975c9dadd400a238ceacf071058e6" } +regalloc2 = { rev = "5d79e12d0a93b10fc181f4da409b4671dd365228", git = "https://github.com/bytecodealliance/regalloc2" } + +# cargo vendor issue: https://github.com/rust-lang/cargo/issues/10310 +# dpi comes from winit (source) and muda (crate) +dpi = { git = "https://github.com/rust-windowing/winit", rev = "ee245c569d65fdeacf705ee5eedb564508d10ebe" } + + +[workspace.dependencies.tracing] +git = "https://github.com/tokio-rs/tracing" +rev = "908cc432a5994f6e17c8f36e13c217dc40085704" +package = "tracing" + +[workspace.dependencies.tracing-log] +git = "https://github.com/tokio-rs/tracing" +rev = "908cc432a5994f6e17c8f36e13c217dc40085704" +package = "tracing-log" + +[workspace.dependencies.tracing-subscriber] +git = "https://github.com/tokio-rs/tracing" +rev = "908cc432a5994f6e17c8f36e13c217dc40085704" +package = "tracing-subscriber" + +[workspace.dependencies.tracing-appender] +git = "https://github.com/tokio-rs/tracing" +rev = "908cc432a5994f6e17c8f36e13c217dc40085704" +package = "tracing-appender" + +[workspace.dependencies.alacritty_terminal] +git = "https://github.com/alacritty/alacritty" +rev = "cacdb5bb3b72bad2c729227537979d95af75978f" + +[workspace.dependencies.windows-sys] +version = "0" +features = ["Win32_Foundation"] + +[profile.release-lto] +inherits = "release" +lto = true +codegen-units = 1 + +# A profile which compiles all (non-workspace) dependencies in release mode +# but Lapce code in dev mode. This gives a good debugging experience for your +# code and fast performance of other people's code. After the initial +# build subsequent ones are as fast as dev mode builds. +# See https://doc.rust-lang.org/cargo/reference/profiles.html +# To use this profile: +# cargo build --profile fastdev +# cargo run --profile fastdev --bin lapce +[profile.fastdev.package."*"] +opt-level = 3 + +[profile.fastdev] +inherits = "dev" diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..101a86a --- /dev/null +++ b/Makefile @@ -0,0 +1,84 @@ +# This Makefile is intended *only* for building macOS binaries of Lapce. +# It uses macOS-specific tools like `lipo`, `codesign`, and `hdiutil`, +# and requires that a valid Apple Developer signing identity is installed +# and available in the system Keychain under the fingerprint set in +# CODESIGN_IDENTITY. +# +# See `docs/building-from-source.md`. + +TARGET = lapce + +CODESIGN_IDENTITY = FAC8FBEA99169DC1980731029648F110628D6A32 + +ASSETS_DIR = extra +RELEASE_DIR = target/release-lto + +APP_NAME = Lapce.app +APP_TEMPLATE = $(ASSETS_DIR)/macos/$(APP_NAME) +APP_DIR = $(RELEASE_DIR)/macos +APP_BINARY = $(RELEASE_DIR)/$(TARGET) +APP_BINARY_DIR = $(APP_DIR)/$(APP_NAME)/Contents/MacOS +APP_EXTRAS_DIR = $(APP_DIR)/$(APP_NAME)/Contents/Resources + +DMG_NAME = Lapce.dmg +DMG_DIR = $(RELEASE_DIR)/macos + +vpath $(TARGET) $(RELEASE_DIR) +vpath $(APP_NAME) $(APP_DIR) +vpath $(DMG_NAME) $(APP_DIR) + +all: help + +help: ## Print this help message + @grep -E '^[a-zA-Z._-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +ubuntu-deps: + apt-get update -y + apt-get install -y clang libxkbcommon-x11-dev pkg-config libvulkan-dev libgtk-3-dev libwayland-dev xorg-dev libxcb-shape0-dev libxcb-xfixes0-dev + +binary: $(TARGET)-native ## Build a release binary +binary-universal: $(TARGET)-universal ## Build a universal release binary +$(TARGET)-native: + MACOSX_DEPLOYMENT_TARGET="10.11" cargo build --profile release-lto + @lipo target/release-lto/$(TARGET) -create -output $(APP_BINARY) +$(TARGET)-universal: + MACOSX_DEPLOYMENT_TARGET="10.11" cargo build --profile release-lto --target=x86_64-apple-darwin + MACOSX_DEPLOYMENT_TARGET="10.11" cargo build --profile release-lto --target=aarch64-apple-darwin + @lipo target/{x86_64,aarch64}-apple-darwin/release-lto/$(TARGET) -create -output $(APP_BINARY) + /usr/bin/codesign -vvv --deep --entitlements $(ASSETS_DIR)/entitlements.plist --strict --options=runtime --force -s $(CODESIGN_IDENTITY) $(APP_BINARY) + +app: $(APP_NAME)-native ## Create a Lapce.app +app-universal: $(APP_NAME)-universal ## Create a universal Lapce.app +$(APP_NAME)-%: $(TARGET)-% + @mkdir -p $(APP_BINARY_DIR) + @mkdir -p $(APP_EXTRAS_DIR) + @cp -fRp $(APP_TEMPLATE) $(APP_DIR) + @cp -fp $(APP_BINARY) $(APP_BINARY_DIR) + @touch -r "$(APP_BINARY)" "$(APP_DIR)/$(APP_NAME)" + @echo "Created '$(APP_NAME)' in '$(APP_DIR)'" + xattr -c $(APP_DIR)/$(APP_NAME)/Contents/Info.plist + xattr -c $(APP_DIR)/$(APP_NAME)/Contents/Resources/lapce.icns + /usr/bin/codesign -vvv --deep --entitlements $(ASSETS_DIR)/entitlements.plist --strict --options=runtime --force -s $(CODESIGN_IDENTITY) $(APP_DIR)/$(APP_NAME) + +dmg: $(DMG_NAME)-native ## Create a Lapce.dmg +dmg-universal: $(DMG_NAME)-universal ## Create a universal Lapce.dmg +$(DMG_NAME)-%: $(APP_NAME)-% + @echo "Packing disk image..." + @ln -sf /Applications $(DMG_DIR)/Applications + @hdiutil create $(DMG_DIR)/$(DMG_NAME) \ + -volname "Lapce" \ + -fs HFS+ \ + -srcfolder $(APP_DIR) \ + -ov -format UDZO + @echo "Packed '$(APP_NAME)' in '$(APP_DIR)'" + /usr/bin/codesign -vvv --deep --entitlements $(ASSETS_DIR)/entitlements.plist --strict --options=runtime --force -s $(CODESIGN_IDENTITY) $(DMG_DIR)/$(DMG_NAME) + +install: $(INSTALL)-native ## Mount disk image +install-universal: $(INSTALL)-native ## Mount universal disk image +$(INSTALL)-%: $(DMG_NAME)-% + @open $(DMG_DIR)/$(DMG_NAME) + +.PHONY: app binary clean dmg install $(TARGET) $(TARGET)-universal + +clean: ## Remove all build artifacts + @cargo clean diff --git a/README.md b/README.md new file mode 100644 index 0000000..edfec11 --- /dev/null +++ b/README.md @@ -0,0 +1,61 @@ +

+ +
+ Lapce +
+

+ +

Lightning-fast And Powerful Code Editor

+ + +
+ + +Lapce (IPA: /læps/) is written in pure Rust, with a UI in [Floem](https://github.com/lapce/floem). It is designed with [Rope Science](https://xi-editor.io/docs/rope_science_00.html) from the [Xi-Editor](https://github.com/xi-editor/xi-editor), enabling lightning-fast computation, and leverages [wgpu](https://github.com/gfx-rs/wgpu) for rendering. More information about the features of Lapce can be found on the [main website](https://lapce.dev) and user documentation can be found on [GitBook](https://docs.lapce.dev/). + +![](https://github.com/lapce/lapce/blob/master/extra/images/screenshot.png?raw=true) + +## Features + +* Built-in LSP ([Language Server Protocol](https://microsoft.github.io/language-server-protocol/)) support to give you intelligent code features such as: completion, diagnostics and code actions +* Modal editing support as first class citizen (Vim-like, and toggleable) +* Built-in remote development support inspired by [VSCode Remote Development](https://code.visualstudio.com/docs/remote/remote-overview). Enjoy the benefits of a "local" experience, and seamlessly gain the full power of a remote system. We also have [Lapdev](https://lap.dev/) which can help manage your remote dev environments. +* Plugins can be written in programming languages that can compile to the [WASI](https://wasi.dev/) format (C, Rust, [AssemblyScript](https://www.assemblyscript.org/)) +* Built-in terminal, so you can execute commands in your workspace, without leaving Lapce. + +## Installation + +You can find pre-built releases for Windows, Linux and macOS [here](https://github.com/lapce/lapce/releases), or [installing with a package manager](docs/installing-with-package-manager.md). +If you'd like to compile from source, you can find the [guide](docs/building-from-source.md). + +## Contributing + + + Open in Lapdev + + +[Lapdev](https://lap.dev/), developed by the Lapce team, is a cloud dev env service similar to GitHub Codespaces. By clicking the button above, you'll be taken to a fully set up Lapce dev env where you can browse the code and start developing. All dependencies are pre-installed, so you can get straight to code. + +Guidelines for contributing to Lapce can be found in [`CONTRIBUTING.md`](CONTRIBUTING.md). + +## Feedback & Contact + +The most popular place for Lapce developers and users is on the [Discord server](https://discord.gg/n8tGJ6Rn6D). + +Or, join the discussion on [Reddit](https://www.reddit.com/r/lapce/) where we are just getting started. + +There is also a [Matrix Space](https://matrix.to/#/#lapce-editor:matrix.org), which is linked to the content from the Discord server. + +## License + +Lapce is released under the Apache License Version 2, which is an open source license. You may contribute to this project, or use the code as you please as long as you adhere to its conditions. You can find a copy of the license text here: [`LICENSE`](LICENSE). diff --git a/README.wehub.md b/README.wehub.md new file mode 100644 index 0000000..5d62e32 --- /dev/null +++ b/README.wehub.md @@ -0,0 +1,7 @@ +# WeHub 来源说明 + +- 原始项目:`lapce/lapce` +- 原始仓库:https://github.com/lapce/lapce +- 导入方式:上游默认分支的最新快照 +- 原作者、版权和许可证信息以原始仓库及本仓库 LICENSE 为准 +- 本文件仅用于记录来源,不代表 WeHub 是原项目作者 diff --git a/_typos.toml b/_typos.toml new file mode 100644 index 0000000..654c2ad --- /dev/null +++ b/_typos.toml @@ -0,0 +1,17 @@ +# https://github.com/crate-ci/typos/blob/02ea592e44b3a53c302f697cddca7641cd051c3d/docs/reference.md + +[files] + +[default] +extend-ignore-re = [ + # Ignore lines that end with `# spellchecker:disable-line` + "(?Rm)^.*(#|//)\\s*spellchecker:disable-line$", + # Ignore the line after `# spellchecker:ignore-next-line`: + "(#|//)\\s*spellchecker:ignore-next-line\\n.*", + # Ignore blocks between `# spellchecker:off` and `# spellchecker:on` + "(?s)(#|//)\\s*spellchecker:off.*?\\n\\s*(#|//)\\s*spellchecker:on", +] + +[default.extend-identifiers] + +[default.extend-words] diff --git a/defaults/dark-theme.toml b/defaults/dark-theme.toml new file mode 100644 index 0000000..8d3c6ce --- /dev/null +++ b/defaults/dark-theme.toml @@ -0,0 +1,210 @@ +#:schema ../extra/schemas/color-theme.json + +[color-theme] +name = "Lapce Dark" + +[ui] +font-family = "" +font-size = 13 +header-height = 35 +status-height = 25 +tab-min-width = 100 +activity-width = 50 +scroll-width = 10 +drop-shadow-width = 0 + +[color-theme.base] +black = "#282C34" +blue = "#61AFEF" +cyan = "#56B6C2" +green = "#98C379" +grey = "#3E4451" +magenta = "#C678DD" +orange = "#D19A66" +purple = "#C678DD" +red = "#E06C75" +white = "#ABB2BF" +yellow = "#E5C07B" + +primary-background = "$black" +# Background for 'secondary' elements: panels, palette, status bar, completion, hover +secondary-background = "#21252B" +current-background = "#2C313A" +text = "$white" +dim-text = "#5C6370" + +[color-theme.syntax] +"comment" = "$dim-text" +"constant" = "$yellow" +"type" = "$yellow" +"typeAlias" = "$yellow" +"number" = "$yellow" +"enum" = "$yellow" +"struct" = "$yellow" +"structure" = "$yellow" +"interface" = "$yellow" +"attribute" = "$yellow" +"constructor" = "$yellow" +"function" = "$blue" +"method" = "$blue" +"function.method" = "$blue" +"keyword" = "$purple" +"selfKeyword" = "$purple" +"field" = "$red" +"property" = "$red" +"enumMember" = "$red" +"enum-member" = "$red" +"string" = "$green" +"type.builtin" = "$cyan" +"builtinType" = "$cyan" +"escape" = "$cyan" +"string.escape" = "$cyan" +"embedded" = "$cyan" +"punctuation.delimiter" = "$yellow" +"text.title" = "$orange" +"text.uri" = "$cyan" +"text.reference" = "$yellow" +"variable" = "$red" +"variable.other.member" = "$red" +"tag" = "$blue" + +"markup.heading" = "$red" +"markup.bold" = "$orange" +"markup.italic" = "$orange" +"markup.list" = "$orange" +"markup.link.url" = "$blue" +"markup.link.label" = "$purple" +"markup.link.text" = "$purple" + +"bracket.color.1" = "$blue" +"bracket.color.2" = "$yellow" +"bracket.color.3" = "$purple" +"bracket.unpaired" = "$red" + +[color-theme.ui] +"lapce.error" = "$red" +"lapce.warn" = "$yellow" +"lapce.dropdown_shadow" = "#000000" +"lapce.border" = "#000000" +"lapce.scroll_bar" = "#3E4451BB" + +"lapce.button.primary.background" = "#50a14f" +"lapce.button.primary.foreground" = "$black" + +# tab +"lapce.tab.active.background" = "$primary-background" +"lapce.tab.active.foreground" = "$text" +"lapce.tab.active.underline" = "#528BFF" + +"lapce.tab.inactive.background" = "$secondary-background" +"lapce.tab.inactive.foreground" = "$text" +"lapce.tab.inactive.underline" = "#528BFF77" + +"lapce.tab.separator" = "" + +"lapce.icon.active" = "$text" +"lapce.icon.inactive" = "$dim-text" + +"lapce.remote.icon" = "$black" +"lapce.remote.local" = "#4078F2" +"lapce.remote.connected" = "#50A14F" +"lapce.remote.connecting" = "#C18401" +"lapce.remote.disconnected" = "#E45649" + +"lapce.plugin.name" = "#DDDDDD" +"lapce.plugin.description" = "$text" +"lapce.plugin.author" = "#B0B0B0" + +"editor.background" = "$primary-background" +"editor.foreground" = "$text" +"editor.dim" = "$dim-text" +"editor.focus" = "#CCCCCC" +"editor.caret" = "#528BFF" +"editor.selection" = "$grey" +"editor.current_line" = "#2C313C" +"editor.debug_break_line" = "#528abF37" +"editor.link" = "$blue" +"editor.visible_whitespace" = "$grey" +"editor.indent_guide" = "$grey" +"editor.drag_drop_background" = "#79c1fc55" +"editor.drag_drop_tab_background" = "#0b0e1455" +"editor.sticky_header_background" = "$primary-background" + +"inlay_hint.foreground" = "$text" +"inlay_hint.background" = "#528abF37" + +"error_lens.error.foreground" = "$red" +"error_lens.error.background" = "#E06C7520" +"error_lens.warning.foreground" = "$yellow" +"error_lens.warning.background" = "#E5C07B20" +"error_lens.other.foreground" = "$dim-text" +"error_lens.other.background" = "#5C637020" + +"completion_lens.foreground" = "$dim-text" + +"source_control.added" = "#50A14FCC" +"source_control.removed" = "#FF5266CC" +"source_control.modified" = "#0184BCCC" + +"tooltip.background" = "$primary-background" +"tooltip.foreground" = "$text" + +"palette.background" = "$secondary-background" +"palette.foreground" = "$text" +"palette.current.background" = "$current-background" +"palette.current.foreground" = "$text" + +"completion.background" = "$secondary-background" +"completion.current" = "$current-background" + +"hover.background" = "$secondary-background" + +"activity.background" = "$secondary-background" +"activity.current" = "$primary-background" + +"debug.breakpoint" = "$red" +"debug.breakpoint.hover" = "#E06C7566" + +"panel.background" = "$secondary-background" +"panel.foreground" = "$text" +"panel.foreground.dim" = "$dim-text" +"panel.current.background" = "$current-background" +"panel.current.foreground" = "$text" +"panel.current.foreground.dim" = "$dim-text" +"panel.hovered.background" = "#343A45" +"panel.hovered.active.background" = "$dim-text" +"panel.hovered.foreground" = "$text" +"panel.hovered.foreground.dim" = "$dim-text" + +"status.background" = "$secondary-background" +"status.foreground" = "$text" +"status.modal.normal.background" = "$blue" +"status.modal.normal.foreground" = "$black" +"status.modal.insert.background" = "$red" +"status.modal.insert.foreground" = "$black" +"status.modal.visual.background" = "$yellow" +"status.modal.visual.foreground" = "$black" +"status.modal.terminal.background" = "$purple" +"status.modal.terminal.foreground" = "$black" + +"markdown.blockquote" = "#898989" + +"terminal.cursor" = "$text" +"terminal.foreground" = "$text" +"terminal.background" = "$primary-background" +"terminal.white" = "$white" +"terminal.black" = "$black" +"terminal.red" = "$red" +"terminal.blue" = "$blue" +"terminal.green" = "$green" +"terminal.yellow" = "$yellow" +"terminal.cyan" = "$cyan" +"terminal.magenta" = "$magenta" +"terminal.bright_white" = "#C8CCD4" +"terminal.bright_red" = "$red" +"terminal.bright_blue" = "$blue" +"terminal.bright_green" = "$green" +"terminal.bright_yellow" = "$yellow" +"terminal.bright_cyan" = "$cyan" +"terminal.bright_magenta" = "$magenta" +"terminal.bright_black" = "#545862" diff --git a/defaults/icon-theme.toml b/defaults/icon-theme.toml new file mode 100644 index 0000000..51c1a7c --- /dev/null +++ b/defaults/icon-theme.toml @@ -0,0 +1,153 @@ +#:schema ../extra/schemas/icon-theme.json + +[icon-theme] +name = "Lapce Codicons" + +[icon-theme.ui] +"logo" = "lapce_logo.svg" +"menu" = "menu.svg" +"link" = "link.svg" +"error" = "error.svg" +"add" = "add.svg" +"close" = "close.svg" +"remote" = "remote.svg" +"unsaved" = "circle-filled.svg" +"warning" = "warning.svg" +"problem" = "problem.svg" +"debug" = "debug.svg" +"debug_breakpoint" = "circle-filled.svg" +"debug_alt" = "debug-alt.svg" +"debug_small" = "debug-alt-small.svg" +"debug_restart" = "debug-restart.svg" +"debug_continue" = "debug-continue.svg" +"debug_step_over" = "debug-step-over.svg" +"debug_step_into" = "debug-step-into.svg" +"debug_step_out" = "debug-step-out.svg" +"debug_pause" = "debug-pause.svg" +"debug_stop" = "debug-stop.svg" +"debug_console" = "debug-console.svg" +"debug_disconnect" = "debug-disconnect.svg" +"start" = "debug-start.svg" +"run_errors" = "run-errors.svg" +"settings" = "settings-gear.svg" +"terminal" = "terminal.svg" +"lightbulb" = "lightbulb.svg" +"extensions" = "extensions.svg" +"keyboard" = "keyboard.svg" +"breadcrumb_separator" = "chevron-right.svg" +"symbol_color" = "symbol-color.svg" +"type_hierarchy" = "type-hierarchy.svg" + +"window.close" = "chrome-close.svg" +"window.restore" = "chrome-restore.svg" +"window.maximize" = "chrome-maximize.svg" +"window.minimize" = "chrome-minimize.svg" + +"file" = "file.svg" +"file_explorer" = "files.svg" +"file_picker_up" = "arrow-up.svg" + +"image_loading" = "refresh.svg" +"image_error" = "error.svg" + +"scm.icon" = "source-control.svg" +"scm.diff.modified" = "diff-modified.svg" +"scm.diff.added" = "diff-added.svg" +"scm.diff.removed" = "diff-removed.svg" +"scm.diff.renamed" = "diff-renamed.svg" +"scm.change.add" = "add.svg" +"scm.change.remove" = "remove.svg" + +"palette.menu" = "chevron-down.svg" + +"fold" = "fold.svg" +"fold.up" = "fold-up.svg" +"fold.down" = "fold-down.svg" + +"dropdown.arrow" = "chevron-down.svg" + +"panel.fold-down" = "chevron-down.svg" +"panel.fold-up" = "chevron-right.svg" + +"location.forward" = "arrow-right.svg" +"location.backward" = "arrow-left.svg" + +"item.opened" = "chevron-down.svg" +"item.closed" = "chevron-right.svg" + +"directory.closed" = "folder.svg" +"directory.opened" = "folder-opened.svg" + +"panel.restore" = "chevron-down.svg" +"panel.maximise" = "chevron-right.svg" + +"split.horizontal" = "split-horizontal.svg" + +"tab.previous" = "chevron-left.svg" +"tab.next" = "chevron-right.svg" + +"sidebar.left.on" = "layout-sidebar-left.svg" +"sidebar.left.off" = "layout-sidebar-left-off.svg" +"sidebar.right.on" = "layout-sidebar-right.svg" +"sidebar.right.off" = "layout-sidebar-right-off.svg" + +"layout.panel.on" = "layout-panel.svg" +"layout.panel.off" = "layout-panel-off.svg" + +"search.icon" = "search.svg" +"search.clear" = "close.svg" +"search.forward" = "arrow-down.svg" +"search.backward" = "arrow-up.svg" +"search.case_sensitive" = "case-sensitive.svg" +"search.whole_word" = "whole-word.svg" +"search.regex" = "regex.svg" +"search.replace" = "replace.svg" +"search.replace_all" = "replace-all.svg" + +"document_symbol" = "symbol-class.svg" +"references" = "references.svg" +"implementation" = "combine.svg" +"symbol_kind.array" = "symbol-array.svg" +"symbol_kind.boolean" = "symbol-boolean.svg" +"symbol_kind.class" = "symbol-class.svg" +"symbol_kind.constant" = "symbol-constant.svg" +"symbol_kind.enum_member" = "symbol-enum-member.svg" +"symbol_kind.enum" = "symbol-enum.svg" +"symbol_kind.event" = "symbol-event.svg" +"symbol_kind.field" = "symbol-field.svg" +"symbol_kind.file" = "symbol-file.svg" +"symbol_kind.function" = "symbol-method.svg" +"symbol_kind.interface" = "symbol-interface.svg" +"symbol_kind.key" = "symbol-key.svg" +"symbol_kind.method" = "symbol-method.svg" +"symbol_kind.namespace" = "symbol-namespace.svg" +"symbol_kind.number" = "symbol-numeric.svg" +"symbol_kind.object" = "symbol-namespace.svg" +"symbol_kind.operator" = "symbol-operator.svg" +"symbol_kind.property" = "symbol-property.svg" +"symbol_kind.string" = "symbol-string.svg" +"symbol_kind.struct" = "symbol-structure.svg" +"symbol_kind.type_parameter" = "symbol-parameter.svg" +"symbol_kind.variable" = "symbol-variable.svg" + +"completion_item_kind.class" = "symbol-class.svg" +"completion_item_kind.constant" = "symbol-constant.svg" +"completion_item_kind.enum_member" = "symbol-enum-member.svg" +"completion_item_kind.enum" = "symbol-enum.svg" +"completion_item_kind.field" = "symbol-field.svg" +"completion_item_kind.function" = "symbol-method.svg" +"completion_item_kind.interface" = "symbol-interface.svg" +"completion_item_kind.keyword" = "symbol-keyword.svg" +"completion_item_kind.method" = "symbol-method.svg" +"completion_item_kind.module" = "symbol-namespace.svg" +"completion_item_kind.property" = "symbol-property.svg" +"completion_item_kind.snippet" = "symbol-snippet.svg" +"completion_item_kind.string" = "symbol-string.svg" +"completion_item_kind.struct" = "symbol-structure.svg" +"completion_item_kind.variable" = "symbol-variable.svg" + +[icon-theme.foldername] + +[icon-theme.filename] + +[icon-theme.extension] diff --git a/defaults/keymaps-common.toml b/defaults/keymaps-common.toml new file mode 100644 index 0000000..43fa4c7 --- /dev/null +++ b/defaults/keymaps-common.toml @@ -0,0 +1,737 @@ +# --------------------------------- General -------------------------------------------- + +[[keymaps]] +key = "F1" +command = "palette.command" + +# [[keymaps]] +# key = "ctrl+q" +# command = "quit" + +# --------------------------------- Basic editing --------------------------------------- + +[[keymaps]] +key = "alt+up" +command = "move_line_up" +mode = "i" + +[[keymaps]] +key = "alt+down" +command = "move_line_down" +mode = "i" + +[[keymaps]] +key = "Delete" +command = "delete_forward" +mode = "i" + +[[keymaps]] +key = "backspace" +command = "delete_backward" +mode = "i" + +[[keymaps]] +key = "shift+backspace" +command = "delete_forward" +mode = "i" + +[[keymaps]] +key = "Home" +command = "line_start_non_blank" +mode = "inv" + +[[keymaps]] +key = "End" +command = "line_end" +mode = "inv" + +[[keymaps]] +key = "PageUp" +command = "page_up" + +[[keymaps]] +key = "PageDown" +command = "page_down" + +[[keymaps]] +key = "Ctrl+PageUp" +command = "scroll_up" + +[[keymaps]] +key = "Ctrl+PageDown" +command = "scroll_down" + +# ------------------------------------ Multi cursor ------------------------------------- + +[[keymaps]] +key = "alt+shift+i" +command = "insert_cursor_end_of_line" +mode = "i" + +# ----------------------------------- Editor Management ------------------------------- + +[[keymaps]] +key = "ctrl+tab" +command = "next_editor_tab" + +[[keymaps]] +key = "ctrl+shift+tab" +command = "previous_editor_tab" + +# --------------------------------- Rich Language Editing ---------------------------- + +[[keymaps]] +key = "F2" +command = "rename_symbol" + +[[keymaps]] +key = "F12" +command = "goto_definition" + +[[keymaps]] +key = "g f" +command = "show_code_actions" +mode = "n" + +# ------------------------------------ Navigation ------------------------------------- + +[[keymaps]] +key = "F8" +command = "next_error" + +[[keymaps]] +key = "shift+F8" +command = "previous_error" + +[[keymaps]] +key = "ctrl+-" +command = "jump_location_backward" +mode = "i" + +[[keymaps]] +key = "ctrl+shift+-" +command = "jump_location_forward" +mode = "i" + +# --------------------------------- Integrated Terminal ------------------------------ + +[[keymaps]] +key = "Ctrl+`" +command = "toggle_terminal_focus" + +# ------------------------------------ ------------ ------------------------------------- + +[[keymaps]] +key = "tab" +command = "jump_to_next_snippet_placeholder" +when = "in_snippet" +mode = "i" + +[[keymaps]] +key = "shift+tab" +command = "jump_to_prev_snippet_placeholder" +when = "in_snippet" +mode = "i" + +[[keymaps]] +key = "esc" +command = "clear_search" +when = "search_active || search_focus" + +[[keymaps]] +key = "ctrl+shift+up" +command = "select_next_syntax_item" + +[[keymaps]] +key = "ctrl+shift+down" +command = "select_previous_syntax_item" + +[[keymaps]] +key = "ctrl+m" +command = "list.select" +when = "list_focus" + +[[keymaps]] +key = "tab" +command = "list.select" +when = "completion_focus" + +[[keymaps]] +key = "enter" +command = "list.select" +when = "list_focus" + +[[keymaps]] +key = "ctrl+p" +command = "list.previous" +when = "list_focus" + +[[keymaps]] +key = "up" +command = "list.previous" +when = "list_focus" + +[[keymaps]] +key = "PageUp" +command = "list.previous_page" +when = "list_focus" + +[[keymaps]] +key = "ctrl+n" +command = "list.next" +when = "list_focus" + +[[keymaps]] +key = "down" +command = "list.next" +when = "list_focus" + +[[keymaps]] +key = "PageDown" +command = "list.next_page" +when = "list_focus" + +[[keymaps]] +key = "o" +command = "list.expand" +when = "list_focus" +mode = "n" + +[[keymaps]] +key = "/" +command = "palette.line" +mode = "n" + +[[keymaps]] +key = "esc" +command = "modal.close" +when = "modal_focus || completion_focus" + +[[keymaps]] +key = "tab" +command = "inline_completion.select" +when = "inline_completion_visible && !search_focus && !modal_focus && !list_focus && !search_active" +mode = "i" + +[[keymaps]] +key = "esc" +command = "inline_completion.cancel" +when = "inline_completion_visible && !search_focus && !modal_focus && !list_focus && !search_active" +mode = "i" + +[[keymaps]] +key = "alt+[" +command = "inline_completion.previous" +when = "inline_completion_visible && !search_focus && !modal_focus && !list_focus && !search_active" +mode = "i" + +[[keymaps]] +key = "alt+]" +command = "inline_completion.next" +when = "inline_completion_visible && !search_focus && !modal_focus && !list_focus && !search_active" +mode = "i" + +[[keymaps]] +key = "alt+\\" +command = "inline_completion.invoke" +when = "!inline_completion_visible && !search_focus && !modal_focus && !list_focus && !search_active" +mode = "i" + +[[keymaps]] +key = "right" +command = "right" +mode = "inv" + +[[keymaps]] +key = "left" +command = "left" +mode = "inv" + +[[keymaps]] +key = "up" +command = "up" +when = "!list_focus" +mode = "inv" + +[[keymaps]] +key = "down" +command = "down" +when = "!list_focus" +mode = "inv" + +[[keymaps]] +key = "ctrl+h" +command = "delete_backward" +mode = "i" + +[[keymaps]] +key = "enter" +command = "insert_new_line" +when = "!list_focus && !input_focus" +mode = "i" + +[[keymaps]] +key = "tab" +command = "focus_replace_editor" +when = "search_focus" + +[[keymaps]] +key = "tab" +command = "focus_find_editor" +when = "replace_focus" + +[[keymaps]] +key = "shift+enter" +command = "search_backward" +when = "search_focus" +mode = "i" + +[[keymaps]] +key = "enter" +command = "search_forward" +when = "search_focus" +mode = "i" + +[[keymaps]] +key = "enter" +command = "global_search_refresh" +when = "global_search_focus" +mode = "i" + +[[keymaps]] +key = "enter" +command = "confirm_rename" +when = "rename_focus" +mode = "i" + +[[keymaps]] +key = "tab" +command = "insert_tab" +when = "!in_snippet && !completion_focus && !inline_completion_visible && !search_focus && !replace_focus" +mode = "i" + +[[keymaps]] +key = "ctrl+m" +command = "insert_new_line" +when = "!list_focus" +mode = "i" + +[[keymaps]] +key = "alt+shift+up" +command = "duplicate_line_up" +mode = "i" + +[[keymaps]] +key = "alt+shift+down" +command = "duplicate_line_down" +mode = "i" + +# ------------------------------------ Modal ----------------------------------------- + +[[keymaps]] +key = "esc" +command = "normal_mode" +mode = "niv" +when = "!search_focus && !modal_focus && !search_active && !inline_completion_visible" + +[[keymaps]] +key = "ctrl+c" +command = "normal_mode" +mode = "niv" +when = "!search_focus && !modal_focus && !search_active" + +[[keymaps]] +key = "ctrl+[" +command = "normal_mode" +mode = "niv" +when = "!search_focus && !search_active" + +[[keymaps]] +key = "shift+;" +command = "palette.command" +mode = "n" + +[[keymaps]] +key = "shift+g" +command = "go_to_line_default_last" +mode = "nv" + +[[keymaps]] +key = "g g" +command = "go_to_line_default_first" +mode = "nv" + +[[keymaps]] +key = "h" +command = "left" +mode = "nv" + +[[keymaps]] +key = "j" +command = "down" +mode = "nv" + +[[keymaps]] +key = "k" +command = "up" +mode = "nv" + +[[keymaps]] +key = "l" +command = "right" +mode = "nv" + +[[keymaps]] +key = "a" +command = "append" +mode = "n" + +[[keymaps]] +key = "shift+a" +command = "append_end_of_line" +mode = "n" + +[[keymaps]] +key = "i" +command = "insert_mode" +mode = "n" + +[[keymaps]] +key = "u" +command = "undo" +mode = "n" + +[[keymaps]] +key = "ctrl+r" +command = "redo" +mode = "n" + +[[keymaps]] +key = "ctrl+i" +command = "jump_location_forward_local" +mode = "n" + +[[keymaps]] +key = "ctrl+o" +command = "jump_location_backward_local" +mode = "n" + +[[keymaps]] +key = "ctrl+n" +command = "goto_definition" +mode = "n" + +[[keymaps]] +key = "g d" +command = "goto_definition" +mode = "n" + +[[keymaps]] +key = "g h" +command = "show_hover" +mode = "n" + +[[keymaps]] +key = "p" +command = "paste" +mode = "nv" + +[[keymaps]] +key = "shift+p" +command = "paste_before" +mode = "nv" + +[[keymaps]] +key = "shift+j" +command = "join_lines" +mode = "n" + +[[keymaps]] +key = "y" +command = "yank" +mode = "v" + +[[keymaps]] +key = "x" +command = "delete_forward" +mode = "nv" + +[[keymaps]] +key = "ctrl+p" +command = "get_references" +mode = "n" + +[[keymaps]] +key = "s" +command = "delete_forward_and_insert" +mode = "nv" + +[[keymaps]] +key = "c" +command = "delete_forward_and_insert" +mode = "v" + +[[keymaps]] +key = "shift+s" +command = "delete_line_and_insert" +mode = "n" + +[[keymaps]] +key = "c c" +command = "delete_line_and_insert" +mode = "n" + +[[keymaps]] +key = "c w" +command = "delete_word_and_insert" +mode = "n" + +[[keymaps]] +key = "c e" +command = "delete_word_and_insert" +mode = "n" + +[[keymaps]] +key = "shift+i" +command = "insert_first_non_blank" +mode = "nv" + +[[keymaps]] +key = "o" +command = "new_line_below" +mode = "nv" + +[[keymaps]] +key = "0" +command = "line_start" +mode = "nv" + +[[keymaps]] +key = "shift+6" +command = "line_start_non_blank" +mode = "nv" + +[[keymaps]] +key = "shift+4" +command = "line_end" +mode = "nv" + +[[keymaps]] +key = "w" +command = "word_forward" +mode = "nv" + +[[keymaps]] +key = "e" +command = "word_end_forward" +mode = "nv" + +[[keymaps]] +key = "b" +command = "word_backward" +mode = "nv" + +[[keymaps]] +key = "shift+o" +command = "new_line_above" +mode = "nv" + +[[keymaps]] +key = "ctrl+e" +command = "scroll_down" +mode = "nv" + +[[keymaps]] +key = "ctrl+y" +command = "scroll_up" +mode = "nv" + +[[keymaps]] +key = "ctrl+u" +command = "page_up" +mode = "nv" + +[[keymaps]] +key = "ctrl+d" +command = "page_down" +mode = "nv" + +[[keymaps]] +key = "z z" +command = "center_of_window" +mode = "nv" + +[[keymaps]] +key = "z t" +command = "top_of_window" +mode = "nv" + +[[keymaps]] +key = "z b" +command = "bottom_of_window" +mode = "nv" + +[[keymaps]] +key = "d" +command = "delete_forward" +mode = "v" + +[[keymaps]] +key = "m" +command = "create_mark" +mode = "nv" + +[[keymaps]] +key = "'" +command = "go_to_mark" +mode = "nv" + +[[keymaps]] +key = "f" +command = "inline_find_right" +mode = "nv" + +[[keymaps]] +key = "shift+f" +command = "inline_find_left" +mode = "nv" + +[[keymaps]] +key = ";" +command = "repeat_last_inline_find" +mode = "nv" + +[[keymaps]] +key = "d" +command = "motion_mode_delete" +mode = "n" + +[[keymaps]] +key = "shift+." +command = "motion_mode_indent" +mode = "n" + +[[keymaps]] +key = "shift+," +command = "motion_mode_outdent" +mode = "n" + +[[keymaps]] +key = "y" +command = "motion_mode_yank" +mode = "n" + +[[keymaps]] +key = "shift+8" +command = "search_whole_word_forward" +mode = "nv" + +[[keymaps]] +key = "n" +command = "search_forward" +mode = "nv" + +[[keymaps]] +key = "shift+n" +command = "search_backward" +mode = "nv" + +[[keymaps]] +key = "shift+5" +command = "match_pairs" +mode = "nv" + +[[keymaps]] +key = "] shift+0" +command = "next_unmatched_right_bracket" +mode = "nv" + +[[keymaps]] +key = "[ shift+9" +command = "previous_unmatched_left_bracket" +mode = "nv" + +[[keymaps]] +key = "] shift+]" +command = "next_unmatched_right_curly_bracket" +mode = "nv" + +[[keymaps]] +key = "[ shift+[" +command = "previous_unmatched_left_curly_bracket" +mode = "nv" + +[[keymaps]] +key = "v" +command = "toggle_visual_mode" +mode = "nv" + +[[keymaps]] +key = "shift+v" +command = "toggle_linewise_visual_mode" +mode = "nv" + +[[keymaps]] +key = "ctrl+v" +command = "toggle_blockwise_visual_mode" +mode = "nv" + +[[keymaps]] +key = "ctrl+w l" +command = "split_right" +mode = "n" + +[[keymaps]] +key = "ctrl+w h" +command = "split_left" +mode = "n" + +[[keymaps]] +key = "ctrl+w j" +command = "split_down" +mode = "n" + +[[keymaps]] +key = "ctrl+w k" +command = "split_up" +mode = "n" + +[[keymaps]] +key = "ctrl+w s" +command = "split_horizontal" +mode = "n" + +[[keymaps]] +key = "ctrl+w v" +command = "split_vertical" +mode = "n" + +[[keymaps]] +key = "ctrl+w c" +command = "split_close" +mode = "n" + +[[keymaps]] +key = "ctrl+w x" +command = "split_exchange" +mode = "n" + +[[keymaps]] +key = "space" +command = "toggle_code_glance" +mode = "nv" + +[[keymaps]] +key = "shift+." +command = "indent_line" +mode = "v" + +[[keymaps]] +key = "shift+," +command = "outdent_line" +mode = "v" + +[[keymaps]] +key = "shift+c" +command = "delete_to_end_and_insert" +mode = "n" diff --git a/defaults/keymaps-macos.toml b/defaults/keymaps-macos.toml new file mode 100644 index 0000000..d082620 --- /dev/null +++ b/defaults/keymaps-macos.toml @@ -0,0 +1,305 @@ +# --------------------------------- Window --------------------------------------------- + +[[keymaps]] +command = "window_close" +key = "Meta+Shift+W" + +# --------------------------------- General -------------------------------------------- + +[[keymaps]] +key = "meta+p" +command = "palette" + +[[keymaps]] +key = "meta+shift+p" +command = "palette.command" + +[[keymaps]] +key = "meta+e" +command = "toggle_code_glance" +mode = "i" + +[[keymaps]] +key = "meta+," +command = "open_settings" + +[[keymaps]] +key = "meta+k meta+s" +command = "open_keyboard_shortcuts" + +# [[keymaps]] +# key = "meta+q" +# command = "quit" + +[[keymaps]] +key = "meta+=" +command = "zoom_in" + +[[keymaps]] +key = "meta+-" +command = "zoom_out" + +[[keymaps]] +key = "meta+enter" +command = "source_control_commit" +when = "source_control_focus" + +# --------------------------------- Basic editing --------------------------------------- + +[[keymaps]] +key = "meta+z" +command = "undo" + +[[keymaps]] +key = "meta+shift+z" +command = "redo" + +[[keymaps]] +key = "meta+y" +command = "redo" + +[[keymaps]] +key = "meta+x" +command = "clipboard_cut" + +[[keymaps]] +key = "meta+c" +command = "clipboard_copy" + +[[keymaps]] +key = "meta+v" +command = "clipboard_paste" + +[[keymaps]] +key = "meta+f" +command = "search" + +[[keymaps]] +key = "alt+right" +command = "word_end_forward" +mode = "i" + +[[keymaps]] +key = "alt+left" +command = "word_backward" +mode = "i" + +[[keymaps]] +key = "meta+left" +command = "line_start_non_blank" +mode = "i" + +[[keymaps]] +key = "meta+right" +command = "line_end" +mode = "i" + +[[keymaps]] +key = "ctrl+a" +command = "line_start_non_blank" +mode = "i" + +[[keymaps]] +key = "ctrl+e" +command = "line_end" +mode = "i" + +[[keymaps]] +key = "meta+shift+k" +command = "delete_line" +mode = "i" + +[[keymaps]] +key = "alt+backspace" +command = "delete_word_backward" +mode = "i" + +[[keymaps]] +key = "meta+backspace" +command = "delete_to_beginning_of_line" +mode = "i" + +[[keymaps]] +key = "ctrl+k" +command = "delete_to_end_of_line" +mode = "i" + +[[keymaps]] +key = "alt+delete" +command = "delete_word_forward" +mode = "i" + +[[keymaps]] +key = "meta+shift+\\" +command = "match_pairs" +mode = "i" + +[[keymaps]] +key = "meta+/" +command = "toggle_line_comment" + +[[keymaps]] +key = "meta+]" +command = "indent_line" + +[[keymaps]] +key = "meta+[" +command = "outdent_line" + +[[keymaps]] +key = "meta+a" +command = "select_all" + +[[keymaps]] +key = "meta+enter" +command = "new_line_below" +when = "!source_control_focus" +mode = "i" + +[[keymaps]] +key = "meta+shift+enter" +command = "new_line_above" +mode = "i" + +# ------------------------------------ Multi cursor ------------------------------------- + +[[keymaps]] +key = "alt+meta+up" +command = "insert_cursor_above" +mode = "i" + +[[keymaps]] +key = "alt+meta+down" +command = "insert_cursor_below" +mode = "i" + +[[keymaps]] +key = "meta+l" +command = "select_current_line" +mode = "i" + +[[keymaps]] +key = "meta+shift+l" +command = "select_all_current" +mode = "i" + +[[keymaps]] +key = "meta+u" +command = "select_undo" +mode = "i" + +[[keymaps]] +key = "meta+d" +command = "select_next_current" +mode = "i" + +[[keymaps]] +key = "meta+k meta+d" +command = "select_skip_current" +mode = "i" + +# ------------------------------------ File Management -------------------------------- + +[[keymaps]] +key = "meta+s" +command = "save" + +[[keymaps]] +key = "meta+o" +command = "open_file" + +[[keymaps]] +key = "meta+n" +command = "new_file" + +# ----------------------------------- Editor Management ------------------------------- + +[[keymaps]] +key = "meta+w" +command = "split_close" + +[[keymaps]] +key = "meta+k f" +command = "close_folder" + +[[keymaps]] +key = "meta+\\" +command = "split_vertical" + +# --------------------------------- Rich Language Editing ---------------------------- + +[[keymaps]] +key = "ctrl+space" +command = "get_completion" +mode = "i" + +[[keymaps]] +key = "meta+i" +command = "get_completion" +mode = "i" + +[[keymaps]] +key = "ctrl+shift+space" +command = "get_signature" +mode = "i" + +[[keymaps]] +key = "meta+." +command = "show_code_actions" + +# --------------------------------- Display ------------------------------------------- + +[[keymaps]] +key = "meta+shift+e" +command = "toggle_file_explorer_focus" + +[[keymaps]] +key = "meta+shift+f" +command = "toggle_search_focus" + +[[keymaps]] +key = "meta+shift+x" +command = "toggle_plugin_focus" + +[[keymaps]] +key = "meta+shift+m" +command = "toggle_problem_focus" + +# ------------------------------------ Navigation ------------------------------------- + +[[keymaps]] +key = "meta+up" +command = "document_start" + +[[keymaps]] +key = "meta+down" +command = "document_end" + +[[keymaps]] +key = "ctrl+f" +command = "right" +mode = "i" + +[[keymaps]] +key = "ctrl+p" +command = "up" +when = "!list_focus" +mode = "i" + +[[keymaps]] +key = "ctrl+n" +command = "down" +when = "!list_focus" +mode = "i" + +[[keymaps]] +key = "meta+shift+o" +command = "palette.symbol" + +[[keymaps]] +key = "meta+t" +command = "palette.workspace_symbol" + +[[keymaps]] +key = "ctrl+g" +command = "palette.line" diff --git a/defaults/keymaps-nonmacos.toml b/defaults/keymaps-nonmacos.toml new file mode 100644 index 0000000..5644ec3 --- /dev/null +++ b/defaults/keymaps-nonmacos.toml @@ -0,0 +1,310 @@ +# --------------------------------- Window --------------------------------------------- + +[[keymaps]] +command = "close_window" +key = "Alt+F4" + +# --------------------------------- General -------------------------------------------- + +[[keymaps]] +key = "ctrl+p" +command = "palette" + +[[keymaps]] +key = "ctrl+shift+p" +command = "palette.command" + +[[keymaps]] +key = "ctrl+e" +command = "toggle_code_glance" +mode = "i" + +[[keymaps]] +key = "ctrl+," +command = "open_settings" + +[[keymaps]] +key = "ctrl+k ctrl+s" +command = "open_keyboard_shortcuts" + +[[keymaps]] +key = "ctrl+=" +command = "zoom_in" + +[[keymaps]] +key = "ctrl+-" +command = "zoom_out" + +[[keymaps]] +key = "ctrl+enter" +command = "source_control_commit" +when = "source_control_focus" + +# --------------------------------- Terminal copy/paste --------------------------------- + +[[keymaps]] +key = "ctrl+shift+c" +command = "clipboard_copy" +mode = "t" + +[[keymaps]] +key = "ctrl+shift+v" +command = "clipboard_paste" +mode = "t" + +# --------------------------------- Basic editing --------------------------------------- + +[[keymaps]] +key = "ctrl+z" +command = "undo" +mode = "i" + +[[keymaps]] +key = "ctrl+shift+z" +command = "redo" +mode = "i" + + +[[keymaps]] +key = "ctrl+y" +command = "redo" +mode = "i" + +[[keymaps]] +key = "ctrl+x" +command = "clipboard_cut" +mode = "i" + +[[keymaps]] +key = "shift+Delete" +command = "clipboard_cut" +mode = "i" + +[[keymaps]] +key = "ctrl+c" +command = "clipboard_copy" +mode = "i" + +[[keymaps]] +key = "ctrl+insert" +command = "clipboard_copy" +mode = "i" + +[[keymaps]] +key = "ctrl+v" +command = "clipboard_paste" +mode = "i" + +[[keymaps]] +key = "shift+insert" +command = "clipboard_paste" +mode = "i" + +[[keymaps]] +key = "ctrl+f" +command = "search" + +[[keymaps]] +key = "ctrl+right" +command = "word_end_forward" +mode = "i" + +[[keymaps]] +key = "ctrl+left" +command = "word_backward" +mode = "i" + +[[keymaps]] +key = "ctrl+backspace" +command = "delete_word_backward" +mode = "i" + +[[keymaps]] +key = "ctrl+delete" +command = "delete_word_forward" +mode = "i" + +[[keymaps]] +key = "ctrl+shift+\\" +command = "match_pairs" +mode = "i" + +[[keymaps]] +key = "ctrl+/" +command = "toggle_line_comment" + +[[keymaps]] +key = "ctrl+]" +command = "indent_line" + +[[keymaps]] +key = "ctrl+[" +command = "outdent_line" + +[[keymaps]] +key = "ctrl+a" +command = "select_all" + +[[keymaps]] +key = "ctrl+enter" +command = "new_line_below" +when = "!source_control_focus" +mode = "i" + +[[keymaps]] +key = "ctrl+shift+enter" +command = "new_line_above" +mode = "i" + +# ------------------------------------ Multi cursor ------------------------------------- + +[[keymaps]] +key = "alt+ctrl+up" +command = "insert_cursor_above" +mode = "i" + +[[keymaps]] +key = "alt+ctrl+down" +command = "insert_cursor_below" +mode = "i" + +[[keymaps]] +key = "ctrl+l" +command = "select_current_line" +mode = "i" + +[[keymaps]] +key = "ctrl+shift+l" +command = "select_all_current" +mode = "i" + +[[keymaps]] +key = "ctrl+u" +command = "select_undo" +mode = "i" + +[[keymaps]] +key = "ctrl+d" +command = "select_next_current" +mode = "i" + +[[keymaps]] +key = "ctrl+k ctrl+d" +command = "select_skip_current" +mode = "i" + +# ------------------------------------ File Management -------------------------------- + +[[keymaps]] +key = "ctrl+s" +command = "save" + +[[keymaps]] +key = "ctrl+o" +command = "open_file" + +[[keymaps]] +key = "ctrl+n" +command = "new_file" + +# ----------------------------------- Editor Management ------------------------------- + +[[keymaps]] +key = "ctrl+w" +command = "split_close" +mode = "i" + +[[keymaps]] +key = "ctrl+k f" +command = "close_folder" + +[[keymaps]] +key = "ctrl+F4" +command = "split_close" + +[[keymaps]] +key = "ctrl+\\" +command = "split_vertical" + +# --------------------------------- Rich Language Editing ---------------------------- + +[[keymaps]] +key = "ctrl+space" +command = "get_completion" +mode = "i" + +[[keymaps]] +key = "ctrl+i" +command = "get_completion" +mode = "i" + +[[keymaps]] +key = "ctrl+shift+space" +command = "get_signature" +mode = "i" + +[[keymaps]] +key = "ctrl+." +command = "show_code_actions" + +# --------------------------------- Display ------------------------------------------- + +[[keymaps]] +key = "ctrl+shift+e" +command = "toggle_file_explorer_focus" + +[[keymaps]] +key = "ctrl+shift+f" +command = "toggle_search_focus" + +[[keymaps]] +key = "ctrl+shift+x" +command = "toggle_plugin_focus" + +[[keymaps]] +key = "ctrl+shift+m" +command = "toggle_problem_focus" + +# ------------------------------------ Navigation ------------------------------------- + +[[keymaps]] +key = "Ctrl+Home" +command = "document_start" + +[[keymaps]] +key = "Ctrl+End" +command = "document_end" + +[[keymaps]] +key = "ctrl+b" +command = "left" +mode = "n" + +[[keymaps]] +key = "ctrl+f" +command = "right" +mode = "n" + +[[keymaps]] +key = "ctrl+p" +command = "up" +when = "!list_focus" +mode = "n" + +[[keymaps]] +key = "ctrl+n" +command = "down" +when = "!list_focus" +mode = "n" + +[[keymaps]] +key = "ctrl+shift+o" +command = "palette.symbol" + +[[keymaps]] +key = "ctrl+t" +command = "palette.workspace_symbol" + +[[keymaps]] +key = "ctrl+g" +command = "palette.line" diff --git a/defaults/light-theme.toml b/defaults/light-theme.toml new file mode 100644 index 0000000..570e6f7 --- /dev/null +++ b/defaults/light-theme.toml @@ -0,0 +1,216 @@ +#:schema ../extra/schemas/color-theme.json + +[color-theme] +name = "Lapce Light" + +[ui] +font-family = "" +font-size = 13 +header-height = 35 +status-height = 25 +tab-min-width = 100 +activity-width = 50 +scroll-width = 10 +drop-shadow-width = 0 + +[color-theme.base] +black = "#383A42" +blue = "#4078F2" +cyan = "#0184BC" +green = "#50A14F" +grey = "#E5E5E6" +magenta = "#A626A4" +orange = "#D19A66" +purple = "#A626A4" +red = "#E45649" +white = "#FAFAFA" +yellow = "#C18401" + +primary-background = "$white" +# Background for 'secondary' elements: panels, palette, status bar, completion, hover +secondary-background = "#EAEAEB" +current-background = "#DBDBDC" +text = "$black" +dim-text = "#A0A1A7" + +[color-theme.syntax] +"comment" = "$dim-text" +"constant" = "$yellow" +"type" = "$yellow" +"typeAlias" = "$yellow" +"number" = "$yellow" +"enum" = "$yellow" +"struct" = "$yellow" +"structure" = "$yellow" +"interface" = "$yellow" +"attribute" = "$yellow" +"constructor" = "$yellow" + +"function" = "$blue" +"method" = "$blue" +"function.method" = "$blue" + +"keyword" = "$purple" +"selfKeyword" = "$purple" + +"field" = "$red" +"property" = "$red" +"enumMember" = "$red" +"enum-member" = "$red" + +"string" = "$green" +"string.escape" = "$cyan" + +"type.builtin" = "$cyan" +"builtinType" = "$cyan" +"escape" = "$cyan" +"embedded" = "$cyan" + +"punctuation.delimiter" = "$yellow" +"text.title" = "$orange" +"text.uri" = "$cyan" +"text.reference" = "$yellow" +"variable" = "$red" +"variable.other.member" = "$red" +"tag" = "$blue" + +"markup.heading" = "$red" +"markup.bold" = "$orange" +"markup.italic" = "$orange" +"markup.list" = "$orange" +"markup.link.url" = "$blue" +"markup.link.label" = "$purple" +"markup.link.text" = "$purple" + +"bracket.color.1" = "$blue" +"bracket.color.2" = "$yellow" +"bracket.color.3" = "$purple" +"bracket.unpaired" = "$red" + +[color-theme.ui] +"lapce.error" = "#E51400" +"lapce.warn" = "#E9A700" +"lapce.dropdown_shadow" = "#B4B4B4" +"lapce.border" = "#B4B4B4" +"lapce.scroll_bar" = "#B4B4B4BB" + +"lapce.button.primary.background" = "#50a14f" +"lapce.button.primary.foreground" = "$white" + +# tab +"lapce.tab.active.background" = "$primary-background" +"lapce.tab.active.foreground" = "$text" +"lapce.tab.active.underline" = "#528BFF" + +"lapce.tab.inactive.background" = "#EAEAEB" +"lapce.tab.inactive.foreground" = "$text" +"lapce.tab.inactive.underline" = "#528BFF77" + +"lapce.tab.separator" = "#B4B4B4" + +"lapce.icon.active" = "$text" +"lapce.icon.inactive" = "$dim-text" + +"lapce.remote.icon" = "$white" +"lapce.remote.local" = "#4078F2" +"lapce.remote.connected" = "#50A14F" +"lapce.remote.connecting" = "#C18401" +"lapce.remote.disconnected" = "#E45649" + +"lapce.plugin.name" = "#444444" +"lapce.plugin.description" = "$text" +"lapce.plugin.author" = "#707070" + +"terminal.cursor" = "$text" +"terminal.foreground" = "$text" +"terminal.background" = "$primary-background" +"terminal.white" = "$white" +"terminal.black" = "$black" +"terminal.red" = "$red" +"terminal.blue" = "$blue" +"terminal.green" = "$green" +"terminal.yellow" = "$yellow" +"terminal.cyan" = "$cyan" +"terminal.magenta" = "$magenta" +"terminal.bright_white" = "#090A0B" +"terminal.bright_red" = "$red" +"terminal.bright_blue" = "$blue" +"terminal.bright_green" = "$green" +"terminal.bright_yellow" = "$yellow" +"terminal.bright_cyan" = "$cyan" +"terminal.bright_magenta" = "$magenta" +"terminal.bright_black" = "#A0A1A7" + +"editor.background" = "$primary-background" +"editor.foreground" = "$text" +"editor.dim" = "$dim-text" +"editor.focus" = "#000000" +"editor.caret" = "#526FFF" +"editor.selection" = "$grey" +"editor.current_line" = "#F2F2F2" +"editor.debug_break_line" = "#528bFF55" +"editor.link" = "$blue" +"editor.visible_whitespace" = "$grey" +"editor.indent_guide" = "$grey" +"editor.drag_drop_background" = "#79c1fc33" +"editor.drag_drop_tab_background" = "#0b0e1433" +"editor.sticky_header_background" = "$primary-background" + +"inlay_hint.foreground" = "$text" +"inlay_hint.background" = "#528bFF55" + +"error_lens.error.foreground" = "$red" +"error_lens.error.background" = "#E4564920" +"error_lens.warning.foreground" = "$yellow" +"error_lens.warning.background" = "#C1840120" +"error_lens.other.foreground" = "$dim-text" +"error_lens.other.background" = "#A0A1A720" + +"completion_lens.foreground" = "$dim-text" + +"source_control.added" = "#50A14FCC" +"source_control.removed" = "#FF5266CC" +"source_control.modified" = "#0184BCCC" + +"tooltip.background" = "$primary-background" +"tooltip.foreground" = "$text" + +"palette.background" = "$secondary-background" +"palette.foreground" = "$text" +"palette.current.background" = "$current-background" +"palette.current.foreground" = "$text" + +"completion.background" = "$secondary-background" +"completion.current" = "$current-background" + +"hover.background" = "$secondary-background" + +"activity.background" = "$secondary-background" +"activity.current" = "$primary-background" + +"debug.breakpoint" = "$red" +"debug.breakpoint.hover" = "#E4564966" + +"panel.background" = "$secondary-background" +"panel.foreground" = "$text" +"panel.foreground.dim" = "$dim-text" +"panel.current.background" = "$current-background" +"panel.current.foreground" = "$text" +"panel.current.foreground.dim" = "$dim-text" +"panel.hovered.background" = "#CBCBCB" +"panel.hovered.active.background" = "$dim-text" +"panel.hovered.foreground" = "$text" +"panel.hovered.foreground.dim" = "$dim-text" + +"status.background" = "$secondary-background" +"status.foreground" = "$text" +"status.modal.normal.background" = "$blue" +"status.modal.normal.foreground" = "$white" +"status.modal.insert.background" = "$red" +"status.modal.insert.foreground" = "$white" +"status.modal.visual.background" = "$yellow" +"status.modal.visual.foreground" = "$white" +"status.modal.terminal.background" = "$purple" +"status.modal.terminal.foreground" = "$white" + +"markdown.blockquote" = "#686868" diff --git a/defaults/run.toml b/defaults/run.toml new file mode 100644 index 0000000..35478ab --- /dev/null +++ b/defaults/run.toml @@ -0,0 +1,30 @@ + +# The run config is used for both run mode and debug mode + +[[configs]] +# the name of this task +name = "task" + +# the type of the debugger. If not set, it can't be debugged but can still be run +# type = "lldb" + +# the program to run, e.g. "${workspace}\\target\\debug\\check.exe" +program = "" + +# the program arguments, e.g. args = ["arg1", "arg2"], optional +# args = [] + +# current working directory, optional +# cwd = "${workspace}" + +# environment variables, optional +# [configs.env] +# VAR1 = "VAL1" +# VAR2 = "VAL2" + +# task to run before the run/debug session is started, optional +# [configs.prelaunch] +# program = "cargo" +# args = [ +# "build", +# ] diff --git a/defaults/settings.toml b/defaults/settings.toml new file mode 100644 index 0000000..9a72289 --- /dev/null +++ b/defaults/settings.toml @@ -0,0 +1,105 @@ +#:schema ../extra/schemas/settings.json + +[core] +modal = false +color-theme = "Lapce Dark" +icon-theme = "Lapce Codicons" +custom-titlebar = true +file-explorer-double-click = false +auto-reload-plugin = false + +[editor] +font-family = "monospace" +font-size = 13 +code-glance-font-size = 2 +line-height = 1.5 +smart-tab = true +tab-width = 4 +show-tab = true +show-bread-crumbs = true +scroll-beyond-last-line = true +cursor-surrounding-lines = 1 +wrap-style = "editor-width" +wrap-column = 80 +wrap-width = 600 # px +sticky-header = true +completion-width = 600 +completion-show-documentation = true +completion-item-show-detail = false +show-signature = true +signature-label-code-block = true +auto-closing-matching-pairs = true +auto-surround = true +hover-delay = 300 # ms +modal-mode-relative-line-numbers = true +format-on-save = false +highlight-matching-brackets = true +highlight-selection-occurrences = true +highlight-scope-lines = false +autosave-interval = 0 +format-on-autosave = true +normalize-line-endings = true +enable-inlay-hints = true +inlay-hint-font-family = "" +inlay-hint-font-size = 0 +enable-error-lens = true +only-render-error-styling = true +error-lens-end-of-line = true +error-lens-font-family = "" +error-lens-font-size = 0 +error-lens-multiline = false +enable-completion-lens = false +enable-inline-completion = true +completion-lens-font-family = "" +completion-lens-font-size = 0 +blink-interval = 500 # ms +multicursor-case-sensitive = true +multicursor-whole-words = true +render-whitespace = "none" +show-indent-guide = true +atomic-soft-tabs = false +double-click = "single" +move-focus-while-search = true +diff-context-lines = 3 +scroll-speed-modifier = 1 +bracket-pair-colorization = false +bracket-colorization-limit = 30000 +files-exclude = "**/{.git,.svn,.hg,CVS,.DS_Store,Thumbs.db}" # Glob patterns + +[terminal] +font-family = "" +font-size = 0 +line-height = 0 + +[terminal.default-profile] +macos = "default" +linux = "default" +windows = "default" + +[terminal.profiles] +default = {} + +# [terminal.profiles.example] +# command = "cargo" +# arguments = ["run"] +# environment = { "KEY" = "VALUE" } +# workdir = "/home/user" + +[ui] +scale = +1.0 +font-family = "" +font-size = 13 +icon-size = 0 +header-height = 36 +status-height = 25 +tab-min-width = 100 +tab-separator-height = "Content" +scroll-width = 10 +drop-shadow-width = 0 +palette-width = 500 +hover-font-family = "" +hover-font-size = 0 +trim-search-results-whitespace = true +list-line-height = 25 +tab-close-button = "Right" +open-editors-visible = true diff --git a/deny.toml b/deny.toml new file mode 100644 index 0000000..e33f267 --- /dev/null +++ b/deny.toml @@ -0,0 +1,15 @@ +[licenses] +# use SPDX short identifiers +allow = [ + "Apache-2.0", + "Apache-2.0 WITH LLVM-exception", + "BSD-2-Clause", + "BSD-3-Clause", + "BSL-1.0", + "CC0-1.0", + "ISC", + "MIT", + "MPL-2.0", + "Unicode-DFS-2016", + "Zlib", +] diff --git a/docker-bake.hcl b/docker-bake.hcl new file mode 100644 index 0000000..d30795f --- /dev/null +++ b/docker-bake.hcl @@ -0,0 +1,244 @@ +variable "RUST_VERSION" { + default = "1" +} + +variable "XX_VERSION" { + default = "master" +} + +variable "PACKAGE_NAME" { + default = RELEASE_TAG_NAME == "nightly" ? "lapce-nightly" : "lapce" +} + +variable "RELEASE_TAG_NAME" {} + +target "_common" { + context = "." + platforms = ["local"] + output = ["target"] + args = { + PACKAGE_NAME = PACKAGE_NAME + RELEASE_TAG_NAME = RELEASE_TAG_NAME + RUST_VERSION = RUST_VERSION + XX_VERSION = XX_VERSION + } +} + +variable "platforms" { + default = [ + "linux/amd64", + "linux/arm64", + ] +} + +target "_platforms" { + platforms = platforms +} + +group "default" { + targets = ["binary"] +} + +target "binary" { + inherits = ["_common"] + target = "binary" + args = { + ZSTD_SYS_USE_PKG_CONFIG = "1" + LIBGIT2_STATIC = "1" + LIBSSH2_STATIC = "1" + LIBZ_SYS_STATIC = "1" + OPENSSL_STATIC = "1" + OPENSSL_NO_VENDOR = "0" + PKG_CONFIG_ALL_STATIC = "1" + } +} + +target "cross-binary" { + inherits = ["binary", "_platforms"] + target = "cross-binary" +} + +target "package" { + inherits = ["_common"] + target = "package" + args = { + ZSTD_SYS_USE_PKG_CONFIG = "1" + LIBGIT2_STATIC = "0" + LIBSSH2_STATIC = "0" + LIBZ_SYS_STATIC = "0" + OPENSSL_STATIC = "0" + OPENSSL_NO_VENDOR = "1" + PKG_CONFIG_ALL_STATIC = "0" + } +} + +target "cross-package" { + inherits = ["package", "_platforms"] + target = "cross-package" +} + +// OS + +variable "DPKG_FAMILY_PACKAGES" { + default = [ + "libc6-dev", + "libssl-dev", + "zlib1g-dev", + "libzstd-dev", + "libvulkan-dev", + "libwayland-dev", + "libxcb-shape0-dev", + "libxcb-xfixes0-dev", + "libxkbcommon-x11-dev", + ] +} + +target "debian" { + inherits = [build.type] + name = "${os_name}-${build.os_version}-${build.type}" + dockerfile = "extra/linux/docker/${os_name}/Dockerfile" + args = { + DISTRIBUTION_NAME = os_name + DISTRIBUTION_VERSION = build.os_version + DISTRIBUTION_PACKAGES = join(" ", coalesce(build.packages, DPKG_FAMILY_PACKAGES)) + } + platforms = coalesce(build.platforms, platforms) + matrix = { + os_name = ["debian"] + build = [ + { packages = null, platforms = null, type = "package", os_version = "bullseye" }, # 11 + { packages = null, platforms = null, type = "package", os_version = "bookworm" }, # 12 + ] + } +} + +target "cross-debian" { + inherits = ["debian", "cross-package"] +} + +target "ubuntu" { + inherits = [build.type] + name = "${os_name}-${build.os_version}-${build.type}" + dockerfile = "extra/linux/docker/${os_name}/Dockerfile" + args = { + DISTRIBUTION_NAME = os_name + DISTRIBUTION_VERSION = build.os_version + DISTRIBUTION_PACKAGES = join(" ", coalesce(build.packages, DPKG_FAMILY_PACKAGES)) + } + platforms = coalesce(build.platforms, platforms) + matrix = { + os_name = ["ubuntu"] + build = [ + { packages = null, platforms = null, type = "package", os_version = "bionic" }, # 18.04 + { packages = null, platforms = null, type = "package", os_version = "focal" }, # 20.04 + { packages = null, platforms = null, type = "package", os_version = "jammy" }, # 22.04 + { packages = null, platforms = null, type = "package", os_version = "noble" }, # 24.04 + { packages = null, platforms = null, type = "package", os_version = "oracular" }, # 24.10 + { packages = null, platforms = null, type = "package", os_version = "plucky" }, # 25.04 + # static binary, it looks ugly to define the target this way + # but I don't have a better way to make it more friendly on CLI side without + # more terrible code-wise way to implement it + { packages = null, platforms = null, type = "binary", os_version = "focal" }, # 20.04 + ] + } +} + +target "cross-ubuntu" { + inherits = ["ubuntu", "cross-package"] +} + +variable "RHEL_FAMILY_PACKAGES" { + default = [ + "openssl-devel", + "wayland-devel", + "vulkan-loader-devel", + "libzstd-devel", + "libxcb-devel", + "libxkbcommon-x11-devel", + ] +} + +target "fedora" { + inherits = [build.type] + name = "${name}-${build.version}-${build.type}" + dockerfile = "extra/linux/docker/${name}/Dockerfile" + args = { + XX_VERSION = "test" + + DISTRIBUTION_NAME = name + DISTRIBUTION_VERSION = build.version + DISTRIBUTION_PACKAGES = join(" ", coalesce(build.packages, RHEL_FAMILY_PACKAGES)) + } + // platforms = coalesce(build.platforms, platforms) + platforms = ["linux/amd64"] + matrix = { + name = ["fedora"] + build = [ + { packages = null, platforms = null, type = "package", version = "39" }, + { packages = null, platforms = null, type = "package", version = "40" }, + { packages = null, platforms = null, type = "package", version = "41" }, + { packages = null, platforms = null, type = "package", version = "42" }, + { packages = null, platforms = null, type = "package", version = "43" }, + { packages = null, platforms = null, type = "package", version = "rawhide" }, + ] + } +} + +target "cross-fedora" { + inherits = ["fedora", "cross-package"] +} + +variable "APK_FAMILY_PACKAGES" { + default = [ + "make", + "clang", + "git", + "lld", + "build-base", + "rustup", + "openssl-dev", + "openssl-libs-static", + "libssh2-static", + "libgit2-static", + "fontconfig-static", + "freetype-static", + "zlib-static", + "gcc", + "zstd-static", + "libxcb-static", + "libxkbcommon-static", + "vulkan-loader-dev", + ] +} + +target "alpine" { + inherits = ["binary"] + name = format("${os_name}-%s", replace(build.os_version, ".", "-")) + dockerfile = "extra/linux/docker/${os_name}/Dockerfile" + args = { + DISTRIBUTION_NAME = os_name + DISTRIBUTION_VERSION = build.os_version + DISTRIBUTION_PACKAGES = join(" ", coalesce(build.packages, APK_FAMILY_PACKAGES)) + } + platforms = coalesce(build.platforms, platforms) + matrix = { + os_name = ["alpine"] + build = [ + { os_version = "", packages = null, platforms = null }, + { os_version = "3.22", packages = null, platforms = null }, + { os_version = "3.20", packages = null, platforms = null }, + { os_version = "3.18", packages = null, platforms = null }, + ] + } +} + +target "cross-alpine" { + inherits = ["alpine-3-20", "cross-binary"] +} + +target "alpine-dev" { + inherits = ["alpine-3-20"] + target = "dev" + tags = ["lapce/lapce:dev"] + output = ["type=docker"] +} diff --git a/docs/building-from-source.md b/docs/building-from-source.md new file mode 100644 index 0000000..970176e --- /dev/null +++ b/docs/building-from-source.md @@ -0,0 +1,50 @@ +## Building from source + +It is easy to build Lapce from source on a GNU/Linux distribution. Cargo handles the build process, all you need to do, is ensure the correct dependencies are installed. + +1. Install the Rust compiler and Cargo using [`rustup.rs`](https://rustup.rs/). If you already have the toolchain, ensure you are using latest Rust version. + +2. Install dependencies for your operating system: + +#### Ubuntu +```sh +sudo apt install clang libxkbcommon-x11-dev pkg-config libvulkan-dev libwayland-dev xorg-dev libxcb-shape0-dev libxcb-xfixes0-dev +``` +#### Fedora +```sh +sudo dnf install clang libxkbcommon-x11-devel libxcb-devel vulkan-loader-devel wayland-devel openssl-devel pkgconf +``` +#### Void Linux +```sh +sudo xbps-install -S base-devel clang libxkbcommon-devel vulkan-loader wayland-devel +``` + +3. Clone this repository (this command will clone to your home directory): +```sh +git clone https://github.com/lapce/lapce.git ~/lapce +``` + +4. `cd` into the repository, and run the build command with the release flag +```sh +cd ~/lapce +``` + +```sh +cargo install --path . --bin lapce --profile release-lto --locked +``` + +> If you use a different distribution, and are having trouble finding appropriate dependencies, let us know in an issue! + +Once Lapce is compiled, the executable will be available in `$HOME/.cargo/bin/lapce` and should be available in `PATH` automatically. + +## Building using Docker or Podman + +Packages available in releases are built using containers based on multi-stage Dockerfiles. To easily orchestrate builds, there is a `docker-bake.hcl` manifest in root of repository that defines all stages and targets. +If you want to build all packages for ubuntu, you can run `RELEASE_TAG_NAME=nightly docker buildx bake ubuntu` (`RELEASE_TAG_NAME` is a required environment variable used to tell what kind of release is being built as well as baking in the version itself). +To scope in to specific distribution version, you can define target with it's version counterpart from matrix, e.g. to build only Ubuntu Focal package, you can run `RELEASE_TAG_NAME=nightly docker buildx bake ubuntu-focal`. +Additionally to building multiple OS versions at the same time, Docker-based builds will also try to cross-compile Lapce for other architectures. +This does not require QEMU installed as it's done via true cross-compilation meaning `HOST` will run your native OS/CPU architecture and `TARGET` will be the wanted architecture, instead of spawning container that's running OS using `TARGET` architecture. + +> ![WARNING] +> Do not run plain targets like `ubuntu` or `fedora` if you don't have very powerful machine, as it will spawn many concurrent jobs +> which will take a long time to build. diff --git a/docs/installing-with-package-manager.md b/docs/installing-with-package-manager.md new file mode 100644 index 0000000..4acd76b --- /dev/null +++ b/docs/installing-with-package-manager.md @@ -0,0 +1,20 @@ +## Installation With Package Manager + +Lapce is available in below software repositories: + +[![Packaging status](https://repology.org/badge/vertical-allrepos/lapce.svg)](https://repology.org/project/lapce/versions) + +Lapce is also additionally available via: + +- [Flatpak](https://flathub.org/apps/details/dev.lapce.lapce) +- [Scoop](https://scoop.sh/#/apps?q=lapce) + + +For Fedora Linux, Lapce is (unofficially) available via dnf RPM package manager, using nightly as of 2024.01: + +- [copr](https://copr.fedorainfracloud.org/coprs/titaniumtown/lapce/) + +```bash +sudo dnf copr enable titaniumtown/lapce +sudo dnf install lapce +``` diff --git a/docs/new-release.md b/docs/new-release.md new file mode 100644 index 0000000..dcd66a3 --- /dev/null +++ b/docs/new-release.md @@ -0,0 +1,8 @@ +# Updating versioning for package managers and whatnot + +- App metainfo: `extra/linux/dev.lapce.lapce.metainfo.xml` +- macOS plist (`CFBundleShortVersionString`): `extra/macos/Lapce.app/Contents/Info.plist` +- Rust: `Cargo.toml` +- Obviously changelog: `CHANGELOG.md` +- RPM spec: `lapce.spec` +- Windows wix spec (``): `extra/windows/wix/lapce.wxs` diff --git a/docs/why-lapce.md b/docs/why-lapce.md new file mode 100644 index 0000000..8ecfa5c --- /dev/null +++ b/docs/why-lapce.md @@ -0,0 +1,23 @@ +I'm a Vim fan. After years of using it, I started to customize it like everybody else. I thought I had something that worked quite well until I hit one problem. My linter sometimes took seconds to check the code, and it would freeze Vim because Vim didn't have asynchronous support. I looked around; I found NeoVim and problem solved. Happy days. + +But there was always this one thing I couldn't solve. I want to make Vim pretty. I tried all kinds of themes. Tried all kinds of status bar plugins with icons in it. File explorers with file icons in them. But no, I also wanted a 1px vertical split bar, not the thick colored one or the dashed line drawn with pipe characters. After hours and hours of search, it occurred to me that it's impossible to do. Again NeoVim was the savior. It introduced external UI. The idea was that NeoVim splits the UI and the backend. The backend emits events to the UI, and the UI draws them. I couldn't wait to try it out with writing a UI in Electron, with the hope that I could solve my vertical split bar dream. But I didn't because it emits the drawing events treating it as a whole canvas, and I don't get the boundary of each splits. I started to hack NeoVim code. I made it to emit split sizes and positions, and I finally can draw the bars in the UI. With joy, I also looked at emits the command modes to the UI, so I could put the command in the middle of the window. And then echo messages, status line, etc. I pushed a PR for the hacky solution(https://github.com/neovim/neovim/pull/5686). Then I hit performance issues in Electron because Javascript was not fast enough to deserialize the drawing events from NeoVim. So I wrote another UI in Go with Qt binding(https://github.com/dzhou121/gonvim). + +I wanted to external more and more components in NeoVim, but I found it harder and harder, and I spotted Xi-Editor. I started to write a UI for it straightaway. Creating a code editor with Vim editing experience was the plan. There were things missing that I had to add in Xi. And working on it was so much easier because Xi was built to be the UI/backend architecture without the heritage(burden) of (Neo)Vim. + +Then one day, I experienced VSCode's remote development feature, and it felt so "local". I wanted to add the feature to my code editor. Then I realized that it can't be done with NeoVim or Xi's UI/backend architecture. The reason was that (Neo)Vim/Xi backends are the editing engine, so when you put the backend to a remote machine, every keyboard input needs to be sent to it, and the backend emits the drawing events to you, which will include the network latency in everything you type. That wouldn't work. The editing logic must be tightly bound with the UI to give the best editing experience. + +So the new architecture I came up with was like this: + + UI +Reads file from Proxy
+Handle keyboard/mouse events and do the edits on the file buffer
+Send the file editing delta to the proxy to keep the file in sync
+ + Proxy +Receive save event from UI and flush the file buffer to disk
+proxy the events between UI and the plugins
+ + Plugin +Communicate with UI through proxy
+ +UI sits locally. Proxy and Plugin will be in the remote box when doing remote development. With this architecture, I can make sure the editing experience is always the best, with other considerations like syntax highlighting being done in a different thread, so nothing blocks the main thread at any time. I finally had a lightning-fast and powerful code editor. (which can be beautiful as well) diff --git a/extra/entitlements.plist b/extra/entitlements.plist new file mode 100644 index 0000000..ad77a2a --- /dev/null +++ b/extra/entitlements.plist @@ -0,0 +1,14 @@ + + + + + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.allow-dyld-environment-variables + + com.apple.security.cs.disable-library-validation + + + \ No newline at end of file diff --git a/extra/fonts/DejaVu/DejaVuSans.ttf b/extra/fonts/DejaVu/DejaVuSans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..e5f7eecce43be41ff0703ed99e1553029b849f14 GIT binary patch literal 757076 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

fI);V1&`p^P@z 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%0Dm&v@4taQGLT-zh3S`AeK1 zI1+##*G1O$a|Q2b75}(AyAGfC1L33JCe+F46RqFg#!-dVZw>HCKD^&vP~}ixK3cy)GU&I9 z)IM=3z7W09$c-9E@dLy&AtBi9(0G7PMLm~LE<%_(1*4nU^;8{x_`l$HdVkFm*oG{(!VULd@*7v=XqPY zgA)2eYhz>hEx5GAmkKA@s`zgOKOKHHybk^Y&2*FeUGZrZa`yp?q_KA^#2G5$lw*eE1EM0nqL zRwrXRZ#$C9jIYa1)xuuRUt{^y(9Pkh7!Oz;#IUS5M@yB}bqw4&!eF6Brdhqvc@cBU> z7KT{L`$naIOy$RRt`Yp44O&I*8?ghIf6UYRMoiM4sdJ-2-^e{sf20&69_1}>F#a1n ztEXcSM^(!t@-hu{446i_$sakO!C{_bmVK@*wyXGWVHnrp*TK(*JRN>?=+oiv=huVt zajeom1{1KBem(d(KNU{%w;TA6l-jD+s47KX25X+d#@pRi0y%q@y^hs8Mod1m84aOnhlei2sw6(Coe0LxlI#SBO zzI&sw2su`0&#*Gp$`|z*I;wC@r`8*bcs4_O1{1IGd^fmr*=JD15YHOScSDZ$46_H% z>iVUjeWrK1TCR=_J6tby;BskfQ(V>NvmLINP%Gruc>TL7K#SIc>!ptL-G*od)&S}+ zRp(w+e&BeJh4>=idZ`ot-cVnFKe#zW&kom1!}#~cbL(nsy|K^f4d;03c&i&HS6QzH zaJ{6CgGsO-xc%$+n0iO@vD>+|@F!1!gRUbyfPdf<-1;wY2o-1 z05{_OoG~LNxd;I~{JbML30Oa1)0^{@h-RaKd+@PwTQO ze{QQqIEATjaikre+i4L_;Tl}q*F`^aeeJ~OC(h7l`nMJiCxPVC08V`7{0kgD&QtN> zR6G?9PpUDT%OCA|DxB|2*YZQ-lk01zJi>?ki)!US`Z~f1izbI#I2`ilx;nzCK!r=M za5&`8^>l<2+Rx>A#7>9n=?JGn6^{1{NzNpH($Nu4gEaWjT71&a5l-NP=!lS$hEKXV z!fCJuhqVT{s(-seKVlvt{=xDm=~(M;^+PEKQAf=&DIR zQe+m%;i?V&kM?qW!1WU53wmwj??V#>+?Ai^ZZi*y7$Jr{JT2(*r;H=x}=j z8|yeb1J$w4sabLZni;pf$tv(&gTG!W3ISz_*Vosd|}6Tx@(hU8_LY)a)jOnZ*$OgoMVQ(ZYhscnKMz7*9JU0q&~B`sq!kOGXIp< zElx|dfk+EyRl57?^TFk)!uR|0`m~rS>5#Und~p&LdodcEnTlSqQ zGtwedx9xk3(=}Yae5_E6PN(|gW&s)r%SHD*M4J2L5%hj$q9FCZ<=Cd?}qkII}mi5;z?i0~mCY^0?+Q<6T zqfc}BoBH^+8u+4KG#;cRmZoxC+wMO=i}7}wxEwH-4W1k~gLP_zdkr$uaa^qVXism< zt7wn~=+@KFtGAFtoO4N0PyFp_;M&J`EpjRyBOg{`8@ z1lforG*I1lV=0mKNHM_rqqvaY?WEy)=$)XYc-dd%*ToqqYkX6DRrm#kW6q&yjaF3d z^W=~?1A0@%mA3vLxKc{Z`Fgkp71!+z&?U0x~`Ar<1^i2(tY(VRppmj*CV^l7GLTskr zMZzK8NL{_Avd#4xd_ZmXKWIBj+w}s`HZ;{U-g?kR3yjzA)uYWDQolJWZQT{#s{Lx) zK-=aaP2@7+d~@0hn{cWIUPD9LHN>|{RsAV)j+K%+foY^0$wZS}h$_GNke@h_3-JK; z&jIx(WSweD!x=@oOFc5v%RxQ{*KfZ5-6qmN9m{tdh{Q>-h3*Xd4 zbaz1wx`ECH$%~Rg-HorIAH1Hk@kac+NB?5OdG16cJ4JQs&Xs$J^nq3<)yp|xW#7`J zAe+UYO>|?(ChPaG>k`=K(qf#faTYw@a{NGQqA#N6P*b1~?Dt~h4ao?WaA3}?efww6 z-Y-6$wQt|7+57jS4Jbcfx*|`4WRbrYU&UQ)zIb0*O6|LgA7{{y&^51PKFFNzVPT;d zb2ruu{dD)r6-7Zw;K}1TotXTg-^1eAe^3vLGyP~nKV0aCE6;@2Q^-V@e2^_An%}n4S;(Os<3=qs(g?=EHeEf&ks8bn7J~8WpdM+* z6T{JJ4~~QvKNHbrJ4*c~H}P-OWb2GZfJawZ`pFZ@yT{~jNd^`BM+`qWLhAj0NI-dx zOQ5!ebFXWVr^-Z0vOlgZfDUdU4`n-`r!ZzILsW|cxV|2s3I(BAvPbY-{D^!DXY30Z z4bI*y$_|$v(O$d?se3LKpkM>Kxa=o^?a0T4^hCG;O+QZ4uMy1%XM#sM`w=bF$)AI! zGuG#Qw)e<~K!RE1#1{9hKXGyc%T)sZ{+sRP^==ndic@40_KCY>hD&#F|CD%#i8}gE z67_47;MVMwORv7tWAeWym|oz14*JJw^pQUS{yHeUKGau&Y~$7~%q3X2_#^RW7R(1iU38dHR`A$%9;jkfRMj!pQYhgi5q=R1n{>6*$ zN2exq2xn`g0}d{xjwe%7-mU7nEH5u6si}8*qVk8L%TjWqlZM0%GzXz-_y>1&vt%#5 zGdP7sWq{3v(_Jqs0s0SYi*b)a`0KKpldJLU<+HCF1UFYGwbZywgR|rWGsG23&GqZ) zlg}c6d0>F#5`-YRD6@3Da&xz%E#zCNobwvDY!9_iEhYJ zk|nMX*2u7^klK*ef!mEVKh%{Ny`!dRhwlF0Fw&V|QT`AMa5lvmU+_jgOah*JiH*6h z6tGwB-xr5iO{)x{tE?v2!wvE2O@7LlPI*@>_wUo?Y(VcW-dOeM<|^?9(9uqmGWhcI zccE{QT^$Oqg5YSOuDc4Sc`nFw=Aj{Pg=+a-QeQG7O|zt&q6n%cNkqKtT)hM9sCvdf63(keEIyT zmAWf;P944BUUOI<^!N9A&ZH=O#om=#$R6kyl4ydvp*7OIH7R^xri*#<{@T5 z4@qwJZMLlG!1*6_nf=!Yq={3kgs^juvLoV@4NHV%6PM$XP>Ig z=R_~vBUOfB>-L}4uD@$^aPs|S#iHx$@y+sut3wm-Usf#mQi?m=r&F3Niu#OR{SNo( zoGy!!E~6*s+Y9<(4ps$l{K!akvJ~OGZkEo4&b?FaQyip+O^d7BVAdj=6=sdEL8{*I z_oTlmul?gmk9XjM1ou^sCy6Zq8v6I-zjr*I{Dcixw$szUCqs&lS-kY73{M&}8NEn% zd@y_@d>)@?QRmN}7gwJ@uk6DAC(oZ(Wrwv=7xs@e5i6v$h@|A~&DTbmm0)4$E#J{- z(@+Cd%%IvDSjl;@;Joz}trpbt%=z<@{)0T!XAs}$q|v8*PyxtK*N9K*GrJQagHM%X zHfx8qMBKbX+>B;W+wE*Ci&Xd)>!=-&JGiKkGBME$xy7Wiufm* zgZ5m*xIL(w*04SH67;`T>e3}~nIhd)YF<#J`&1NjHD6pQ-h<9{p__;WWO1N07d&l5 zOnqxtbhr?Y{KE8OceJEsdHzBjXGYe!fER}U*+0sC1th8L(C!LU-85Srv z(M{*3cQd#-xH-EuadSb^aTX*7>4NaOZ;(Tfb5N5Ymr%Uyh^r4>`U!(vMhT0AJ;ED8 z^TBK|u4R<$`C^bxS%bLDawpyfz6uj95Q6sP)quptkjH*&SeW0lqHTy)_q(2k)tg4>bdaQ z9^E}WCIz^EFK~f6dF52@~D~Se}@eGzjUlk`fCC!Lt}X+RMqgN6$@h z{{B6CEt=b>_sz@aDyBM+!WSl>|F59UdfsNNZXpxIvC8hHtgDis`!=@bH}N*ct0W8r z-*>@x6QLEo4X2J^o^mHKGMwjEO4csMK>pX-gMb>;RCy=cx;@L1f+r#I*I#NNDV{oiJ zL!RX}u}~)J*lNg|R$^CX^zk*JqbU0=Tiri5xBsXiF)=Z1iuL0B8fe~m3+K&!Ja^6_ z)IA#ImZBV17*EP41SuIz7?HSKZS<((m^N)9 zH)TMpP34`kgxeSSw*QLvr2fcBi#;DL*X%L~>V2srY#rD+8f*w)M+lEHr)sd_DEl#o z!4B78?Sc1z$~x!N!b*U5iNml5uHh8{_CH=PTsjRl0cEdnyneN?fxx@V@v!f$;q?RT z7Y-Xx3j@!RMf?=?Vvk0{TgFl(3)=`7_PXsb;eFsa0tP=!hnVFwz(KIO1CYhjQO-FJ^Xzk6z7b!89M!hk29r5wTH z%6GtVU~zElfCS-Fzei#>X+ZJZv#oCnpxke~N1$2(pJL%plTb*OiD zEezHkyC#LB-V-VeV-(WWAJkptH%ibg9@x01RQGBsUn3crW(x4zKhljphes&NH5RUn zI@G)8f#Ih=`snoV13hv5<|Wa``m5O18pDp_synmTjG2>?tGZFPkCdW zGJYOr>J-~v`IJ5tQM@(+DFq)SE`p|n!snMis3xz$gcMKwM}#|4JB0%U3JW>Bkcbr} zq%j>bns13|5#BaaIpZ0` zN$Q~ckAvsfJwDB@q_=#saY*r{u3g3U`5w)m{mH}oQ#P87`RtfikD8!owkcoTTQ6Po zl%H&9;Z6EysO`4=I`k)^HsP51Jijf!4>iOtDbd{slN>e$zbGIG+3RpYfVb3USi!i# z!@i!OTu`>KQ7pOg>*B$er~Uf(tRb6TjNM%77U9eM)5GR1f6fpY19rNw?ZgJF>eA&( z@et($v}(s;TislNn&(O(A{_5 z!6mPE+HLI9b7{NvL4ZYV+rE+e=&1eLWKlR3m>m7Aqo8i79?m%_iy+wJY{A1{TbiIUqTFadkn_^w&QG-PyChFJ7}|F}tCkH1qE7 zr`UnJGxPoW9%Q4GEnOz;8+u~U%tggJ(|4}A^zP7CyLR6`VE+8U%hQf+`Q_q(w@UVX z_@XYx`svzdm#kGjIzMib^%dQfNx4f|hVt$z>yBl;O-V@u`}W8QcMIFFVEg{&%@4L{ z(Z7FYw-DD>o0e^T(_~^*Ux-67rg$42kbec%H^vxmqY+K?HQ{K1+DIPi#T|J(`=cs? z|Fd~W(6>%myJ5px@g4c=ce*d1e*FSF&xD$VvpZB~3>rRk#IOY`M(xYo_u_Y-lpN{V z`<23F%Z9ISe|FDbUlk6ELZj|I%k+yMe`R2EUl?v(rn_?WtCh#Yd{)mnlF&5Z|7eqk z1Db=el7@H-`E)_rsEMY$G8i^V3CQn^)Nu5nm%-_Si`w|#BwYYwc)$WgLqcQ-etWa| z;I?re#fqM>KhTel<5C9)&fNaJ^38kKmG7$L(|h(P6@hF`;FI7zdwvX@-OSpPzR7MC ztKQ{*R#mL3nJ3Mo&#G0{(c&g1S5zo9_TMV78bJ2NI8**#@ajUIp=Wq7HedMdB`~g9 zvQT`Z?1>35{fk9|fcxZ+ZnG$dj_RJbT5ZZ>d}00Mqq;97<*ITWn^t-EFFiiYTCp(f zo>kw!q=OxSc+w=i_y2&u7kY{OaO5j`4s|m;`$1j>T@uHdWws6WxD;w^ZMfvvbf^D8 zpACU*r*Kf-5VIz5MN7x{)}bLSO%WbOC&|Up-61MC!qedH;O^3_sSwdBBqsgx+4!2X zXAz*pKiYrs<-Z_aDPX_t_Jg|*?rM85H`1{W1Bc5I{!`tC3wOPI$?Njt4p%()sp9eW zrsh-4g!9FmMd!HwUSpd~a4mH!GnToRd6apM^%@^k7F-rm7FuR14Vw@?Hgarqm7&U^ z%CX9+%DJjZl}nXtm0Oju%Du{?%JYSws^F@Ss?aJ^RajMcRYX-}Rg0>YRjsO8S4C}$ zj>jB#G&&d^gB^k$2YB~uKF)h|5Kh7kR`Z`C-K!ylUo7m4Unp0ix|oCtlF6KqNINA- z_{D>kV0qP`S4*~C2o^h-tv`tjfyq-T%5%XNww1g(XyCD-zbO}6Trw|b>|OKL7A*Ph z@MF5+SH>2eKT+w|#uVJfukyr&!m(K4SSXV!ePe=6F}{_IvCuB)vldW{J{T`pKRlrU zv9ka*4|fN;$dvTX+hWE4tn*m4QXpFXwids=QR*+ww=NT>S?5l%28o|qV(gfRL9*IQ$E;R8ZJx|7Gj`9;+_M(xT+47met#n zQb20iNoi%~u1jQuF4^n}IR4_!W^xy0U-kYagy9JcKc@|&EVJtGB=>}PhT|SuT&<20 zNhSg<;(*!#l*r^&OON&WLILSAJX*qmyrNMp(L^m#2GR6F;xNk2P^V z(k9sC=k0#be`LpLuU%x(Lk8qF^Un$!n$f9eagU5P3B!Xk-P}C9dlyx}4ISH!-9FUR zyG6f*)T9ZUQ=^*sH4jQzWbM)-Cc@Rl*Ebkxbz6#`Z5*3Bv28-Z+G!(4o7)Hb#Dw9 zIz@X%I5~y-_V182bns$nZOxWhnE@$2O_!AB&Ko~sgwv|=jKYfr48oy z^XQ9~lt0Nc5_00nWozAVxQ(iZo22IbB-uh{;q{!zW6Rf-&B`nYjWz#}GjM77u>RxU zm@}?s$)Il2mQ9@0Js#%}V><!mckynJRioEi@B?)F=rH%vrP7;GCPAJR_;SJ4>G z{9ar#VaO2UG~Z=%f4MPcIY!hipLKh-@AR+ z)afjA#Pl&0D;D=DE98GDo zYB^adupXVnm`TRGrDj4k@TrM$p+&H<5rDo4!PXd9!2I>GYr^0##3NwD7Rf%{=P60j z+9ob(ukR`TXv*Yo#y(`eOD9_=g9KYOqpI2n62L5SZV&JSbV zofI*;fHo&EIy{r=x{K5T{*q>pCl|dkYSb%5g+&E}Mjk7_%r4J3JZf-3k+Pf(>NwTS z)wSt_j`D73;V1tk-5VAvD)*VU&(y0d)tzNsEcd;0OAHNrvRnGwr(;F+&XOY&I$|7) zbYBzKqkOM}N83o1!Z7rbe}Cdm>hmJ9%U`LUUj5`R8IdY5O(*6w1TG@i-`|b z6dLOkaq>ln@-fb@QZR>@X~dhxnPpeAvb_&t+vY!Y?K;fv&@QdR$6vqGqf_?u>&n{h zo%GgIW>N5n?!H!6SXtS7e&w72gTs8fc3Pl}VRJXe#_jExF}bp1BK&OB?}Ykqp?-gS zF{-I|NZ*I^{Q`9jh{q=CEoF?dWB*URq4ayQ#0#_p+{sbS|A>&~U1g5)g4ld#=~v5k zm43}`E7e#DmcCT>jr9rhV{IT8NJsu0b@-sC1QtTuM=~y*RE2}lirJnfa$_3XJT92W zxKPRVL=jtAuj0yZ{83hJ-n>%LUHReKjaz&7Di2tby?ghPvCCyxJMjExbd@{a{0BfmH zxNw1J)U}0TWLi@+Mt{=UlWu31xaAz9i-eB0PYqw;mM14@ycV<%U3&^dy{(nv3VeGYNE)gfgmGnOrzky19K+k$Qv?%w;n<2>oltlW;>)-Q1CrMP71`fQ*7!WMmgQLy=N zSn~^y|Gp?KI-J;i>-u%uf)Wpf20Z@!^4|d({|fjI#wyZT=m!4V-~<--tZ60FTrS-4 z28WB*KKNyk|Gyik&wF<6G1hx#*faBwq>YW;wCqClYiq*SEkD$*^2xIQR}0zfX0v{O zo+Y02NF5m#<>wSK_kSDoNf$hOmPEw`h>QNumXcnf94V2|!+t^t+N5UScdt{mf;%Q| zybrUlJ-Wz&cQ(E>W5!Dx?+hIG+al$FGLtP~{g(V@bv6ZU+ZLo7KD9$(;*;pa!mJ7y zmQ`A;;)$m`C?I6Na$GsFAN9ajcn|NTPUL&ihi@ev1uGN?L&syF_3*8UH|{{%OEhP=H_F~=bvnBc9C3L(bWI5G-p zL(13vAL}(=B1r!vL7~!;&Zc!s7%?KD+l7?mzCC;QHmBe=rQW@A6H~-5Yl?S{->`A4 z{CZ&9$sd0_DJ@XCJhN1G_Au>l?c*lb?3Rt*t*gU4oaI*4H-jfvAt>#!jm%%LosRkR zBgSJ>ST-#v|IEKn6F!OThpUVcVYLUUB>hunhj@b~jy!(Y)TzUUPMfBD%NBg|jWXwJ z-Nt&;BCv+0MGs6CdHdQmRXbSlj%|;wTz>TEGVO4JH-}!}%@ei_JYsnI%+-o=U1@%HLE*0=A4mjPh%4z!^p|cB;O1|#*%x2Q)a6&!h0v}5|H?fHLekKZo6^3PI-r7>w#A}dbB8K? zq<6##>`{xwXQ2 zv!48X#f#lWd$kN~Kq{pz42pKgDt=wN1I zhAGO;BP7Z>vTt_v%YscD2X4A|2}(4Eg+&=#1$wlMNnJFfhbbI8Wssk!{H;?TSonxF`{4Vxsla!QQ;q!LR0JMHkZ0zI-m*#8@2-U6W(QS4}TDR;e zX+c4yJAeCQTUxR5OaCDsujm^TWKNwu?eGgjCba3YY{ulGL5a%aKB?iRv8J0tdKIM2 z+cRTo=7^Px*3C9Be{ocsZk>w!eazj`GUD@oetB8NC5y7_l6LO(Lj;J(@1?zFPjwE2 zVEE%SaP43D%7rJ-Ur@eaYegTnRw=dqs+8&`J^r80g+3##OU3DrTZ`AM;UvGVnDo!W z#%PK!u){OdJI(b5r0`0R_*#i`GjhekV+$Rf#ucysI(WuW7ISo3_BYelzvL+HM#ytp zOjqyzL(cEDuG4#2w+@-OV@(*Q0nx^8M=k9HL%6R_qG1Qpo*vXS_#a0-*wSOsY^AG` zlUV)pnT^p4k1oh~wBhsM%46St?)p&g_3Nx*OO=No{(gsotE}Cr-H5u*%^J~@=%?Af zm&&omq~Z(aj&{kMeN(Y+9wfQj=Yd!4wBiGR&w}#iW6msCRhn)#`kMlR9Gsm4ywZB~ z%?Jsag{{&};dIH$rCXeu(nHF5QxM7o?jzrMd-}4CXcgp1s;FS#(Nr z_YZ6n*FL~U&UB0n^6+WVYi>ce7LhP$XgwT<^)MT}hLBEe&rq{EOKHC|DX~3n$-w-s zoAaJ_1e)5g1PtR=lvSiIS{*WDWS5MboGUpwNf(a)kvxBK%8=5DD=X*DoHu*+`Q>G+ zuCAInuW(OfPTsO%J?1>KcH+n#E0)g~zkc}1A%EQLlcP&ciHm7l-FA3e-anndQ>pF` ze&@PQ(;DE%T+2sf7%s+y3W=o6O8lk!9vf;W^=yz9+5o06Vj0(%SX$UGeRN)yW0YU% zj2Vd~1*?=Nxt+{OE=k?|_=7`THcgb>X859-h;%sP{klLe-DNL5Vd?L(Q zl3NBVE{*kTnwPaXx4G*g*W0BtOhH|jIb^k86=6X%&4B^d77%RQ_T`%x7Ih=X~qqHR$tTyhjwkeZ5F{N@~_9av*403HB>0De#5W zD*@@*g7rq9;4?>$9up5)``}K;kFdCWRC%cFv7^W>C2x6Ix&HFYEKJQWr5qlKB=*+( z%E@6PU(r%cJ^6vXfP;DxZy1 z3aqgsM{?aT=}D0M{o~g1_fO#Sz!rcHZ8!rObhmtKAx88$w02{bWu4{4EWskgyzc52 z6=RWo(+{x?zgYxJ^bJd!bW5})@TSG|vC())p5OkE&dDMI!5Ii9cZ;)!#W&UB8=O6+ ztHsx7X=yQ80!`h>i-=r z!hiycm-Z!PpvB90*gqoJBB73X0;k~@%Pg_RLz1jmBpZ)UX^(~bDeCAr4p znr?A9qzA~5ZgESsxDhu-i;D&CdRin?w=roJXW+V6yso06;2V~xR7(`+IM@<#)e>Rx zCopksiLpdkyilU8k^bO89C&ZcZ%)A*5&mAmkQ9H?(W3WF>0xooEubp?iJzHMU`NcX zZTu0v!Nt|h4%hjn3>-MHPG(*fe@$jykeTn(W#+4uhRl48hXYM58^|oqB3ld~BIFh{ zIb?J*Slo<<^zOe|(2F{Et5Xxv<&aMAV3Ca$UAnVV6G{DQFk1BZIxrzAK8Xev0-4^p zTo=FL#z%^3LXVL4GS|C=RYIgTc^xx~FKj!$PPuO#w@v9Zm=K0cK`E7-m2 z@$%^>LDEO_HdK#)k|}>*lQ?gKSo+*M?>tAJ-lIqN#>d*JvJ&HzVdp{rqwWGcR=Pno zn&vvW7r}x=KlS*<-Gjcm8zXi09k6hCA7GEdb9(1*l$PvromGXbDDW52x(QQgB7JuIyr7TwdR-P!&vKb8L zwoXh_UMuLEQ!sMb!o|-jFJd}jPL?WZx{lJHxUC=^Jd(z5s7;eq14cap!#wP(0Rlp# ztR&Sl;Gs@2X=%`)eb*K(%styrO&s^TEd)bw$Ht{ zyXNjE{dZ zPVOHV{-$;78{u-&lh*>n-V{f?8OHlC%XUxSOdpT2hO<44JX*W8=_!#3X*b2yWwMbC zf*x1*0$^{F0TPnjo_WI%P*;9!2LMZ~-N2W!g4(SbJhopzQQ^i<@`4g#v#XAkn$!H7 zn*4nN+B^12;PU)D~n;%yO1+|Fxo7}ctP#+rG{jkKx6ZIIXd>}7`!a0Llg**hGw8%z zpB8;u6-^&Kdd13;(a~)(Ggr6I%xquOw?k%TX20Z(C8I}|Y}_@fx$)A8XJW$UbjX_B zHZCk6IC^!fn%&-;SNH1P-7hG!B=D`O6@&J+PWj-IsTCDdElrxt%)_0AFNj+<6y)dU zUC7HXs+hWUTSY~MDR_9kYuusy%2`9=!p2lCoHw=OAh}I3Cb(xi-!m9Dh)?4^{7FJteyBF?&jb*6dsVu#j+16$P`zQ7}+F&`>FihY_c znnRIN`*!nZ!&{1b)LG`sXBW#D&@!6Lf9k7O!S6!w>wtCr<)cC{Vjdy*1S2Zpis*zZ zes`g`2!0O%%oD%st|PSZE86-PA8{}OBu(*4OMFuC>4wihe8%E41D|F1Y{KVNe2(Gs zAwFN@MU0;ISz@;L3uh98j=Xk8o`7gQxB&AG40Xe0uo~>t;V{U@cCjg9blb+dux= zugVf-Jl-0vVH;4ZjI$Eqy8ikPz$oqMw4wQ(;2B}^#QfC4+L4SdYQ>=mbGTVYz9p6r zXWD1L=}u1*Tle|-_C+-vGTQRkcIV{&%E7YiA?*B|VrS)e6nirzz<18VSugib=x)8X zY84$6V2}K*E9>Ii$arLlLTKGTU_sfz6-LkTI5@z5RtCF8cUm~S=2?dKF7U2^ge(Uw zbYI~N6P;jEk4rT=oza~3cN?7IFel*sFqoP+F5qqwe;SY<*`Z5J=ags0u3nKirOTj^ zF`avu+owD;;<;G~V?R5(bJx-5Ry@0MneHvT&eSTVMXOQCqPg!5EN+&2qH=-q9E);$OA=C;g97h0=5T= zDE0=5g8s23dne!T%-!82fWE))`@STby=7)jnVBY)IKNt)o4leQ z*}kA8$an{4ig!Twm{Y#3orW#USf`H=Z>bNPd(ufaSPgdza_EH^6fhr?v*1)x7F~lN zu5lTl5PBFzXdHp*#x*(^vu2|l`HDR_Zpq^5aUBOoEZy9EY<$F)IQ,GZiO*k^1+ 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


*Toc{%?n7Na{@W#kyM+}-t@ zl`z3{4HI>%paEfoP#so^%nk*Q){2G33zzRaO6gHLr@pK3hu70rSFNJ2u4n!>x*mq# zg|an@o8-$x{Bq0)xcnB6egst72ST=|B zI~6{0E`YVM2oeX23Q)d{o$Q+U@>oyqcR!L(sPiCfT(!n}?mSEWeHJr?lT@B1+sXE` z^f0UUzc0u7Gv#E!)?cIiQ78w4u3_Y_1Xl=1sHg;<<_WJ1@);z+4_x2!RxEX!J(j`$ zWj(j*@cNFYUW7u;zt6_#37UT*l{hbK+l6Ho1*1g;#Kyx;J8TFB9Tt+oyM+r^@Gb6a4-p6bK`B|O|LYf-eIZ8~ub^HRe?QFPj(WCengv2Eig zpwxWooSonCM*i3Ha1j_~cD&9#O6t%?G`hL0h1C5hwezy&mO$Y(-q>#C=JOf(@sd04 z>sIbyQrA+}ES9|cf^rEd|LHB^MfoE*ofoYLiI*NO(m+jx10d#}x;)yq@wz$7Zdfp5 zVq;Uo#4*>;`5wWl9vA?BpvC;`+P;n1IXM{<#+_My<2#cYa#^@?;BN8<@`v5%gj%+O zRAUV}j(I@Rr}oKGa2A!0(+XH*EGU7WysoE+XDF~c7-tP@p9N9))$4k=zwasEbEMnT z_6(Q&47v58-~RR?dc!lZ54lO@@DkMR;Tq4y|J5^Z1H}I9iWSciJ3_7T_YBUw>{o29 z6)HPt;S#V%4yHm`5{2KBAgloslYHMJ%Jhx*SJylO4=7%80L<-JGMelsOCGK1d*7yX z<)gGGnL``M{$9jG$I_2c?m{vZecy-mlg;m#8(7zhf<;158H7bshn(&_dUPk<9(xe( zEn@pmoWLLM;1AEXv^@Jm{fHC9ed2`Jz6XDLNnEoNt3(vi0kMryC0w(Zm<8ORe8wX+ z)%R~qS3dGnDZPX2rwzU6M`)ghf8kMO`sRIoYaacnCmOyV4R2r#$DH|Kyx-|ej~3m< zZkOp7VrK&ehpCIQn~KFHqOVVA{;}OKAR{c;^sDOr1C~1(K0`x5K$P!VTzG>$FLwQ=%E}?B!BQhoxux0 zq=YT%5c=2vKqL)*7Y&DzZ~0#mqSue)8dGNiK*V-~ci4F@9Cj zVRnS&Ip2|tf83~JO7P6-rj6;tcT5U+MDLDd3O~JL1$` zk@D54!xz$+mnp$_Da7ABVvrlqGpsHyU1>-%yZt1@l;wSXQCS}8OaV$4HM8->$+i){ zqMZK-C&hrSMQnF`&an$};8?t!1*k}Z(-JmH#9nUe;|o}$(Ttp;!t#QBP*0t+uXJ{P zLA0mM>+s4I5&WCl(J>W&xD~0rsw`o%#bOUkA3S(^DAnS1g>rhOMjP@A8lqp#oA*_; zp&*}$>4EEgWQ-!8e^|zvXJrl}yC7S|RISkzkY|t)p!5|t#YFZMU*S}a*{#7(0d%dw zw=i#&_(2RW*%lEA*r>q|zT>MRU!gcBS1XN5B^+Dv9$ujkR4OI?7~aqng1k}S6)J@) z)~+(>6nt4PvH%GbaFoWis1&e-Av6NNh!VF_1$V+y0eE3ls^#Yt+-+t9N*8#r=L&;b zu5H!|$|Qxr%ke@`9nru%E3eSu+QPzxR_+rx>qeDu<*eW}M^plWa$Zm*DFx({tEF!O zijBib_7&D#OB_xTKM&AI!yy4DShc(?oTB`NaB{#DK7K^E+?T?MZ3F-(Iu~A);r?xnpW{PkcSV!6uaM~upX@vx*rZ|{bb`eZ)ak!bmDM_H)S>HuKDOIO|gDyaw z>jKnWcUd`7+8t7~qZ_DH$f=BjO3sR8u)`a!ch zJbZe3iG^D+Z1koBv#+~9T3j5xKkwlETSmv;s8~IqW#d!)rXEjiY#Fe+0&T(l2>Lj8 zQjv;tb{R=0(J-GX6K@1CJ4U!V3aYagmvAT5ttE5-N62+@eqyhzwFPgyM;}${Nb-pO zR{FShBpLBA|LyQ$>+;?r8G*wnq2<$4^Dx#1n zIm}4Ito=ujWSx>e`raD_YqNSyd7~BJNFvhMrOvc6${UwKL5Hri_eRx zIyPdf!O0%QrX&|S!t9B<93=f}Y}*pF0;@E z@gTQ?-`p{`W3H6$exz%a(jk$W6mYHd88GiTzz zrZ(<1;oVqfTT{%+Pka6R3HhU~t>+;%c)ep6_XWP5lG;1&r~fF%32(4+Va3-00E$lu z0^$RXJ0q6ez1&!~k~`Jb#C_4R>vehQ`TEvY`J?Agyv|RHS)1BonT%d!vtT2?pA6JV za!W805>q866a0wt2Zl?D0|$a74mM`+!)~~+AMsW%MiW~kxM_=fj~Mz~-I(&~>R_mM zA`C}YpS01oM!Kl&Q&l*3+^7ZDtX@9r`mv2U+1WXbBNwvROcHFX3I&7Fvg&;k#tk3Y zJ02O{v+A=px`?cA`*d={_2WhsW@qP)9e4fQB{$ENVsNa?;5|&X6nz*auE+7#u(o&J z#fZ1o5$}Z9vCghBE+XD-`Rs`^XDwfS&4N+ma#7W|hPjDYSoJ9y(n#CdK2bV?)#YRA zo*O!%ckfWJIuRy$jak{*g(K0to0p(@V^IQ&HB4qX(S^^ddJeBHiw1+Cs@@}qkDIVB z9%1v-PybN8CxoHo)KfMD9kM~0KgcF20|`itjbD+eBmuFpj$pJToInlkfyRBqL?P>d zih`6R;ov~^9$nn_Dcz$D<~2_}OTRcfwK*@S{mpMQDJ)K`ES{nvXlBO;Z%$|$JR}wN z*B?Ge9#%V2hYW5aWpusql1Sul~j;vbXP@5(~!Z@*voVmnO0WJ!uW@;><~xRB6~&4Lq4XK-ExFeE1)BF z>eMUwz16+B-s)T~S1q5A*IUEEWVlQrv@0|+c#ebQjF-0)j�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

JVuh<&iTWp{J;w*9G-ib5g= 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

( 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 z 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 literal 0 HcmV?d00001 diff --git a/extra/fonts/DejaVu/LICENSE b/extra/fonts/DejaVu/LICENSE new file mode 100644 index 0000000..df52c17 --- /dev/null +++ b/extra/fonts/DejaVu/LICENSE @@ -0,0 +1,187 @@ +Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. +Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below) + + +Bitstream Vera Fonts Copyright +------------------------------ + +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is +a trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of the fonts accompanying this license ("Fonts") and associated +documentation files (the "Font Software"), to reproduce and distribute the +Font Software, including without limitation the rights to use, copy, merge, +publish, distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to the +following conditions: + +The above copyright and trademark notices and this permission notice shall +be included in all copies of one or more of the Font Software typefaces. + +The Font Software may be modified, altered, or added to, and in particular +the designs of glyphs or characters in the Fonts may be modified and +additional glyphs or characters may be added to the Fonts, only if the fonts +are renamed to names not containing either the words "Bitstream" or the word +"Vera". + +This License becomes null and void to the extent applicable to Fonts or Font +Software that has been modified and is distributed under the "Bitstream +Vera" names. + +The Font Software may be sold as part of a larger software package but no +copy of one or more of the Font Software typefaces may be sold by itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, +TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME +FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING +ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE +FONT SOFTWARE. + +Except as contained in this notice, the names of Gnome, the Gnome +Foundation, and Bitstream Inc., shall not be used in advertising or +otherwise to promote the sale, use or other dealings in this Font Software +without prior written authorization from the Gnome Foundation or Bitstream +Inc., respectively. For further information, contact: fonts at gnome dot +org. + +Arev Fonts Copyright +------------------------------ + +Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the fonts accompanying this license ("Fonts") and +associated documentation files (the "Font Software"), to reproduce +and distribute the modifications to the Bitstream Vera Font Software, +including without limitation the rights to use, copy, merge, publish, +distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to +the following conditions: + +The above copyright and trademark notices and this permission notice +shall be included in all copies of one or more of the Font Software +typefaces. + +The Font Software may be modified, altered, or added to, and in +particular the designs of glyphs or characters in the Fonts may be +modified and additional glyphs or characters may be added to the +Fonts, only if the fonts are renamed to names not containing either +the words "Tavmjong Bah" or the word "Arev". + +This License becomes null and void to the extent applicable to Fonts +or Font Software that has been modified and is distributed under the +"Tavmjong Bah Arev" names. + +The Font Software may be sold as part of a larger software package but +no copy of one or more of the Font Software typefaces may be sold by +itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL +TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +Except as contained in this notice, the name of Tavmjong Bah shall not +be used in advertising or otherwise to promote the sale, use or other +dealings in this Font Software without prior written authorization +from Tavmjong Bah. For further information, contact: tavmjong @ free +. fr. + +TeX Gyre DJV Math +----------------- +Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. + +Math extensions done by B. Jackowski, P. Strzelczyk and P. Pianowski +(on behalf of TeX users groups) are in public domain. + +Letters imported from Euler Fraktur from AMSfonts are (c) American +Mathematical Society (see below). +Bitstream Vera Fonts Copyright +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera +is a trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of the fonts accompanying this license (“Fonts”) and associated +documentation +files (the “Font Software”), to reproduce and distribute the Font Software, +including without limitation the rights to use, copy, merge, publish, +distribute, +and/or sell copies of the Font Software, and to permit persons to whom +the Font Software is furnished to do so, subject to the following +conditions: + +The above copyright and trademark notices and this permission notice +shall be +included in all copies of one or more of the Font Software typefaces. + +The Font Software may be modified, altered, or added to, and in particular +the designs of glyphs or characters in the Fonts may be modified and +additional +glyphs or characters may be added to the Fonts, only if the fonts are +renamed +to names not containing either the words “Bitstream” or the word “Vera”. + +This License becomes null and void to the extent applicable to Fonts or +Font Software +that has been modified and is distributed under the “Bitstream Vera” +names. + +The Font Software may be sold as part of a larger software package but +no copy +of one or more of the Font Software typefaces may be sold by itself. + +THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, +TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME +FOUNDATION +BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, +SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN +ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR +INABILITY TO USE +THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. +Except as contained in this notice, the names of GNOME, the GNOME +Foundation, +and Bitstream Inc., shall not be used in advertising or otherwise to promote +the sale, use or other dealings in this Font Software without prior written +authorization from the GNOME Foundation or Bitstream Inc., respectively. +For further information, contact: fonts at gnome dot org. + +AMSFonts (v. 2.2) copyright + +The PostScript Type 1 implementation of the AMSFonts produced by and +previously distributed by Blue Sky Research and Y&Y, Inc. are now freely +available for general use. This has been accomplished through the +cooperation +of a consortium of scientific publishers with Blue Sky Research and Y&Y. +Members of this consortium include: + +Elsevier Science IBM Corporation Society for Industrial and Applied +Mathematics (SIAM) Springer-Verlag American Mathematical Society (AMS) + +In order to assure the authenticity of these fonts, copyright will be +held by +the American Mathematical Society. This is not meant to restrict in any way +the legitimate use of the fonts, such as (but not limited to) electronic +distribution of documents containing these fonts, inclusion of these fonts +into other public domain or commercial font collections or computer +applications, use of the outline data to create derivative fonts and/or +faces, etc. However, the AMS does require that the AMS copyright notice be +removed from any derivative versions of the fonts which have been altered in +any way. In addition, to ensure the fidelity of TeX documents using Computer +Modern fonts, Professor Donald Knuth, creator of the Computer Modern faces, +has requested that any alterations which yield different font metrics be +given a different name. + +$Id$ diff --git a/extra/images/linux/code-file-with-highlight.png b/extra/images/linux/code-file-with-highlight.png new file mode 100644 index 0000000000000000000000000000000000000000..ca8a100e4fc5e2f3e2258ad91618371003f86ca7 GIT binary patch literal 198184 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

vS(oPT9 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

  • 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
    3Jp6vn<7zoH!H(7i31B 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

    ua6oadk{iQ5Kiv;j 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

    ETDsQ8{KEE=KNIZr4mBdLd8n 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 z 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 literal 0 HcmV?d00001 diff --git a/extra/images/logo.png b/extra/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..73c0b50e338bfac7f13071e0cf49d436ff7784c6 GIT binary patch literal 242292 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 Cr4AcOijjGj!vqA#3J6AZUK;CNscD0W_v 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 + + + + + + + \ No newline at end of file diff --git a/extra/images/logo_app.svg b/extra/images/logo_app.svg new file mode 100644 index 0000000..4865afe --- /dev/null +++ b/extra/images/logo_app.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/extra/images/logo_app_light.svg b/extra/images/logo_app_light.svg new file mode 100644 index 0000000..d5106d0 --- /dev/null +++ b/extra/images/logo_app_light.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/extra/images/logo_color.svg b/extra/images/logo_color.svg new file mode 100644 index 0000000..3a78178 --- /dev/null +++ b/extra/images/logo_color.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/extra/images/screenshot.png b/extra/images/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..d56df3d762434e3c769d0a9b72edf167d0f2e8f3 GIT binary patch literal 966575 zcmeFZc|26_|2J-_v`>pHSq3GPNDA4el8_{+keD(dA;~h`P;2n8nPTbDz=s{rP@>_x*VM{{H>$$JeVdK7Hz;;JzFNg*K`t7SnWa=*3kCgn(UJ5_Ig>-#c~f znQF6`%k>b^Zo?O6vxV;sJz`r-PBwmNcKuk>Sg%mAkNq6@h z@Y%Q~|BUQF%g1=0;z04)Z(NA(!}V%vz8Kwms3AFZA0qaLYOnZR6vqEeVs4Z5cN05> z-Lc5YBgS`Hl{b|HM&_vQU`6cjb2+y`YC_aZ4xOPCfi!3yo4@zQDwP;}vG+^@{Zo!= zeB94VH-0Gd+?;9-1CCdGhn1(!IORp(^*?=a+IF+$Oxgj36kb&B2^_{xI3<|a47T7D zLna2Fl}=xq7+H&fR}B|E8=y9ioN|Kh6{Sl!SE)8w+L@;e{W!jF{GRlhZR>Z$KhQDJ_nM9t@+$YJxtjPiwRX~};%w`r z`6K_G{jrSLb^#--|F~%tW(&#qp`UYWMb*ZybN#=6|E6l78@JpuG85?eqJf{-EUPdOg+AIC*CqByfe|OXoh|l=$$K!i7`!RZpevsWaVhA$I=w+jyf!jd9hxl5R$_ax$js zG%@yrvGco|Pc2*d_$oA?_&|00Wv|>TINj25#us%ZF59^9CAPzVNpUbv z_}RwTN1ERU#&mRK)uhuNn}2Kaj`BACbm6LE!MeVO?%#fWFC#mS8j>Re)@8?3)CG@) zQ8fbOaa(a3xLq~U1aWj6Dvt1o@|8JC*g3t%;K7z}VPBPg?7XnSXTzh17rx&hY__!)M+rX3Ljv*Nf!s-C-7S!-%HvC~3_r=?n61 znr^6>BQyK*qn0AypVZo`mnhs6c|#>o@^f-kT*#A z)phFgxtW)n&mVmwc2WJ-k)v5(lCPZp@WS!A;p-Y}D=Ur5-ZmL;6|9)9W3%U4q!Hr?;0r=~4u@E0ZD`o9gilrX#F z=f2%VVA&wHlra6#PssPMZ|}^JY5mT+xhr$$erCO^v|v8?^N!j|%_cu0N7W-` zq4S8JCB0ES_RlMdILvD5EJQxa3sADBrG6%TK@k+w^%O^tN**VT!FqXpHsU*9&nZ9n|SJN?=E_WkXO*aww( z&JO0zKX`+y26y$h26JcJ<}yY<6H8nZ>-JJ#IV9;;M^~?L)TWZSDbuy39U_+eJ|Saqxy!Bm4Z7n-^~ePL~{-I}~W!eZ%)| z0+cY5bXIyEV$3X6dF8jgJxzT1CIHv*NroJjF3C zjKqmzBy%3S#a@calC|H((P&2%>@6_BIdNaI-fj4@A@O1TsS8dXV}E{tZi3xf=jNXN zIb3~b<(H(G=49I^eQT`CWNT7MkIM!Z88d~wb&3n-EBn`rU);Eo#BQ=rEO-F-ikT}+8Yt#kt~|IF6YmzCY|WDQsHGsD0)Ay}pr6cnWG?QnI;J*QBw_cg>Qi83 zQ{n?f2lfeeaN3157ge5L2Cq2LnUdCU&})B(dZYR@SAIHT_T zX6{U0N~R4?ea9{bm2!2pgW#7lpJtmax1v&bM?UE~`_1j{J37?6qwh@Lh{IILZLi4F zW{zf4D@}8A+8?z=Jp%~dz4a}*?YTqRR@y3BWoeI6j^5V#Rpn3bqm|P1cHwrF*)Ns9 zAEtS~yE)h9Su=F2e9lXK1e|bfA~LaS7Ty#dDOCMsHk?sOXBYH493!rzKKU9ZvAB- z9rTI4e#*4XswBsLR>IGC*_6j!sR=I)XVgEeFUQC?Jk8Y4oQ)llA^CitK2>M-A<6xm zmF2EyyY;iMU!dsu)^{cOu6miSM^U=sz#j%Xf689{q2niCjm5FgVz*mn%pKFtU1fX< zncp~druI_byXC&C1wVPSG40P?eeu(DHj%+-o0 z>$g!44QBH=eFYDumZoxlh5x!_5Nn_mBpmEjmCkrMmpec4_1$;W5wM>&NL%iNQ&ZI| zPU>4e4Z18Yyv6EL7*$vtX&BiFEgAJj+>bNH`x-9rTG_)i#XsiEufv6}3Y|&sYmSB@ zcwoRG_dDnJ#cv8X5tM#?^UTJtLk0p%YXsJ58J*9IY3-?f5M3o4z5(1B*ZQk=Y~%T` zj2E4cvFm=zy`E$X+^P{U!dR86KR1yF8rClSY1JGbrWBA0|i@) z^KwRBcb(<5)DEc~QZU>oCnu+W_lAq^g;S^h*&Y7NK;fpZ?;Txrbu1REhSgN_y6dX0 zaqQSJ^+Si%4<9}VZ*kBk@V4*ufP=Sv_WV7_zsEV{?1Q=McE{Jv>$V*KxYwP${Co`* z6!<6l&(GiMbPjO)uQT2D`RBIa8&v17QP)sAr2d~{!@KJ9m+GE(3vl+ZJLTpH=L|lF zA$(an`l~zqAFKZBl>cp4+yC12u#TqIf8X`Lt@_`0z2xJ3*T~BgKB=$ae|=&9?EK$X z{i_xH3^%%yYA?ZGq_o>9%Zui0fO_@?(fS70{fV)qghD}n7D-|);7Hj8~QJ*oWF8ZFjukR z?LC_Ond2{%_FueYapH}|bcEQe%f_CH7Zb~0?tgqn<&yoQhg!(z=g%Fxx8C55sL;V< zI^H`PVizRi8W{aP*)zQ0KgApH+!E5IFdJ5%2xG&^EGrH)`4AY?Hl9^paQS!8_ZnKW?|7m7bU(MGFIU zXP))4@?H5mV_pGKx9>-#KZyC1n78E&-qJwInwBcLhiC7*>FN(rj~^-e zp66Gz$zRb$JMxa=W(U#}D_SLHNH6VwE4;q8r(oPItcxHi0zOI6`9QTM)+bjv*PB9O zzl6j!)=GIRT1q8@Z90oK?|-<(;DfYYj~~=Ly;3nP_UW-o|6~4DFL~A9CpamdbLaMy zXefGRXmk;bE8u(jcKT{l_qtp_b1Qe(0q-m1yzCg2z?SF)@ZguVYEB!q#?EAGDf2S_ z|9H#6m!Qd?Ozkx%<<^}1U2y8_?|XGK)0@S7!*x#vni!sVu?5ul6d$)jP3WVV%Cl9H zEDhhN-hUhrqthm>Y01h1rt5=HF~M>A3$JHIgO1Ez;;3`NVvo-zeK|ba)LJxsai!w7 z;<*I^7kVQ+K;l}0*z%+mQSM_#qArb%Ja5O1wB;X)jrQE%A0P3-^E}7p<@lB*WvOvn zb#;A=RMj@YBg?x(*lwDZy1IgM6J~~{tw)?xUza`vRb6|_7?e!j5q@t|TPqlyyiVGrVNc9Agx}(=p4Jw3)U13< z?1?~+lB_S|>Ytu$l6aE!DS`GlcX@G;sM`{I9U15uf#Ql^ty}x-$GNj+fj_!}0v24e zoEtvIRh8Ew!A%8YLg$>6Ucb_JaxOw85!|AbsD_6=9 znB(OMv4MlrMlv_fIMBrPzn=DJ@NJDcP<4StG=02fCOvQ0=KQd;aFrL+|LW3nv;~v( zscRoR!0vD|(w%g(fW!=hrQX0Lvd^adMS3;00?mtgWcb_sig)9Ax$u6I#ymTEv zA5nmk;L0-zh*!R`u+3YM3VrO%dftxG+?qp_p_e|9VRI46<3LB`Jh2$r6Y2N1+8bdP zj%Ws3b)vOgTf6uBkC&jH$Ma4o6{A{k=aqW%8TAG?Bn_20n&d-+&onIG^(PR)dnXwp zS&g77=R}rm-k=mS9zMrBF}n7qPrd#JClf=C@Wuh8uL7rJUc}ES>z3EBQR-+|G5;dk zBv&tD9-(~W|G0=R`#GBCb6)Eoel>^^XwP)@{3Lj);oOr1T2YMQZuP*MVfBXtWpB2| zO^mBcc;5dKnIaL%dyIw0+#JJnq+fjq2eG#pH9#W!U)HCg8oa#=(7mCj zByxckSg$hSp7Md@*u3nwN!UXVsV13vlM|I5oTz8YFbYvSal9ey{BJUU*TcM-gJ4VzWqkXPQ9DpOnD27(3{cg0L=|h4@QI8A!+c+j#f>3+pToD;Qj*EIUb<^AZjAVE z44m1Gw)%ehmQjh+Zf&$c2aSzGwlF1406i zlN)q}g@;TH9uG8VanhUT(rGah39cU4=y7%E=;MG0)YIbW_kn)($w73dygzobfzlD> zMacWxZy*QdS|%4TXQ~4O%|dTRjLUmv`XwhJ4sRN{CVW5Ulw<2zH%)c*e8fV${|It^>jUlnXl)s5iP!=O}BaUe@^v33H*O+79&A(XDEl()Qbm2 zSn#s53c{PACy%ATs)nM?Iz1mqloi5BCsj@Yz;lrlHpO|^#F7VzD@FQ#7NEuEuO~MG z2|6IU=cV-w8m3U1l&E|_b#Rsb8(An_ zzz>||{$#sH$LRrTuFcDVJ`R(~o$M02lJ21kQ<5V3`GkZD+j4R8{@Xp z5bFlLKn!kM*z7mELBh^*B#4tf=z{KoE42vkx0Tn~64ZS9JYwbfmd^I`dD-_8{&S2r zxUO{|WS8rYaB5?lz~}$h9VEW9-Q(MgC5!?Fwp}xFyD@X@_Wrq}HLpBsiu7seq_i%g zNH#U&iT%saUqEsicM-XK!eJm+yFBAN+2|L`BZcBp$$gzuwWQ9ITE5=1ozA)77bluc zHG^E%{0L9fi4CZLnRJd}w5}5leFlXLs22$hyNPBZCvt%q(i_BVvs!ggo2V>uw%&FB zZMQz1o)fQT&@h9lePch#%w3{O`dQ-qT8n3t)p_R7=}-y3AKaRYzxF(G4e2mw)S|^| zHk(6T1S{le84ZGZE*_yz4y!p)TF8l`brF`ldPMx3(?Q=tKT-al{7GB<y{u+>-0!=Bt_V$3AMZc zf#E$OwHsm}Q60FYBVyL|L!s;R$0r`ealaU{(N9pe_ZQq)9Kvgz17M*ArdwnOP#<(B zD1_OBfR^H9ib*g>cL~ns*>Q*EL3K_h3=!JP%UBqOI?P1zbtHc8JgD2j#xN3C>o)Kf zGtW%LwIiobP8B*^`hr)Mu9KL3?f5K|9?&jZMt7aE9DCDF$|C3i>aK-2XpTu}C;3Eo zu!CViD-^J8e;NwRaLh^QRLYkAh#G=wz%wRilmA3KYm@BsdlFP17zkdH%_q8nkYfsA zZ8fSd>K^LBRf=ljRw0S)G2xFFaRKl9I&4jz+#kg(HR|oE2sK^6WEV|`-9N&5`R7~$ z@hZZB;QrILvVM8x+kIVD=nreVo~T^ES4yLJt|WdD{UF58X&6{7ZYBMW3{wX78|*s4 zxD}Ji^`e?k`#=`SHU~y2o9qYJu8f@i=rKxNn*VA^%b`b1ZSHDEZ(29j#dfDk&YDuO zRAvnc*|B{o2gY)6VzLOjfIrxyjHZhF)lZJ++LxiCeNt!*pDV+=4xAEr6j^`})YAGPqOCn5VN1jH zv$iec(lKP#pVp+q^|qGi=GcQooyndMPa3;0PG0)K>D$$~-p$`OA>F;(tQpFb!E;wo zbCOpuKPdbftd28D66U1qX32af?_PV}&p*qYPAt z0c!p)V3@j-bnU7Y*I?*z4Y0(^qo6~fIqqlHI@KK915u9^aMONGwK)oug-X-e89Ku) zx|D(gGOjIRU$i4j7CH*V0AlbfR^>kt9QnB@dL?p<@^7lL$;R`eep!TsYV#Vcr-3J) z`N=tjFbYT_^TbN&z|ovo2GzhGI|vfau(R!7=byHDbnlG!C0e47w4nAFYkQc55<4L* zX4d63f@s?-&~GW*ynD@@YWHcGP<10ipYY_okSU8HHTI%4BFm5Gq`kX*oM;;kQA36I z&ydpoKnyfPiK92v$|cSd5HTnkp=3l9P}M4Bx%WoGc~JL#PA57^Jt0I9`bbD!K$VjN zCnSk?o?Fdo^OMd+e2eu3(=l!B$fzv~T#dOOL8S9@Ba#GY3K0L*1k*t}EcWmv9bAPS z$13zD)s>3nHxs!IwtM6YJ)kYvX+itVPpmKaG*pC9LZ2$es?oU{dMlSKk>R-PONOCx zep%cg$UYSjm;<6yL&lBMq6O3qzwBP~BdB^{`1l%m4=wF9DX%tlJo&S{-P%B8Gc9qy zt3mcME!)@-qhSe|1J0ST>&%W-j(4w9kI<@rS>?_vZD|O3F%D~x+LX1-EH{o zFi&){DIvgoX|*5BTQ>xhv3#gI>qsTIze9QsU1WX0pTi6AP`wH2VAIDbaan}4PjBhi zDazlrPSkLoqD(wEK|+e52AC0naD#b4L4*S7%m-7qyZ>&(gcqrY0^gL5lLLi@4y`=- zgKsMm{j_-8y{g~5)CzGQi4)slUX;o#<(Z%ZC8I#`gCuJFE{7dL`|A|9kUs7dayt9= zLXvBDw5K)oX3m$-Z%Rl77Bls-4Suaflmf2ZL}jN;OJK%fS)Zz1Yzg0b+d>jTrSV?; zi>uxId+vidiigEGBd$E*yDp&xbY0~uFgqzE7X?wLxSh{g!Hf^A3%q={)gBEOz-x%T zp28D;HLT#yT^e&RxcRrYqv}aVR?!PHkF9NlF(aFG|1E}Ut{a(6(H{ZLVFo$D^ba)E#eOA zgsQ5h?`{*YN3d_dvf3fF=I+h}Z1?;al9WP@l?stIAD}JlrtD?Mwxq|CTXS<&@jgBW zoAaXO9b58{%ke0M1X2Y!PVB$8eXr~&iktxZ4y91)wTS8jSkjnW)gnuPMfLI`miy@( zmQUotD8f{KP+Ik3)x%y&UjhFm%CMs4uWe1dv{iaz*+AV$!j z#Ig&iseY+uFUH~|Mdnp);SLmZ5eAG_T#X?S$Voej;Bw>%fgh9A=eeJMY#BUrfow6S zDh{+i76phpq5u}o%uhDm@fZ+XFz5;`C(&k5W-*^jGkQB+#R-Rh`wVw;3qvaFG0&zS zY?nZHtwn?qx8`YFuYKMqJ$$V60%hOHPL+4lv{cG zvSztaV#+5mqyhiMgR@AuO1*YYiY(W+)Um7t2ze@y$TdtP*y4E7wTl231lJ;|L5J>n z%5|7Nm-wOB_zmG>cplt!O{gLo`!B*p(vIt}8VlG>M48w8A(EAqkba+)KnoaAK&3{( z<$?nq^L&!YdBFRgy{H1N%VfQ^a;sD4+vY z=Tg)gsMDNob`9!<$u$$zThjhFxhGJKUNW2-sL^OPcsCK{noxMQ{>km_f{s^xHP(OH z!0l*wpsO8oq*7Xm<3@xA{2CQ7cc98a}$})?h6QZDbt`CcC%~OHVO&-gg@u3dy zqw2^F<#KHPtq1&ac%9qN#zZ3Z;GV3r#6&SIVMGM^!aSx9H_aVj@3ik=SJJhE1g?v( zfE~<;8q^Z+8wD|3m{f|0s3-OBpwKkd@hqcIZWVF7nN3+HhM@t^%R-#wZp1L+bU8YG z`M1m&u7Cup6R&@R^9AL6(<3jAS02MVrY9s6%*bBergvdiLeG{H)d;Bs{U?^PFX!te zweNernrl0o1s&bQlkak%NhWD!htjg5r0zQXO2ov`*b>JLXy`22`iM8yhTH<`UiQ-H zXEk=xG`}u3oKBy9%S0U>g5aS5rS}3>J?)&7mjs8_J6z`0^}{Ne7b7hz9`<2e0E5~R zBn{Rpp@X2U;cN6bQ{9&@T)ksOWu1rn2S1Ju34vljJ6sKR0c^cn)F}^fwK1lv=UHl> zhbzB)JV8xXKlha5i>7o!3F#pCi9Uw#l=R-}x}RI6L0nkkB^dZWg}g^1Mt~ckhMeBG z&JF@yyEc-hs53QzJd#{?E=Uf5vjQ%0@p5 zywC_sGVI=OwK-R<2S*JoYC@t<;11%0p2gp_C_Dr1)n$+3!J_T^Zb5B2HvpGPV1R)v zErD8U+@Uh)xE$ZPVkGXyX1+xBZ)i*N{z54})^XwJtVGp7e&Euu=O8=ySa1yW)KsCQIQi}00mC1Z zCP#KU-ctIP48yY3Ks$PlVwbiZ*gdyru9St=^9s7cRYEfG`rJt~`B}vYdl5w3oR;5J zRtDg^Zp|8Sv%?>^-tFos-WTo(jebEh^n=hwsQpc} zA+|N@C#)=EIcQ$&j2{bm18;0tzWpxH!BiljzU+{>cTfGdKyUEVN9HBU2hY5HnJKh+ zAvyH7(S~o>syhep8)rZ597^q@$~5>}4@ve>XXZXJh7|Ey;O9FRR<6iu=aBWblE>ap zn;?hs<`1^GR!MdHJmuPm)C^hGP;6UG5#ONOc2McC&kTBwptnR|;z4`^R0<72*f59) zIzz=k%RnAn{Rnj8T|>s^wi*c{sSd>tEXc%<5&lLEq^5hGYr{1One*Di4Zp~>=aSg2 zBO>!L?LZc!3pbF;ZVJj5T;L9|vBx+|oQ5nON5nhBHE?Ogp8)t@Vx(yf8;=m^`T>cM zk?ca1NSBo%FV|=uQAMN1$~Pzy?S4`ln5gCmb@5(}Ha0Hf!=o8o&_!}RESr6$TXbY!;9}!zR#fA%*h}SA&kkI#2b-=&j8V7u9 zt@K!_8u|%I4kev@o#qDBO}^qpv_}OVr|F`ad%t1M3aaauCOmZh5LU(k z`qeli$=!1)X4UMXEUw+S=2qJ0#wyu}!$*1#Bn838VAC53f0mUXR`8?&?KqjUoMr8W z^H3sjP?@~XG7Mk^xJvBA$lmPn^2=V`ehI}xnR7cq0?1P0V29hUHv~NItZ}2i;h*$x ztD)C?D|qG)wt}t@9o4|wjC&}un-^smvARDzH1WIMH!*%$f#DYNiC2#oO;6+^j6v+U zpXU>(SYt+m1o{h>e?)OWY!yrW3sBK~uIUe}aMP6&+$PCU|Hlwjqaq0Guh?4u$aM62 zTXxLrc`NYpgx+M(Gpm|nvz%Q*LS=6YbmZ@SJK=Uj|JtL&vyu(z3dbETtA)F`RSCx*3z+_S+VMA z=y?`oCa)Hs$+md-T@2t4DSvMi290ABf-kJ||6&hyV@ZUFWA+9)ni$iG$ zap78H_RHv2Kb{%Q%?Fi8J3kdHPYh_5^ONbdyp*th{p*P?yZo=t7qgG5DR;k#9)Dpa zXr*6&&!Yn0tV63cF?blF6_FP4Vb3G!2Idrt98fuKtxcP6)&xH^+7zgekD;cj-FfX3 za1Q-x#Mi(mz~-p)2qBzq5FOHI$F<}Tc*Kz=Xyghv35MJO{*7Qe;}r|2f59qb5p^~V zeLR4N{hg6!W*SUE;9%DRu=OFnUKD5#g3+?xrW_!Iv8^| zFt8iJX%V6`8|}ezp253rtQYsX&`49`^%XXXsFz=I51IN5w-VQH#5 z)DLZAN1Nb{#`hR~SDpnhDwW~ue1qZM|96L)Rz2Qr#0F>#(Te+oI5K+!23vXmY#aXc37 zP2BN(c<$BM^KEMCyhzLFhCvrU z)aUQrt|oE`Xg$%Hwc5_ES7^6w#xpn7kW+bj^sAjR<`VFp+s zfkZHd>Q1$!B8rZKUdIj;qt599u^f}&GgWhT2$VfHxSy>D7m21-J2nbxgpJ=Q6a#?N zL0uj*g73Q;;h_Ehcs6{~l)<_5FTI(s1b(vT7={29rwhrTAn!El;Xfz|ZHFHeRJUjx zE~0WhrzL24<_By1g*OxgX4&SRg3)ISh$toQLi)JB)37Dihc(#MM|jP5+_S|te zD@evi7PdF+oescv`{AyE&=qh7_`Wo^&|7c{*ZwvO(t}{$!mI&WH6l2wkogk7`TV6W zxoG~3E7gD8W0;*QYE}K@z=J6f3yv4-7B%^iEu*6?mcVC*ci-xMk!r$GYvik*6&)-j zp`52Lx1;Inr;-SUkS2Dvmx`q4wXw6yajf51Ug|=j^n~Sm=2pSxYSaDkXYO~s+m`eF z{+1^i`{SQD-9mG|ZR$LiwHzDv%nz9yfDd6yid-m|(Mip;H{={z$E7{ht$?3QT!-Mb z??DeEQYhTtHm~nmG!&h)hwLUSohm4bd^*z>JQC_U2xfY&SxMk!gl_iV$rIRV3MKIz zxEs>%A!h7&l%9z*T=l!@XiyzWg8|(2?q$wvHZ*X05{d$zKu@5L5$CC1RA34psO}49 zE}WPmP3RA>E9d|TwE}iC3u~Zdo=>^(Df7V}8vgSfcM`f2R`Zv6os@#tp}+#?oojv# zioq+Q#L>0$D%qSl36ZO>c_v%SCoYpM=XYSTm>hAQ+F{UJHdZA(DP291kX2EYEN{)} z+Il&9OXuxhhkkQ_E+jMUx3mZ0X3t?#Hj#MoqD{gJ^P;R)=QW3M# zJsyWq-g#`YkCso+FldhVn#T+|H<2oEllNMU#%qPMTzQ=FC}W!IRm&gKC8H!YzV0My_-Fp$aPibp@ipd>j--_$UD{r;NE{*@;|AG@}3bD?T5ox2^rD!78?7X7~KKoz0f zn^KtI;2M%svL|@8h=D0p5S#1{d8-b&mEihT+$sp=*)<$4YB`=9r?MRDTupN$e=lN$ z(HtxU?x=6yDsbv#5wU}!!tY2(BY4;`v!A&*0v^Tl2`0)Atv+}g13JZ2`t&tR2 zPs}gguesvAet>kEEg&?E)SEo5@MM>VB3cJYZ3|X{%FO_=xuL zku*dZ%hbv0&FW;K8HF0?nAn$;)%EaP9`yU`UW8YXp|l#DiYk=0n8m>VGC#J2SDBT#!E7R*ikfiDUXXa){Ze z!jP3;ParFzgm4%5QEY=`vY82FiA(m%xM;}f*E;IipiuqJ>^NoC_*|4v)~o#+0!7U) zY`7>kcyYaU+ndMx5j@GL!}*5~$u1_neN!HD`1PbGnw4y#7nIM z$YkJUc4IEm_cD7CzmEiU2}tU57V%HjjB6;G{Eo_RiME3o!-!WM&i&9lWj+b6P)O!b z)sUF}AfTx*fM*YTPqWGKEIqi17%Xrz;Cg=VIE(<^5#)@Ka`VFMWo99lI71@**tt1S z7dR(3yq7BX2xjj{runK?m$9J0&{(zak2ait=K6wP_`7j{R`%EM-Cnm-T$TTdu;M@^ zns0JM5nL;6VJuCqno_5%alFjEpH-8>0m#h8k`-WVk^TeSd_-2yk~<;syV8*`;cZay zfKcq>en%W!UOW8AeCYGuly4RWhhx+;^{dtyEgJ2Y2~26zch=73nKf_&;v=wo*>8Ms zN=?|Ey5VOCsWYEm<%DQ0nwFa9HHl&`!=@k6ApuRoj5AxF1~(m#HH;k& zzo}=nCmZNf0bpi-6iQ%p-!7Ow@Pkhw#x}t-h#L4hUeaIL<>=6(f904z93v8X1?*u~ zP&3Kt6b_k&>{{Y2Pd4;sZU|CX=9N(jv13ddLR_?#S1bM}_zf7LSk5c*Rf(z&J0{+z zDuorNv3Dw@i)j<^RYbvSpo#!^O5O$sE@_vOsDWYu+DUWdI=W!H`0VMT&FjVwX2zZo zLO2iZZSJ^|kngjZ2B(Ss)eC7oD4pp&uBeXiiFbX5Us&9a7tQwOMQuId5 zrpS{ue@)Mp>}hV%Gd;ek@zsVkZDgtksMhR4U4aMG`;_?pJ^FQMbJZ){W9}wY=KGz` z|7EAJ`+-r0_470tphl~ycORa~jo1onDtnmkR}gCY^RZTj}Qvt+qK?gXMMIi45%RN%1m)iT~D!1%fS->zK z=NiNA!P@FbjX z;zOncNb=M;a;EMdWv^=7&>N)LKu^|Qe4xx-D2bYtc38!z-AAnrFkxeG zb?^5TUN~RvIK?Wq5=gn99Fv>)smau2Z9FN6wGg3sN-~9#ZvAunx4CE22T*|=SbKG{ z9N2SLtu%?GND7=!BsiiD|3;bB99AmdqnbWv$SxpnV>ci5Ya_2h+*>F;u6|?MC^%fR#!kasN6r8#?B{7RhKbtsJvl{E|gR zG4IKKB&x_Wv1ZYq4onXj z&!g0QO0=?#cqnR*-8}T8MsY=sTuK6nVW>Hsac*t@iaHtD>odKQAc)H6S>(OVsmvai z4+yknIvA_Y-rg&EKkeP&3}$YjHA^wTq_|3Ur{YC7QyJ@tiP<+U2iY3sj)MT@d_9AJ#MXz8$KeW!2T`sd9=Kj^VhP${$nyn>xm@iMn zVPwG)+1GHr^!(x6k7{U#$-!xO%InXBC9g-p{ZJf$5zZ!Ma@)^ek2c?UdDcMG2XYzPlb#wIYtMlP&hiH9;mw*cQTdp&Q# z1TIJIBbxuLLmj#$?nQlS4!W}U1dM50j5`#`Tax zu77y6QJ?DOeZLg(K@*uavUj(B1FAuKGd2_!)Qh%$BONX29VdR-2DW7D6oPqh#hoY4 zM|>>O&tv2H28!)oxEX5fYlGA{*J0t;2KEvEGS}<#eDYz(HCUUrb5u%^@u=wZUp|%^ zkYsRyTm9RLTit)gH>~=5HyhKt{m|&pTHGtXb@;cZ^XKRYBlxAY@4X0j0k&C_vk0!L zD?InkNdA!a3xTa=O9cZ~AOiC4r8DiuYlEjjjBJPe6uLfnD;2=G>dbMJMs9@QyT>e9 za?3GXw>cz9k&9Jj3sL&lZr*8gJ>a94I~Jg64Y=!y$j)bZrqcB+@wkS9vaEn6F2 z1dR*v#~ezzp>rnfm)@h;n(gke!VEvQgk{4xCy93*?+nB>@F^T$2@R8xAOgwiH16NY z_Iv>OgiufMf(zfjLCQj) z?uGPA?9uH?8YAVim0h$bdfQzaUh-m<#C){l)r}QzSXAkt4VTCBHBrtL&Bxyg)oSkc zug~2|8&l<7(wS}3D^I^rZjlj7xhkT>(GPKLO$1Q6;DK3Zml6ny& zyLQN(9b!XGWEODJqKQ{WF`teH5Mg`!UyFTM=e z+dDBB64+}Oo~FAJbLL1a#^7+kOza8W)D$l?D^PA?pbuB7f^_!V%*v05x3puwn)8;f z1$VZT<1zC|6rClXtZ|qzTGxb{I*72X%E?xUg(S<&&;-OnBB}t1!#mKjM98p=<#!Ct zDd+<-XbrILKT85wd9d}7v;Z(Dcc8p2s2&J@whINzl0-8q7H+Y@)9eEfJVnT;9bl8z zs{7^9DYONF%4e&RT^vBEz3upeSpipq3cBSKz8zH}b4{HOMg#r%^V|9J)pO_#R65-E z$pNf|dQrj)#5dgWWRv0d2mTRjdi{MtTaT$gvKM#x(hzzild|}pfoBggOPPfvodpgu zq{9u2V06zDrz?7K(KH<_E#f`WkdwU+h$g(g-N1c=Ig~vvty0+Mm7&Fnr8Ri}{+#o8 z?XN9AHr)@9G)%Ty=E{L69+V{P+XOD?`@?8m;BS)#c0hF*hl#Z9%rPq~rKdae!2 zcQtr&HxA70WiP6bd=CQEvNxiuqKUwU7WTjY7eJeCJTJo&%V7HQk<$dwe}WD1WpN|27sDKe zMDI}F{P{F{`l}fU*^`!3gSuwlqu9O76bazdo@EvI;g<{siR(~C@hUm@QTutPBMiS# zKiSycxW5itTky9}-K8ua&~TFChSH~U zD{ya=@lFbeN&KT z@GNUIVrA%L*qxz>^>T@8gk4GPge<_sJ^?mo7BkO-SjJA4xhw;InE9Iaa;`Pwji-$v zRC!I&B@6nC2maRTQ(H>nR9D-yA&+}P+D&z4L~@}qo$#2I85*fyZ{W_gL{8oMq7E)A zs2`SN!B3?INt@Srw?%tZ!{UVlJV&(8u;6;%iVTp9n)Gy4b%Wa+dJYwOnw?ztNPn+Z zB`qgJ!$*JckLg``?AW-K?tQFG&9>%JYIO6lU2%_t8V$!~y1nzmq+QhxIin=}uj6Y?qPRWz9h-J5CLBvI-AMcQ{pHMMSC9~H$O6%>#X6%`O60tbMDzVaX;TNMeR>Id-j`?a%fg}9=8Y}U z0rKknE$sOL331&FJuyFU(?adv30PMNx@@~i!&5WyiWO*8o0RY9zenVNJj&}K5L5tjZf0=3wQ=7 zOL_jH$vTg{leJ%sO`s8x%^ zG|j#Q7P)k9t&Y45ubA!tGg0m9Vc*@`kL?~b;%OM?c~y;9dE4++!wQ3Jr0wZJIg~X>IZ0f;uZ1I51{ygVy>d) zpV%zHk9m$0a<8pb65a@ux6@p4KwKvP20&|}&oCW-rR(o94K^z&J!c{?ehj`HsNDei z6al*|D*6lA0`==a;8ZlF?(J0Dt>Z9>Hk^!nJ31?3+QP_QJ`&MzZ}SXVLQdaWILGVkB9KX9f{`gr*@6#rQN5-DwvUFabGs)rlS`eL zPQ>{r9Ux0atpd-&&Jk$QMskAB-a3~W8ZE?8dk$i=+K;(^<>=0TIG)oS(BU6CbUsNO zacX0q^nn9(OQ0j`sMOg)ODKDh@u7HpZ$|+|o7Z?lSRlDH_)5fS0vinX;;TWrO~%+B zq%ku)eNLD)7cWoc_2G?}+c1vQUclaEoGqg4!-s}7hT%v&J&R|RnAtMXdp6z+ zSRq%4SjGm42&gL?uMk@|Y%ydda+mi=^hkd+AQo0uHV^?g?SQ2PDue)&0$Lb;*|Ank zHdS0j1mNHAUL$h-lPpZiH&Kz3KT&zJLLCY8gJh5`P-N`Has9=w_17z{B$4BwLD&i} z>y=txvr-Bma+gVASj@zjDq{MGm*`*~pj-D~F^U`!HkfW#Ow(`5c$gms)?^@>8=Ub+CV~?0@k^JfTAOeP; zBAR=@JNB1BPSV7%5YrdA&0JNkM*59}R%&leh!{{@k77<0K>u-`(eyC0rvum-hMAy@{W$V`A`4|S+ z^^dA?e6iRr6RI{uH1-ljXlV<^ZD0)ywOl-74^=L^SJPciJl1ek>58|2=tzDnwMf@RY_o+OO>R7WGAGmS+Wjm>c9`m{m|#owI! zQ}TV!DbJcPr_+TRA^Q=iE)Beq%Cmd1lw;&F@qXx3%Q5#jIyW;aL+DfO#CqQbl{gmHg0&_%>|MVFhSxcf{U+)gW9o6+JLCLBA*Sz=M+`u^E`ka+Les*ZcXoF00@GF zQor*ziKP6;d!}GqxRInCsRWVe(e~y6Onar@cICBWYH!;SGio22B`XSMtH8B5p&s8H z2xJ!TbGL}F!6j90WIG-ZG#TIX1Aeuh0d6~ac*OEWV{1VDPXC)$FRo1|{uH8w!ZRjM za;4P3fLO`@VK#;&9qSUS?4t$(&SH8GN;k|JikjI&+D8v6H4dDVns*=y7r(oY`$bq2 zSdWlec%9`)gQ#Z59##hZD%7Mal1XADy^w<3NcFSJ%VyaT-1?CrF4loNB3TDOjlWSW zAKxiUGeUG3O`IB)%BG&`#+^;S_ytC`@OfJ>B)qDPUOELeAtx0&?Cv?f)`U4=Zi?b} zEbuLomK~bG&5Jn`a9a!4m_Q|ia6kD8+$?x@8b&T^y@y8&qSI^%m}z%slxrnOk~|c3 z*P5U>5I}l|aU|+Ot`fLvSo1x?1QAd|G}2k9(8n6_Uj>_rgne?- zFHuohI{4?Syfy%}$y93vuZ2XpPdY1>()R5@FATXWIOuyaaEi;BzAQfQ(_%T$+zn8f zoO6J-yA`3SxM)GsW_I)hvXIz^SUTPj{{{>U6Nzh|j6xOc?p%4Fa(i24zEy6RbWPLB zP1l@pco^#VM0BdbztQ3##hy*AD8vD-$9c%Kwyz|0KUF7S6#EK2-e+gnHBYXRa7J+{ zPRwcPz3x$;Ad`ymHxJjHBxmUr$(De|`_wpF-^IcIRasK(*;SF{5h~L&aBJOLj zI4(#0O%}6H7iZsPwy$GQrUdW4d;`3OgvH#QUl>`Lu1pR3D@vk4W>_r2BsLBX&`aLb z5V*3*U2w_dH3-$C-!{Ojc-s6DbkoF>H_I+EAAdw6uwO{(3MU@meC&zGa(m$5Td{DI z7M_FsfaapxRPlr+Jlkey{V%m7QPjEo@+P*;TLMsgpoK#mXeSIg4OEP@#J18ad8sH3 z2FN9U{lp_5VI#!e(OXsf=UBAMsG%((t7x#M4o;e?*xKs9XDu??pI}H6+{lNbG`PgacuSF`4 z0)jBl$8FIl*AC1yQ%Vc%!x zE&&J|@U2h+9{`%k_+eV!lGf0Zg1stp2RPsNib>)=$*HWmZFjnXa?6Sf<8a6+LA1zz z&U;yIlM(4&uO)g@;v3bM+&9KEaIt%zjmwI|Z5LK)Wgz);xw;+wWb73?)Lv0WFxt5KXB$M@Wvk;A_40n{aG2XIvvuU>RM3; zm+%P~v9It&2aK|=P4c@0`wUIG7Zo1~ldr92ju+fP%(XTWOJT9o&1(!{7aIdE-tgVt zBjk#FJ`Q)B0ZinC#pC4O17Ik)XY#cLuhdXdf}Z$p$7AYlJ=tdz)b0BHC^;qEK_$p5 zeW7%}T!6#*g~|7c=`7jrjEP!vdqP2E!jpX+nGgA^&-6gLnCj9{@^@f%4!bcHnSkz( zrOT7E(xBV?GIC62fcF0kF<_4>@f6vxFGpqT%EvTUwX_=ctpm*dZEkne0C|?jEEijM zmxqp5g$C{6Uj@K!D{fw`$$j(0Yuz^BRVXDy(vlvmR1<&n7F7Tjzw;a=&SBX~rehDx zMHi=jIWH~BI$+yw14wG}w;!fs!;L_yC@8rABraEBs>BHp0S>;Omr``yx^nCBl7ht* zqK4jc(c;&@31G~^lf%D;@*EOhMeh&Tj%`{qZTx~5pD5!P4x73X(gk8RT)B4XSBpqZ z?*-0ZLhjT^eEXOrt2rp@S zfhkzy9)aEw&BWNb-CN^8Fwn^vF8Td%HP8YOn2TR_V$PSTxW__D8*AnppAQGfR2lA_ zR9hTJ`KYgZa}i{%M$HR$-fM$19r^fK+sQVwkVg5#9#sLXYjcS$V}X+=h)Ay z!saB;=X*sK{KzR}52@a9w#n5Z$T>wN$T=x3Axk>MEa~WY40s+i?B)x>n(rN8vR=FUj=kTkdyA`%Y=I%C(y6 z2jgRs50-#Tj;kQnp>Cm9ElsRFUi!;yS_{%%vPA(N)L8gNL-8>cOb>H@YS28C*=5#f zhq6s$IB5WRt25!~PD=1hA}ApYl@`RG&Z06}fm2LUCm7}sK&HHL<6#chK?OVWHVkQk zqCHT=QGH2lk8Bcya|Z6>Ueyaswi)Wt^O z2c9ectrw4-?px7`SCsfd(bFG5?_Aw?4$QIEx}{ueGnOwtmZBpN_i{*oS%@&$IRUNp z!*!_LY6~htAS$C01tPG+qB#d#N*!Jiq&Wm4N0bUbguxOqL?RqARnp@e!ro*f#o=q_ zS2Lg3Au#MGcFv(Z9;BLE566g$@S>j(^tc>MSQa{_CLUFT@tP=B`Aok~R{b=}Be;C- z#Y5H|Cu*xnpiBkrv?wTlyV!{Xnea;iV!^bTAx;le8+~%CNTMDic-37i-A=HCdXan6 zyfX`F#!oqr8i|Jy8SK`-5HwahVbOEn@eD5>ncTH@@Tknyb9FDuS~?Tfeo=ihzPEp3 zbZsQ&1Gu@=c0U`T=JsWQx>8JIt*HoRO16Mfr+C}&hqFrln(n;>_9k3P}* z0#Z|sVo%r^y0bmr0npj+A7q#VT^4Ku)*Fn>8Hr@;xomdMIXs4LHscC{gCebFgB%dz{HE@bT;TGEfRW>+@*IA zXEF;E3;a7o@ctgA!X{p^Mwl)d+O0ZZl8won+YZ5`e)3De@du)=bj_b7$WKa-{PuD6 zOD6YKBM#y&H4u#0>ebbUFZ8lmKE2ET5EM1R`a=UJQb20Cf9&7EUa~d>?iv_NDF?K_ zs8b)&e49xht!|%a?mWC^%9Jkd5yxTK989YnmQ6>EZh{b4u3$m$B=84!(hkaRZ`Gri z7#EyenHu+hx;VP4;il}oRy*{_nq&@vW7^3YZlxhnbDdyb27*5d7W%=ss+7<%8F1=n zRA{hslFEX*FQQ!#JAQzEGFbAeDzeLGs(n+*_;jt_Ft#}KDIh~3XMlyKCxz~IagEWXxObXu;%4J@}Q=Ir=H);V6f5@~Nns1nYIY|;oO6;T`E!zimh zuVHpA#Y~`%518a~mrQseL_rmiog7Lsz|!^b;-v&h3q?3LNf*JeSUr)=gpG~t|8dQL zl}3brF$0+v^KvC!$UgK>Gw`4ZyDd;WgOiNoFcOgDJ4n=9$D5u;T@NmQ)`&T!y){JQ z1DI&4I}N*0lIW`Fr3VxNZoEe3%#6r#;dC(WRjA1#^RAt50-84({lWMoR0wncNNZq~ zD5XiRNf48cMvA;^vPsWt-Ryx>^k~Zu9{<(a9|O%gg+jE@x>BAz3(I z9QU(HEr?Cu+)rX?3^ZI(YYGdT%fEAR<{Z)rwc@Q?c8}V|{17tM5UEHP57Pw%te`n9 zlunmOOGdKj0%I6E&;UtjdTG7>@$vuTl@j$u#Gw*-UI>YQGF6z2?Mw!qL6*2mB7_T{ z14B6N5Td%SPRsg1hjHJ1oZU5?TjZe@AmgEjpNxw$IJ((DLn%9!B*4=quG8TiTVXig za}^Fv_3re`=lfI@mH~B5+?79J3~MMLa^TU#OtS@Ip1{!|Y3-1=)cxwsU;IN?w{F@; zZ;qqzvpoRz3KF60)uSP;38&A(24VqKSXd?d7`kMU>ATz%m=_g>=6||HE|YW>D<{Vm zSn#^+FE0<^(aa`}q>9S15dXA<5QN5(Nt~!|GRYnP1oHne##v8w(G6bX$vQ_}icBV{ zpnhTn55Qb8Og!jE!Q9zBuGd*RbZX&*uUbb{>@X?iV`-q$nF`}+j0JhAXfuowB=J3@ zQbn6iJ(4gtFjL=MD)H$H7l&XTC(bu{uPY?h;@wE-v6`Jb^v06^uPj-w2EE4o}P zlhFaEG2Hn3*1pueLEaRDm;HR8$D)Sz62Tcotjbim+MK0wU_gz!<#-j@)UB*IKHt%X zbZ@hfy}|O(0c`wd^&=)YD~T?{PAI@G;Y48+Q%)b1*CXard#jgsS1LXEzlO`>FTCyL zKD4i`Wtir&JHzZQV=)uUBuQwJTl|D@m{H_1b7?Vuo1aBY2yVE3B};P-ohqnBpcxskMOT! zfDPs~oUvb@UUNEV&kTSclBHGq->^lN^c&wSRDfdXic_uCcv+oV(9LuLvB#ZQ>Qwdx zQlhKT&NBb^J?E|F0`@+*2aU&U?_Q(s-=h3RD~5U8dAKCfDE49SGZT?AN$!TJNwKy0 zUgbctiW5IWnP-x2Lh^@_nSL5?iXo zPSTGc(&Ox$lRo}qLCT?0Tv#Sr>_~U&W_jE zoEa9pd_UZ|AO%{U^e5riM#rdci@*jVaC z{+!nJqPA26TtN$p7@yeWg{^?Rm1Eb zk_I9VDFR^`5K$Zi%cz&j`uHCqw?`^ZdX@Op7zF@Dtt^UZ5sDVc>#YUhK``OZ$rIvJ z8S_3rgD2y={>xnYa+_^Ie*6uLl4%K-#cYPCh{7s4RLPggd3w-oR%scmk9Y;0RoytL z@Nb7{pvG#P>GIFX0W62k@5Kt-B}?=WAa6o-wOFjqS|cj8nJl<|C8I;1Zv{+|oF z?SX+a7Q@Phi~A>EAh?6~`YVvEx`E*W6v=qF1U24Xwq!Q7lMr_DKSS^M`a#q6i{J&q z(wN*)Ab-wH`r$F&d^V%C)fI_yVY$JH?tYRr!W8-ceCL-Rs&^$K4sw{a5Qu~>z0DVQ zVwWkxB+2d9U-dd!%%!_!(IKytt~7?cjW%L+g=|PPj_<048x2>yHyI}Gr=Ox}gq)1B zT+72S6%<`I(_cn0o0?sLHuZ`Sc|}y#jFziDP(Rh(IjLy#D6qMx7Q-l8$<CQ23AQct7fIrg^^T7DpjP4oyrQGQHBs(LL>esCH|QkM`pGIk%m)*F+9OT0Dpqq zQF#pnZ6J}eCb`T+T=xUM|M`ExxOWrwEk2QhmhtLHST`0~6M|I1%xNVD5~oDTf=nX4>UZL?sGwMSW$ZbHhx8^ozlJKx$8zPMOfXu^f>=pTFx6d} zJMsVcj60;#lEiLf6zqatvV{uj4r>C;^-osp%ozJeD6c$+5tr>j{*_k3PekU6oHv{ySioby*i=gvM*t2US=UJk2-@pi_98AH#wyXRBd-I6rbcCEJX^foW)hRp<|+Sbmt{ zRmu}6u)h*sCqJe8K7uE8@WI3D8=pN?Yg|1mlxhnmFPkX@H4$V7=3Xd)XI>rvyuW%X zAg}kT8i*%v@XU(w*`W8|dl7x_x4AYEEeWo*2FrUTy-U>`1U~^Q!HPIoeinAX62i`x zfd~C3aq7AMMUJ@0n?{`G|D1dv4IV_-+lijG)`DQcTZ&HK_%C31P;q^=5Lh*YxRK)J zjGYG(<+dg9%3hwWDOkMx?`aX3?7erfQ5AP5v>D0oCkkL99I&IUVgz+dXn-kD0Zz&s zt^khbR7?8lSHbkouF`A|%i;7T?E`@jk|1G;2KIBiGocA^M?f;IfmOnxYxX$sT5u%& zLob->h$I_!0UP)-HFFhiUW#K^+$Ms?U8#1%oD&6`%g0d-p@*XV5525*g|QZ+(7kjYu#rMgZyO!PIMH_{`XfMaHC zKsDk@PQp}!`00P3y)U+VzDP7CXkbys7T8UKpaxNZVk*-sHx@Mg1K9u(8?yTW#e_4r z1m=jD%di;?T|o4$C2rpJkGyBAy10UY(!_;X2wnxAH;u$E=!l6iXl+@)sc1nIE!BcW z6P?jE^~L&DYkH`Nop{;&Uej|y`}xOR$&TfcGvr4m7wOo%37bq9u6jImQ#P$p&sLee z7t+2p($y%+HRdX*yvN*XtnzfS0HNP?xM`VkuXg$DIJ9N^}%u#R{LmjS{v8Mn{PsW%sKia?;!OE;VI5r9N<4OM3ecU%OLrwc z)e;XBQ1L)XcXkESF9nl2us(^pfjSniI6tyG1g`<8BhCnfoSArguKxg-fMMol5t*s! zy7G8od1&(z(5KbnqrK>)Vfb8gXRwX@{WTl?ww>(QzU^yi=ulXIb}v)cd^kJk-l_yS zUFV-}IgD?4Op+X_`qKK267=j(OIY03g3OOv8lGC%>UnQK;sp#&Q<3O~pqT-2J(V2> zq-{autaB|oRa1-YA!bM+t zbTHlO)x{|hMI+=MRyLIH82+%Ty-lcqum=VV!j&;`^cw4+ya?G)x7BtJrKCUqR%cPV{l?e# zAduUtVz9;yQxsyR7iV$<&_sDXOl3RX`>x!HPD(*)Om&{Ci{Z>Bm=uJmAmi&COJZL% zS0D<@#Cix0g23(2q%H#37GD3)c-yr~%=t)UTEd7Z8r$F~g7r0j$b`Gco$-&C{yIkw zZ3~(&u`>XR`>@3ok_Q3Kb7XpI^r^VZW>P_-f1O+$LfJvE-pU4wxIXHd30;g2 zVd`e_BnDu_Ou$3Q9I=`Z8by zk>25a=L~F>YwiGJrp1_zDfxQYIZuc(bAb$ z3^OtXb1U;DPhp%SO6Y=FeoX`P`9ILy?d?IdNP|+j@M!)lwiae6y5H3P-@p2*e52HG zkciz%kqp8H!^i$$h&U{noBt5!>|T6%1cH{M1Ovm%IA9Kp2q}4Rh6#aFUUcdWKNxRI z=YT8bevUpdqGP{-@EkSXXuBZc{WgyJ0p6J!>~v~tG#;9czG1W#O}5JeEDJV(Yt6#B z=UbvDZz&_nKgMXCNc7-Gfw{d6>qm4>{*eOB!aUnSd>zGGXHdE*}kA0NJv z)UrRxPm~rYu1!riv!|(AFJ>GY=e{ssnLk^JrM%b@BN=qnTP1Vke_s#82d|y*!O8?e z|NZ}ey(TE-{@Qw6(Ors^)tCQuT^m`yxtaP}SDeTIiRP9E@){3a9xu`Yd+gb6(Cw+~ z_tC<=EOum(z^lSbp30+?nv^bDh%n;5F8WPw2iZ{d$+2V;56sYOd!# z`qrH6Cchs4blGzv2no4TvOQTbteN%UsCez$eBn|F+{f=D^Loo}sQml~bS6}i;+Kyg zirZZS=-Oo?E_x4Y@n1Zh1^k(ph?>cnTFGbVTcB_KuWR$g)w^Ut9dfk7KRVV?m_W{xG(gJMy6=IS(LyU|%tw*S)07M*zWS33RVi_cPO$vAzd z?}tPgE{CGfKh7rG!x|8Vad;h!3nvri7AZ_*cG_+2)^TZ$edJ@W>6#nIV`y+_J$G&P zZh?2D9^Yp8;Z2d$>1*qM^IV#MTxe;s03YcN@(9++@r;U>&)IGhvS{5lx4aY=rjPFZ zWMpfDqEPP;K zfHtcCDMaaDW_fu0ezSt^ z{wSEZm$cx>rM+NvfhKFW)OTDzD|hBaNA%^Z=kFzCG`#Yke4qV(C<(+rQy-Idk&&21 zfm(%69-9yI4;-%7ygqXvRuGE|l6UQ%sFi*NQqG+$bWmV?a7XeO5Eg5- z+ecd-88zXaTPDnLbqi%Pz)6${L)IjgnCmsvsI3`(-Oc!q^;fLWkE?HiJOAEdBQIB? zXD{Qm1X5u5 zzd|_i%QaQtF4sa-^GJW+_}3=phkbbhA?(kj9CO3nuuL%7W`L12m`?INFUZJ(dr(u~ zz)rD-a#OYW56uGYXEd7$Co88fdKk2uch4TSbUNs%J8x?;4apcf%+8wAVB^EH`>$9S ze-sw$^5QG(ZP3h42+MOT%svT$xr)|dH`z==Fq$NDto4b=HZ%0rkB>C-N7`4L9bc^d z9j-~;A@5iHyYu>xwMVMrJaEei@2)G6{Tt?{%rb=I`=Ea043N`#TlYh(PoY;QE}e^* zWhGcW%M#9!$ik&&QMzx$8*X=r=fL88pmA=6#?1-8v#ig@JnB9l%gYWJw+L8>ic_u{ zd$88*cc))jQ)ND!nmfFcXkVZi zS`}{BE9v&__%5&Sb>(;bvER*AjDLS!NZ8BMS?C?ynL1nLA~36R9bh^YU?#qF^+-;p zT{VC49KTyFBb-=gx zGBho$u=J2{3sr0`99yW`9Y^*#_jkVC>I&>1a08^r;@>j&1I)Id9(;}3!PKA*6_rnR zxe;)*kj_b*rF?z7A=ifl-<5)2d5Bx;<;PBVX#YrnzVe@jw4XogdFI95(>H1kT1EV9 zArz-{+#)CFV7d>KcZL=xEX}e!l|>pMs6|`M)hsPeXF@@kPZHiR0+pK}x?ON3>*jnu zC13RMOo(DfytL=(hx^nkW)SgT;$ z1g>-7^i3645L_V)BxA_F})Zrh(#z zrKRGXvas|F4d){_Z=~pDY8(WIII=zWg+(^1{=Oyu>(4<2W8;96Ar>JySIeNgyyqjp z$mwSxWi|mcukP{dKH{8F9r|>w3-f(Jdxy!sr?{5>*H6vu?9K)R&PTK@x80()D`?tz zMGk}xC~Vs0-(U)w{_%ThL%ggZF61&4m^PuKrlhR;+M;1m_9jU2s0pmm%q7s>{a(O$ z3^CY`_4-@^s=cjO_$jqOs~$+;_EzZk*wyIJzw^_BucyB}9Q(?>>=^TBE?l4TvTO^H zt&H8>oS+qn<$ZJ47rmdyhSY-VI`L3V!csk@zA(cwtxIxTiF;Fmubxl+(T&8=JbgG$ zFw>VuhX0ig?>?51zjcD~M9ygk%lU5TVJBu4cShfiv^?+l$IX8Wl2tOdet&=qo$IX0 z-_wQ)PG2>VXwtIT)- zxu&A)imE*}2`aC&OSSA;Z0@y@{DhB2&AYw?djvfME52%CAXD>kSi4NjTOuKWg>b!9;eZ&1O z5|;a}1kkY^>rcxA=6>F2Z~66F8z{4#Mj{OiGu#VqvOk`^B#bp!2uojEFId%__pc)| zJf$R5VOlvmsWAi59=XnJdMsVKLC7c*&YR~6isuJ$B z<1yUNi~HuYpV#zf5pK7eh?fLE)H8`zzpag`-FOwLKN7Yf_IS@ta9DGt>>8#U1Y^bf zJ9`w|}7%S=sz%Z`wSQ z(aLy@&ODd8+w3W>abwZFL+u-G>1Vb|Z>M|rM@3!Xk1)A2>GKSr0~vXWI^fx+usuK7 zc;C&oJFWckMx#ySai^{%^E2`;V>6zwPPw*x{^aU@81+Vr;2UCr*2kOo`bhJv=rnaiCE(e)!=#_i$ zb-()M)E5i9IHcyT&1L@<7k6JuiMhG-2nD_K+3yB1J*f{)U!m1JaV{Kx(7X7Pe{6QH zFK!bJU@tKte)J;V29y~?d6QfUepSL`kv{(Ht^}>K$CeUwTR)w`o&o3XKj@XkpL37e z1+#({XLzJu)|q9|@)O5n#W99ff-bvH!iizNkn8f%%>58MD@SwJtV>aukW3;xeZBG4 ztylZXrHUUmmOoylRCD@jZs*LJJ>Mg2iDS1Tk6m>?2T7TI$G9FT{X;{`{BVs4I;gif z?sIlp?#v}j@QGp*GJfbbVw$wueZLA%$5;0t5vuN{)P3ZKHf&;Vs2@~sa(qj@=Rp6W z*9RXxMsk!#lLIxA^fL3XYFzmbuS$E3cY}LV)RC($kLv5+$$cN&a8s=(fKEniulQZ; zFIwh0gQ=I$(@CmhAjoMQhKEed)$W8c(Z$UVhh}cNtg}^+b#QQfw_|=%woGHnzrKK5 z1|rEJ=bzD+80YE-tdb>g;!)vh{Dzy`Q966 zFrSOMb}C13!s1TjKsZP`*`Hs;w7X{dozm1HC>rqI&kd#sPZ3Q&SIM?@5RNY44t^_*xhIGi9L5YwD?LA9#aFL5k=7x zv!$|V8`N6xdU-9+hfS6wsnf?x5U%Lrgv8%6-L~R8$ik~x^<*8LSOlj2VrWg{Z9k42 z=58z)9MMb8J@(Po^ESgBq40>X+#W@CpPZ{;A-z36zu_uqonv&bm7tE;z&%9VIvB^Tua08}|NYbwbC6=jQJ2o>M*h z_6loWxd3yD+LaJ3UB~rEA_h~bmwTqMfSYmf(}zSvTs^!6J#Iz^zcfni`a2M>E$%qh zQC}CVw?^ww>6D&2<|)@U z!>I-Z_Y?(JoYBXAvV`JHxZ@$@T9nnjst2hL%3Pf=^pl(ZPk@dsc#XFrd^( zf|WdhgnG0X2ZmD4U>tlv8w3A`>;q8!8gYH`I0zV{Ng1{oI$e!W#A#-u&xI>`E%Cn1knUG8=kQXeA_k@P4+vYjqx{QXhjm9MI?SKx zF6ss{s?Rctg;@>>18bh`vu_M}@X7!2=P#>BFO}}Ti8_}|n>hfgpXz3qt(Qh3v1k0M z8TF)7&DQC9YW{AaI~ecT&+r=YO*3cRF5mvc37wt$y2+pv)7i}}qvzw`*s_|}#=Ved z&$AqL_ckbD?k%26ZA^Y%bWy{2Xjya(ju@UlCDvY^mFFO!sa zV`f9;m+^|v?DDTFgvjhfF!~MZlH6gi@C`-*?h0$7RErR}R; zJm*LmzFbM49JHLupDb>(%4*C3bppet)W0(98{GQM2T$k_%@t@p5aOgiay|9(parDw`u~p4sMD*b2qVIv zK22@vR3FxN;GxiYgnkIGpa&nKg$aTOxbsL%P33QI%1Q`{$w%JmFL0Y4Zqn^$qPI!E z3!Ag9a|4_GAgMa3VfH`eGP-a(*UZ0P!gKYsUDXf1J~uW}>zG7LvD-YM>Wm4UxRzEv z7;qTeE&FI!=M^Y9zu@X*NduJK?9X=#Mep|BKMz^+!8y-&qm=9I?b{x>DXTMGiH|Gl zYM0(#Ymqi*)m<>@=L=gj-~pP5iG7)4KkJ(jJP#e-m_=x-X6bFaP~nk!S1WuNR6JLY zhvvFOTlOGvt>Ps>RiRb~csT?px@PGc)MN3-4yFZ=TYiomq@K-At`BfKlYLkD)mZP) zGuNt4yRvQW*v9X#FO)p={W!!#u*){%QV%gK=jJ+iTSQ-BVhw@I6s#x8z`iwG3iRpsFTIQOv_?V{+ z<2?qX_x3h=@WOqL8A^F^Yb(y)Og-SE;A7C8211u?t@HlEoojoPYhP@lQfY+La7Nu_ zD|4Ip-dU&WF{F;@zaHPn>AlxByqgz1l^81abL(-CJqR z)1kVnLu6#}0sWmcHnO^~pAafi^_iN7JumSDx6xhw>z}Kgk76N$u16>t7G9N%lVH1X zCWU!3mKSoW2M-Bjz>sGN@<>A7L{qIBsO1QyxRncVzptf z>jSm4$#N};u1o8Tt&R)#Sx|o`-g-ky*f^)`ncz82Vs>Y!FoTI1qDx?m2zyEn{{;&I z2@RNU^n%8V@a-}P zUi>E)+S4rzIG&FXS!eqFC2f5vlU%YA^$FA(A`i)vT)ysC=eNPQMH_w%RjUP}|dnl-w6Q56#6VcAL0CC=2r4R0A5j9q7H zg0#%%;?bFuG{A>i>Kxj-=RD?mg7T0OJ<(93K`F!$=!LO&dh1}kD@^6$&~h_+W00nf z_t|ToDh}_&>i^hq+dvl7I&j}0KV(0&=7zsx8DqqIRVX`UJ0q_->bVa|#rC<6D%Rii zKzr-%!gnO<`BU0cg$K1&GmBq;HjpmCCO+F+dyMqGw>s1nJyyAefe5^(B-`LR75OYX zAFAD;jJ-4Sq3V#%-P^fER<}Qee_+naT>4Zg47%WG(0MpTqS*iY{-e1L;AXL>Q;uYV zWFX*Y@~QeTvGLM|zk>Y@5s*TwksWLH0w5xYO0WC$Crw#nIYNgDVKjnZS3OoNkPOrR z_!r#)VHS}WPgY@m0g0Lo;Sel4`e5SneZD$%off0{6g%G6IkN zF&{X`sQl%?dTWbF%VOi2IEyXCZpw{5*TWG&1}=T=BFMJ2*t<@rPZbw9FunHrqWnIKiRI`Q_U z!wum!4RLsvPTjE4EWM-d*sB}Eksj~ga3N|@QFbjUyU(RtsBM3o8~fl=!mHb3L*D-0 zm$N%O7Y|7m4C@+%V2izVZC(yEhZo=oY*2YX%$f7bFKg(`_;O)2&805UT3^?Zk?b-y z)OEUMyfq*&4lirJ=JwdfJf+Lf2pKKbhe+1+V5KP`bheWF-CvrMa7wMF)G*WW?jI3K zdPbE2zDyIW*zJO?^s$Rq9IIL@1g>9|9?pfox;n^G+T8hctKyDEe?j4OdH|BZ_YX`Xtqa!H!{=*yn}7Z0+O_qkWq)ZpXO9ameLDV_ zzW~D`S87Kje?--Cw)X&p2!t4AIjG`_wAeS*@&d4Mg_9+G*|pTTv5{a;4~3mr zW@+GMDzZu<7K}ZeC2qGH&j-ZTBuaQxR1`N1ggxS*t=!jng#;2%J`t5TLm`y3ty`2# zZLJIH>ww7tTfKgrI^XZEe&lpv^Zj9O&EbUK-i>}w`CF#`a|dtLSq&ETW^q1nnK%gBzpKZguDZnYn!@6EJ3qDHa4zZxeSUV%IQHcV z6BERjc$Tnkoyj9VauX+1x{s8USg#?xDvmZsZ&m+%eA^}E#DYCH%BCi!YwMIS^PQW1 zgt`>w$=~+-7;cM4h$lj8j?KS4a1f%PdFtz&+ChO%B*P8?*$SSp+nSny;?K437KdA! zw1sP66*PAi>v*+Q^9=Hx1}+=wk2PmyD(x(Cx1v++t7i`Sk(T4FLglsi4D=fhNUM=hW(k!GghL3z8uv`DNMiR*K^N zzKUeaaL*Fkje|M4f>M{;A3tVE@qgSm)vvADv1e+_mnv3f>=RhXu{{3RQ7!NV<9RPF z9bQgMy2r`xvZ7apcBqis*)OhcDD~U!JtXT{qWjRP|NC__8H7bnWyq<+qO3QbWw4xqxwyi;#?lZ&Luv(lqtl2qRy%ukjBrYlm2Wwy znzpt+WMuKrr+)3__LoP3T3`QQWQfZBmviad&f_=uNpMmAHKghttlk2vv1w|K16+~J@lp<0hAVo-2)JO-Z zf)XLpr5CA*ih|TAHFS_BB_K_jfC>Q(y*KG3^pemL2zWo%(pC1}=bm%!{R1(N^2p45 z$2;bjW6rOsAsthM{pKzK)( zgdzs>|gHRdz5 z!*)uBr^ZZDlyYSYPlU$-!rT@&@Wn6-9Ri4X&D|N2v9>xBs>13oGj)b`QtlV+_a^)GNfFz^V;^a;hYs-_Q+%~_T2k~;a6*&fj88>-`2}8+z5D34VE{& z`0Pru7q_(4ql>^{PqbS$;oCx4+sQnU^DBBsaq>=pg#7;T0L7QsGaKqmmx_>P&hrA( zvU46wJt))?iVykHeR!zxmH%d4ywVdVO$P*oGjf$nvpMEFN-{0ktq_3M;IE87DT4aL zw(qV}5wW$3F=7wyj=XM8IlO84O6$k)!Wiei24;ft)csDb2Q9X4q|R(z5ayGy)l+ob zly{!D(aO8o@G97+1c2Wkd-W)8lk)YwgwKNN7*0pjOm&_Uw0dom;xQ^sBSO9H5*6Kz zH)?X2Xd6Cc`b{chUu{@CWc3NE&M~`6-$95NGr9MnCMX!tcvoa6eE;~*h5epY5+7$H zDpql^>u3M$l_wWn{dod^-R?DPK<>jqvpK56{f;zGswkX&tt|;&)im;CL@HyPC% zdfiJcqy^)6c4V|dY}DakOkO)WS$Bt!XFxrJ*q{bA-M^PNDT+Gd4`JFn3BKTXXY~X= zP1y8obA6<4;8dnj#Cmqzb`eS!<$D*G2srV?(6vxS6S#o$v+B)MulqfXOqi#I`yc;3jtv-ouwV zgI$R^Ud2Ois;XEGEoX|q_cZpU5{F)^R+xyMXjgrgV6Ty(RyksT%Q7Y z#0AO)*ThKNK9&WlKy{k#Zrgr-K3RKiPVQ$~oO1%`W-i^A2AI0<)XDxPzb*0HZG6!9 z`dmAPJ@)=KId#k$4EEX*6u#X;+i~>N1&X)31RSw7Ve*apg875tp@B*}tCplErez;w zuLGNcnsyMwA4XAY1|q_>S6?cQZ8!E$=9bq;X)2O3W?ROFHa>6Fl?$!ZDgflSzu-Y- zECX!QUM==gcp?a0d?9LIKEGLV%zKI{Zco+j>DP*+c?_BhXisKm5V^dNTqwM^RgsqMQ& z@Om_-4@smfzC}gtUO{@(qtHTP=gZ={mUbiLIy>CEEiu>pD?0vLQx#E9D-K5emh;hA zsBS&G;gj2K+$rwH{OGj?!~<6gTH>;afJ*vFqnhjIW$Aml=y3;*sXu$DX-AfTGuwsQ z3}(khj^H^LGA~~@1^gkD*;{ANE{mb&w8BCO*);iH0S?QP^|3UC(^hAp_FjCwFF=Bz z?chvBijy*_2hbsYJX{)TJRS^{p}xcT;Y0Ilxz#cUTA!2G*`Ma;cOA?7YJT7K?fR)N z1{a5-nu%i7$2`^?IVY_`VjG4*Lx~IY4k-l1AT!xQz$g2_&E^s)oJRAD*36#gsFKw&Nvol%9F1rqUK~up;^#nKMToqZuAa}cp z;hi)tuGIWq?}Jlc(}vQ$-NR*VKU}AN@RN0@ z30u2V)8=b>p;V!Pt>CY}+K5g@tgj#Ty`2=QH7%Nx0E5|$v}p}n<7a-)k7u8i$BPXg zuehkW&e&P5 z^K=a5_0c=qMF^ON@6nb$7mJ$e0Jk zK!?`+c;e3UwJD3j3g48O8Tt*1>y;~hjUu0u{RYeHHZ}tGoZ#iDl*xQE8%WhRsauZG zS0cOap6p9Mor%89IwDwg$Jn=1ud6r!eEZBhFQO3witZa|#~2azcntP}!$3u=7U8># z{8_%%UXp#xbfV%r^L7ZpL_{&qMEN26-es@nv==J1#8O=c%CnyDT(K47Dq@ERTC}9m zT|?9`dt4T}6FOHS4zCgZ+-cf(u*s;A=k^I2fc5TYJ8<-<IaqsM*ONtciE;|2U{~W4pb^&lnkSO@ zN9^5G9NfET&mUrt8<~A8s<-l|tG|B?k&9AN*46u7>8|GMN(!a~25!`G(;MvVh&zTi z&y+X5%14Vv=DbOa8qjU#+s%#04gU>s!L6XzAUavb<*?IE-)6;fpF1gSfpJ;rvZlAa zt9s?byP-Tv3P*5y(T^$F_&oICahKwYPq%H;ALp8~s#%UK==&+B`wjOQIXBN6d1?5x zE=g`12L}QER4vGakPTyc`nK?&_bmPOYhUh#1cL&F1$RXR1*-vrW8LAcKY;w`>1Pb4 zo;ry?zA%V_NkCopA-h7VO;I#UBY|bA2^3k*B0D4I1@u+w(~BMtMyP%qo*Ed}1eoqO zUCnT4)%=n^arpEo$JlP$hSs~u!FDf)kMlBxc|-ugYd2zmjzL0n=5KDMZ!`3w@sR+H^bP^}g=6!m`|NY6& ziPF)7*qbggHgNke`MC>kT2**j6p;~K?hGrrV85j|plvns*ZHltbq&lD(M+!SMX~pD z^&u^0EmGMZ34AUp%JCz~azo7udkPHBl0Q#o1If=* z%mn`4(P6cgS;Rl&g-?}+c^acE?OhD6Dz%xo%iWQ?cyxav#CV|OdOaZN0n8h0`<%Xl*}&Y zW>krsTUI6ItrwR0PjgL9>dhNW>2WxEJ$gW!>gpwhoun6f<@a}W%qHIMhi(50+;)GE zw`iP$yKd2*ShMO`&0G5R>)m%36Mr;hZE#Pq_1nMtQ8o1qrH`;jtiaJpvWi(X+ZA&2 z6;l^kNXx#%W!_b5hL=j1_tK*BGd;w>C+u7nbJc58zqX+Ofq^Tb4~r(iO-?U3P6dJ( zK_wW|!``$Q}pVTC$k%GFq$pr!u-Iaqwn+>;vR2#l&)ECWB6E zATi0C+5fbOGjr zD+5IWn#l@cqcoT!?n2*mYh%if#q8v>jL6S4hRH7>rgy3Py<}0+hHIOglsF)_4G2=h>Pg;Dzk#znxix?zBUCX z_L~w6A5)oKJt67jI0dUw+6tf<$XzGdv}%xQ*={#=TPDWeFj4)w-V1$c&3WA+^K2U- z9@hR$&iKO2633d$j-%n|dEc=~94Sr4WOC0#o2No)slkl&%&@#6-zxdFOvXd6)1I%H zm{iP^Kg2zG68LK6ecEgG9=P; zj7O+dA#R!~@{Ukwo72#s7t(86uptu6mwo34kINNe05SWyE7o+sGf}1Vp>TTYi6;iv z5ZL6iF7lJ`rq&(5bI0d=NHFf<*@lLXjts#&JGv`B%N?!T4~N#z>`SR!J?7?Z9SNxv z%9P2}kKJx)VR(fMs{XXBD74i4*4gurxr}elqg08|NI|W+>#IrJwd^6twFOl<8n9S~ zXRRHj)6OLuP8;`;Z6sT$t(m~95%_Q2lap%VVTf?~59G>?K(7!I6Q~YH(Lhm}sCFz? z26p>=HoL*(DZ{};p)}&oE(wS?QrPHd7{aK zC%fyL6*~nf#ISa5bG^OB0xRfFCo2|9kGZX$RW3P=db6$FGj&vu- zSt-?ROEC)BIgatkk`BY5wPlWs^MBno``3=s3)YHx>`KeZaMInRy%}mvIjM;U7+T#o#;!$RR$tNBeD$kzpDA%J);)G-I-8cOLfyCJ>*UGp)8EpM zX_TF?k7;tQ4f;*!;QsbR9sx9$p?|Wz+sVNZKYxec%t{n)7G8QA7cCw0Rx}A5nV;=$ zfodXZkU$}z;CAe=L4xAfLdUua`B6_&QKzDZ`UO@&RBnu&PM)z!fr8!c{8@RE?m6Q9 z3o&g{nUh{SL@^R!MTs?KkMBo<$LbZ5g#ZGtCfG2L-b82>|D^iH3G(%&-R@(Nylo8O zQujSsdqM;}myF@Oa{hz;01p##Wx|s(?58{SIc0TR0B~Zjp5XobQ_Bs1bcnTwFX*j# zl3!{=gYWVsVMxS}rM1ER%k$wXi`>Ku6=#A;0sc!s1JrMRstEiN>)-3mc1m}FyUVqpV}Sr>7QOG&+AH$V2(DS}_|whslL0v$prb%0LrIf^T;U@!j@yOD1=6?POflPtaBJT5ZBtgf`O_5tq8Te7@#+N2hp$`=a1t zu8X?0iw2EGWl}oZvD7jx_1soJ>Pxz?%e=+F6B)eTxoAiP%5U=+OCERu7J?Ezk8`>{ ze^*2njWH$&eNeCEYCa9ZS!y6?8~i<{w9;^iHH^7Ul2`9V5U#_>XPv)3MaFNy8aC~U z2h2Bh{e68E+`&>XMZiY9H%*E0+zUMeesnWSqs;DfIqQtE;l%*aPRVea@9(OstBU0M zb9FOLPu_E2YFmCC-bS$*)uhG2J~Y(~Z>+f5uRKF0$#@xkoSJ+C-dYR-OFP~gOe)PC zx`}07jZkF3qu#NUIb8UTjj#m0jfzK!6t5PPi3mENefTEXK_A27FJEG2Px0KG<{Z_V zij6(dA39VFt8ugKeowHRY_iLz!-;r|_71X$t{Ah})sCT+%y{Z zldl1Os{l?CG*QHoyaYde8PvVikd!fYXw?R> zV$$95)fp+f@`&%KAAZgov2{HH!lPw&hQ8|ppil-0ZxzLzP$>k(X&L-(5Ro9;w8Vf) zY`5=aI$~pLuh#s|b0S1Mct&xng;T!xUU%;n6-Z;Av1-zAjmxc2+S?HE0$cGl(#(sU zn-%+sA#KWUfq`uIKEA3Bp8`&ijRx8Eg|>$^zy2jz`Cn!@3o*~k@^&}|?M`6=p&(95NjbWj(e8a3# zSsLx#L}yVMaoMH2T;)r|{^dwuI`X}I`)}q0A9rK}GK`+6>;>Z_3di`yMtaK27fij0 zs}*G08)tmCVB>2u5mQYU<*Jtr(O=~k^5%j{l5;1QgLqDw@e5VoCG33KwVPCferJ)T zJsls6*w%yHXIRDnDZo4YaHXyK58ALD zbIsLN&AnP&_SBD=UbrU9f|6gt!vk;mXO#p|erB$t=ZftY`i#m8urNBs^L1!9^HKFL zj>Ew&?CaJ3EY%Q5V9fFS z1M?lBETsAR4ELG?=94DS_6oX8n#D=V!xk1T5Z&fROx-CqQFt7jYF$>q(~=XgxcTv6 zuRn+iCeG@zG4%&HAqf&w-7_}dtbjUc&GG*5H~^Dc7W-ZT!%)X?o9-;jmjbr3Z0X2M z^YBk16ow!Nv&X$261PUxKdyhybY2SJbsh=uu-y4>>e}|zb40!#LCj&htM^^6hIu}R zuIk?Xe&*knI1~)~FU$z57`V*R)M9aUCfxAK8iCq)ErG=f*TANtnap>d#Gp=T^G9w= z&-F)VKPJR?UGzX(SvnlEUG!DBs_@pHgg5$;PGd*}ywhV-aXZ-V;~fAlAlHB0k`hJL@@Aqt^=g)iUYN@>Ae zZQ8Rsq?VIz(Vw|6zA6Mb=*^Fst z29(d9_hZAr1u21VU?P;rgWSSpI!!eI7>U;tH(8G~%7iRBylIIZ8+ddHYOFN4#KIs7 zsqDCa`F4m(iu|UqxEPZGw4GB|iJaHkR~ti(hV6X4wbY{a!4g;AWebWPhFm*&rA85A~ysJfmdejmVVb(M0orbJiM)xWnnP3?3=z$Ec^AhoqgW&C+;aUqH8ZCLlxnAN4Fi+vQ*jhK$&c`>E z(toO{70+$j7#^G^;#&aGxChtQ-%xpO5ylUgRFi2#%lA%muMC~xM)nPCdp7ObNT3LL zz+lvJDW(FNb~W~|+h84h5GXx3-_`%2-Yv>LQxo^|YLTD$Ua=72Ju@n`9R zFkASbkap?w0s{$j4d>eaCrGejgagB8Vs(=uP>`Pbj$Y*a>$=8#L~yH-pKmjGZ75|V zxt6x7kKFb(ieHP9w=x~o{`f(xde^Gm+9vpP=$SJ!p?n;X=&RzC=m?GawY!8Y7O!_v zUzQj1_rAQXsZla0K%I9O>pBB%n;Bi&6$nuBBfrO>wpTG*rCAt78}(9Y^s5Phl3JR6 zSoEt3satJcQ!C+{Nu-Y4R_Ec}>d8JI1w^N^Zxokfde(`M^kk(=jjddK2rbUj^(OJ@ zA`5mm?k5%^4fnXdX>vLYvn2FC4sG393~j9&Ju_^uuH_ddG=Abwkq&qf$Oe40Oxfjg zCHn#aF!k^>A*fw$Ex&>ku)x%McwMJAGnJwYq9s^6j*Y_J@HYMe^@oyd?^8V`>v;Pu z|G|7=9M66NcIG(7wec)I$M*OcCQ9sz%N6pDWE$*A(@NiB@L0y3t@1oirCrB;nLtN3@aWPjL|~)Se6tp=ElkAI zbc}u2a5>n%`H7+Z55t+zzkgbSt3AhnWl)nhb&&Boo0Ds}Se{Fp7P7 zETa8)#k>e>|G>lkAK?LHfQ}z@RURwh?9HcVm{yj;Xu)wI;|Ofv*2GtuIGAzBp7V#qncVmTIC9*cg=~h4`wy>pne!@<{3UmHIz@8BQ$1 zbU3x*;?1{J-dI7k7L}Bsy}JRByG#%ojB#5n6yjFoyCfZO#r--OFdZq*Iq4R0)y!%{prC z?6h{>3l-Cc551o$U&_32le=l1$mt$%!f8M?D^aAFf4diq9+S8oOn znfHwyE2GsD^yxdkv_Ul_Ut_QiF{4n%WzvM$KUO=X+lQs$!590p2`6!~j6ElDaby2H z$UtC=TyR~p1D$-`mWoR8CKN69gum{Dzmn=2irIRsRxC!WQsQ>#*F`A^H`A14{c_l%&nf?gW_(9ocwYu+;phVdOp8TgkVbueRo`sZUUt^*kr z&$O+6VhI=|zFA{^@xpSe16nZBeNMjjZ9EzmOjvUFMJRY6SOGpDSwI8R2+f!*Hi#go6v)oI!M^XN%d9CHII_jrBmS1UCL z>*sT4iBO}AwHAj=|C^_S_#zC3zAbJprni4AO{RRqSQYkJvunkx`I6qej#J`v#WY$l zVtW<&wnTPGI!Iy}Z03BOc}W(n=M~tnv7=HNF3%1LB^1`0gO{ZQRNx7Ww>~RgNW6S{ z4fClOEx&op(nAzcaBBUcIF>x|&M5e>wMgwf2@TS!PF-zQS4vq#tS?FDhFq!p6tIlo^!84VM;gAYFXbJFr>$m9+s$l8a(h76isy=iqO zm+GeHsMOuD9Jh6`{3p}={WQwmKfd^V@C=jq&I7kaYxI<{5Kd=`R$mjiP`z3CQ*!?U z+sC!}JBGY{zgMopzH5IxpRzwFpW^fkRCig{_5cSOhlr&ul7ic!?n`hH)!?_zo(c;{54U#5ta zUqP2u-Ol-CwQl}q{{xKH(_Q>@cLF~L);0#$D>i;44&+htJ7+TIaFUI1iMvJ3w95Ov z{wc({lGD0Lixv-%`Oy&LDM$P_G%79yd5_z9(7*GdK_%KNY%q@}H%O_4bTuTaEiU%? zWEsaPA%=ee?@tFu*?XaMrNWrGp{Ird?_f#Kk^3B1#^NNAD>gvA-Z_f5BUQ{dMR) zWuYL?)2LR`>9DRBwso6#+H<@%!G_^M0<9O;g2O;|xna(6YR(xuJzRT3>AQFs-=@fi z`5t)8Wpt4i+7_WvsV4vlz6a1cpt>f;_{;JFin0>p{ab92&(F9%?ULp=;CEI|(N#g% zM_Rm}E<}dUG?d(NIZy;;ueX!yIix0r*D@(6QLY4*Td;GZ2(fkMQ~rgfXV)-|x%WWF z2>lAR2kX$h+R)yjJ~4l zDz8rvSe44cVBvXJmOuaIUoV`5SqBCOS-52(Txdw~6_2H%d%Fi#UIYnc zz8m;a<0o9J)&GYG`^(%HDDVsr3oZx~1I*RU?`ywI_+;Q7h541Xh%m-$ zZClGU)5y_vi^_dPX*ZgRzek6HH8Hp2Fi`_OPNbELO0gRV6-N3ofVxGfwG4L?; zMn~;s-ur?41;1srD`d&LtT`RyeFdhs%$LWB?h@!zw~^Evl(Q55ELyd}nLMFjW3mX; zm8)A~HxAeXbRAK%K643QXs|H-1*D5?9P)=+v4DK1o4BA3iULP){pJ6W!1;$<+u2+y zvguAQQbL_vSRSEezy3Es+dre@*N&awRgg9YPP_9|_&3miz5HwDzcz;aiuB0~9b&?@ z(vgao_Hf^h8{|}EjQ{cYP5tXtb+b;-1>ci9`T92a-#EsBP`)yT#8_*?qG>fz0YNlGx@D?R z$rxcO5nXGW2H%cxANRMZ3C;8J^=wdsq`NLp18yX>>m&u=f6oTtkY0V+JY`Y{7#RVV9X;@i;RWc2qMrr9b^xL4yph14r7%aKO)OfezzE2nO-gu?jve9zNuf0=Xg4 zT@jh$@Cl%GQ(3CzUfebmIp-LZwx&CLFyS|a@dK4_Cc(T>2K45p@}+Hn{@H=_1vWu& zFe@Z(Q}9C7N@wTnk};HS^WZ{vLiUnaoy)B9%@eq8F0mbUZcv$wBm_ptEHyh=1n2l#Ac=UY3l<6bysFQ*jW1lw zHSm4Z@L3B`J*aWrro@D`iGWE*YJj=Z-?rHOon-wFULSq_OEWzyjFe2lQd0w?RJy}uI@QQ`)`C1DAOTDW8{HtCMl%qgv4zgXu35Ad7aA>!x(e5sOB(Q&ayn+{gOB$q5SeBvZ_2(_1?&bUJAV~RB{f&MF&fXmhEfM*1ycZ-t@Q_SsLX!wr!({~S>bn{^*{RKwI6K1N@fd7 z(+DjXq{}Y%7IO$+L_$br$Ro`m72+IX@pFeJ`A%Jqys<9^SWnbgoY>E^&=P4VFB8b* ztap0NS{jTqK>ErAqRCQ)GD*7bQ%%NkDGHLks)@zoOFH6!&=npk6J`^wys$HJaRBLf z>B_NVx)%;Gc5wG}!TgLjg3|p}=5R0KnXnS`KFz2 zlGH8pQ-&PxCf$xvC5Z>}^O$@ObeT7N4m_<|7kb2(Mwjtj;UYEr*De76LUWal<_bta zV{Vv%a|y7@&z<`{?bU_-=`uZ#^9H}(Qa^Aebx;6m{svxVSw8cf64o*^4J@Z} zybiYh{{)fAvF7j1`<02?n<)R$2(W^VbVTN{(_!Zq$ekLWDR-(xQZ8q0HwcI$)QdW- zx|%ZT&kOElGA(eiDH|Ku+#1XabjRtzshRBhSbV#JYcSTYrFW&%xRM?i%lz72uK67|#{$4>#3M*HGb^4wS0wyLpuytdn$S&<7bEY#s^lr?M9q1L0dObUwrJpx=#N7{;uZ3$p$uaTreTlVv<00QU(hqWvxfdo@ePbw>}pa`_;%C zj@o+;t!9C!X=}n*_$5wC7#@AYr3)Vp?tkr z3}|PA(Vc+l%B`{Cvy~pCdw&|mG2giCa`m6m_diL-|Adarq7LO)g!WvnJtqalw14o; zNSn?ww>cLVnJQNuZ5b&;?7VHO!KGm%bPo{@_KTxgZ+txsDovl&iksqRioY8Q_M0=5 zu{;T#KbKOP-q2K+A1l9Pr7@F=i%J2it8K;oewz2JD0G2f+PGMc-=&mzXlH$*XFo5i z`#zZE(!qlUj?APf7AN0#^iLId5WEW2(NH8s5}ndGZKV#$ht!$I+gdUcb(FOx z%k7Odzf6`y>v`JTBISlU?SAzE+LnV`Bn6DWZk8mMvU|9uWF@#DKcpBmwJp;RCru6WMl7 z6d{?-x!v(jGYF#w^3}h(7yOcGO^lkT=(FrK_Snv(De+H?8D~ECG}RMVJZ6DYHlGj8 zw#b7H@!SY>%K7_w`tM)Arei)e=C$*@xw!fgps$^M@p@dQT1i2ZsHTx!n!rlm9BWWZ zxuX>n6HyVGc}8Ecm2lU>*eca%Jv!1TSj-uWRBY(tGbTjuNoVKQbk*6SCv7D5EG}&p z1&GAVTZW1RY?lV>^r`dUKEa&lR?6RuKh(I@l?&&%RkW=w3E%I8Y+n;*YBt>*_b+NR zviG~xXyLH^$~{`3x`rr(CNqf31A~1f1>RBc1&oliOg*aDn<`Sh;;<=)Etu-MLYpV3*l3R~7= z#<*68_CPwQIeE2fp5OLH^rR!U*ZgVdQz6(+WH7Pf!JP>U@IhDrINP`gks zN#A!b!Pw15<(G-yp55_sgGA1>0JWnrLvZBFUkSq~vcFpOZecU-k8NrHBTD!5_@e(c zV6-s*kQF_w1$o%)oa9a)GYfXS;2R%BG4 z-Q!jqAmKBM$i3%mU517@llUdF6fphw<5H9^yY$Rhg`#QmYbA#6xmqEhELv{e6(4}; z(hfde8oY6WJ;PI>^lYwnpSvWZZtb<}W~RvCbPg1j!BkVi1fe*hnJl^7J;D_IY9=!QyuP z5JGI>K1!ZrbltErN7jYX(c4+@TfhS^O-W@dlMbonq4@LH4k%xHC2{zu#C5OL&cH*U z)>yy3xPH?ecogX45!q8X zf$|s(RDy+NWz>MbSnf0BU|{ofV9$a}(SHvdf4kOq&h9HMiVtFlB?2I6w6%;^$4ymk z6%e>!9TQ4=^MTdxLT#xcX0tn1!j;p0E_*jP5NbfQ3I{fNk89;$b{Mqc?KZ`Nvms)n z)eDf?Tn&zwN`)5WKY@>gE;b~_g?aTrJc(}M& zWBggb>5Z9e4lKGBT@(fP>YYrFg~8WsgJ6&2CZ_=P9uVjS0z%!BBISGYI4ScwjI>#S zb1^x5zA%E61+d|uAN#=WdeMQ(pY6hD$}jf=flqKr`dvk&hslq#BSn64>+Y7He zSVd(rtoh?&O(SY)#U}SE3x=PPU{6#o<$teNM3e#iHg3e0X@mK&=u{ryf}76v4bGE_ zURy8I%=6r!aw75<-XuqXeJn!3n^B8+8d+q`FoAJeEsl0=vjp~XR?_==yu?(lCvld6 zu2w;Mhoy7gBF32j%cG7C-7f%|tzjhn6vgSLSFn^sN)*-A2rJ42CN-^_Ti-LxE9)}! z>AA>Mi!WrFT}_;V9|#I!k2TOz+stl@yZWQ94-h?X{;GbSDTnNbqi@Hh?0*#wA0Z$w z_G;FRqT7kS9SW*i!Bq>x=GX<_LzQ)~8QBtt9VhsBEGr;PjpS>%zN zbHAzT=6K*nuW7&Ea%kX^DZ*JV^7`}}A;M4yR>UHgkKv_v13re#?+^T@8kt3FUs8-N>ZQW+SLjl|s(GQjB#@NO<2E9>fnW6*gvZ?KO{2 z2n2IqJMh9EjHOwZsTkYqQPuVN18DqHSxg)>j9UNe@VI`J^C(q819jsda(D40N6 z3J+?HV4ql==y(qPufDxI`V8>f2O0)44UeeT79%VxMH-AL;Z7nGuygZjOekGHxk$>V z!kcI@SF*lcuJFLCk81Ee3bS(2EC2CAf3J1?^#qqIBpe4Y+}Hs7n)8ujH&V)jPub3< z&NZVAX!N&U0VjPna_GUuY5GRB1 zb}_8!n{FN^KKoXbf9>NAo21z@q9DY1UIc@VT&osb2yNiiQ6f&rMoTsx1$5QUEb8pS zC)3IMGm5uv z;NVKc;V;_D$usB{@&yFaGSNL0p1g~_L6R%feym*qWXvClgM0au zEjVPsmuk!Vzss24Q!Le%j`aqKvn1Y@K2e*J>?AM&4Zf-ZS6HyDNbL%V1ysB!6IJ*Z zp69!dua4`#MW~Cry!zULk$=ogWOfU#=TzD&R&$>v1e!iKwbNrHJ7?V2CUOec@T@mn zTTLrG%=;mqKB>=YM7TH-G7|FG_B(5S?V<6fX)kTA+YTN}xH+4C`p%HA#i!#3CMWCp zQFGR=YY7*F$&qSL@o*;A$EVcnzT8_d(}c_xnQ1B*1KFbVHU>HGfATp~Ww+7n`61Cw zvP%CA^<%i2?US5t?GzH*^bGcINppNZX(HGN&2IlMNkcuSttmX(dIB~C?q>9SJ!e*b z;thw=At>wR_jH;UZipf;(6s0nFCZzYk)|Fkou}bFRh>ez9L^m8< zr}dFIY5mZbNo1)&F%k>zX7)#0k}h(I2}ER}zSFwoi!nTbRq=X{jkNyk?xLAk`sO}! z=|g)}hJMRiZ;vqB-~GgzT#^y6yg)gKm26>4e)4#zXn1xqdofEBdDV0ew6h3<9^e<>hJ;vg6 z!c2Q6(2}Q>-~v69 zebaQCXI021E*sra>|bl%5u7e!;u&{t*|trulb%sX!FZ#)tVkRO_!@9B7V!1x6nUJ0 zkRJ(-vyjn0HQ0F>hJ0bf6WVE~HJ@;?1l1QaAD0&??3I+*oMdz?Vd6EjVbS2Ra}Sm| zq1OyfJbUWr9Wf}aK<>;!P;F0A%mOn=tKArR>;oYK=l4?`RqyMyDrFjPgY&sxayCR_ z`x@jnA|*5j1n?4YY>4}8hE!8UG_OIL=jzB*6S}giv2>&7Y3hvI6qQvrdbS!`MmoDhWGy+<8<+xJ<}_g>oJMu)f%&k$ z-F~U{FvV_ZC`4pMcj1c=fSgnt7P8ta^j9s!+^Wi&=+U(@jtJ=&@6TowhZP;X^6sTA zq7--p%6QPt1Uttp(zGN~#i5f|SzNFQL9i6eH1osRu1M_n*=Tt5^SEx~XtkoA$!wZP z%q;WLt-XPcej|@!3-~lF3cmRz1T*bu1#90sOh2aNkjNH%lHsqkdB+T-jZRX*M{$qE zet08A&3%P8UZ#7v;bYeNIFL5lhv__%_dHs@TF>=cojl;m2216lqj~2Z?_xo_;O8q{h;D&6cc{eW*zylHnf zb}^$~lV(WJRx>3=k5!$~6!jxyOPFlCbBN`(9c%$VI7aHitRGQ#NJ%W#XL#7qeB|1- zEFn5j*pU+tMLERiU86Th7nt61m~1zE+fWwz9H6|Z@N7VsLw?RKEHqlG9L=kM69}h8 z!I-!fF^+byCje>-|ApGOUhSjyY6ijPTY4?+{O#pVpCdx2W{xA67LN5CdA7Lbb`0s) zcjWq(GhOj9%0?9Ki%pvEx7#O5$)Nb+o_4#w5ukQoL9334}w@( z-eABV?;QWAO?h3~(g}01Z^&$5G`qCZV{p?F|X$Tb58evlsY33@qe`c}zEPaAR)?g?ZfsuKP!6kx=g!@^nhO zZlGMx7T>BXEH4K0`rf){P|J=E3OAl3_NV_ikf*IUDthYhU*}O<{n(?r_i*7TKeNKv zALc_Z3(NTT(@{Bf7R>W30Csjqap}cm0IXjihU*YgDSGJ4)-H#@p*i>Y7nA0S{p685 z$>&&_nYb5i-bkmoH5lw!>+R7)Niyt#iUR`VY#d0%uYtSQyZI8HW`Slzk%g08A_5`w z|A(-z42yDYyH+s(l`f@0x}5v9NfuXxQhAwHCfr0sM z_ukL@{`kIUe}6eR_;GVx=egE8*SRjgjo1EK7Ba`{9rv3S7M_Krxz>D2o6)htux6L} zkVigB(O47Vn$@s9n<~I5>WhD7V~>0+)YG`$oh5vQ=LLZ15>(BJE@<|vJdu1JWY#W= zgnUDnvn;)Vj%S?5G8Thc=6bX#y!Th?jDo{0&$}qriP)!i^X~TN?ck0YmR6td;3x*Ysv$G2qTxtOwGVgxEmceV4qLL5F-6U8ob2s{ zuG$7cs%1hibS@_)&-$o@ILqD;Lv#p|)INdfc6w;?RdojryhU?{alHU<4 zZKi)-<@ip%!XM+|vM_KA$%+0KuRGIzx@lj+g2CK2pZnLUF*|swi09Cc;Qjse7Vtd1 zqsQcaRuqnb(5=^SNtz#Oz&EAX8qnSO1NZ;$X8O+$iJk)m&kd)dRm@)9U|K=6VE!%> zfg&=Ku6vB`h-thPku+9l<{G{~8Ky2gkJFHjd0K5TAkx`w9@{!)xrl9UDU^nJd!of& zdjh67DL_rT`c=R7_wCJg(-XXaJslk65_cyk3raofRTs0b71*0H#+<=x|EQNLkj_bF zgdKWi%g+^Hsu=c^T(;ZtL6ckVSF@}~_irigy^M+DjL8?Ca~(w3aaEgu2Guz?@!&jh zIPn~Q_I&F7*|n?!B4x8pU-Y&$1K?~Vb|&Rzls`(Pjx&w3XFfSO|EF9hF8|@a{y=XTCr8_H5^JkQD3hdrK#5)2j0C_x2|qfbhjSlljMR zFkzS(>J4$2c@SsDRRucM`;RXP{23M$uHYIuiFtV@$U+bTU*cR*xNt{bGr(EySb4gz z_7k-AWPJLnC*oy+I{QXT)AVn9#jXMBo9NxU&eYB|(U=%$}!#jv3489z|i2_f&|<}g&-td!lR zN8n+MQusN8db2Y+HK@sDT4#8nSF0s{pTdMAuC~Wp(wI11Z2TK?)>Cj@PGGIoDE+w2 z0rswmCgR6GOh+qfD^stqqZ9?zAkMXK-@gr0=+=9iS7vIH7#XGt#7W)>R`V;9t;pkRbGo1tkqKST?yua&W)$^ z=!gJ^AhN^@Ia$o`)-NPx`vogi)cC`ikv{#vb!QzwBWp zQm_2qUJCGP!h5q^`#@z<+2WwK1Fj=T<2*H1@&>;Lq%NA>aBJ-ytSJvvG0lMch})>U z0CEFT$(_Vn-#psTTOl&0k~fv4(f}>WWkhuMhyj zT_3?>!Z{rnWi5B3Z`i?lB~RgNQFxxulnA=gcFnP_mEY)yZSB%$s%vzvaWBRXB0ODR zvwrsn{XPWHFUoVT>3?gsB=>(Rzw6RTl@0*gFu-v;m=n|hY^x!R+>0xaXLbY7F6%k) z4pAG~KlicY*(v|O-^Y+J$wIZv_V5%awJF>698kub=!&%2aTr?Uodsd!A@UKF-jvb& z>X2YFMB>cL?z&kr+@HR!W4+nB+^Cc zP8E6WbqOJ8#@0H12@S?^wd)f>%=Ym%rW;fY`rGt1I2Kt`zk3FU(9Pj}pzX`{>Jo7s z<74vavd86=8rv2|aiv4tPSB^GPpkXP- zo}9jjUp}y=Ou09ga^#K#Q*S(ijz%ypxajK+6ngq?n-8e&E%=)1y=O^0c-E4+}!7O`aOD%acV^gnzj5=gTO8cGmv`)N&7 z!>3pw_BGvn5B;Wc^iHOQV$|7@`hs1#z=ISUab>1?0%vFbX6|brycq<=?bw@;*)aw5wq@8`WWa?(QwQC zYuC8W$)J1W8~L)8y0?5demEQT4*T`hb@gE8*6&5EMAG*b(LbfzJ(m5=WTtmYOEd$S z=bGG}y_r&k5!3FDI7c|0RWXG@8C6S3r1$;5fW!^Gkg~)WL`Z8i2Ce|l@$+MDK4*Ab zy!Jx2bhpB1zvGatNM8@6!L3OcHSraDv#-k0>Z8Mln^d9s(3&@V`OfOp&zNi%$qI(e(S=})BRr{KwuiJ z#r=FE;y2Z|c3iA+kHjM4R)BSgzBnL(f5wS9_G)Y`h%2Y| zZ3!Tk1{xzRa$9N;G`9V6ZV2V0P&~NxaZR{dC`oVVOvC%Jg0IXEFYYD#H#witZ4%&8 z2eSOk)Ai?#_-HHwsLhAEs!rU6m(0meFUTW1%d_g zEDqFv&$U7a1|5yk zda_SDH1wdJ3-~bsIj5gr2cM-FQ;<-hmc_XrbDf1z`n&pOWC)+#XX@1n6ra{k7kG#9 z!rm!Z1+{{487v5)ejO540!WEp@&4(eQeqM@jRggaM1t3~`vK*3gP#31=*b(Mi)2Lo zX3K%A^L-`KKZJE0Kl0{^eX)D_W8JA#Ll&Y1>dkW0!Q2SwD~^qTBD zCl+@lgBs@{A^HAlh^?^*szw5ZXHOhgb&{KycP%#@-z+yf^-VQsx+j}}K2xtikH+k$ zIR?u&foPX%U^hYZ>Yg+?p{D@&uIEOcs_ZdQR70m}G@eAJ@-@I?d~kewD+uX-6!Gk- zoU*B>VHjWmd&^V98T*sE%Eo$trd}T7R$G^=+jbZDw@S1MVZ!iaWJ%7IVD1+xN?$a@ z%!hB+F$y<@%8#mz0rWx007G zT>~#o+8bW_FI?Vz0{ju*KdOWp^AOV*)%?HAExyv?%>b3g6dx2R1oTYrJj{YfN*&97 zt8UT#nsjuIx5dhY=JYHk><{w^Z;YukE2ea!qQ#18Q|zZL&p(65MIK^V5iDy%uV%F~ z62;4|259LH#tK@`h((PadC%fMHfGwBB%?pkiZb>?%1K`bIrar4WsyK9jE_fIvh?>y z=}*QDZHHSfq}$Y_J^)BmTFzF_XH6zUE<1kv0}7U2<_fVXY@Szdk%Y4ZrwFCT@0avq3LvT3Zv8jKXy9 zyPMt6j30T(Ng~BP={AmCqejN@PU<*T^pNVI1E0{kjuA=k6{H>|{-=Y9{oablp-f@6 z8M9Ynen?SX5(qRiwot7yL_TTOV|DQzaNVZYN&~>U0rU!)0T9_wHPu|M!YVA7w%8Ac zwcpOrJ@DTuG*5=$S9Q6|uFFI-^bu)S@Pi^#ZZPYkchz1C^GGY)T3a+~ zP7U+=AV5RUc>~-&(VN&IOPWFKc3bHB2k{9~WqZDA0X=%U#BN`8?tUETI*POkEz&CZ z{5z;P*kg%kT8ncb#n4@~oHf=3%~UqQJlsdZVeqg#$^Yh2=*0nPI@A1Tmc$OW4#<;^ zEFac^FCE=hA+%Omey^=Zi!D44GwWO4%bR2*c$d-r#fQ0=7ia(N(BR{J5bdZK8$9GS z29a-0?=sKnCWV*WpY95nENA^}TcFNL6!4CUj;JF_W<|U`Mx`4r*It-6Okt>~&;!@z zu~ZX?CYC;4myTjiMkH@{&aMZ!!z5F#ti@-TB{wl4nPs&k!T8-4gTFqdZHzLDCkPyt8~x5QJ1$=+d`7W7x?@0ah3Rtd zGl&jNM1f*Jz;hGneKvmSxFGQ4MZ}L%YkL1vUhOT|; z`KJ3d0w~g|T%SMnokFl&h?QvGo2>_xRmw(2iuhV!aps~p;r$Bk@T|CBhvAcP-OT%W zWGkl51|i7atip`*pL5E@DO?Csl7R6E}X}xn*NV8Ex(=U`(vgd7VD!BY+L0R zMdshrCfSvGC7Y|L_hU!tYm8y15OQ+HArwbOgZp%NKZBzmwMd;UiJC#cmrAu1p7vv# zjy7zGVHAIhNJM=ejLX2G)@a7J{~cUzh{D@6RKs_L8uu|<#h9Q<7Rp8FaDSYK+^E1O zuJX`7Abd@p%AckMy)^$t_>jHfkAy-VrqS}%80vHABdO<7=GLK}$Qbf?NYw9_-%rF) zvFumw3Z`4G-EphNqfK&po(d#N1P9FqX7pHcw(~qa$9IlQ*VQ$0t38_3h49UxH4jLP z_$YjP@Q=|AeN!pBtyKIx3%=vECO~#xQPa?k_~nws+3ut$%D%#98sY*Ia~7bebe{1X zDR?~`b|7)XSM+hPk<^exzt)y`$$u}#>G~bI^yO9%T>5Wa$9HR3cmKcYI+8_yX1ncT zYnh@3A@J2IspILo_Al;|PeLnLmgpfu9T7wx3Boa>K;ZA&IAin0i7c-e*r-exGn0R( zhW{ooL7nOl3)?)BUysW2+Q=PlB6Il!)!9qp+-S=gr`m}7aTZyTEF8>@baBCZOpb%p ztM`{0xr!voeZX2EKqn3uKJm!thD^C2_Fsn2WeXFBDg0ogB1FIwYgMntgw^gpGB?uS z{N(!dMAdD_yEiV6=}G2PK||j#1vjzaAeV%15|@YSc5fVYFx*%t8*$O~O{2wjd9p)O znZu0b`w7BDJdXb(0C@BJO&0M+}zw zUiF``U>Rd(v7!wAHrU)`_v|4)8OIMe@7FCrpKHjjDJC+?WrQ%r<+5?LF`vph2TEu^ zH}?YLM-uze7Za0X{czh8ScUy5j`Nh-A#z#c`aj(6D?R(`M9VUhd}&xCQ0|asN-Rh(cU>DMKHp2(@1DZC*-tiEJd-!eVzVs$>M)&r?<`51%3(sL zA+VP5qqxLj7aBW;A;wF5hY@_y74sSu*Na}7#6l;Yv@t-zG|^j^yk3*AlEH;nVJP9! zN_gLB$mvP@R*1 zCVHYaK$r9hj;=G)N76qir+*~%m`PK{0P$&?YcofzzF_-O# zd@s0ix0spCDZ=jESU*%)jSSSO?!sKKNygUZmK%4`O_5V&8ZWfH-f+w98(guxS9M8CPZntIvSE#t&5y07 zuBk`xuC<~$4PDMHOg0C+N^rTV%nO|+xS3|rgJl?cSw0s15Gm(whU92! z&A|+QUX@IqeE+C7KYv6W08-NNz1t6G2g3iA4OHHt`Oo3Y&}a!0@06S8Uc~W?bz(!l zf4)Tj5eJkfJrxwS zCaK4MN1-BSG-qu+Pk^OScaIQrX74@=m6>lPEmIZV6@r&B3|@d77tVZv*%GdH-w#H| zr=%D{C{^W) zl=AB_zLssj2%~Nx$9ia7rnl|6hsnor?~SRd30@?rD^JysJ8eQFd5}hn%<1eZ%73w= z$!Pv@M1gm6p*m#-AuNeZVUYfkm#3!(^M?&~Pd*VumPG0qNIAQdoGg?t=B!RH`#&8o zRE=7%C^pqCfLLdT&^5YW?9T?~7E~X#bI{G&?@mPKal&gI+w|_#?~E6QG|HuN65%&i zHJwiczj%`wV6+8@wZOOG!klIzt2Z)_A8Drw(kf6H65I3|+L$)PTdD{E!=5_e#m#dx zS*P;)sHFePZ@ zqDm_f7vJp%zrdGN4*st5PM>E~jthpfcw=O3q2F&Gl7}u{&WLhezNTNqEeUlUj(NEN zEP}Z2NwhZ~wh&(@-4yM6mkyM-2E+SIb@JETTFP#!$Io`g*%(xHH@gQhqd4b418MyI z<$@rO@-N#WnI?h-1C@5Q8hNSZf8_bT+^*@>{|Xp@YC(K2UxE2yloT2$yH>yu)OQ9{ zH}TqCBRiFgQFujttUYAC-`F!A(@-Hsi`@Q8E-aZ#b=5vcx>9z`v(toK)V}iv@D3U9 zuB5gxz8U|BFIEKhd+e&ryr`;vzVYpX1^{ueouR9sqSkeQR_~ZOafZbyT_tb~GUy>hJXDzghvD_cw)v|Hm^gn-aSI zp}70{i>9{H;ia5v*#qE^*G-^!Q>gdJ>yjE^aWDa=`l4QLu3Tw~A1-kJH({J;4r^l0 z)bL@|iwstJq98vlU)rV5AEqy^R-@dCZ(rZw@*D@@E)a6t^@)2r08&w4d+rC@*2i))smCl-8|jp!jJeR_R)z=&x(SspMQmTlG_(!M5IL2z?>{>x+45vuc| zbc*#YM>H+LyODsm+m7#C-a;xo+MY; z#WHMI0?j9eM9^pJR)9Xdw4{zXo1aEZ-V{EgB|V|9$Xs`v&5;fL`mjnva0_+N zr%czY7`4K*2av7>Q+86tux+csEMm|NBKK%uJgz(atGV+0sDk4os5B zgrs}ty%Brn5(fO%iGv-xcBRCQZ>1j{$8{gj<1SJs8<@ZlzeuJJo)uC$zG(lFDie4# z9ncX2M++||>x)RP$kME~p>IWx0}4L(kTdn8B|%G_;YlSGRqlHBRWM#HLdIy^4hRK_ zu@@4iAD@6Lystoy#YM8j`*AZ|7lNHWKNxFQ(cEfu&C!wWsK>B8@A!1F`SMA+eVweH z%|`3pdwe`*U0lu;>NBU<>*EEll_^|(X8nyvselK3sKi?GX1)mK9ptmc~Fau;IVscU#~LPxOfe3^)21O zoa_y*gi5&JW;FGsU&A>BP3jgPeAPM9j*>ub2kC`SFjR=oCoR{wj6c;4%leUAOCDZd zgb;D40LO`6y+xqDtD9ylNc^~Fx0^;J2Tp^hqAFXhpk8z+>%Ex+4?HTIL z&Us*AJO|hb$wtjYQIrb%;-Q4hOLSa(z4B%{vnx<%NfI&2)T47%>eGF`&oK;Qk|1WL zpB}wlsD90XCa7%9ksU3Daw?Hq5{AFG?fCFB!*_getXqvqmf^ihWO{OgL=AOQ= zg*?SzzR2v3OaU?ia6uGNo5|ds$?8mH_@?GoJW`qKhE|>I-7Vne0I15%qbIFq3kZ}h zb3uZ(!-E-QyyQDSu+lrMc<@8kPZ3Q7k#AbF*0<`D`g&?kPg#QcN!SW3XOu2b;S!&{mG+bNz{aExA}0s1ia zrFkQ)gP&R*XRG|XIhmlJPQz`k;wm7l4h}*ku{W*uXghQmIw0O4F(>pQaRKcP)m34e zIp$Ad#&$yuBxg^~y&aZzg~CL7?ZF5A4VOh5e@+r0z&*MfqfU4>BWSMTLs zNd30Izj2EpFf}2@5!{Df^w51FVq2}X#km@ss1_&P(_!%LyWh6u3r5K@zRFof-!?siJu^@}&t%s3@&;5}jgWaah1eh#_ZY zs4iAP;f@%+`_bE?9i6c3&s*27tuNc$9{d!MUqD{o%yWvi`t2(n?Zt5=jf`Q?PTBGb zIGfJ3rEGFZDPLWYj{7EAsUCDh7D|R5ns=1>_**u`I8#k`yX^?|J=-TPE8FAHf^D0B zWbetE3s(dC(w)-_1IOTb$7`nI%C0oKFu#jy>3tW~*KZnmR=J%|Ri_7~S(mKM{AJ&! zuvXO9FZm8Skm*Z=qV^cJ9$*fAiv5Lu?>+e5Lo}joZ>v`~$q#f6bIJsKI?%W~aR>hb z9sm={XP#^_6!y7G7vLpe$xhv9_Y3~Urp90bXBXK7ILTlu?9w}D*GQmS`pu% zS7Q|^*00X7O@}`GyeIt0RfXE5imr1v*hWp#+GU0}j1n~0;>OE_MZGV4hhvb7TB}>A zrV$xYaX!)wK}N)I#&DEY(nF^P^qfn{&k;(gQ1_j0>PWi1t(N_bUiPY{Y3?8Y!(@h zHnJ(Mxb6$#_6GQKBX%G?_wk~X@#~SRYp1c2X7ryJruZnc8?*sl zHXS0x>hMJB7-OE3w5isPnCfOX%<0@`tz&(*4NOA>6+o4|^u}%@Fq8SpFc-Wwy@!9j zteW|(F2LSguhtLKhqKLmrfxXl?xI?pf4qm(@gc4d^O@1R!3G>wvQ{xv$Q_%CdCmS# zrLcoJj^|syn=fOJcKf+tpx~U`SYZ}vMsog>l5IhoF&X+d93%)Eq+#`Iw_rFBcWDa+ z^@jm`KRiz%!Pg#4CaaLUdz2yU(!Oax=H;=+bHYii4DnqRF8P4;DmCr%Nqu_tv`1U7 z1y;;LfT4&5g9cpK&_G#VqTeQw6-i=cbLh%2Q}JHy-HC{{?RtxW6|>vn_kMwS!Mluz^A3%EGMtd(g9q`sA+VHiEl z^ulCGSIQhJ?o$Uor=$X1ujjt(#`F>Qxu{lZHLxhodT-QvJIA*AThuYCu=xl09_VD7 zkf*b|qVBjcurP{iiPqk764v~gFh)KW#bf9wV}v!`LyaRMrsaH%QDTk)E>kFr z7Nh)oo}?yl6(X(V_PJaf6~i>EK^7s7$olZH_t$&2R`gfW`*}GmNvgC=)ZU2K$KIAP z!}BiqTNw!sA_DTaVs^$cz^xzgXNSrr^;Q+JN{;+iZC zaX0AjBas2s*2DvEAJ|n73KNDBxdZNp@FkpldriM4(!(P45}a7kniD;u-tzhF;Q3{H zrPV#b20^ zSG_45`C|+cJf|;##Q6Ou3!wA#zmMWpFb8l0HJONl)M@>P^wgNCO#8{-JtB@o66lL5 z9E&1X$SDmK!mFJaEu^VMk2#)=%WG%65t30%I%^piWKy_u+y{5`$di2T@g5)x2QKO#So|GcB%B_#R;}nf@nu)k}e= zD>cy;g)!V}>NM_{=@S|75h*wsi_0Fzac^6^Twh-U$t)K*E9;>)hoaKOA~E3uKSpukK7M zpeITJ2N;2tzS4X&r+qt~YNwzG)8@3t?iI{#SX_9sT342Wt4yBlx#-jHzxiXs@jEMC zWXas+m4{y{EzWSQ(nrTzhy0@${K!i$)agsN?CQuaFmg&B*X9W5Hqo>+tV=$Z2gL2K z7(u%;iFD3*?fVb5p!k;LCRptwcqLtNzNYJP{@9sz9K@_xjzUfva$w4AJ-Hv=msnxc z&h`|V=R_Z~^A>ZWLdVr4xDxVc2qA!8Q>CA?X`}nbt=7|w=svT5+D*da;n=*Y&l=H- zo+S=_!##1|ZObPkFk#i%V@EE-Vqa)8UrptFWP2|Gj_;3vR730z+&YY}De%HB7tWWD z=E76>C#}nt(36a-TIwL%Lldg9808=K-vI(oPei(QuIRRErY^)m5K3E(z6os`l=dyG z7D{SoxLh>r44@aL3lKsaRgNi@bl$$CAC$P*4m$P@$G*mxz2R~RxPZn!olL-T0LCGXR7>s*N+-duLmyWGx*X#4;ufaq1hvrV_t;KoMUSpp2GMsND!x}UQPN8NLW9uF$|C0N z%H9|Q0fUaVdljLZNoo0y6|a-ti7aB0tICqgG2MCa&;G<&^kuRKy>(Fn|^P!sk_4MEtdgd!HiuYTwAMDh2}_VUDl!DqE8Y$^;u)UrQISWi#j4P30c_m zSp(>p74yRbXtvC{z9GBdWojp9i5j2(#BW=-o=e6MIyyq5XQGc%Q;YTHA z&bmFqvDRWgDaL{XM+>Riqx_T|s=@}7pvx+8pL3i5&`HC$pfhw_dU?qJf9oZ<_BGYA z*pQd{z+gzvxVkt=mM<#a%NLxVvDK(vN`T0X6MGq_S`PmpLGfG>z3m0{o2En;y={Mb zcZTM$?b^NJrVSmL)N3IlJDDZ!)13{xfmF_7aI_YHnOE({e=%2m=yM`JqJF8Z5^Op( zXyy^aKaE3a5e@IiqVCef>z#N6MD z9!pQ^7rm9s4LWz$$A@Ak6Tc8;douYrki8wo#~j90mq6-;kViJWGLdc8iN9R(Dp6!T z?OqoSz()RYM-KI#WdGYd<=3BKV6~PeaPN`{Ba5DJ_r*SQ|Cti(`WT|gGcDpoH=2)9 z>6+o~4tyI$)%rq2Uq;5_YKFO>s~Rk3`Zkx_y^}^FCu4w(q;U)+Fp!(VbxLscyk7@N z##@L$R5BjFN`iR4EkW5(Q-;9}1nK+A1bAPk{b*hi+20V`+TwAJd*Q$ zbqm;wbQ%ZpON%)nA5JZPlUKxj8;k98&(~q#@niS9KA1shZLUlfJjFfbv3Zx|hLp;{ zZl-%`?E@VyO-4Ez~ePjLT z(4WlF;V!yQ@V)h|ME>nj&}GQ?;pP{u0bf7TB@vY*_+5yOgd6O2?pzT>Uh-<5+R8b| z4M|v8BamBAQ;AD;B_-d5;sTJ}q?VQx_lv4@hf=-QyZ~!w$wthz8G&$V$*RwK3$uvz z>o?_9KZ@5ChQ-AgB4MP^F9$u(!GJ zZ#inO!uA9Qza7dikD2{$6$V^T&V=hR)@)tWdHd0#$FjEfT*}T8J!)f{aBTq{ErvW% z9uA|A1JSx3F7YnCb^86LF!+s5QVXs5_Lr?Nz~B+(%q8TpEmrYBY?{IcRg?`(Tf1EG zxWd}_*jtXf!X-n_q=;^CUs;%%XPyi6pwJ`Qd+(z66n(~T`3p8e2Ogn4)QkJhkP?*b z-mI#M?Z7L-#lBjU)YaaXRO0mUI(usm@t5kII+$f<*VHJU7lQZ`K;URL!ll!1Qil>~ zXR|KO>&dm3M$@5k4okBNL*WiW3MIJ9e`)h_s4^AzMZe*Z3iMAQ2C3us{S{<5 z!lnBuPg7U??&$fRZ;&4Izwi6pn-pTJnMqaHUO4hcju+hN=t%t6UU>)Tm0=p;P+rDh zIJf)rA_v-pmmK%-NgZCaDBuVs!NJ9j#X^N7qKHHU-3)huEKz#vne7)s4=rS>G+)7F z8j*pp4Zk`Na8`&qQC#a&LlQqSc&`XJ0%4ZM+}pg+O{>xt1kH?#wb8aM$Ng^=*0gic zBrkrzd8go`Cf&UWP=N?40JhtqZzSb{SB%Enn{U!<|{9sS`KnsSRc@@Zs2(!#F%xzSUA zO5OXeEfZ{tSwZ(yx6Xr=^O$!UqTfvOmduj z$GYmqs$RC|UqaV^boYcWp^_~%V8LY6UeIBCEw$>E>#?GHXTUH~#gy7Lq0R zJr3X*qKas(Nw7`l+w=o>Kml&Ds43&hMhweS*@1Ph^Kzka-DCs*5Nr9#KEpsfWGpzqcNJ;XKEZ+-(-`j& z-h!mjiVr(JSfFw1vSAt+E`7E22hB1Nk&d5#Ay@+oH?WT2)I9hUA`6|;DMinf44 z)Y7%#s!zH7gsqea2Xq#$&w*iD>wnA$NS5g9>)O@t>JnL2eo6R|^-Jzyl{=OOvh#Lm z_ctwfEve+So-DaWRUWvD!dUPlpV^C9k5``8iFT1w!OfA-Mt7|VU?M>-*CHa;A^=Z9 zcxMg?%C?dHb**6Z9WMW7dY^dshhLKJZbfedo3bkT+C75Ew5JC%MdWotx*D%s*~^*T z&)j-KlQB5+UC&lC5*{rvKyq?ANM8+me{wZCNue~mg8M3|14{*jTZ9H1^6LImIj8}) zfafXxX%dwELn=9W$k#8`fJou6DeJ|#$BKJwop14N??!|a)jB*hyi#a-b7ysAbG=(H zJ+Dk&Uc0BK1cIvJq80go|zONfQ)S6+tVw3S9v=f?N3aYt8 z(_It2R5+!$S$^W1I&e$Ag5Kr7~ z0L-(P+5h643`9XnMe&hdR3T1hiQoXozP?Uxnay+!l`M&h8BU5B50?DW>U_=PfyP1J z$#6E_mW?3Cj#}tu1*?@3^X>UG#7;Zpte*?S|8Z4+Tz8D$Vg99?Qmo8mR3K^kcx<*QA7Yl?pZu?*#a4f=-!! z$fOR0t<+xPv^67ss9{Pg`~9)ov>|?%AKIwcp$62J_w#x!4O38`|Du8eaCe=`Gg}_Q zT>TuXXOm6H>Gx?LB=o4MF)Mx>4{11$&BLI8=B zW8ru?pj#;ECOd(3G8*3>e~YOEK5oE?^`U{A)@?lqKJ=bAQK7&=jtfxqjLhW@q~N z8vJZMjGD1?FQ=*2DX6E4DdV|oZVwFbOR`x-X$;uilet9pj;n)6DwOw6Q~~`FM2v9B z=aD+Dn?Iy@=veK=x50SdLGGJM-GZ&?HGkGSxV93rTonRN*}iL6P6@eem<_YtEsCZT zoy*cHuZvtq^%;*VR2c%M9EY^-FsuJr)ck*BfqWCbm#@Oixjy_%)Z;gWF(oLP%S&#K z`#UQ7Wc6Ii{bxjmf&VwIA3b&OOgM%|0*S%?y4~VT3J&$`c-VN6=gc>C3K?hXak7)O zjtxF4{{a&yb}Qzwu%6=|>~{uiM1RqXjDp(tK)Yxw_JNi8hCcNLS1t<@H&n@2H`n2Y zs<)<9l|(-m273U0)BwegnX7D~b{Y8dJ1e7g*6axkP1 zV{KhR7)!_V{SZT}I1<9PbVXb7B@$OG?B;omf6O=-y83jyZ59==+38>wf0u=Ir#UvW z4&1gAcfNr4o3o@LvU9ajhumHjZ?uHFSySsA7DZIZBsdMdj~l^FJ5c*4yUNU-2$QR`oup0GfY_UzLaN8WfDxd3+`-C#nu3oXX*G~)0`}=IZWtQIh3ik3 zE5G6IC+>K7p>?bsA-k!|;_mOfC(4yz=H~3_n5$GWIm>@$2>5*30HanDsD9og<)!tJ zCI0UBAt4qOXcrfFkj+omfF5=GA!zOXWN;DdLbXM|(^7~%SSCD5qBZLgY0(f6x=wa1l5uGvC=YrAeX4ff3oE#xNbWY{>RPPu-^XN z&J{x@hG62C!m!<>5m(bvS`Og4GgNO$5uT%Bq7-p0#rSyIq*6^DSKhMU-f|1cpXLBl zWO)!1^NWO8JGR`~mheajQ+U8ftUD`^M`)9Gd7m(0V)aK9LEB!r)j#%Yhi^^FYNw;L z8iU~z{;MGd!N0}5$r>9ReHX`7`A>ar70viu+x~J_2%gPedj9tnTcLYTWB!afAK&~n z9>I%jt6L)#T~T-+PE!JEQ2>$x4&fiqU`UbHN0 zs~V=+)tG_c#j~i%7#zr*l@DcKQ)}p!c~T-xO{Jk^_gDwH-X6o$>iU5Ej!NSA*{0W@ zA$ILlui4MmVQR>TTyDR!licC>a(n~0Q@DctBJ)b1crg60Oqd47Vhwiq>-zlU*vBOY z)L?K~8H9EYaEm)wg>>U_xoS_yB3NdDwW;zc$j2!T9}}MliYL8kyMc{k1*-EuYf}g! zX?tsJ77M2CqZejC?!f+3*DK(nuso6CZl1EchRb!XGPNR$4j(9D$E!SPjd{h)IE-O% z{zRFag$%j3m)k+`js!>0PmKG|aC7%PT9S1sAU}3B3ThR6`sgfT+|d{K-wL3v4aXl+ zQ+s}jca6Do|IP6NAbaGsFTBvUUa(17mOTfoHP1kv=tY%$S^p)91pH38VW6JRNs(0u z4rM>)_&EcSmQg}_E*@*SrdKV`EHJ}2v(VafXhen{9m`X%$7n17Y+r}J(W+Eikzw61 z+jQ-9cgE+UYJEz4k!e9{Gl#r;9a9$|Mq+>GyB`hBbQ!0f|7~zctk5f0FaD@WNz{lM zd)$7xd};?K4#Dn}r}WX>o+{f%cSdmvv8kYr!>nC@!F0PKv!T8xuMyp<(_mM2>htYc zHWadF%~aN`{9xYU2ZIi!`1zSjF6>mN_Zq)sJCn_D{!{9FJ%s&_5glR|KTCTkMR#p0UM<0(1r9A9x!q?+4V!KXA|&u?xKpXO%r;9X5w zW5wfhE=KbKizk;YXn23TJQT0Vhpq?-XG` zW~{r!DBBOETWZ$1Nc&|60uOolU)?r4c5DRvpb>Ok>V~=hnMEGrVyXWXVD(=%+BMYg zE5&OVKKX|^MHZ>ht1)IMQaVwu%C@Hv$tMWQcsq0F)5ju`5ws^92NOR&k$kj)lj;=ToCtI>q&0^AeX`Bwo6Ya zgcSwtaYnb zI^5=oRI_*H27*yC*4;SD!ERIYG#a!v@H}cZ_D@`1Ak@ka>?Ttx?XdU@hL6@tcP0(z ziuE0hSS1Rbv40Gkg+bH97V^6>$&MM|e@ytew})9$%Th~IkGPAZyJL@;l1jWOwvT1p zjw)Ia3yL#dqU2OF_&wBrjD4$kk+TOMl~_5odAL&rNwOPeE53ImE7xOfJrhP$3w8yE z$=y(Rvo|>*tc#cCs?$o(_9`_z_qxBBY>OCm)cGYpkr%u6@;nH812_#DFPkm=o)^~- zHIWC?`W%pUh+p+!n9O`vA0!lE5HR)_B)%BmhJ>CAZd1E2n?bFwfinY{kZbxq%@AKjTwc{i$Ew5S{!mMF8GHRVWC)-s|^+T#V}XSkNBICSQ|EM-XNqqroW`e_;~tphsUyCVnp`P z-2frJ(&}AXXQ8vtX6ZH6#Z&k3KiLtp1fxm+++cu1^q=>dg?8iQD9t--+=lJFon8do zFlXd={0l^q3}#quGws)UthmzK{R}ttj>{kl2XlC=+${#W&B)CLVY#2WUEa3=`21N6 zeSf_?d{F#zpo^ZM)kZ65^v!R%a!B3*T@~(|#NvenK<4Q*zMShqtJ218 z_9+4yO|qV8@6q|U_`mpI-tdIw%~OGzt&AVJy9MNE5)gWS+_h=+O03Y?%tV#VOPX~P zji~_p+x;zVe$j7Hr*b*`s>>fIDr=x2Lu6i8#|A0(%^q3izd7Bm`(lOtq)Ipd&(W zq!M=U^q*nw2idO9LHEP`Hib#MFB^eL2IZ~$Mt+)YP2J32{BTaXgYdtbe^)Rk@bCJO z_`;p#waK$-g^eZ|ZG(IN7|{VQaN#fRvDi26KSyP(g;%88^JVy^2d*rr4TnX6ZOS7p z{Hrm1`6_EzM=+#Uk3vn~S5sogItg-tD13C`%5?UFKu3#0O@`Ci_QY5>>C0^`k*A`j zv^G?*!bveuWOl|n6BCDvsWcv`xJd0(jIg;fz(o-?rFWs)Oh1ZvUA8OxV}Q&IPf0w; z-ggJ0%@JB4(Y9xPDweTK!yZ{ej89cUC!@1xXrA~K3D;r;`0(gK<+#IY_M_ir8vlp2 z?~aB$|Nc%yg4J7eqxTRIHD+`})I_ht2%<#v2!n`TNAD$~_b!Oe5H0E`i6jgoS`q{q zf;=C)o8A4L-+uS`?sJ|$GtS8|*S)XzEwB5!3g_##by28_aN@Gp_X@M`(y;0zmREx; zVD(uan79@mZvk|W&|rX&q-Pugr=TiJ|K(wx66aRWhWt)_pEZ<&M-KVwKD2tINu4d7KI#PqiL?PYYs9nXq9GLu!IH>;H!50$sB^lU;XW$-m%@h~N4{Jx z9p65i)rIzxWH4l0w?;e}mD;NifpY^|=bxCGCGhm$x+|`netSoYYxOEjs``4)T{;bC zZ5e-04QBd&Jnb^6(#K$LQEE-G;TRBtf%vCJ7m6{n8-eW#w`)32I1&@sovT}C+pP6C z?yjFs0Nv6$GlA))w}pUn8&Ii+ z(i*+aMlas(*EcNc73j73nh^e(oB|uzU>wi#V!@?EjprUDtu~tq%igyai2p-GsMBY# zHlU02623}AQWEbE<};ui*xl96PSUw`iz<0T4j^?|<21&nNi~EP_zi`Me#{rB$_Et3 zJQ+29e(RK>>vVSO&`F>#Mpv5s=EF|cXP7N*)m4i^itC{Jenzw;Urb(<6)imc*kCe z%_w0-*63B4HIV^4&H%(|R1!8&nNR!S4Mqn^`sHt*UfA^2cm$AYcyH2(8Ux4dpBot% zyq<0;dZTkb$V}TT=>GPf=}z*yzpV&J-NJ@o{GF=`wwHJpj-E2O6#FD_ypEzClJ)Pb zyeg>&yIlYczt75&eS3c&CC)AEzt3+p6UJcHl35vQJZ$}rKKv?+N9Np{bZVsDu0sYd z&o$tnF)Ir};+w=gG)_CRQo}jMBpk1QLOKl+;_$$M$y8)lrAH{&4 zp8#TXo-rP$Q?mPY*!Y^+6ihesilO)Zwxm@pAcOhv-HEyuPzu}5(RpvAd88~{BW%mG z;*xDwbX#Dk*$lOidIu;eT&1TndjMLo>P}mtsIKT$fHg`CjPJ~PpSpYjfI%GC^9}W1 zri^lGzVyP851%nfcQmss#P{^sXSbs*PY2j1iTBKs(yxDP9Erx>&5*LtOsjs^%O1|c zaMhx5Q~d7fzAtAa5_tGy1OvhsYS`rWDsFd5ey_F*p9#@jd~Q3Uwq5j#jX+7BFQSrb zVQP&W2XGOkIq3~~DI(cvH1<^Zc+S3rZBx&hb;Yb!B3eIHnl$tRyN0wx@Kz5Q%Dj2hRt^ih`0<*=~oS3?2fkN)gIzvtK&CT&(-?jj5UphOqRmE_i-I zj*dji9CD4k<1sK=AJ4fZ39L&6_HEU4+*SAz97T8&b)fHdnY~cbrPxEu--Cy?mArZG z7VATCO10hi6}^0c9f0?si}i}UCb_ie`YDB0VCv_Jn2wSG8_T!N4ri&82pfS>J@IVE z6E!93sL0kFgM|`z58K{@0WA^^0*|lVxZM@Jnm*_W7S}C;r_Z~%?=fZ&DE?eJ&-&%+ z@7vTWgM;ld!*DM#SY*`WZxT)l(oCnoHu?-?QuM_^N*zg(=qv8~Gy0E}y z<;Q?(EI)-z8OP)=gwBz{7oML>?4^WV4x5!1TDzR?C3epOBOvFC;!Zu8+**BQ>D@TB ztOPr%Vp8#&G_A|8Nv|*AzVcn;TcXprFD-SLGV)w{5b~?^U^EXcFU=flfB^@@W1T3Y z{El+|9+igyrGrymnH0D*#_RBL+M98aE~YcD5v{MzaNx0&sGPk{rLS_bCh8dqOk-(; ze%HCF z^vb-tyA`ZCD}>d(M)XUS)xFdO==36|irmkIi(>Wir7TqPVR<9hx)kTF2j3|I)&6TC zrsp3%=J`|Qf(|vMa1-@;bl(SmSb!i$xW1TJnN!I{KEt6k)08D0+b{OH0gD)ffLCbq zCywY47VmlSN^7)XS*p;ox&QvM-|}QQs5WYqx{xeBudF)?$Q^mJ12*02>TlSTSKswd zX}8bzR&1BP;9o7TyEy5xU%(+cXCM%tl!pNJ%)mvyU&f>5^(=Kv$3zWLlK!L5e|&!X zu$MN?R{dlBgY8r%qw{_!*V~f0(Al1qWXJd8;8W#idyj0VI-ujm*evqF>A}qy2C-hJ z8Zsm;iv3*)9%Y(S(42wP9hea5bi^}}gZFL5{{W0gQ*>tJ106&ha(6l9q zWA1sd*bto@#(iqD+pz!b&D1hZqa^7g{%W`=6ye`fVD6xq_1g9BhTzra{pAQM0+6SJ zER)@AB&*q>O2E;GC6IZ>I`nC>9?zE$G*<=#1Nb@`oh_BTH`l9^_*~CLPp3i)qir+m zBodu?YwtlT#!8y^rTL!(lRwq2bGXa_@Ou5>jus9eru_&+IxqRkO}e9o4~D5@z+%rB z*Ks}|7 z>Q?ZndA+~OJ6tSRbAllrN9B259bUQ;pca+41}xn&2LY;fziRA6uf$*SDqQO#715yoeQPRqYbJd?S>c|v>p&?)vcUi0aYd9)%16{y*rI?`^Dn?A z7@3?_CcWLb@U1TfM=kHGgLq1Hv!nfh0EtK6GWJ4$2>333a@|_7{k8iy-FNhN{rz4V zwp6!DTfMmnG0N;}yg$jI8_SHh3^+QbDMuqYJ23f;$qoWpr%vQ;&4`T7foX^9iZx!Kjcz&Nh=nU*lrRJDzU0W zE>CD>6-?OZX%oerbz|fP2*Z}yhwMbqEA^-3c!_y%tS7>p?o{{}9*!3I#b1*cE<4%q zwSx1>okb}G9OL*Ts+_BsKH7>fp^6pVzMWkH6a#T5hJ3|Q4^y)40~8$wiyy>jh7U{Ltt`<}Pl~7;4@&$TzsaZ+ z`J7FICB*@}js6BK%&A-v!ZluNo@)Ad= zYem3%a~-Z=c)T6H_GX3mJ#ZY(P!>UXlAI@v%^zzrkUdIQA5DNqR2wSpg;8`{v%ler zE~z1P(9W{5d}bzTQ=ugor`Gu9=GQXP&QXOo24tT5DqK8aCy^CN#RnPXcnKMgtHj1c za`v3!L|b36Gga~Da8@HKnI2@M*d(WwScaM6lNN7m`TY2kC zi+FE5{N_-^97TkIiqosy@0Zm!*Uf=gc-BJko5&wV#)GuW6rga(7PC%L-Y5KB!(K2chlWcVHKR!CAAthEr( zg*aSqRIQ2?ZQV)9^K_hUu`{$r0{2gF2UHJge-$|`VxveRbx3j$-j9)9-wK(y4M?m< z=~PJP2o0!ZhD)n|_MH$^Wz-3|he*+>6W9K@E-2ycd%;BVxL~E5$3mx^SC~LzxaKrV z;FqsBw*8c}<|Y>KcT)P354(@6b)6rd8~FF{_$=sm8K^5^&Fj6=`7P_(86qvp6u-#> zDr>hs6hod16hmFB$p3$5UsG~4xsJt)GL~hB~J&^jRbT>}kfqkM??<24)(RWy9fvi`ejk&OvKc2BcU-9=gVM{bCodQ|X<~Jz z0JKqMcVW8*%nMGys@eu%9Dc|!l9g%T4Y7>!7Mq0sVa`C4^}CQKr0hZwp+!t=)!ol* zZA=^Yiod?O2^>rSs!0DQdLP>EKs5>tvyPdF#K zf7eL6q-5r~oULo_Su#pz&hfi2FGtDZiwr2BFgVQFLTtRw3ib`n@jkLxe_!xX_Ewgd zy|>Rn%JQ%IoWKA=czY`THw85&Dib93AGU^;2$RY1u(VO%npu$b=L0c?C?S#`3FMEK zAyFX5cO<+tEavLFT&R5I@WQhg@fzbs=KewG*ZoO$j?Yu}x#{cu3@O(eY+sU1!Hr#MHsUv%1%yejy zl6*9qQ#lF!{^f|-f>fzd(b-GUNol#p3z;%&ww6c6#DJn|-8$!}b@&ozk0mq{CYl1< znmXIH{xPgD!W_Q0QV~%79?-DP(33sxhmSW#)kPfm8HZxtb|}`dFJpdwcN&J@Yk_+u z)jerjA($)SGnZuWNT2?uKu3yKO2F@MF5tK^4J#RYWDXw!1hD36=P}XYu#YE<0mlw^ z=}!+{UH4cUl|gxw9C7|CfR!s}>GDq--RDD+uN>!s$Rb$`HUuGXH^{QVR7vO$sS&bW z&MGG9l+nlnez`S@*yXzdar=!J_!KW$;(!fFMn<;lb@U4t8fV*a*{$x>OOxq9tH4&< zA3@XCMtic;W9X+F07xKU8l!4%n;-F$H=8n@&XAk!aRSnGO(z-?fYy~Y=bI;l4gF}< zjRpqgrNk_yr70>UtNTfrFUn&49eJ%H@&@`W>n2u$@B7Et)<~n^nzHUr7PGOUH+je; z<`csSWc>FV`xR@vCOI+(!!D_tp;9{biu|mqicbx9C^_^$l!PjSpghm77RfXQGi z3(n-6(EVK&SvTD`drIY878(4l^D9Q-x0g}&j%jQ9u&@0FLd+S^l2Zy` zVAMpmR)+-ybrNPQz1LrH=9cZ*AhkB5;~wLK2_8=yel4!<;4}FIZeVrhx*W-HmH$bT z)qX26-K$ad4PX4)C&QPab?I}#AwE+d4+YHtcPm(Q)S?Z=%@^^;6M07Ltw3Rlu)2FA z#spgl9i9#v%medF@4u`^`+6z&$ls38ajN5x_IiP`HzC)DHNgI$NmB=4tQ`nIlHa8IErt+f`VNqQCH_vE)LoNCkJf{92Fl+LSs zUPzRzmNkc@!*))l+CoLZ=qb$8^B!_#Jb|0zzv7ZN& z6Ui(SJX=1vC_eCHjDVa8G8uw-(hL9HNuG87wB20N7S2VB@3W6)&Lp8HK3+qBc9!lU zrH{l)!b+9|SSoFVq>`(7Y|3I-mU82+WwK?G>6lP;1zZ$A3 z7{^m+3?x{}y*V?v;=Xo-b*_9F3mW(4I`>nw&bCtu%qv*MI&oIe>tmz#6Hm1AeAQ<~-cf#&ZXg`IIRbKY|f`aba3W zzBY`ef-aQI)SvC}LRmHd6l&w9b?d|85}1jto~dxw_zU-HT8!-ieT#I^dj4>Vv2}(` z1AoC6h`I{899WzC0PJJ8j@LwkomE<{xFijE1XGmAJ}D|F1oeA($>*?N-vVuG@l`iK z=axTZ>MkzF%j8q8Q{da3W=rI^C|&SMyv%qpQ103U@c7e!TqkgB(5Tc!F)+gak<1M}KYIveKC*{g@98^EL|j0O|PVUAXS)RvWzza4sx zx%`cC?Ce#r;BC?^D`Why%n-hcKK^=q73rP98m>hFI$vy093MgV1$yrg+0~htzy**5 zs$4?sxlDgK`O#LUB0nJH(lVZi8Yzeu(mNeVv5@atcfy#K0}lA1>| zrs$`!o=}$Z0(J@R0NiGO5fWvo#dpT1>!r;(5%9aY{@)Sp(HF=@^;_s?${a8#m?>)6 zx;OTo>e8d$@Q`$35Y<_sT0Ji1c+>b~S0%!xyMTsVER`0*8!%jRJX$VtOVqRia>`z= zLy8aX#If7@AFeatsH5eab|H1@H4sIEvVyN=0S61U6}%VDO89|EVoPvTx2&jo9Q&WN)26U{JMi}pqb#tY*(rj{UUJ9%#;sq&5?^6`o z3xBOO5~-_frznMO(v~nVDFxJx*468Q_G&lvsF{M(g+;G8Lwx3UBB{0b$b^J`;`in+ zK_)+}9xA$7fLoByOsJ#e@N{#g2t676s#<9h(0k}xVfTN z9Xa>dc#g}lzIbVXty|@OwX^Qn278JhS)V0&mzSnKHZkBLFCs)cpinToY4X=#j zDX#3S#2?_3EBAzQn zsLZ+g-RWbrczkts{nenUmw31UvEM;N4REE!-%FFM5=*T9R?tzERG@^61MD?XXYVQ% z7ST{2DiBRp4eVhC>5#$WsjhDmius;UpvobBn;yj11EP`wO9kqRs<(|qql`%5bqO%= z?ZMn2(!kAz0a!;_F1(05?Uy5Z#ogO(O1qbdQ9Qr|uOf?eL1!5juI6o6YilSI{BzWVH34T~*Yt@J-b^ z80uq`J2ny-);nJA(|urf(0?>?yzX?B>QTr##VU0R^D|j4Cr{h2GW6k7`ChJL6fRz& zO~>e98zg8qVsA+2nIc}Q_Q8VKuul*_%x-flD1ki3eO+?~I&Rs4s#g>!hDhMQJT{Q^ z4zZ*-x={fU-7X6TgG(9#=+wZ8ss2#{RSb~^L_h1Gf5LW-; z_E3ornpaLyNW7LaN@PpY*zu&iUp&mH_kOl2|c)ODKW`r z9l-Xo#BBMHrIX#sZUK}K^=lj=dhw~FE)hrnZjqoi#qJPHo3FXc>|YXmf+_xQKeYh< zD<4b0^hYe-G9TzqXH}Bb#3f-gC7={xypc$$KGKT;^p@wW+~`o1HOFLEM$QjDlLn+`1=Sdv z1qi!?Uuc+g3}caW$R++jBDSqfdP>J#BUV%*LEvF!N*V*d&BgGJ!qI%$a@ZQX>Jh$h zgKtl@`S4hb_5rQYtPvS@jk$7!{*Xg72}$p1D|EKaUHNig{l(Ezm2kF{TjIV)w*5QZ zMgO>fuP=8yGN%2Nc2CaY7xR8I+9>Ts>Zp&uB(VGp$bW?Jze1Lb!n55l47lK(sObB+ zi$;1ObH;068C*ip!;?2E4?u+fw+|65_&tIjM2o+rk3>bvSXZ$5|Uz&^$vJ; zJu)BSi`J9F1c&iQ!wpJSyUMRh6w1)~DIXY97l0dliy?mS@~>g#pA>r!qcY*MnLOMw z*Bi(}wVc5CsMK(D-{d7bo$R&x;#pf4#6fK`u^f@pll}p#Ypx3w_CaH;cgPUN6}*QL zuLl_GYxnAF;u1)~Zh#LR?BvHCj#5N@Cufv(?hlEqdYSK&A4;cgK?kC+J`j1>CC%fH z3$na=5XhSMJM>(Y#n-44XXDILyTE;C0Go@`#?+qvJ}`@ z+tg{8-Tj3d?>!S76(49L%hxPVH@p=aadLMt$OFG`Jqtp;amBl%i zM%keoeynTJyv>v*{P4|?{jG^EdXRSoT zSzU~%wb5g>J75^eeoT$U4jPHvK+oke z=h#%XA1zt;@oJx!fuTPu8+i+MtMjzH`tgiVAde{kG&mp1CAp42^3eY~^fb~2sVeTW zQc41u5zSZRdyd(tOGJ+n#eLmmCmqH!6)J(^Z{0Zh{%EE-2_oT!j*(JodFncH{rzbP${&;3*zhnv$SGFqPhc-P($&*d2@AQ0-%RfQc ztKgtUz+OVuV=Av^^jSKatXy`luQ*(l^P2r=Ao%pMnXf1sF-v~`C3&_&dc`R2X(P->oZU1nqBpI>^0 z_B;VXuN=>3SrqCa8+$&!KAYcadq!zILFu!zcRKxDtmNAIb==8+>rl_e2x&qvyOgrv zu!t^K-epMdG7Whm*mqZ;iOe80yj%+YDwHA|82a<~==h?8orc<4!7?YPkN03vhpPrG zo~tt^H&+UdM{(AiFZOhav+z6i9Im}|U(x`-7Gd$j-gR*%$&pKaKu6VRG(#AhLaJVK zvW=FN0TZG&;@8J#L^CoooY;u zM!;=1x)A9MGWJ3q5X9u2yey=FT&mXQol768MUMew-hN8dnJ@LM_UD6CDgr=obP*CFP-Q02&HwNWSc(b(b~H&W9c^nxPD0-bz3b zMpoi;7&CSCEzeVy1ac4cfuc^|UY(D&hC<#aJ`w%Vnwp@^P?P7(+eN%_;;p5y&jv7i z!v~-Gz;i~~$7~>_)*U?(F`(ZvkJzbQ28!S-Og~}yj|2$h*8tdJJO1S}N;Mvu?<#+J zxBqh|@BAl@&}TY%kd4=GRX;N@7 zZ>r~1Xs9pBexRf=;SxKq6Y$(#5zE$chg1JZmW{wPLBq+F%ym#@o$mapCcsZe!jHKF zX~Et{s2juw=u4uwTBG;Ivply=&Gsw#SaQSe>k^bgVlwT7Pj{gA9?p*)3p`7PEu}TU z4U*Q^X4h9M+BO3XQCC1ml$Vy%GV5#`&;@9;BJtN0+1rgJl6eMI%X0Af3IZss|U$1b!0p|3d0~T-JkoL z^6c+yhEwL4@KM@jb!%}GeIIoZN_AIADO+RKl`~^mGfFl_q=4%}9}_AqBj{C4<8m;o zLX9}^HDGR=>Iac1m_I)`*zsCkeV{YZ@wH=w?q|uVJryz&?y+>vx}muHTenIfEOuREr*WCF=3EM za@^b3KfA<#`>_A*`yX_y#MTnS-xBi@`q2hHdS5mO_so@RSucvYhc!s{;t!fG$6Jv4 z!FnPQ>MVEBl@il!6lJWficSF9)()1_)fhc!GKS=q6u%8aD-E)VD3b17pP=Mr5pyGb zF*!CBUQShDy6&m!SzZ9B>y_BCn?ThTlHI51wHk~Xw!P@LDV!)TK#|&FPVh);(&eji z?(F3S;*j}!(3)dgt*Sb`JXu+ay%mxAhe960tZY;KVaNA$vVA8sT{as^Kp|d_i*Lv| zos&fL#mJwsT?oQ0Od?hKh>I>(kW}Uk zyes?f5c;o{E2l6new614=<$C04fUxa0+t$;@cSWs>sISS6^qQj^pLZRjSOgJvpNe2 zicri>QCCR8hy6`pV2W^7%2Kr3HbcY{wDi4crGaYTF1mk}L7F+CTe%U-V6GI}ibt*i z(2JqV-Yl>mTa;G)k>BUdEb35C^golO9e`_71Tc-cd@cD%&7FeVHs6i?!vN;*zzM*x zXUflXzPxvs(K7mSwQcttqQ)r|MHbc8?hb?7)hX>zHT^GU1Pue;tSALwRz;W&fW6N3 zU6mO+Ck)Lv2~>}x1JiGFZ3{DQd4Schz@WqTM~C}N#Ur3QX(AGlh!L=;tv`TMS$4D! z^mN5uoz_~iBp41U#61n8HLX1O}^aW0xpI;C3lPBCYL!X4=5Els5nh&fa3O<+Po;D{FOv~{)oMw z>5_ZHA0GBsH~Aw(|F>1TnSo&oFCj|Ovcsq)CRX&?m3Fl&y(E!zkiu8(>$kOw4@WWg z;o&wztR1*ipyj--0drHuBJ<#-(G~}FWsp__qXu_=%Y!DP2m83hXp`Ndz|w}CuPcKw z@xk=?KY&Ie&>o+$W5Y6NDDrHvh1kS%=e=g>?Jz8ESws*lc+BRUKye7M-V>HzA;NW?p z1)xz4D)5V;)#M|i`6GMYqyQ@Tt)2W<+kcDE&rHq>F~5-APad=gX6~vVwQAE=6B(=OZU|7{BPHwm}=l`h=o;BADVnw&zueEKVar zp~iPTQc!{WMMU>Jn%8YT;fAVzDeP#aB%mm%W>c&}=b%`|HZRKP^oFW**4Gk9-5yYL z(E@G%|4-lkc;8YcwrwL5+$Y5|U?#ex(2Jr0C3SeZvQI_}@^`t{FomkLpu%eD=Ja2X z+60@avu+d0knY}^H2TKLGLvJbG&s6nPyC~mKq!r#R479Q@-VHZog=2Z+Z-d|qO0Nz4JuB&= z^N;aj5rm>M@s-^PeM@vkj=lA&U1NFq&%Eg;)+uQ}f1H0;oS zTdFWt|Dhgef8J7*Jt_?^g&ccFlFjFGIjRyEPOlbPAIe;i!3UqoB(oAWc-D;q0w?uE zLRh|@{;*dswh36Ccg{~Uc^z=*g0ZROk4L;Rl}VyjYUzrUxd9~l&}G-A4_ML2|sOKsg{2Y|v5RF2GPIx$`$4oqUW#g*WBaaA#hwfiGg z{@)1tw?G>t&32v#=Puvi0Y?AIlH_SlxC9dAY|WOO9o~egI7^PHTKMFMc4bTElr`PQ zWG@CCGN1JF8XwPc5pDa@`Wg(jPxIO*gFKU`7TE@lJ(p7WEVGSJTZs8dQBG4Q*c-G* zuzf6mrUN_70~ft6*dcQ@yB?KRiU+A1) zPJyV?Q|h%;`j~%3dQxfK!2b|v?*uyP>U>nG>2QwXwBMk6YknzbZ<5LH$U92>02s>B zg6`sgSF^nB6=l~%v$6Qt7932SsR@O65Uh~kC=Q$=ClCM2tDa{<3ZaF z(Di7O_+h)#EGIbUXKsld-XOc>rz|mR%iKDAJnux6*lct^EO>pXGR26X=t{VP6tg$! z#aEhSLHSC z?iHPOZW?_>y(Zk9`)TB&t2U|N)YjZhxSl`40CwmYxVKc0o(PK~E2|ETLl8np&}gAs zkOx<3T|BHPyA|#;-+^SV)J8DcTChGD*zFO%BkQ+uSzlagI5dYKoX`qB$ysRtZGbOm z=$nc8&f>1`TTMFj-Htu+Cl)b4@VghujMQmMWSM~j|${)Z3QGk>D@~4wToI43_ zVzK^TJBbi5XxP^-aB0tEiW)?vvtEiTRA$!koQh70)I!{~+jiy30J_Dr0PG$KmTYJ4 zT9*a@RG{62Sn-q58^X<6h$ddu5UYbwQg+rmtnR~kCf-$bTZi{%2_aZUSPos*A&w6w z)S&;R=pkAY69=4WzWH3CK<0u3n8all1tm}LS68imUGS4}WS8t#S0!t_P^w_Dmwd3W z6_l72v=lr6BCpURIk{&91Q6v&)CBq2C`nF&FX7Qhz{GON$u{L?aL(q65?D2j{xsaB zV2s%@9%88;{l)^95j{;e7@rFCJ1>AL2y@sW4`y570Qc}@xnrvo16 ziV&vA`>KNgCkX5ZtSwvj+H{FJVVmmN}(30c* zBFnlF=&1lKy&hI(JK|$P7w`#N(Jct9-f;uZm3$GhfxhXBBbK{*+WVE1*bAEQ42?V4$9$)|N;;4$ zb@AZ`9Nl47f?rD^VjN5!{8380Ahgv$_3>!^hKlZ+2%rn|W5Qa2FIQIjf6^HN`{d@P z`u%JBtcA#9P_N?Rj^o3* z>&rU#^5^2Un6=?Uv9G$ewa)qr>{UyScXTK{)tW#u*tA%1N1E@#O&h_vx~ly_fNGZ{ zep&L$MLb0h+u+sN+}1@8`a`@Nh9yrykuzLvO&sk6USTUewwJ(4gWsv%5II}{nN;HA zAqa?okAxQ;&qrFyj2j_ z*qgv&r{~l|ZIoZ6lm zNNiG+9s?Ti(OHq8U_kGtLF9BYZBY}Yi##dUAaf>c*xxp(fWq}*9RjIsBCDK$2tgin_xU#VpFio&Ur=`w#v5!5TyFmCOFG=SkOi!XYYWV zjMZAvjqOk1u_r{#07odkSI3iqw{J0|j0ksdz4IHl@Cu86TXi{zRPsF+=^OZn=OIH$ z5rY`xtMaDRvKQ&T(%&TBeu{5?Z}*+#OAYc!B~-V44)VPu$f+`;SUV$8o8)<2;X?!{ z(Cb^r*Tc+;8cpErQLW~m?dbm^$Nox-hayGU6x2O}%kR;`k{Bp?lf`8c?3?C$^%c7026Un*kegKXN~JjZ4PPO};2F`>*4lnC9G; zE10EeCUSB~Dpqcw*|Dgu)LM6P2sWb0(F zJMyWDd-5#I+a%>0qoLteXHwfShodIJp-9IZgrE}}`g&Xo-n>KJo%pL~w}fg4{1mvwq0`w6P~8V)($h6!vf*`#tn_|6#T%Yx(0 zq#HOoOCeqngHVKlbGgo!VUe7}J&_dy5DXoz1dxa(se_U3cL@NFT|l``Afe21ujTG0 z$n0fE2n+koYCGd;sZ03_R5w|kGQe1$Am%SwJ$5|`Z^NU2tYe|F2MdCbRFmW^hC2{P z(V46#Vci<6SG+@-j!`-Xb#=Uw5JHI%urE43x5K?bc%>|Vac>f!X;H8enk=AWr6Fybt*PX}^cy zq-<7ZGQ+O(t9IN23;p1^USg4KK-(oHUE7Npp^XA79#Y8jg6+$c4nYwxaI}^3uIhBCPXZGBzB=0*uKiZ zN}x&s?t%B1zlpF13OYHIV4C}M^k#vc{{de>31$fDk1Yyw#to|iG*7$I`sB0naFKvb z0?;8QqF!~Lx}Z}(kHG?0cG9QKg+t%?sguUnipqb4qp|5r`<=sX~kdUe%N`W+VB2~A`{*FgHuahJp3@2r8MbL--nc=Lu6@Ne>{`|oAo(h5 zrfEjgaTO*@%GCV8)TXLQ?C4G%Me1P8V_}QHF@p^h9V}jEa@_jESpab3d+F3+JN@Hy z^V?79$K=NRZ?9_td*@(W_bD(7kSu)kKI2ZL?QR!r0ladyxvIV~EGVpTYrE0I)Ml(n zOqA(6uq{5Fq$8W^(sK4@|4l{HkDNJ6_iM@?x!+Zp0%Z<1o2062gV?_JuON$=9<~c7 z*%ra<-yKZPzIDlaQIfM4zF($uEeE(cP||qZEq+6IkoDke_w%6I&fZ@Hi>sR73s<$h z*-V)O`5>8Y@x1dMDZS~tpLF}}T5HG0Vymi}*4H^N`&*l}n4D|xVEuwUz~8s0H-PIF zL-@-Uknf?0;zZq(h4DasQs6A&{_Ot7Mx~hcSj*SbS%*4phe+{Z84rJKU#>s-MKe!Y-h={sJWlHtWvMKLtAoJ2C*DkKWO;6ZcO4Vfd)k6grF5< z<*i%SmrKn^D>LnnEGd)0J>yk90PZYGsL>5mj@(9;2X`GOfB=GBny&#E5iyx-lFrX7 zihitw_GY*CQ_&K2s_IKLBe0vzpKz)Qe>T5Y>nnw0+rAuup#^q|h6XCbi_CHA#+SGx zt~dpaSb_@%jil3ohrh~}+~6vJ?!x$>eKm%Pw(`h4xPBg3be@go86PcRo;sWUg0B_PxK;f^ zq0FT|%;)jsð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%0DK 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�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 z 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≫Ot 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 z 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

    1#bz_a@(mKG0PZ$DqR(t4d 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�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 literal 0 HcmV?d00001 diff --git a/extra/linux/dev.lapce.lapce.desktop b/extra/linux/dev.lapce.lapce.desktop new file mode 100644 index 0000000..ba7ad9a --- /dev/null +++ b/extra/linux/dev.lapce.lapce.desktop @@ -0,0 +1,20 @@ +[Desktop Entry] +Version=1.0 +Type=Application + +Name=Lapce +Comment=Lightning-fast and powerful code editor written in Rust +Categories=Development;IDE; +GenericName=Code Editor +StartupWMClass=lapce + +Icon=dev.lapce.lapce +Exec=lapce %F +Terminal=false +MimeType=text/plain;inode/directory; +Actions=new-window; + +[Desktop Action new-window] +Name=New Window +Exec=lapce --new %F +Icon=dev.lapce.lapce diff --git a/extra/linux/dev.lapce.lapce.metainfo.xml b/extra/linux/dev.lapce.lapce.metainfo.xml new file mode 100644 index 0000000..64ed1a0 --- /dev/null +++ b/extra/linux/dev.lapce.lapce.metainfo.xml @@ -0,0 +1,63 @@ + + + dev.lapce.lapce + Lapce + Dongdong Zhou, et al. +

    Lightning-fast and powerful code editor written in Rust + MIT + Apache-2.0 + https://lapce.dev/ + https://github.com/lapce/lapce/issues + https://docs.lapce.dev/ + + IDE + Development + + +

    + Lapce is an open source code editor written in Rust. By utilising native GUI and GPU rendering, and with the performance Rust provides, Lapce is one of the fastest code editors out there. +

    +

    Features:

    +
      +
    • Modal Editing (Vim like) support as first class citizen (can be turned off as well)
    • +
    • Built-in LSP (Language Server Protocol) support to give you code intelligence like code completion, diagnostics and code actions etc.
    • +
    • Built-in remote development support (inspired by VSCode Remote Development) for a seamless "local" experience, benefiting from the full power of the remote system.
    • +
    • Plugins can be written in programming languages that can compile to the WASI format (C, Rust, AssemblyScript)
    • +
    • Built-in terminal, so you can execute commands in your workspace, without leaving Lapce.
    • +
    +
    + + dev.lapce.lapce.desktop + + + Lapce source project opened in Lapce with Rust source code file opened + https://raw.githubusercontent.com/lapce/lapce/refs/tags/v0.4.5/extra/images/linux/code-file-with-highlight.png + + + + + https://github.com/lapce/lapce/releases/tag/v0.4.6 + + #3821 + #3832 + #3818 + #3819 + + + + https://github.com/lapce/lapce/releases/tag/v0.4.5 + + #3795 + + + + https://github.com/lapce/lapce/releases/tag/v0.4.4 + + #3795 + + + + https://github.com/lapce/lapce/releases/tag/v0.4.3 + + + diff --git a/extra/linux/docker/alpine/Dockerfile b/extra/linux/docker/alpine/Dockerfile new file mode 100644 index 0000000..f318350 --- /dev/null +++ b/extra/linux/docker/alpine/Dockerfile @@ -0,0 +1,123 @@ +# syntax=docker/dockerfile:1 + +ARG DISTRIBUTION_VERSION +ARG RUST_VERSION +ARG XX_VERSION=latest + +FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx +FROM --platform=$BUILDPLATFORM rust:${RUST_VERSION}-alpine${DISTRIBUTION_VERSION} AS build-base +COPY --from=xx / / + +SHELL [ "/bin/ash", "-c" ] + +# install host dependencies +ARG DISTRIBUTION_PACKAGES +RUN \ + --mount=type=cache,target=/var/cache/apk,sharing=private \ + --mount=type=cache,target=/etc/apk/cache,sharing=private \ +< debian/control + Package: ${PACKAGE_NAME} + Version: ${RELEASE_TAG_NAME} + Conflicts: ${conflicts} + Maintainer: Jakub Panek + Architecture: ${_PACKAGE_ARCHITECTURE} + Description: Lightning-fast and Powerful Code Editor + Source: https://lapce.dev +EOL + +depends=$(dpkg-shlibdeps -O -e usr/bin/lapce) +depends=$(echo "${depends}" | sed 's/shlibs:Depends=//') +echo "Depends: ${depends}" >> debian/control +mv debian DEBIAN + +. /etc/os-release + +dpkg-deb --root-owner-group --build . "${OUTPUT_DIR}"/"${PACKAGE_NAME}.${ID}.${VERSION_CODENAME}.${_PACKAGE_ARCHITECTURE}.deb" +EOF + +FROM build-base AS dev +COPY . ./dev + +FROM scratch AS binary +COPY --from=build /output/lapce . + +FROM scratch AS cross-binary +COPY --from=build /output/lapce . + +FROM scratch AS package +COPY --from=build /output/*.deb . + +FROM scratch AS cross-package +COPY --from=build /output/*.deb . diff --git a/extra/linux/docker/fedora/Dockerfile b/extra/linux/docker/fedora/Dockerfile new file mode 100644 index 0000000..03dd426 --- /dev/null +++ b/extra/linux/docker/fedora/Dockerfile @@ -0,0 +1,190 @@ +# syntax=docker/dockerfile:1 + +ARG DISTRIBUTION_VERSION +ARG RUST_VERSION +ARG XX_VERSION=latest + +FROM --platform=$BUILDPLATFORM ghcr.io/panekj/xx:${XX_VERSION} AS xx +FROM --platform=$BUILDPLATFORM fedora:${DISTRIBUTION_VERSION} AS build-base +COPY --from=xx --link / / + +SHELL [ "/bin/bash", "-c" ] + +# install host dependencies +ARG DISTRIBUTION_PACKAGES +RUN \ + --mount=type=cache,target=/var/cache/dnf,sharing=locked \ +<> /etc/dnf/dnf.conf +dnf update -y +dnf install -y \ + bash clang lld llvm file cmake pkg-config curl git rpm-build +EOF + +ENV CARGO_HOME="/cargo" +ENV RUSTUP_HOME="/rustup" + +RUN \ +< lapce.spec < /etc/apt/apt.conf.d/keep-cache +EOF + +# install host dependencies +ARG DISTRIBUTION_PACKAGES +RUN \ + --mount=type=cache,target=/var/cache/apt,sharing=private \ + --mount=type=cache,target=/var/lib/apt,sharing=private \ +< debian/control + Package: ${PACKAGE_NAME} + Version: ${RELEASE_TAG_NAME} + Conflicts: ${conflicts} + Maintainer: Jakub Panek + Architecture: ${_PACKAGE_ARCHITECTURE} + Description: Lightning-fast and Powerful Code Editor + Source: https://lapce.dev +EOL + +depends=$(dpkg-shlibdeps -O -e usr/bin/lapce) +depends=$(echo "${depends}" | sed 's/shlibs:Depends=//') +echo "Depends: ${depends}" >> debian/control +mv debian DEBIAN + +. /etc/os-release + +dpkg-deb --root-owner-group --build . "${OUTPUT_DIR}"/"${PACKAGE_NAME}.${ID}.${VERSION_CODENAME}.${_PACKAGE_ARCHITECTURE}.deb" +EOF + +FROM scratch AS package +COPY --from=package-prepare /output/*.deb . + +FROM scratch AS cross-package +COPY --from=package-prepare /output/*.deb . diff --git a/extra/macos/Lapce.app/Contents/Info.plist b/extra/macos/Lapce.app/Contents/Info.plist new file mode 100644 index 0000000..d99ad49 --- /dev/null +++ b/extra/macos/Lapce.app/Contents/Info.plist @@ -0,0 +1,58 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + lapce + CFBundleIdentifier + io.lapce + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + Lapce + CFBundlePackageType + APPL + CFBundleShortVersionString + 0.4.6 + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 1 + CFBundleIconFile + lapce.icns + NSHighResolutionCapable + + NSMainNibFile + + NSSupportsAutomaticGraphicsSwitching + + CFBundleDisplayName + Lapce + NSRequiresAquaSystemAppearance + NO + NSAppleEventsUsageDescription + An application in Lapce would like to access AppleScript. + NSCalendarsUsageDescription + An application in Lapce would like to access calendar data. + NSCameraUsageDescription + An application in Lapce would like to access the camera. + NSContactsUsageDescription + An application in Lapce wants to access your contacts. + NSLocationAlwaysUsageDescription + An application in Lapce would like to access your location information, even in the background. + NSLocationUsageDescription + An application in Lapce would like to access your location information. + NSLocationWhenInUseUsageDescription + An application in Lapce would like to access your location information while active. + NSMicrophoneUsageDescription + An application in Lapce would like to access your microphone. + NSRemindersUsageDescription + An application in Lapce would like to access your reminders. + NSSystemAdministrationUsageDescription + An application in Lapce requires elevated permissions. + + \ No newline at end of file diff --git a/extra/macos/Lapce.app/Contents/Resources/lapce.icns b/extra/macos/Lapce.app/Contents/Resources/lapce.icns new file mode 100644 index 0000000000000000000000000000000000000000..691e4b1eeee866f909eb52f607250ad566e3116f GIT binary patch literal 368832 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

    Ojd!^21(g)^A^%@QgqerSEd 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 z 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ℑ@jWh0>|Oh*iTo@M@_+p4nD~Qx{%d_u@imRJ1 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 Kzh3@%Uid$i=X}`! literal 0 HcmV?d00001 diff --git a/extra/proxy.ps1 b/extra/proxy.ps1 new file mode 100644 index 0000000..42bc12e --- /dev/null +++ b/extra/proxy.ps1 @@ -0,0 +1,47 @@ +[CmdletBinding()] +param( + [string]$version, + [string]$directory +) + +$proxy = (Join-Path $directory 'lapce.exe') + +$LapceProcesses = (Get-Process -Name 'lapce' -EA SilentlyContinue).Count +if ($LapceProcesses -ne 0) { + Write-Host 'Proxy currently in use. Aborting installation' + exit +} + +if (Test-Path $proxy) { + Write-Host 'Proxy already installed' + exit +} + +switch ($env:PROCESSOR_ARCHITECTURE) { + # Only x86_64 is supported currently + 'AMD64' { + $arch = 'x86_64' + } +} + +$url = "https://github.com/lapce/lapce/releases/download/${version}/lapce-proxy-windows-${arch}.gz" +$gzip = Join-Path "${env:TMP}" "lapce-proxy-windows-${arch}.gz" + +$webclient = [System.Net.WebClient]::new() +$webclient.DownloadFile($url, $gzip) +$webclient.Dispose() + +[System.IO.Directory]::CreateDirectory($directory) + +$archive = [System.IO.File]::Open($gzip, [System.IO.FileMode]::Open) +$proxy_file = [System.IO.File]::Create($proxy) +$compressor = [System.IO.Compression.GZipStream]::new($archive, [System.IO.Compression.CompressionMode]::Decompress) +$compressor.CopyTo($proxy_file) +Start-Sleep -Seconds 3 +$compressor.close() +$proxy_file.close() +$archive.close() + +[System.IO.File]::Delete($gzip) + +Write-Host 'lapce-proxy installed' \ No newline at end of file diff --git a/extra/proxy.sh b/extra/proxy.sh new file mode 100644 index 0000000..6542860 --- /dev/null +++ b/extra/proxy.sh @@ -0,0 +1,104 @@ +#!/bin/sh +set -eux + +# This script is written to be as POSIX as possible +# so it works fine for all Unix-like operating systems + +test_cmd() { + command -v "$1" >/dev/null +} + +# proxy version +lapce_new_ver="${1}" +# proxy directory +# eval to resolve '~' into proper user dir +eval lapce_dir="'${2}'" + +case "${lapce_new_ver}" in + v*) + lapce_new_version=$(echo "${lapce_new_ver}" | cut -d'v' -f2) + lapce_new_ver_tag="${lapce_new_ver}" + ;; + nightly*) + lapce_new_version="${lapce_new_ver}" + lapce_new_ver_tag=$(echo ${lapce_new_ver} | cut -d '-' -f1) + ;; + *) + printf 'Unknown version\n' + exit 1 + ;; +esac + +if [ -e "${lapce_dir}/lapce" ]; then + lapce_installed_ver=$("${lapce_dir}/lapce" --version | cut -d' ' -f2) + + printf '[DEBUG]: Current proxy version: %s\n' "${lapce_installed_ver}" + printf '[DEBUG]: New proxy version: %s\n' "${lapce_new_version}" + if [ "${lapce_installed_ver}" = "${lapce_new_version}" ]; then + printf 'Proxy already exists\n' + exit 0 + else + printf 'Proxy outdated. Replacing proxy\n' + rm "${lapce_dir}/lapce" + fi +fi + +for _cmd in tar gzip uname; do + if ! test_cmd "${_cmd}"; then + printf 'Missing required command: %s\n' "${_cmd}" + exit 1 + fi +done + +# Currently only linux/darwin are supported +case $(uname -s) in + Linux) os_name=linux ;; + Darwin) os_name=darwin ;; + *) + printf '[ERROR] unsupported os\n' + exit 1 + ;; +esac + +# Currently only amd64/arm64 are supported +case $(uname -m) in + x86_64|amd64|x64) arch_name=x86_64 ;; + arm64|aarch64) arch_name=aarch64 ;; + # riscv64) arch_name=riscv64 ;; + *) + printf '[ERROR] unsupported arch\n' + exit 1 + ;; +esac + +lapce_download_url="https://github.com/lapce/lapce/releases/download/${lapce_new_ver_tag}/lapce-proxy-${os_name}-${arch_name}.gz" + +printf 'Creating "%s"\n' "${lapce_dir}" +mkdir -p "${lapce_dir}" +cd "${lapce_dir}" + +if test_cmd 'curl'; then + # How old curl has these options? we'll find out + printf 'Downloading using curl\n' + curl --proto '=https' --tlsv1.2 -LfS -O "${lapce_download_url}" + # curl --proto '=https' --tlsv1.2 -LZfS -o "${tmp_dir}/lapce-proxy-${os_name}-${arch_name}.gz" "${lapce_download_url}" +elif test_cmd 'wget'; then + printf 'Downloading using wget\n' + wget "${lapce_download_url}" +else + printf 'curl/wget not found, failed to download proxy\n' + exit 1 +fi + +printf 'Decompressing gzip\n' +gzip -df "${lapce_dir}/lapce-proxy-${os_name}-${arch_name}.gz" + +printf 'Renaming proxy \n' +mv -v "${lapce_dir}/lapce-proxy-${os_name}-${arch_name}" "${lapce_dir}/lapce" + +printf 'Making it executable\n' +chmod +x "${lapce_dir}/lapce" + +printf 'lapce-proxy installed\n' + +exit 0 diff --git a/extra/schemas/color-theme.json b/extra/schemas/color-theme.json new file mode 100644 index 0000000..3dc4821 --- /dev/null +++ b/extra/schemas/color-theme.json @@ -0,0 +1,202 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$ref": "#/definitions/ColorTheme", + "definitions": { + "ColorTheme": { + "type": "object", + "additionalProperties": false, + "properties": { + "color-theme": { + "$ref": "#/definitions/ColorThemeClass" + }, + "ui": { + "$ref": "#/definitions/UI" + } + }, + "required": [], + "title": "ColorTheme" + }, + "ColorThemeClass": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "base": { + "$ref": "#/definitions/Base" + }, + "syntax": { + "$ref": "#/definitions/Syntax" + }, + "ui": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "required": [], + "title": "ColorThemeClass" + }, + "Base": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "required": [], + "title": "Base" + }, + "Syntax": { + "type": "object", + "additionalProperties": false, + "properties": { + "comment": { + "type": "string" + }, + "constant": { + "type": "string" + }, + "type": { + "type": "string" + }, + "typeAlias": { + "type": "string" + }, + "number": { + "type": "string" + }, + "enum": { + "type": "string" + }, + "struct": { + "type": "string" + }, + "structure": { + "type": "string" + }, + "interface": { + "type": "string" + }, + "attribute": { + "type": "string" + }, + "constructor": { + "type": "string" + }, + "function": { + "type": "string" + }, + "method": { + "type": "string" + }, + "function.method": { + "type": "string" + }, + "keyword": { + "type": "string" + }, + "selfKeyword": { + "type": "string" + }, + "field": { + "type": "string" + }, + "property": { + "type": "string" + }, + "enumMember": { + "type": "string" + }, + "enum-member": { + "type": "string" + }, + "string": { + "type": "string" + }, + "type.builtin": { + "type": "string" + }, + "builtinType": { + "type": "string" + }, + "escape": { + "type": "string" + }, + "string.escape": { + "type": "string" + }, + "embedded": { + "type": "string" + }, + "punctuation.delimiter": { + "type": "string" + }, + "text.title": { + "type": "string" + }, + "text.uri": { + "type": "string" + }, + "text.reference": { + "type": "string" + }, + "variable": { + "type": "string" + }, + "variable.other.member": { + "type": "string" + }, + "tag": { + "type": "string" + }, + "bracket.color.1": { + "type": "string" + }, + "bracket.color.2": { + "type": "string" + }, + "bracket.color.3": { + "type": "string" + }, + "bracket.unpaired": { + "type": "string" + } + }, + "required": [], + "title": "Syntax" + }, + "UI": { + "type": "object", + "additionalProperties": false, + "properties": { + "font-family": { + "type": "string" + }, + "font-size": { + "type": "integer" + }, + "header-height": { + "type": "integer" + }, + "status-height": { + "type": "integer" + }, + "tab-min-width": { + "type": "integer" + }, + "activity-width": { + "type": "integer" + }, + "scroll-width": { + "type": "integer" + }, + "drop-shadow-width": { + "type": "integer" + } + }, + "required": [], + "title": "UI" + } + } +} \ No newline at end of file diff --git a/extra/schemas/icon-theme.json b/extra/schemas/icon-theme.json new file mode 100644 index 0000000..9bcc116 --- /dev/null +++ b/extra/schemas/icon-theme.json @@ -0,0 +1,60 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$ref": "#/definitions/IconTheme", + "definitions": { + "IconTheme": { + "type": "object", + "additionalProperties": false, + "properties": { + "icon-theme": { + "$ref": "#/definitions/IconThemeClass" + } + }, + "required": [], + "title": "IconTheme" + }, + "IconThemeClass": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "ui": { + "$ref": "#/definitions/IconMapping" + }, + "foldername": { + "$ref": "#/definitions/IconMapping" + }, + "filename": { + "$ref": "#/definitions/IconMapping" + }, + "extension": { + "$ref": "#/definitions/IconMapping" + } + }, + "required": [], + "title": "IconThemeClass" + }, + "IconMapping": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "*" : { + "type": "string" + } + }, + "title": "IconMapping" + }, + "Extension": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "[a-zA-Z0-9]" : { + "type": "string" + } + }, + "title": "IconMapping" + } + } +} diff --git a/extra/schemas/settings.json b/extra/schemas/settings.json new file mode 100644 index 0000000..a8bba8a --- /dev/null +++ b/extra/schemas/settings.json @@ -0,0 +1,353 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$ref": "#/definitions/Settings", + "definitions": { + "Settings": { + "type": "object", + "additionalProperties": false, + "properties": { + "core": { + "$ref": "#/definitions/Core" + }, + "editor": { + "$ref": "#/definitions/Editor" + }, + "terminal": { + "$ref": "#/definitions/Terminal" + }, + "ui": { + "$ref": "#/definitions/UI" + }, + "color-theme": { + "$ref": "file://./color-theme.json" + }, + "icon-theme": { + "$schema": "file://./icon-theme.json" + } + }, + "required": [], + "title": "Settings" + }, + "Base": { + "type": "object", + "additionalProperties": false, + "properties": { + "white": { + "type": "string" + }, + "black": { + "type": "string" + }, + "grey": { + "type": "string" + }, + "blue": { + "type": "string" + }, + "red": { + "type": "string" + }, + "yellow": { + "type": "string" + }, + "orange": { + "type": "string" + }, + "green": { + "type": "string" + }, + "purple": { + "type": "string" + }, + "cyan": { + "type": "string" + }, + "magenta": { + "type": "string" + } + }, + "required": [], + "title": "Base" + }, + "Syntax": { + "type": "object", + "additionalProperties": false, + "properties": { + "comment": { + "type": "string" + }, + "constant": { + "type": "string" + }, + "type": { + "type": "string" + }, + "typeAlias": { + "type": "string" + }, + "number": { + "type": "string" + }, + "enum": { + "type": "string" + }, + "struct": { + "type": "string" + }, + "structure": { + "type": "string" + }, + "interface": { + "type": "string" + }, + "attribute": { + "type": "string" + }, + "constructor": { + "type": "string" + }, + "function": { + "type": "string" + }, + "method": { + "type": "string" + }, + "function.method": { + "type": "string" + }, + "keyword": { + "type": "string" + }, + "keyword.control": { + "type": "string" + }, + "selfKeyword": { + "type": "string" + }, + "field": { + "type": "string" + }, + "property": { + "type": "string" + }, + "enumMember": { + "type": "string" + }, + "enum-member": { + "type": "string" + }, + "variable.other.member": { + "type": "string" + }, + "string": { + "type": "string" + }, + "type.builtin": { + "type": "string" + }, + "builtinType": { + "type": "string" + }, + "escape": { + "type": "string" + }, + "embedded": { + "type": "string" + }, + "symbol": { + "type": "string" + } + }, + "required": [], + "title": "Syntax" + }, + "Core": { + "type": "object", + "additionalProperties": false, + "properties": { + "modal": { + "type": "boolean" + }, + "color-theme": { + "type": "string" + }, + "icon-theme": { + "type": "string" + }, + "custom-titlebar": { + "type": "boolean" + } + }, + "required": [], + "title": "Core" + }, + "Editor": { + "type": "object", + "additionalProperties": false, + "properties": { + "font-family": { + "type": "string" + }, + "font-size": { + "type": "integer" + }, + "code-lens-font-size": { + "type": "integer" + }, + "line-height": { + "type": "number" + }, + "tab-width": { + "type": "integer" + }, + "show-tab": { + "type": "boolean" + }, + "show-bread-crumbs": { + "type": "boolean" + }, + "scroll-beyond-last-line": { + "type": "boolean" + }, + "cursor-surrounding-lines": { + "type": "integer" + }, + "sticky-header": { + "type": "boolean" + }, + "completion-show-documentation": { + "type": "boolean" + }, + "auto-closing-matching-pairs": { + "type": "boolean" + }, + "auto-surround": { + "type": "boolean" + }, + "hover-delay": { + "type": "integer" + }, + "modal-mode-relative-line-numbers": { + "type": "boolean" + }, + "format-on-save": { + "type": "boolean" + }, + "highlight-matching-brackets": { + "type": "boolean" + }, + "highlight-selection-occurrences": { + "type": "boolean" + }, + "autosave-interval": { + "type": "integer" + }, + "enable-inlay-hints": { + "type": "boolean" + }, + "inlay-hint-font-family": { + "type": "string" + }, + "inlay-hint-font-size": { + "type": "integer" + }, + "enable-error-lens": { + "type": "boolean" + }, + "error-lens-end-of-line": { + "type": "boolean" + }, + "error-lens-font-family": { + "type": "string" + }, + "error-lens-font-size": { + "type": "integer" + }, + "blink-interval": { + "type": "integer" + }, + "multicursor-case-sensitive": { + "type": "boolean" + }, + "multicursor-whole-words": { + "type": "boolean" + }, + "render-whitespace": { + "type": "string" + }, + "show-indent-guide": { + "type": "boolean" + }, + "atomic-soft-tabs": { + "type": "boolean" + } + }, + "required": [], + "title": "Editor" + }, + "Terminal": { + "type": "object", + "additionalProperties": false, + "properties": { + "font-family": { + "type": "string" + }, + "font-size": { + "type": "integer" + }, + "line-height": { + "type": "integer" + }, + "shell": { + "type": "string" + } + }, + "required": [], + "title": "Terminal" + }, + "UI": { + "type": "object", + "additionalProperties": false, + "properties": { + "font-family": { + "type": "string" + }, + "font-size": { + "type": "integer" + }, + "icon-size": { + "type": "integer" + }, + "header-height": { + "type": "integer" + }, + "status-height": { + "type": "integer" + }, + "tab-min-width": { + "type": "integer" + }, + "scroll-width": { + "type": "integer" + }, + "drop-shadow-width": { + "type": "integer" + }, + "palette-width": { + "type": "integer" + }, + "hover-font-family": { + "type": "string" + }, + "hover-font-size": { + "type": "integer" + }, + "trim-search-results-whitespace": { + "type": "boolean" + } + }, + "required": [], + "title": "UI" + } + } +} diff --git a/extra/windows/lapce.ico b/extra/windows/lapce.ico new file mode 100644 index 0000000000000000000000000000000000000000..c78b16b406a3ef049f8212caaa3d5929666872b8 GIT binary patch literal 410598 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 literal 0 HcmV?d00001 diff --git a/extra/windows/wix/lapce.wxs b/extra/windows/wix/lapce.wxs new file mode 100644 index 0000000..dd37ac2 --- /dev/null +++ b/extra/windows/wix/lapce.wxs @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/extra/windows/wix/license.rtf b/extra/windows/wix/license.rtf new file mode 100644 index 0000000..420cb6e --- /dev/null +++ b/extra/windows/wix/license.rtf @@ -0,0 +1,53 @@ +{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{} +{\*\generator Riched20 10.0.17763}\viewkind4\uc1 +\pard\sa200\sl276\slmult1\qc\f0\fs22\lang9 Apache License\par +Version 2.0, January 2004\par +{{\field{\*\fldinst{HYPERLINK http://www.apache.org/licenses/ }}{\fldrslt{http://www.apache.org/licenses/\ul0\cf0}}}}\f0\fs22\par + +\pard\sa200\sl276\slmult1\par +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\par +\par +1. Definitions.\par + "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.\par + "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.\par + "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.\par + "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.\par + "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.\par + "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.\par + "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).\par + "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.\par + "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."\par + "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.\par +2. Grant of Copyright License.\par +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.\par +3. Grant of Patent License.\par +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.\par +4. Redistribution.\par +You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:\par + (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and\par + (b) You must cause any modified files to carry prominent notices stating that You changed the files; and\par + (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and\par + (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.\par + You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.\par +5. Submission of Contributions.\par +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.\par +6. Trademarks.\par +This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.\par +7. Disclaimer of Warranty.\par +Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.\par +8. Limitation of Liability.\par +In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.\par +9. Accepting Warranty or Additional Liability.\par +While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.\par +END OF TERMS AND CONDITIONS\par +\par +APPENDIX: How to apply the Apache License to your work.\par +\par + To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.\par +Copyright 2016 Joe Wilm, The Alacritty Project Contributors\par +Licensed under the Apache License, Version 2.0 (the "License");you may not use this file except in compliance with the License.You may obtain a copy of the License at\par +\par +\tab {{\field{\*\fldinst{HYPERLINK http://www.apache.org/licenses/LICENSE-2.0 }}{\fldrslt{http://www.apache.org/licenses/LICENSE-2.0\ul0\cf0}}}}\f0\fs22\par +\par +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions andlimitations under the License.\par +} \ No newline at end of file diff --git a/icons/codicons/LICENSE b/icons/codicons/LICENSE new file mode 100644 index 0000000..a2c95fc --- /dev/null +++ b/icons/codicons/LICENSE @@ -0,0 +1,395 @@ +Attribution 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More_considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution 4.0 International Public License ("Public License"). To the +extent this Public License may be interpreted as a contract, You are +granted the Licensed Rights in consideration of Your acceptance of +these terms and conditions, and the Licensor grants You such rights in +consideration of benefits the Licensor receives from making the +Licensed Material available under these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + d. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + e. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + f. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + g. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + h. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + i. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + j. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + k. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material; and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. \ No newline at end of file diff --git a/icons/codicons/README.md b/icons/codicons/README.md new file mode 100644 index 0000000..0b0eca8 --- /dev/null +++ b/icons/codicons/README.md @@ -0,0 +1,3 @@ +# vscode-codicons + +Source: [https://github.com/microsoft/vscode-codicons](https://github.com/microsoft/vscode-codicons) diff --git a/icons/codicons/add.svg b/icons/codicons/add.svg new file mode 100644 index 0000000..aed9bc6 --- /dev/null +++ b/icons/codicons/add.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/arrow-both.svg b/icons/codicons/arrow-both.svg new file mode 100644 index 0000000..c0fa479 --- /dev/null +++ b/icons/codicons/arrow-both.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/arrow-down.svg b/icons/codicons/arrow-down.svg new file mode 100644 index 0000000..1c9268b --- /dev/null +++ b/icons/codicons/arrow-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/arrow-left.svg b/icons/codicons/arrow-left.svg new file mode 100644 index 0000000..6e65875 --- /dev/null +++ b/icons/codicons/arrow-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/arrow-right.svg b/icons/codicons/arrow-right.svg new file mode 100644 index 0000000..f61ddd1 --- /dev/null +++ b/icons/codicons/arrow-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/arrow-swap.svg b/icons/codicons/arrow-swap.svg new file mode 100644 index 0000000..6496412 --- /dev/null +++ b/icons/codicons/arrow-swap.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/arrow-up.svg b/icons/codicons/arrow-up.svg new file mode 100644 index 0000000..81a0220 --- /dev/null +++ b/icons/codicons/arrow-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/blank.svg b/icons/codicons/blank.svg new file mode 100644 index 0000000..7aacd32 --- /dev/null +++ b/icons/codicons/blank.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/case-sensitive.svg b/icons/codicons/case-sensitive.svg new file mode 100644 index 0000000..9faa9b7 --- /dev/null +++ b/icons/codicons/case-sensitive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/chevron-down.svg b/icons/codicons/chevron-down.svg new file mode 100644 index 0000000..59a4873 --- /dev/null +++ b/icons/codicons/chevron-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/chevron-left.svg b/icons/codicons/chevron-left.svg new file mode 100644 index 0000000..7095e36 --- /dev/null +++ b/icons/codicons/chevron-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/chevron-right.svg b/icons/codicons/chevron-right.svg new file mode 100644 index 0000000..507b2b2 --- /dev/null +++ b/icons/codicons/chevron-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/chevron-up.svg b/icons/codicons/chevron-up.svg new file mode 100644 index 0000000..f103cfd --- /dev/null +++ b/icons/codicons/chevron-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/chrome-close.svg b/icons/codicons/chrome-close.svg new file mode 100644 index 0000000..6b9a55a --- /dev/null +++ b/icons/codicons/chrome-close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/chrome-maximize.svg b/icons/codicons/chrome-maximize.svg new file mode 100644 index 0000000..7627e7f --- /dev/null +++ b/icons/codicons/chrome-maximize.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/chrome-minimize.svg b/icons/codicons/chrome-minimize.svg new file mode 100644 index 0000000..abcc15b --- /dev/null +++ b/icons/codicons/chrome-minimize.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/chrome-restore.svg b/icons/codicons/chrome-restore.svg new file mode 100644 index 0000000..1537b4a --- /dev/null +++ b/icons/codicons/chrome-restore.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/circle-filled.svg b/icons/codicons/circle-filled.svg new file mode 100644 index 0000000..955f153 --- /dev/null +++ b/icons/codicons/circle-filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/close.svg b/icons/codicons/close.svg new file mode 100644 index 0000000..a63b1e0 --- /dev/null +++ b/icons/codicons/close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/combine.svg b/icons/codicons/combine.svg new file mode 100644 index 0000000..02a09a7 --- /dev/null +++ b/icons/codicons/combine.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/debug-alt-small.svg b/icons/codicons/debug-alt-small.svg new file mode 100644 index 0000000..49020ce --- /dev/null +++ b/icons/codicons/debug-alt-small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/debug-alt.svg b/icons/codicons/debug-alt.svg new file mode 100644 index 0000000..f1b4fdc --- /dev/null +++ b/icons/codicons/debug-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/debug-console.svg b/icons/codicons/debug-console.svg new file mode 100644 index 0000000..bcdc388 --- /dev/null +++ b/icons/codicons/debug-console.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/debug-continue.svg b/icons/codicons/debug-continue.svg new file mode 100644 index 0000000..a6d8eb7 --- /dev/null +++ b/icons/codicons/debug-continue.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/debug-disconnect.svg b/icons/codicons/debug-disconnect.svg new file mode 100644 index 0000000..bb050c2 --- /dev/null +++ b/icons/codicons/debug-disconnect.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/debug-pause.svg b/icons/codicons/debug-pause.svg new file mode 100644 index 0000000..099a2cc --- /dev/null +++ b/icons/codicons/debug-pause.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/debug-restart.svg b/icons/codicons/debug-restart.svg new file mode 100644 index 0000000..9eedf67 --- /dev/null +++ b/icons/codicons/debug-restart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/debug-start.svg b/icons/codicons/debug-start.svg new file mode 100644 index 0000000..1f9177a --- /dev/null +++ b/icons/codicons/debug-start.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/debug-step-into.svg b/icons/codicons/debug-step-into.svg new file mode 100644 index 0000000..1a684d7 --- /dev/null +++ b/icons/codicons/debug-step-into.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/debug-step-out.svg b/icons/codicons/debug-step-out.svg new file mode 100644 index 0000000..253190b --- /dev/null +++ b/icons/codicons/debug-step-out.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/debug-step-over.svg b/icons/codicons/debug-step-over.svg new file mode 100644 index 0000000..e725655 --- /dev/null +++ b/icons/codicons/debug-step-over.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/debug-stop.svg b/icons/codicons/debug-stop.svg new file mode 100644 index 0000000..f2f47bd --- /dev/null +++ b/icons/codicons/debug-stop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/debug.svg b/icons/codicons/debug.svg new file mode 100644 index 0000000..2072b40 --- /dev/null +++ b/icons/codicons/debug.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/diff-added.svg b/icons/codicons/diff-added.svg new file mode 100644 index 0000000..9eca31e --- /dev/null +++ b/icons/codicons/diff-added.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/diff-ignored.svg b/icons/codicons/diff-ignored.svg new file mode 100644 index 0000000..bbbedec --- /dev/null +++ b/icons/codicons/diff-ignored.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/diff-modified.svg b/icons/codicons/diff-modified.svg new file mode 100644 index 0000000..cae06cb --- /dev/null +++ b/icons/codicons/diff-modified.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/diff-removed.svg b/icons/codicons/diff-removed.svg new file mode 100644 index 0000000..2da06cd --- /dev/null +++ b/icons/codicons/diff-removed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/diff-renamed.svg b/icons/codicons/diff-renamed.svg new file mode 100644 index 0000000..f865506 --- /dev/null +++ b/icons/codicons/diff-renamed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/diff.svg b/icons/codicons/diff.svg new file mode 100644 index 0000000..4af4ba7 --- /dev/null +++ b/icons/codicons/diff.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/discard.svg b/icons/codicons/discard.svg new file mode 100644 index 0000000..a22942f --- /dev/null +++ b/icons/codicons/discard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/edit.svg b/icons/codicons/edit.svg new file mode 100644 index 0000000..552fbf9 --- /dev/null +++ b/icons/codicons/edit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/error.svg b/icons/codicons/error.svg new file mode 100644 index 0000000..4cfb5bb --- /dev/null +++ b/icons/codicons/error.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/extensions.svg b/icons/codicons/extensions.svg new file mode 100644 index 0000000..bbdf50f --- /dev/null +++ b/icons/codicons/extensions.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/file-binary.svg b/icons/codicons/file-binary.svg new file mode 100644 index 0000000..18bafda --- /dev/null +++ b/icons/codicons/file-binary.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/file-code.svg b/icons/codicons/file-code.svg new file mode 100644 index 0000000..f6d50e4 --- /dev/null +++ b/icons/codicons/file-code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/file-media.svg b/icons/codicons/file-media.svg new file mode 100644 index 0000000..0667efb --- /dev/null +++ b/icons/codicons/file-media.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/file-pdf.svg b/icons/codicons/file-pdf.svg new file mode 100644 index 0000000..b1dc9d5 --- /dev/null +++ b/icons/codicons/file-pdf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/file-submodule.svg b/icons/codicons/file-submodule.svg new file mode 100644 index 0000000..08261df --- /dev/null +++ b/icons/codicons/file-submodule.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/file-symlink-directory.svg b/icons/codicons/file-symlink-directory.svg new file mode 100644 index 0000000..77aac76 --- /dev/null +++ b/icons/codicons/file-symlink-directory.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/file-symlink-file.svg b/icons/codicons/file-symlink-file.svg new file mode 100644 index 0000000..5cb31f5 --- /dev/null +++ b/icons/codicons/file-symlink-file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/file-zip.svg b/icons/codicons/file-zip.svg new file mode 100644 index 0000000..95da245 --- /dev/null +++ b/icons/codicons/file-zip.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/file.svg b/icons/codicons/file.svg new file mode 100644 index 0000000..18ce72c --- /dev/null +++ b/icons/codicons/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/files.svg b/icons/codicons/files.svg new file mode 100644 index 0000000..8671a7b --- /dev/null +++ b/icons/codicons/files.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/fold-down.svg b/icons/codicons/fold-down.svg new file mode 100644 index 0000000..f34b8c4 --- /dev/null +++ b/icons/codicons/fold-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/fold-up.svg b/icons/codicons/fold-up.svg new file mode 100644 index 0000000..11f72c2 --- /dev/null +++ b/icons/codicons/fold-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/fold.svg b/icons/codicons/fold.svg new file mode 100644 index 0000000..fd41cad --- /dev/null +++ b/icons/codicons/fold.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/folder-active.svg b/icons/codicons/folder-active.svg new file mode 100644 index 0000000..d50cabf --- /dev/null +++ b/icons/codicons/folder-active.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/folder-library.svg b/icons/codicons/folder-library.svg new file mode 100644 index 0000000..b5a25ac --- /dev/null +++ b/icons/codicons/folder-library.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/folder-opened.svg b/icons/codicons/folder-opened.svg new file mode 100644 index 0000000..52eb52c --- /dev/null +++ b/icons/codicons/folder-opened.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/folder.svg b/icons/codicons/folder.svg new file mode 100644 index 0000000..2940f74 --- /dev/null +++ b/icons/codicons/folder.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/gear.svg b/icons/codicons/gear.svg new file mode 100644 index 0000000..8ee3ec4 --- /dev/null +++ b/icons/codicons/gear.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/git-commit.svg b/icons/codicons/git-commit.svg new file mode 100644 index 0000000..9c11c79 --- /dev/null +++ b/icons/codicons/git-commit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/git-compare.svg b/icons/codicons/git-compare.svg new file mode 100644 index 0000000..e08789c --- /dev/null +++ b/icons/codicons/git-compare.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/git-merge.svg b/icons/codicons/git-merge.svg new file mode 100644 index 0000000..92ea231 --- /dev/null +++ b/icons/codicons/git-merge.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/go-to-file.svg b/icons/codicons/go-to-file.svg new file mode 100644 index 0000000..4c688f2 --- /dev/null +++ b/icons/codicons/go-to-file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/group-by-ref-type.svg b/icons/codicons/group-by-ref-type.svg new file mode 100644 index 0000000..4c688a0 --- /dev/null +++ b/icons/codicons/group-by-ref-type.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/history.svg b/icons/codicons/history.svg new file mode 100644 index 0000000..53d41f7 --- /dev/null +++ b/icons/codicons/history.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/info.svg b/icons/codicons/info.svg new file mode 100644 index 0000000..fff5a9f --- /dev/null +++ b/icons/codicons/info.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/inspect.svg b/icons/codicons/inspect.svg new file mode 100644 index 0000000..2de8bfb --- /dev/null +++ b/icons/codicons/inspect.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/issues.svg b/icons/codicons/issues.svg new file mode 100644 index 0000000..666a3ba --- /dev/null +++ b/icons/codicons/issues.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/json.svg b/icons/codicons/json.svg new file mode 100644 index 0000000..ff10d4b --- /dev/null +++ b/icons/codicons/json.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/key.svg b/icons/codicons/key.svg new file mode 100644 index 0000000..a8de847 --- /dev/null +++ b/icons/codicons/key.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/keyboard.svg b/icons/codicons/keyboard.svg new file mode 100644 index 0000000..0757621 --- /dev/null +++ b/icons/codicons/keyboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-activitybar-left.svg b/icons/codicons/layout-activitybar-left.svg new file mode 100644 index 0000000..87378a2 --- /dev/null +++ b/icons/codicons/layout-activitybar-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-activitybar-right.svg b/icons/codicons/layout-activitybar-right.svg new file mode 100644 index 0000000..43a8940 --- /dev/null +++ b/icons/codicons/layout-activitybar-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-centered.svg b/icons/codicons/layout-centered.svg new file mode 100644 index 0000000..9865f13 --- /dev/null +++ b/icons/codicons/layout-centered.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-menubar.svg b/icons/codicons/layout-menubar.svg new file mode 100644 index 0000000..98666ab --- /dev/null +++ b/icons/codicons/layout-menubar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-panel-center.svg b/icons/codicons/layout-panel-center.svg new file mode 100644 index 0000000..d720c12 --- /dev/null +++ b/icons/codicons/layout-panel-center.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-panel-justify.svg b/icons/codicons/layout-panel-justify.svg new file mode 100644 index 0000000..67a749c --- /dev/null +++ b/icons/codicons/layout-panel-justify.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-panel-left.svg b/icons/codicons/layout-panel-left.svg new file mode 100644 index 0000000..181dd75 --- /dev/null +++ b/icons/codicons/layout-panel-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-panel-off.svg b/icons/codicons/layout-panel-off.svg new file mode 100644 index 0000000..fc8464f --- /dev/null +++ b/icons/codicons/layout-panel-off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-panel-right.svg b/icons/codicons/layout-panel-right.svg new file mode 100644 index 0000000..7cf4177 --- /dev/null +++ b/icons/codicons/layout-panel-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-panel.svg b/icons/codicons/layout-panel.svg new file mode 100644 index 0000000..7ac17fb --- /dev/null +++ b/icons/codicons/layout-panel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-sidebar-left-off.svg b/icons/codicons/layout-sidebar-left-off.svg new file mode 100644 index 0000000..50019bf --- /dev/null +++ b/icons/codicons/layout-sidebar-left-off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-sidebar-left.svg b/icons/codicons/layout-sidebar-left.svg new file mode 100644 index 0000000..b513bda --- /dev/null +++ b/icons/codicons/layout-sidebar-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-sidebar-right-off.svg b/icons/codicons/layout-sidebar-right-off.svg new file mode 100644 index 0000000..951b957 --- /dev/null +++ b/icons/codicons/layout-sidebar-right-off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-sidebar-right.svg b/icons/codicons/layout-sidebar-right.svg new file mode 100644 index 0000000..1017deb --- /dev/null +++ b/icons/codicons/layout-sidebar-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-statusbar.svg b/icons/codicons/layout-statusbar.svg new file mode 100644 index 0000000..7f60e5b --- /dev/null +++ b/icons/codicons/layout-statusbar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout.svg b/icons/codicons/layout.svg new file mode 100644 index 0000000..655d365 --- /dev/null +++ b/icons/codicons/layout.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/lightbulb-autofix.svg b/icons/codicons/lightbulb-autofix.svg new file mode 100644 index 0000000..aca11c8 --- /dev/null +++ b/icons/codicons/lightbulb-autofix.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/lightbulb.svg b/icons/codicons/lightbulb.svg new file mode 100644 index 0000000..37df948 --- /dev/null +++ b/icons/codicons/lightbulb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/link-external.svg b/icons/codicons/link-external.svg new file mode 100644 index 0000000..9a594b7 --- /dev/null +++ b/icons/codicons/link-external.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/link.svg b/icons/codicons/link.svg new file mode 100644 index 0000000..46bf4d5 --- /dev/null +++ b/icons/codicons/link.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/menu.svg b/icons/codicons/menu.svg new file mode 100644 index 0000000..4bb38d0 --- /dev/null +++ b/icons/codicons/menu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/merge.svg b/icons/codicons/merge.svg new file mode 100644 index 0000000..0e3049f --- /dev/null +++ b/icons/codicons/merge.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/multiple-windows.svg b/icons/codicons/multiple-windows.svg new file mode 100644 index 0000000..7ee7455 --- /dev/null +++ b/icons/codicons/multiple-windows.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/new-file.svg b/icons/codicons/new-file.svg new file mode 100644 index 0000000..caac07c --- /dev/null +++ b/icons/codicons/new-file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/new-folder.svg b/icons/codicons/new-folder.svg new file mode 100644 index 0000000..3ada63a --- /dev/null +++ b/icons/codicons/new-folder.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/open-preview.svg b/icons/codicons/open-preview.svg new file mode 100644 index 0000000..765c739 --- /dev/null +++ b/icons/codicons/open-preview.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/plugin-icon.svg b/icons/codicons/plugin-icon.svg new file mode 100644 index 0000000..93badcc --- /dev/null +++ b/icons/codicons/plugin-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/references.svg b/icons/codicons/references.svg new file mode 100644 index 0000000..280b3d8 --- /dev/null +++ b/icons/codicons/references.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/refresh.svg b/icons/codicons/refresh.svg new file mode 100644 index 0000000..9196015 --- /dev/null +++ b/icons/codicons/refresh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/regex.svg b/icons/codicons/regex.svg new file mode 100644 index 0000000..1f45856 --- /dev/null +++ b/icons/codicons/regex.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/remote-explorer.svg b/icons/codicons/remote-explorer.svg new file mode 100644 index 0000000..0152f47 --- /dev/null +++ b/icons/codicons/remote-explorer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/remote.svg b/icons/codicons/remote.svg new file mode 100644 index 0000000..736f9f4 --- /dev/null +++ b/icons/codicons/remote.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/remove.svg b/icons/codicons/remove.svg new file mode 100644 index 0000000..cf31dfe --- /dev/null +++ b/icons/codicons/remove.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/replace-all.svg b/icons/codicons/replace-all.svg new file mode 100644 index 0000000..f5a5153 --- /dev/null +++ b/icons/codicons/replace-all.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/replace.svg b/icons/codicons/replace.svg new file mode 100644 index 0000000..65bfaac --- /dev/null +++ b/icons/codicons/replace.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/repo-clone.svg b/icons/codicons/repo-clone.svg new file mode 100644 index 0000000..ab8f19a --- /dev/null +++ b/icons/codicons/repo-clone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/repo-force-push.svg b/icons/codicons/repo-force-push.svg new file mode 100644 index 0000000..37c9a3d --- /dev/null +++ b/icons/codicons/repo-force-push.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/repo-forked.svg b/icons/codicons/repo-forked.svg new file mode 100644 index 0000000..0cc8093 --- /dev/null +++ b/icons/codicons/repo-forked.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/repo-pull.svg b/icons/codicons/repo-pull.svg new file mode 100644 index 0000000..8210959 --- /dev/null +++ b/icons/codicons/repo-pull.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/repo-push.svg b/icons/codicons/repo-push.svg new file mode 100644 index 0000000..8faf451 --- /dev/null +++ b/icons/codicons/repo-push.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/repo.svg b/icons/codicons/repo.svg new file mode 100644 index 0000000..72fd4ac --- /dev/null +++ b/icons/codicons/repo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/root-folder-opened.svg b/icons/codicons/root-folder-opened.svg new file mode 100644 index 0000000..b31bb8f --- /dev/null +++ b/icons/codicons/root-folder-opened.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/root-folder.svg b/icons/codicons/root-folder.svg new file mode 100644 index 0000000..93839d0 --- /dev/null +++ b/icons/codicons/root-folder.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/run-errors.svg b/icons/codicons/run-errors.svg new file mode 100644 index 0000000..37391ed --- /dev/null +++ b/icons/codicons/run-errors.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/screen-full.svg b/icons/codicons/screen-full.svg new file mode 100644 index 0000000..59d6403 --- /dev/null +++ b/icons/codicons/screen-full.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/screen-normal.svg b/icons/codicons/screen-normal.svg new file mode 100644 index 0000000..e64985e --- /dev/null +++ b/icons/codicons/screen-normal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/search-stop.svg b/icons/codicons/search-stop.svg new file mode 100644 index 0000000..7a80b70 --- /dev/null +++ b/icons/codicons/search-stop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/search.svg b/icons/codicons/search.svg new file mode 100644 index 0000000..13c4df0 --- /dev/null +++ b/icons/codicons/search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/settings-gear.svg b/icons/codicons/settings-gear.svg new file mode 100644 index 0000000..0abb193 --- /dev/null +++ b/icons/codicons/settings-gear.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/settings.svg b/icons/codicons/settings.svg new file mode 100644 index 0000000..67127ea --- /dev/null +++ b/icons/codicons/settings.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/source-control.svg b/icons/codicons/source-control.svg new file mode 100644 index 0000000..edb96f8 --- /dev/null +++ b/icons/codicons/source-control.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/split-horizontal.svg b/icons/codicons/split-horizontal.svg new file mode 100644 index 0000000..d744a79 --- /dev/null +++ b/icons/codicons/split-horizontal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/split-vertical.svg b/icons/codicons/split-vertical.svg new file mode 100644 index 0000000..3a18ab9 --- /dev/null +++ b/icons/codicons/split-vertical.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-array.svg b/icons/codicons/symbol-array.svg new file mode 100644 index 0000000..6bae1fb --- /dev/null +++ b/icons/codicons/symbol-array.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-boolean.svg b/icons/codicons/symbol-boolean.svg new file mode 100644 index 0000000..5941b6b --- /dev/null +++ b/icons/codicons/symbol-boolean.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-class.svg b/icons/codicons/symbol-class.svg new file mode 100644 index 0000000..d837c94 --- /dev/null +++ b/icons/codicons/symbol-class.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-color.svg b/icons/codicons/symbol-color.svg new file mode 100644 index 0000000..d94e57d --- /dev/null +++ b/icons/codicons/symbol-color.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-constant.svg b/icons/codicons/symbol-constant.svg new file mode 100644 index 0000000..ff60164 --- /dev/null +++ b/icons/codicons/symbol-constant.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-enum-member.svg b/icons/codicons/symbol-enum-member.svg new file mode 100644 index 0000000..1236b7b --- /dev/null +++ b/icons/codicons/symbol-enum-member.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-enum.svg b/icons/codicons/symbol-enum.svg new file mode 100644 index 0000000..c7839cc --- /dev/null +++ b/icons/codicons/symbol-enum.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-event.svg b/icons/codicons/symbol-event.svg new file mode 100644 index 0000000..ea695e8 --- /dev/null +++ b/icons/codicons/symbol-event.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-field.svg b/icons/codicons/symbol-field.svg new file mode 100644 index 0000000..a344cf0 --- /dev/null +++ b/icons/codicons/symbol-field.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-file.svg b/icons/codicons/symbol-file.svg new file mode 100644 index 0000000..f5db8ad --- /dev/null +++ b/icons/codicons/symbol-file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-interface.svg b/icons/codicons/symbol-interface.svg new file mode 100644 index 0000000..cef462e --- /dev/null +++ b/icons/codicons/symbol-interface.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-key.svg b/icons/codicons/symbol-key.svg new file mode 100644 index 0000000..c96351a --- /dev/null +++ b/icons/codicons/symbol-key.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-keyword.svg b/icons/codicons/symbol-keyword.svg new file mode 100644 index 0000000..02f6c70 --- /dev/null +++ b/icons/codicons/symbol-keyword.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-method.svg b/icons/codicons/symbol-method.svg new file mode 100644 index 0000000..1506657 --- /dev/null +++ b/icons/codicons/symbol-method.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-misc.svg b/icons/codicons/symbol-misc.svg new file mode 100644 index 0000000..330d87c --- /dev/null +++ b/icons/codicons/symbol-misc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-namespace.svg b/icons/codicons/symbol-namespace.svg new file mode 100644 index 0000000..af267ca --- /dev/null +++ b/icons/codicons/symbol-namespace.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-numeric.svg b/icons/codicons/symbol-numeric.svg new file mode 100644 index 0000000..f654887 --- /dev/null +++ b/icons/codicons/symbol-numeric.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-operator.svg b/icons/codicons/symbol-operator.svg new file mode 100644 index 0000000..6567ca0 --- /dev/null +++ b/icons/codicons/symbol-operator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-parameter.svg b/icons/codicons/symbol-parameter.svg new file mode 100644 index 0000000..5167ffc --- /dev/null +++ b/icons/codicons/symbol-parameter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-property.svg b/icons/codicons/symbol-property.svg new file mode 100644 index 0000000..e5222f9 --- /dev/null +++ b/icons/codicons/symbol-property.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-ruler.svg b/icons/codicons/symbol-ruler.svg new file mode 100644 index 0000000..3d9b7c8 --- /dev/null +++ b/icons/codicons/symbol-ruler.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-snippet.svg b/icons/codicons/symbol-snippet.svg new file mode 100644 index 0000000..ddf3ea6 --- /dev/null +++ b/icons/codicons/symbol-snippet.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-string.svg b/icons/codicons/symbol-string.svg new file mode 100644 index 0000000..9c041d2 --- /dev/null +++ b/icons/codicons/symbol-string.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-structure.svg b/icons/codicons/symbol-structure.svg new file mode 100644 index 0000000..23e897e --- /dev/null +++ b/icons/codicons/symbol-structure.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/symbol-variable.svg b/icons/codicons/symbol-variable.svg new file mode 100644 index 0000000..9dd5073 --- /dev/null +++ b/icons/codicons/symbol-variable.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/terminal.svg b/icons/codicons/terminal.svg new file mode 100644 index 0000000..2ffc08e --- /dev/null +++ b/icons/codicons/terminal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/type-hierarchy.svg b/icons/codicons/type-hierarchy.svg new file mode 100644 index 0000000..bcbc902 --- /dev/null +++ b/icons/codicons/type-hierarchy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/unsaved.svg b/icons/codicons/unsaved.svg new file mode 100644 index 0000000..3357526 --- /dev/null +++ b/icons/codicons/unsaved.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/codicons/warning.svg b/icons/codicons/warning.svg new file mode 100644 index 0000000..9a33f87 --- /dev/null +++ b/icons/codicons/warning.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/whole-word.svg b/icons/codicons/whole-word.svg new file mode 100644 index 0000000..d415932 --- /dev/null +++ b/icons/codicons/whole-word.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/lapce/lapce_logo.svg b/icons/lapce/lapce_logo.svg new file mode 100644 index 0000000..6d3fe1a --- /dev/null +++ b/icons/lapce/lapce_logo.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/icons/lapce/lapce_remote.svg b/icons/lapce/lapce_remote.svg new file mode 100644 index 0000000..6bf4828 --- /dev/null +++ b/icons/lapce/lapce_remote.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lapce-app/Cargo.toml b/lapce-app/Cargo.toml new file mode 100644 index 0000000..c0f780d --- /dev/null +++ b/lapce-app/Cargo.toml @@ -0,0 +1,85 @@ +[package] +name = "lapce-app" +license = { workspace = true } +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } + +[dependencies] +alacritty_terminal = { workspace = true } +anyhow = { workspace = true } +backtrace = { workspace = true } +chrono = { workspace = true } +clap = { workspace = true } +crossbeam-channel = { workspace = true } +flate2 = { workspace = true } +globset = { workspace = true } +im = { workspace = true } +include_dir = { workspace = true } +indexmap = { workspace = true } +interprocess = { workspace = true } +itertools = { workspace = true } +lapce-core = { workspace = true } +lapce-proxy = { workspace = true } +lapce-rpc = { workspace = true } +lapce-xi-rope = { workspace = true } +lsp-types = { workspace = true } +notify = { workspace = true } +once_cell = { workspace = true } +parking_lot = { workspace = true } +rayon = { workspace = true } +reqwest = { workspace = true } +smallvec = { workspace = true } +strum = { workspace = true } +strum_macros = { workspace = true } +semver = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +regex = { workspace = true } +tar = { workspace = true } +tempfile = { workspace = true } +thiserror = { workspace = true } +toml = { workspace = true } +toml_edit = { workspace = true } +tracing = { workspace = true } +tracing-log = { workspace = true } +tracing-subscriber = { workspace = true } +tracing-appender = { workspace = true } +url = { workspace = true } +zstd = { workspace = true } +floem = { workspace = true } + +pulldown-cmark = { version = "0.11.0" } +Inflector = { version = "0.11.4" } +open = { version = "5.1.4" } +unicode-width = { version = "0.1.13" } +nucleo = { version = "0.5.0" } +bytemuck = { version = "1.22.0" } +config = { version = "=0.13.4", default-features = false, features = ["toml"] } +structdesc = { git = "https://github.com/lapce/structdesc", rev = "bb56969f22fdb2c2d6c03f158fd4a2bdc983b659" } +base64 = { version = "0.21.7" } +sha2 = { version = "0.10.8" } +zip = { version = "0.6.6", default-features = false, features = ["deflate"] } +percent-encoding = { version = "2.3.1" } + +[target.'cfg(target_os="macos")'.dependencies] +fs_extra = "1.2.0" +dmg = "0.1.1" + +[target.'cfg(windows)'.dependencies.windows-sys] +workspace = true +features = ["Win32_Foundation", "Win32_System_Threading", "Win32_UI_WindowsAndMessaging"] + +[features] +default = ["updater", "vendored-fonts"] +portable = ["lapce-core/portable"] +updater = [] +vendored-fonts = [] + +[dev-dependencies] +criterion = "0.5" + +[[bench]] +name = "visual_line" +harness = false diff --git a/lapce-app/benches/visual_line.rs b/lapce-app/benches/visual_line.rs new file mode 100644 index 0000000..e78d2b7 --- /dev/null +++ b/lapce-app/benches/visual_line.rs @@ -0,0 +1,278 @@ +use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::Arc}; + +use criterion::{Criterion, black_box, criterion_group, criterion_main}; +use floem::{ + reactive::Scope, + text::{Attrs, AttrsList, FamilyOwned, TextLayout, Wrap}, + views::editor::{ + layout::TextLayoutLine, + phantom_text::PhantomTextLine, + visual_line::{ + ConfigId, FontSizeCacheId, LineFontSizeProvider, Lines, ResolvedWrap, + TextLayoutProvider, VLine, + }, + }, +}; +use lapce_core::{ + buffer::rope_text::{RopeText, RopeTextRef}, + cursor::CursorAffinity, +}; +use lapce_xi_rope::Rope; + +const FONT_SIZE: usize = 12; + +// TODO: use the editor data view structures! +struct TLProv<'a> { + text: &'a Rope, + phantom: HashMap, + font_family: Vec, + has_multiline_phantom: bool, +} +impl TextLayoutProvider for TLProv<'_> { + fn text(&self) -> Rope { + self.text.clone() + } + + // An implementation relatively close to the actual new text layout impl but simplified. + // TODO(minor): It would be nice to just use the same impl as view's + fn new_text_layout( + &self, + line: usize, + font_size: usize, + wrap: ResolvedWrap, + ) -> Arc { + let rope_text = RopeTextRef::new(self.text); + let line_content_original = rope_text.line_content(line); + + // Get the line content with newline characters replaced with spaces + // and the content without the newline characters + let (line_content, _line_content_original) = + if let Some(s) = line_content_original.strip_suffix("\r\n") { + ( + format!("{s} "), + &line_content_original[..line_content_original.len() - 2], + ) + } else if let Some(s) = line_content_original.strip_suffix('\n') { + ( + format!("{s} ",), + &line_content_original[..line_content_original.len() - 1], + ) + } else { + ( + line_content_original.to_string(), + &line_content_original[..], + ) + }; + + let phantom_text = self.phantom.get(&line).cloned().unwrap_or_default(); + let line_content = phantom_text.combine_with_text(&line_content); + + let attrs = Attrs::new() + .family(&self.font_family) + .font_size(font_size as f32); + let mut attrs_list = AttrsList::new(attrs.clone()); + + // We don't do line styles, since they aren't relevant + + // Apply phantom text specific styling + for (offset, size, col, phantom) in phantom_text.offset_size_iter() { + let start = col + offset; + let end = start + size; + + let mut attrs = attrs.clone(); + if let Some(fg) = phantom.fg { + attrs = attrs.color(fg); + } + if let Some(phantom_font_size) = phantom.font_size { + attrs = attrs.font_size(phantom_font_size.min(font_size) as f32); + } + attrs_list.add_span(start..end, attrs); + // if let Some(font_family) = phantom.font_family.clone() { + // layout_builder = layout_builder.range_attribute( + // start..end, + // TextAttribute::FontFamily(font_family), + // ); + // } + } + + let mut text_layout = TextLayout::new(); + text_layout.set_wrap(Wrap::Word); + match wrap { + // We do not have to set the wrap mode if we do not set the width + ResolvedWrap::None => {} + ResolvedWrap::Column(_col) => todo!(), + ResolvedWrap::Width(px) => { + text_layout.set_size(px, f32::MAX); + } + } + text_layout.set_text(&line_content, attrs_list, None); + + // skip phantom text background styling because it doesn't shift positions + // skip severity styling + // skip diagnostic background styling + + Arc::new(TextLayoutLine { + extra_style: Vec::new(), + text: text_layout, + whitespaces: None, + indent: 0.0, + phantom_text: PhantomTextLine::default(), + }) + } + + fn before_phantom_col(&self, line: usize, col: usize) -> usize { + if let Some(phantom) = self.phantom.get(&line) { + phantom.before_col(col) + } else { + col + } + } + + fn has_multiline_phantom(&self) -> bool { + self.has_multiline_phantom + } +} +struct TestFontSize; +impl LineFontSizeProvider for TestFontSize { + fn font_size(&self, _line: usize) -> usize { + FONT_SIZE + } + + fn cache_id(&self) -> FontSizeCacheId { + 0 + } +} + +fn make_lines(text: &Rope, wrap: ResolvedWrap, init: bool) -> (TLProv<'_>, Lines) { + make_lines_ph(text, wrap, init, HashMap::new(), false) +} + +fn make_lines_ph( + text: &Rope, + wrap: ResolvedWrap, + init: bool, + ph: HashMap, + has_multiline_phantom: bool, +) -> (TLProv<'_>, Lines) { + // let wrap = Wrap::Word; + // let r_wrap = ResolvedWrap::Width(width); + let font_sizes = TestFontSize; + let text = TLProv { + text, + phantom: ph, + font_family: Vec::new(), + has_multiline_phantom, + }; + let cx = Scope::new(); + let lines = Lines::new(cx, RefCell::new(Rc::new(font_sizes))); + lines.set_wrap(wrap); + + if init { + lines.init_all(0, ConfigId::new(0, 0), &text, true); + } + + (text, lines) +} + +fn medium_rope() -> Rope { + let mut text = String::new(); + + // TODO: use some actual file's content. + for i in 0..3000 { + let content = if i % 2 == 0 { + "This is a roughly typical line of text\n" + } else if i % 3 == 0 { + "\n" + } else { + "A short line\n" + }; + + text.push_str(content); + } + + Rope::from(&text) +} + +fn visual_line(c: &mut Criterion) { + let text = medium_rope(); + + // Should be very fast because it is trivially linear and there's no multiline phantom + c.bench_function("last vline (uninit)", |b| { + let (text_prov, lines) = make_lines(&text, ResolvedWrap::None, false); + b.iter(|| { + lines.clear_last_vline(); + + let last_vline = lines.last_vline(&text_prov); + black_box(last_vline); + }) + }); + + // Unrealistic since the user will very rarely have all of the lines initialized + // Should still be fast because there's no wrapping or multiline phantom text + c.bench_function("last vline (all, no wrapping)", |b| { + let (text_prov, lines) = make_lines(&text, ResolvedWrap::None, true); + b.iter(|| { + lines.clear_last_vline(); + + let last_vline = lines.last_vline(&text_prov); + let _val = black_box(last_vline); + }) + }); + + // TODO: we could precompute line count on the text layout? + // Unrealistic since the user will very rarely have all of the lines initialized + // Still decently fast, though. <1ms + c.bench_function("last vline (all, wrapping)", |b| { + let width = 100.0; + let (text_prov, lines) = make_lines(&text, ResolvedWrap::Width(width), true); + + b.iter(|| { + // This should clear any other caching mechanisms that get added + lines.clear_last_vline(); + let last_vline = lines.last_vline(&text_prov); + let _val = black_box(last_vline); + }) + }); + + // Q: This seems like 1/5th the cost of last vline despite only being half the lines.. + c.bench_function("vline of offset (all, wrapping)", |b| { + let width = 100.0; + let (text_prov, lines) = make_lines(&text, ResolvedWrap::Width(width), true); + + // Not past the middle. If we were past the middle then it'd be just benching last vline + // calculation, which is admittedly relatively similar to this. + let offset = 1450; + + b.iter(|| { + // This should clear any other caching mechanisms that get added + lines.clear_last_vline(); + + let vline = + lines.vline_of_offset(&text_prov, offset, CursorAffinity::Backward); + let _val = black_box(vline); + }) + }); + + c.bench_function("offset of vline (all, wrapping)", |b| { + let width = 100.0; + let (text_prov, lines) = make_lines(&text, ResolvedWrap::Width(width), true); + + let vline = VLine(3300); + + b.iter(|| { + // This should clear any other caching mechanisms that get added + lines.clear_last_vline(); + + let offset = lines.offset_of_vline(&text_prov, vline); + let _val = black_box(offset); + }) + }); + + // TODO: when we have the reverse search of vline for offset, we should have a separate instance where the last vline isn't cached, which would give us a range of 'worst case' (never reused, have to recopmute it everytime) and 'best case' (always reused) + + // TODO: bench common operations, like a single line changing or the (equivalent of) cache rev + // updating. +} + +criterion_group!(benches, visual_line); +criterion_main!(benches); diff --git a/lapce-app/src/about.rs b/lapce-app/src/about.rs new file mode 100644 index 0000000..75f9281 --- /dev/null +++ b/lapce-app/src/about.rs @@ -0,0 +1,213 @@ +use std::rc::Rc; + +use floem::{ + View, + event::EventListener, + keyboard::Modifiers, + reactive::{RwSignal, Scope, SignalGet, SignalUpdate}, + style::{CursorStyle, Display, Position}, + views::{Decorators, container, label, stack, svg}, +}; +use lapce_core::{command::FocusCommand, meta::VERSION, mode::Mode}; + +use crate::{ + command::{CommandExecuted, CommandKind}, + config::color::LapceColor, + keypress::KeyPressFocus, + web_link::web_link, + window_tab::{Focus, WindowTabData}, +}; + +struct AboutUri {} + +impl AboutUri { + const LAPCE: &'static str = "https://lapce.dev"; + const GITHUB: &'static str = "https://github.com/lapce/lapce"; + const MATRIX: &'static str = "https://matrix.to/#/#lapce-editor:matrix.org"; + const DISCORD: &'static str = "https://discord.gg/n8tGJ6Rn6D"; + const CODICONS: &'static str = "https://github.com/microsoft/vscode-codicons"; +} + +#[derive(Clone, Debug)] +pub struct AboutData { + pub visible: RwSignal, + pub focus: RwSignal, +} + +impl AboutData { + pub fn new(cx: Scope, focus: RwSignal) -> Self { + let visible = cx.create_rw_signal(false); + + Self { visible, focus } + } + + pub fn open(&self) { + self.visible.set(true); + self.focus.set(Focus::AboutPopup); + } + + pub fn close(&self) { + self.visible.set(false); + self.focus.set(Focus::Workbench); + } +} + +impl KeyPressFocus for AboutData { + fn get_mode(&self) -> Mode { + Mode::Insert + } + + fn check_condition( + &self, + _condition: crate::keypress::condition::Condition, + ) -> bool { + self.visible.get_untracked() + } + + fn run_command( + &self, + command: &crate::command::LapceCommand, + _count: Option, + _mods: Modifiers, + ) -> crate::command::CommandExecuted { + match &command.kind { + CommandKind::Workbench(_) => {} + CommandKind::Edit(_) => {} + CommandKind::Move(_) => {} + CommandKind::Scroll(_) => {} + CommandKind::Focus(cmd) => { + if cmd == &FocusCommand::ModalClose { + self.close(); + } + } + CommandKind::MotionMode(_) => {} + CommandKind::MultiSelection(_) => {} + } + CommandExecuted::Yes + } + + fn receive_char(&self, _c: &str) {} + + fn focus_only(&self) -> bool { + true + } +} + +pub fn about_popup(window_tab_data: Rc) -> impl View { + let about_data = window_tab_data.about_data.clone(); + let config = window_tab_data.common.config; + let internal_command = window_tab_data.common.internal_command; + let logo_size = 100.0; + + exclusive_popup(window_tab_data, about_data.visible, move || { + stack(( + svg(move || (config.get()).logo_svg()).style(move |s| { + s.size(logo_size, logo_size) + .color(config.get().color(LapceColor::EDITOR_FOREGROUND)) + }), + label(|| "Lapce".to_string()).style(move |s| { + s.font_bold() + .margin_top(10.0) + .color(config.get().color(LapceColor::EDITOR_FOREGROUND)) + }), + label(|| format!("Version: {}", VERSION)).style(move |s| { + s.margin_top(10.0) + .color(config.get().color(LapceColor::EDITOR_DIM)) + }), + web_link( + || "Website".to_string(), + || AboutUri::LAPCE.to_string(), + move || config.get().color(LapceColor::EDITOR_LINK), + internal_command, + ) + .style(|s| s.margin_top(20.0)), + web_link( + || "GitHub".to_string(), + || AboutUri::GITHUB.to_string(), + move || config.get().color(LapceColor::EDITOR_LINK), + internal_command, + ) + .style(|s| s.margin_top(10.0)), + web_link( + || "Discord".to_string(), + || AboutUri::DISCORD.to_string(), + move || config.get().color(LapceColor::EDITOR_LINK), + internal_command, + ) + .style(|s| s.margin_top(10.0)), + web_link( + || "Matrix".to_string(), + || AboutUri::MATRIX.to_string(), + move || config.get().color(LapceColor::EDITOR_LINK), + internal_command, + ) + .style(|s| s.margin_top(10.0)), + label(|| "Attributions".to_string()).style(move |s| { + s.font_bold() + .color(config.get().color(LapceColor::EDITOR_DIM)) + .margin_top(40.0) + }), + web_link( + || "Codicons (CC-BY-4.0)".to_string(), + || AboutUri::CODICONS.to_string(), + move || config.get().color(LapceColor::EDITOR_LINK), + internal_command, + ) + .style(|s| s.margin_top(10.0)), + )) + .style(|s| s.flex_col().items_center()) + }) + .debug_name("About Popup") +} + +fn exclusive_popup( + window_tab_data: Rc, + visibility: RwSignal, + content: impl FnOnce() -> V, +) -> impl View { + let config = window_tab_data.common.config; + + container( + container( + container(content()) + .style(move |s| { + let config = config.get(); + s.padding_vert(25.0) + .padding_horiz(100.0) + .border(1.0) + .border_radius(6.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .background(config.color(LapceColor::PANEL_BACKGROUND)) + }) + .on_event_stop(EventListener::PointerDown, move |_| {}), + ) + .style(move |s| { + s.flex_grow(1.0) + .flex_row() + .items_center() + .hover(move |s| s.cursor(CursorStyle::Default)) + }), + ) + .on_event_stop(EventListener::PointerDown, move |_| { + window_tab_data.about_data.close(); + }) + // Prevent things behind the grayed out area from being hovered. + .on_event_stop(EventListener::PointerMove, move |_| {}) + .style(move |s| { + s.display(if visibility.get() { + Display::Flex + } else { + Display::None + }) + .position(Position::Absolute) + .size_pct(100.0, 100.0) + .flex_col() + .items_center() + .background( + config + .get() + .color(LapceColor::LAPCE_DROPDOWN_SHADOW) + .multiply_alpha(0.5), + ) + }) +} diff --git a/lapce-app/src/alert.rs b/lapce-app/src/alert.rs new file mode 100644 index 0000000..48f6bcb --- /dev/null +++ b/lapce-app/src/alert.rs @@ -0,0 +1,174 @@ +use std::{ + fmt, + rc::Rc, + sync::{Arc, atomic::AtomicU64}, +}; + +use floem::{ + View, + event::EventListener, + reactive::{ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate}, + style::CursorStyle, + views::{Decorators, container, dyn_stack, label, stack, svg}, +}; + +use crate::{ + config::{LapceConfig, color::LapceColor, icon::LapceIcons}, + window_tab::CommonData, +}; + +#[derive(Clone)] +pub struct AlertButton { + pub text: String, + pub action: Rc, +} + +impl fmt::Debug for AlertButton { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut s = f.debug_struct("AlertButton"); + s.field("text", &self.text); + s.finish() + } +} + +#[derive(Clone)] +pub struct AlertBoxData { + pub active: RwSignal, + pub title: RwSignal, + pub msg: RwSignal, + pub buttons: RwSignal>, + pub config: ReadSignal>, +} + +impl AlertBoxData { + pub fn new(cx: Scope, common: Rc) -> Self { + Self { + active: cx.create_rw_signal(false), + title: cx.create_rw_signal("".to_string()), + msg: cx.create_rw_signal("".to_string()), + buttons: cx.create_rw_signal(Vec::new()), + config: common.config, + } + } +} + +pub fn alert_box(alert_data: AlertBoxData) -> impl View { + let config = alert_data.config; + let active = alert_data.active; + let title = alert_data.title; + let msg = alert_data.msg; + let buttons = alert_data.buttons; + let button_id = AtomicU64::new(0); + + container({ + container({ + stack(( + svg(move || config.get().ui_svg(LapceIcons::WARNING)).style( + move |s| { + s.size(50.0, 50.0) + .color(config.get().color(LapceColor::LAPCE_WARN)) + }, + ), + label(move || title.get()).style(move |s| { + s.margin_top(20.0) + .width_pct(100.0) + .font_bold() + .font_size((config.get().ui.font_size() + 1) as f32) + }), + label(move || msg.get()) + .style(move |s| s.width_pct(100.0).margin_top(10.0)), + dyn_stack( + move || buttons.get(), + move |_button| { + button_id.fetch_add(1, std::sync::atomic::Ordering::Relaxed) + }, + move |button| { + label(move || button.text.clone()) + .on_click_stop(move |_| { + (button.action)(); + }) + .style(move |s| { + let config = config.get(); + s.margin_top(10.0) + .width_pct(100.0) + .justify_center() + .font_size((config.ui.font_size() + 1) as f32) + .line_height(1.6) + .border(1.0) + .border_radius(6.0) + .border_color( + config.color(LapceColor::LAPCE_BORDER), + ) + .hover(|s| { + s.cursor(CursorStyle::Pointer).background( + config.color( + LapceColor::PANEL_HOVERED_BACKGROUND, + ), + ) + }) + .active(|s| { + s.background(config.color( + LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND, + )) + }) + }) + }, + ) + .style(|s| s.flex_col().width_pct(100.0).margin_top(10.0)), + label(|| "Cancel".to_string()) + .on_click_stop(move |_| { + active.set(false); + }) + .style(move |s| { + let config = config.get(); + s.margin_top(20.0) + .width_pct(100.0) + .justify_center() + .font_size((config.ui.font_size() + 1) as f32) + .line_height(1.5) + .border(1.0) + .border_radius(6.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .hover(|s| { + s.cursor(CursorStyle::Pointer).background( + config + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + }) + .active(|s| { + s.background(config.color( + LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND, + )) + }) + }), + )) + .style(|s| s.flex_col().items_center().width_pct(100.0)) + }) + .on_event_stop(EventListener::PointerDown, |_| {}) + .style(move |s| { + let config = config.get(); + s.padding(20.0) + .width(250.0) + .border(1.0) + .border_radius(6.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .color(config.color(LapceColor::EDITOR_FOREGROUND)) + .background(config.color(LapceColor::PANEL_BACKGROUND)) + }) + }) + .on_event_stop(EventListener::PointerDown, move |_| {}) + .style(move |s| { + s.absolute() + .size_pct(100.0, 100.0) + .items_center() + .justify_center() + .apply_if(!active.get(), |s| s.hide()) + .background( + config + .get() + .color(LapceColor::LAPCE_DROPDOWN_SHADOW) + .multiply_alpha(0.5), + ) + }) + .debug_name("Alert Box") +} diff --git a/lapce-app/src/app.rs b/lapce-app/src/app.rs new file mode 100644 index 0000000..a1de1a5 --- /dev/null +++ b/lapce-app/src/app.rs @@ -0,0 +1,4321 @@ +#[cfg(target_os = "windows")] +use std::os::windows::process::CommandExt; +use std::{ + io::{BufReader, IsTerminal, Read, Write}, + ops::Range, + path::PathBuf, + process::Stdio, + rc::Rc, + sync::{ + Arc, + atomic::AtomicU64, + mpsc::{SyncSender, channel, sync_channel}, + }, +}; + +use anyhow::{Context, Result, anyhow}; +use clap::Parser; +use floem::{ + IntoView, View, + action::show_context_menu, + event::{Event, EventListener, EventPropagation}, + ext_event::{create_ext_action, create_signal_from_channel}, + menu::{Menu, MenuItem}, + peniko::{ + Color, + kurbo::{Point, Rect, Size}, + }, + prelude::SignalTrack, + reactive::{ + ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith, + create_effect, create_memo, create_rw_signal, provide_context, use_context, + }, + style::{ + AlignItems, CursorStyle, Display, FlexDirection, JustifyContent, Position, + Style, + }, + taffy::{ + Line, + style_helpers::{self, auto, fr}, + }, + text::{Style as FontStyle, Weight}, + unit::PxPctAuto, + views::{ + Decorators, VirtualVector, clip, container, drag_resize_window_area, + drag_window_area, dyn_stack, + editor::{core::register::Clipboard, text::SystemClipboard}, + empty, label, rich_text, + scroll::{PropagatePointerWheel, VerticalScrollAsHorizontal, scroll}, + stack, svg, tab, text, tooltip, virtual_stack, + }, + window::{ResizeDirection, WindowConfig, WindowId}, +}; +use lapce_core::{ + command::{EditCommand, FocusCommand}, + directory::Directory, + meta, + syntax::{Syntax, highlight::reset_highlight_configs}, +}; +use lapce_rpc::{ + RpcMessage, + core::{CoreMessage, CoreNotification}, + file::PathObject, +}; +use lsp_types::{CompletionItemKind, MessageType, ShowMessageParams}; +use notify::Watcher; +use serde::{Deserialize, Serialize}; +use tracing_subscriber::{filter::Targets, reload::Handle}; + +use crate::{ + about, alert, + code_action::CodeActionStatus, + command::{ + CommandKind, InternalCommand, LapceCommand, LapceWorkbenchCommand, + WindowCommand, + }, + config::{ + LapceConfig, color::LapceColor, icon::LapceIcons, ui::TabSeparatorHeight, + watcher::ConfigWatcher, + }, + db::LapceDb, + debug::RunDebugMode, + editor::{ + diff::diff_show_more_section_view, + location::{EditorLocation, EditorPosition}, + view::editor_container_view, + }, + editor_tab::{EditorTabChild, EditorTabData}, + focus_text::focus_text, + id::{EditorTabId, SplitId}, + keymap::keymap_view, + keypress::keymap::KeyMap, + listener::Listener, + main_split::{ + SplitContent, SplitData, SplitDirection, SplitMoveDirection, TabCloseKind, + }, + markdown::MarkdownContent, + palette::{ + PaletteStatus, + item::{PaletteItem, PaletteItemContent}, + }, + panel::{position::PanelContainerPosition, view::panel_container_view}, + plugin::{PluginData, plugin_info_view}, + settings::{settings_view, theme_color_settings_view}, + status::status, + text_input::TextInputBuilder, + title::{title, window_controls_view}, + tracing::*, + update::ReleaseInfo, + window::{TabsInfo, WindowData, WindowInfo}, + window_tab::{Focus, WindowTabData}, + workspace::{LapceWorkspace, LapceWorkspaceType}, +}; + +mod grammars; +mod logging; + +#[derive(Parser)] +#[clap(name = "Lapce")] +#[clap(version=meta::VERSION)] +#[derive(Debug)] +struct Cli { + /// Launch new window even if Lapce is already running + #[clap(short, long, action)] + new: bool, + /// Don't return instantly when opened in a terminal + #[clap(short, long, action)] + wait: bool, + + /// Path(s) to plugins to load. + /// + /// This is primarily used for plugin development to make it easier to test changes to the + /// plugin without needing to copy the plugin to the plugins directory. + /// This will cause any plugin with the same author & name to not run. + #[clap(long, action)] + plugin_path: Vec, + + /// Paths to file(s) and/or folder(s) to open. + /// When path is a file (that exists or not), + /// it accepts `path:line:column` syntax + /// to specify line and column at which it should open the file + #[clap(value_parser = lapce_proxy::cli::parse_file_line_column)] + #[clap(value_hint = clap::ValueHint::AnyPath)] + paths: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AppInfo { + pub windows: Vec, +} + +#[derive(Clone)] +pub enum AppCommand { + SaveApp, + NewWindow { folder: Option }, + CloseWindow(WindowId), + WindowGotFocus(WindowId), + WindowClosed(WindowId), +} + +#[derive(Clone)] +pub struct AppData { + pub windows: RwSignal>, + pub active_window: RwSignal, + pub window_scale: RwSignal, + pub app_command: Listener, + pub app_terminated: RwSignal, + /// The latest release information + pub latest_release: RwSignal>>, + pub watcher: Arc, + pub tracing_handle: Handle, + pub config: RwSignal>, + /// Paths to extra plugins to load + pub plugin_paths: Arc>, +} + +impl AppData { + pub fn reload_config(&self) { + let config = + LapceConfig::load(&LapceWorkspace::default(), &[], &self.plugin_paths); + + self.config.set(Arc::new(config)); + self.window_scale.set(self.config.get().ui.scale()); + + let windows = self.windows.get_untracked(); + for (_, window) in windows { + window.reload_config(); + } + } + + pub fn active_window_tab(&self) -> Option> { + if let Some(window) = self.active_window() { + return window.active_window_tab(); + } + None + } + + fn active_window(&self) -> Option { + let windows = self.windows.get_untracked(); + let active_window = self.active_window.get_untracked(); + windows + .get(&active_window) + .cloned() + .or_else(|| windows.iter().next().map(|(_, window)| window.clone())) + } + + fn default_window_config(&self) -> WindowConfig { + WindowConfig::default() + .apply_default_theme(false) + .title("Lapce") + } + + pub fn new_window(&self, folder: Option) { + let config = self + .active_window() + .map(|window| { + self.default_window_config() + .size(window.common.size.get_untracked()) + .position(window.position.get_untracked() + (50.0, 50.0)) + }) + .or_else(|| { + let db: Arc = use_context().unwrap(); + db.get_window().ok().map(|info| { + self.default_window_config() + .size(info.size) + .position(info.pos) + }) + }) + .unwrap_or_else(|| { + self.default_window_config().size(Size::new(800.0, 600.0)) + }); + let config = if cfg!(target_os = "macos") + || self.config.get_untracked().core.custom_titlebar + { + config.show_titlebar(false) + } else { + config + }; + let workspace = LapceWorkspace { + path: folder, + ..Default::default() + }; + let app_data = self.clone(); + floem::new_window( + move |window_id| { + app_data.app_view( + window_id, + WindowInfo { + size: Size::ZERO, + pos: Point::ZERO, + maximised: false, + tabs: TabsInfo { + active_tab: 0, + workspaces: vec![workspace], + }, + }, + vec![], + ) + }, + Some(config), + ); + } + + pub fn run_app_command(&self, cmd: AppCommand) { + match cmd { + AppCommand::SaveApp => { + let db: Arc = use_context().unwrap(); + if let Err(err) = db.save_app(self) { + tracing::error!("{:?}", err); + } + } + AppCommand::WindowClosed(window_id) => { + if self.app_terminated.get_untracked() { + return; + } + let db: Arc = use_context().unwrap(); + if self.windows.with_untracked(|w| w.len()) == 1 { + if let Err(err) = db.insert_app(self.clone()) { + tracing::error!("{:?}", err); + } + } + let window_data = self + .windows + .try_update(|windows| windows.remove(&window_id)) + .unwrap(); + if let Some(window_data) = window_data { + window_data.scope.dispose(); + } + if let Err(err) = db.save_app(self) { + tracing::error!("{:?}", err); + } + } + AppCommand::CloseWindow(window_id) => { + floem::close_window(window_id); + } + AppCommand::NewWindow { folder } => { + self.new_window(folder); + } + AppCommand::WindowGotFocus(window_id) => { + self.active_window.set(window_id); + } + } + } + + fn create_windows( + &self, + db: Arc, + paths: Vec, + ) -> floem::Application { + let mut app = floem::Application::new(); + + let mut initial_windows = 0; + + // Split user input into known existing directors and + // file paths that exist or not + let (dirs, files): (Vec<&PathObject>, Vec<&PathObject>) = + paths.iter().partition(|p| p.is_dir); + + let files: Vec = files.into_iter().cloned().collect(); + let mut files = if files.is_empty() { None } else { Some(files) }; + + if !dirs.is_empty() { + // There were directories specified, so we'll load those as windows + + // Use the last opened window's size and position as the default + let (size, mut pos) = db + .get_window() + .map(|i| (i.size, i.pos)) + .unwrap_or_else(|_| (Size::new(800.0, 600.0), Point::new(0.0, 0.0))); + + for dir in dirs { + #[cfg(windows)] + let workspace_type = if !std::env::var("WSL_DISTRO_NAME") + .unwrap_or_default() + .is_empty() + || !std::env::var("WSL_INTEROP").unwrap_or_default().is_empty() + { + LapceWorkspaceType::RemoteWSL(crate::workspace::WslHost { + host: String::new(), + }) + } else { + LapceWorkspaceType::Local + }; + #[cfg(not(windows))] + let workspace_type = LapceWorkspaceType::Local; + + let info = WindowInfo { + size, + pos, + maximised: false, + tabs: TabsInfo { + active_tab: 0, + workspaces: vec![LapceWorkspace { + kind: workspace_type, + path: Some(dir.path.to_owned()), + last_open: 0, + }], + }, + }; + + pos += (50.0, 50.0); + + let config = self + .default_window_config() + .size(info.size) + .position(info.pos); + let config = if cfg!(target_os = "macos") + || self.config.get_untracked().core.custom_titlebar + { + config.show_titlebar(false) + } else { + config + }; + let app_data = self.clone(); + let files = files.take().unwrap_or_default(); + app = app.window( + move |window_id| app_data.app_view(window_id, info, files), + Some(config), + ); + initial_windows += 1; + } + } else if files.is_none() { + // There were no dirs and no files specified, so we'll load the last windows + match db.get_app() { + Ok(app_info) => { + for info in app_info.windows { + let config = self + .default_window_config() + .size(info.size) + .position(info.pos); + let config = if cfg!(target_os = "macos") + || self.config.get_untracked().core.custom_titlebar + { + config.show_titlebar(false) + } else { + config + }; + let app_data = self.clone(); + app = app.window( + move |window_id| { + app_data.app_view(window_id, info, vec![]) + }, + Some(config), + ); + initial_windows += 1; + } + } + Err(err) => { + tracing::error!("{:?}", err); + } + } + } + + if initial_windows == 0 { + let mut info = db.get_window().unwrap_or_else(|_| WindowInfo { + size: Size::new(800.0, 600.0), + pos: Point::ZERO, + maximised: false, + tabs: TabsInfo { + active_tab: 0, + workspaces: vec![LapceWorkspace::default()], + }, + }); + info.tabs = TabsInfo { + active_tab: 0, + workspaces: vec![LapceWorkspace::default()], + }; + let config = self + .default_window_config() + .size(info.size) + .position(info.pos); + let config = if cfg!(target_os = "macos") + || self.config.get_untracked().core.custom_titlebar + { + config.show_titlebar(false) + } else { + config + }; + let app_data = self.clone(); + app = app.window( + move |window_id| { + app_data.app_view( + window_id, + info, + files.take().unwrap_or_default(), + ) + }, + Some(config), + ); + } + + app + } + + fn app_view( + &self, + window_id: WindowId, + info: WindowInfo, + files: Vec, + ) -> impl View + use<> { + let app_view_id = create_rw_signal(floem::ViewId::new()); + let window_data = WindowData::new( + window_id, + app_view_id, + info, + self.window_scale, + self.latest_release.read_only(), + self.plugin_paths.clone(), + self.app_command, + ); + + { + let cur_window_tab = window_data.active.get_untracked(); + let (_, window_tab) = + &window_data.window_tabs.get_untracked()[cur_window_tab]; + for file in files { + let position = file.linecol.map(|pos| { + EditorPosition::Position(lsp_types::Position { + line: pos.line.saturating_sub(1) as u32, + character: pos.column.saturating_sub(1) as u32, + }) + }); + + window_tab.run_internal_command(InternalCommand::GoToLocation { + location: EditorLocation { + path: file.path.clone(), + position, + scroll_offset: None, + // Create a new editor for the file, so we don't change any current unconfirmed + // editor + ignore_unconfirmed: true, + same_editor_tab: false, + }, + }); + } + } + + self.windows.update(|windows| { + windows.insert(window_id, window_data.clone()); + }); + let window_size = window_data.common.size; + let position = window_data.position; + let window_scale = window_data.window_scale; + let app_command = window_data.app_command; + let config = window_data.config; + // The KeyDown and PointerDown event handlers both need ownership of a WindowData object. + let key_down_window_data = window_data.clone(); + let view = stack(( + workspace_tab_header(window_data.clone()), + window(window_data.clone()), + stack(( + drag_resize_window_area(ResizeDirection::West, empty()).style(|s| { + s.absolute().width(4.0).height_full().pointer_events_auto() + }), + drag_resize_window_area(ResizeDirection::North, empty()).style( + |s| s.absolute().width_full().height(4.0).pointer_events_auto(), + ), + drag_resize_window_area(ResizeDirection::East, empty()).style( + move |s| { + s.absolute() + .margin_left(window_size.get().width as f32 - 4.0) + .width(4.0) + .height_full() + .pointer_events_auto() + }, + ), + drag_resize_window_area(ResizeDirection::South, empty()).style( + move |s| { + s.absolute() + .margin_top(window_size.get().height as f32 - 4.0) + .width_full() + .height(4.0) + .pointer_events_auto() + }, + ), + drag_resize_window_area(ResizeDirection::NorthWest, empty()).style( + |s| s.absolute().width(20.0).height(4.0).pointer_events_auto(), + ), + drag_resize_window_area(ResizeDirection::NorthWest, empty()).style( + |s| s.absolute().width(4.0).height(20.0).pointer_events_auto(), + ), + drag_resize_window_area(ResizeDirection::NorthEast, empty()).style( + move |s| { + s.absolute() + .margin_left(window_size.get().width as f32 - 20.0) + .width(20.0) + .height(4.0) + .pointer_events_auto() + }, + ), + drag_resize_window_area(ResizeDirection::NorthEast, empty()).style( + move |s| { + s.absolute() + .margin_left(window_size.get().width as f32 - 4.0) + .width(4.0) + .height(20.0) + .pointer_events_auto() + }, + ), + drag_resize_window_area(ResizeDirection::SouthWest, empty()).style( + move |s| { + s.absolute() + .margin_top(window_size.get().height as f32 - 4.0) + .width(20.0) + .height(4.0) + .pointer_events_auto() + }, + ), + drag_resize_window_area(ResizeDirection::SouthWest, empty()).style( + move |s| { + s.absolute() + .margin_top(window_size.get().height as f32 - 20.0) + .width(4.0) + .height(20.0) + .pointer_events_auto() + }, + ), + drag_resize_window_area(ResizeDirection::SouthEast, empty()).style( + move |s| { + s.absolute() + .margin_left(window_size.get().width as f32 - 20.0) + .margin_top(window_size.get().height as f32 - 4.0) + .width(20.0) + .height(4.0) + .pointer_events_auto() + }, + ), + drag_resize_window_area(ResizeDirection::SouthEast, empty()).style( + move |s| { + s.absolute() + .margin_left(window_size.get().width as f32 - 4.0) + .margin_top(window_size.get().height as f32 - 20.0) + .width(4.0) + .height(20.0) + .pointer_events_auto() + }, + ), + )) + .debug_name("Drag Resize Areas") + .style(move |s| { + s.absolute() + .size_full() + .apply_if( + cfg!(target_os = "macos") + || !config.get_untracked().core.custom_titlebar, + |s| s.hide(), + ) + .pointer_events_none() + }), + )) + .style(|s| s.flex_col().size_full()); + let view_id = view.id(); + app_view_id.set(view_id); + + view_id.request_focus(); + + view.window_scale(move || window_scale.get()) + .keyboard_navigable() + .on_event(EventListener::KeyDown, move |event| { + if let Event::KeyDown(key_event) = event { + if key_down_window_data.key_down(key_event) { + view_id.request_focus(); + } + EventPropagation::Stop + } else { + EventPropagation::Continue + } + }) + .on_event(EventListener::PointerDown, { + let window_data = window_data.clone(); + move |event| { + if let Event::PointerDown(pointer_event) = event { + window_data.key_down(pointer_event); + EventPropagation::Stop + } else { + EventPropagation::Continue + } + } + }) + .on_event_stop(EventListener::WindowResized, move |event| { + if let Event::WindowResized(size) = event { + window_size.set(*size); + } + }) + .on_event_stop(EventListener::WindowMoved, move |event| { + if let Event::WindowMoved(point) = event { + position.set(*point); + } + }) + .on_event_stop(EventListener::WindowGotFocus, move |_| { + app_command.send(AppCommand::WindowGotFocus(window_id)); + }) + .on_event_stop(EventListener::WindowClosed, move |_| { + app_command.send(AppCommand::WindowClosed(window_id)); + }) + .on_event_stop(EventListener::DroppedFile, move |event: &Event| { + if let Event::DroppedFile(file) = event { + if file.path.is_dir() { + app_command.send(AppCommand::NewWindow { + folder: Some(file.path.clone()), + }); + } else if let Some(win_tab_data) = + window_data.active_window_tab() + { + win_tab_data.common.internal_command.send( + InternalCommand::GoToLocation { + location: EditorLocation { + path: file.path.clone(), + position: None, + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }, + }, + ) + } + } + }) + .debug_name("App View") + } +} + +/// The top bar of an Editor tab. Includes the tab forward/back buttons, the tab scroll bar and the new split and tab close all button. +fn editor_tab_header( + window_tab_data: Rc, + active_editor_tab: ReadSignal>, + editor_tab: RwSignal, + dragging: RwSignal, EditorTabId)>>, +) -> impl View { + let main_split = window_tab_data.main_split.clone(); + let plugin = window_tab_data.plugin.clone(); + let editors = window_tab_data.main_split.editors; + let diff_editors = window_tab_data.main_split.diff_editors; + let focus = window_tab_data.common.focus; + let config = window_tab_data.common.config; + let internal_command = window_tab_data.common.internal_command; + let workbench_command = window_tab_data.common.workbench_command; + let editor_tab_id = + editor_tab.with_untracked(|editor_tab| editor_tab.editor_tab_id); + + let editor_tab_active = + create_memo(move |_| editor_tab.with(|editor_tab| editor_tab.active)); + let items = move || { + let editor_tab = editor_tab.get(); + for (i, (index, _, _)) in editor_tab.children.iter().enumerate() { + if index.get_untracked() != i { + index.set(i); + } + } + editor_tab.children + }; + let key = |(_, _, child): &(RwSignal, RwSignal, EditorTabChild)| { + child.id() + }; + let is_focused = move || { + if let Focus::Workbench = focus.get() { + editor_tab.with_untracked(|e| Some(e.editor_tab_id)) + == active_editor_tab.get() + } else { + false + } + }; + + let view_fn = move |(i, layout_rect, child): ( + RwSignal, + RwSignal, + EditorTabChild, + )| { + let local_child = child.clone(); + let child_for_close = child.clone(); + let child_for_mouse_close = child.clone(); + let child_for_mouse_close_2 = child.clone(); + let main_split = main_split.clone(); + let plugin = plugin.clone(); + let child_view = { + let info = child.view_info(editors, diff_editors, plugin, config); + let hovered = create_rw_signal(false); + + use crate::config::ui::TabCloseButton; + + let tab_icon = container({ + svg("") + .update_value(move || info.with(|info| info.icon.clone())) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.size(size, size) + .apply_opt(info.with(|info| info.color), |s, c| { + s.color(c) + }) + .apply_if( + !info.with(|info| info.is_pristine) + && config.ui.tab_close_button + == TabCloseButton::Off, + |s| s.color(config.color(LapceColor::LAPCE_WARN)), + ) + }) + }) + .style(|s| s.padding(4.)); + + let tab_content = tooltip( + label(move || info.with(|info| info.name.clone())).style(move |s| { + s.apply_if( + !info + .with(|info| info.confirmed) + .map(|confirmed| confirmed.get()) + .unwrap_or(true), + |s| s.font_style(FontStyle::Italic), + ) + .selectable(false) + }), + move || { + tooltip_tip( + config, + text(info.with(|info| { + info.path + .clone() + .map(|path| path.display().to_string()) + .unwrap_or("local".to_string()) + })), + ) + }, + ); + + let tab_close_button = clickable_icon( + move || { + if hovered.get() || info.with(|info| info.is_pristine) { + LapceIcons::CLOSE + } else { + LapceIcons::UNSAVED + } + }, + move || { + let editor_tab_id = + editor_tab.with_untracked(|t| t.editor_tab_id); + internal_command.send(InternalCommand::EditorTabChildClose { + editor_tab_id, + child: child_for_close.clone(), + }); + }, + || false, + || false, + || "Close", + config, + ) + .on_event_stop(EventListener::PointerDown, |_| {}) + .on_event_stop(EventListener::PointerEnter, move |_| { + hovered.set(true); + }) + .on_event_stop(EventListener::PointerLeave, move |_| { + hovered.set(false); + }); + + stack(( + tab_icon.style(move |s| { + let tab_close_button = config.get().ui.tab_close_button; + s.apply_if(tab_close_button == TabCloseButton::Left, |s| { + s.grid_column(Line { + start: style_helpers::line(3), + end: style_helpers::span(1), + }) + }) + }), + tab_content.style(move |s| { + let tab_close_button = config.get().ui.tab_close_button; + s.apply_if(tab_close_button == TabCloseButton::Left, |s| { + s.grid_column(Line { + start: style_helpers::line(2), + end: style_helpers::span(1), + }) + }) + .apply_if(tab_close_button == TabCloseButton::Off, |s| { + s.padding_right(4.) + }) + }), + tab_close_button.style(move |s| { + let tab_close_button = config.get().ui.tab_close_button; + s.apply_if(tab_close_button == TabCloseButton::Left, |s| { + s.grid_column(Line { + start: style_helpers::line(1), + end: style_helpers::span(1), + }) + }) + .apply_if(tab_close_button == TabCloseButton::Off, |s| s.hide()) + }), + )) + .style(move |s| { + s.items_center() + .justify_center() + .border_left(if i.get() == 0 { 1.0 } else { 0.0 }) + .border_right(1.0) + .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + .padding_horiz(6.) + .gap(6.) + .grid() + .grid_template_columns(vec![auto(), fr(1.), auto()]) + .apply_if( + config.get().ui.tab_separator_height + == TabSeparatorHeight::Full, + |s| s.height_full(), + ) + }) + }; + + let confirmed = match local_child { + EditorTabChild::Editor(editor_id) => { + editors.editor_untracked(editor_id).map(|e| e.confirmed) + } + EditorTabChild::DiffEditor(diff_editor_id) => diff_editors + .with_untracked(|diff_editors| { + diff_editors + .get(&diff_editor_id) + .map(|diff_editor_data| diff_editor_data.confirmed) + }), + _ => None, + }; + + let header_content_size = create_rw_signal(Size::ZERO); + let drag_over_left: RwSignal> = create_rw_signal(None); + stack(( + child_view + .on_double_click_stop(move |_| { + if let Some(confirmed) = confirmed { + confirmed.set(true); + } + }) + .on_event(EventListener::PointerDown, move |event| { + if let Event::PointerDown(pointer_event) = event { + if pointer_event.button.is_auxiliary() { + let editor_tab_id = + editor_tab.with_untracked(|t| t.editor_tab_id); + internal_command.send( + InternalCommand::EditorTabChildClose { + editor_tab_id, + child: child_for_mouse_close.clone(), + }, + ); + EventPropagation::Stop + } else { + editor_tab.update(|editor_tab| { + editor_tab.active = i.get_untracked(); + }); + EventPropagation::Continue + } + } else { + EventPropagation::Continue + } + }) + .on_secondary_click_stop(move |_| { + let editor_tab_id = + editor_tab.with_untracked(|t| t.editor_tab_id); + + tab_secondary_click( + internal_command, + editor_tab_id, + child_for_mouse_close_2.clone(), + ); + }) + .on_event_stop(EventListener::DragStart, move |_| { + dragging.set(Some((i, editor_tab_id))); + }) + .on_event_stop(EventListener::DragEnd, move |_| { + dragging.set(None); + }) + .on_resize(move |rect| { + header_content_size.set(rect.size()); + }) + .draggable() + .dragging_style(move |s| { + let config = config.get(); + s.border(1.0) + .border_radius(6.0) + .background( + config + .color(LapceColor::PANEL_BACKGROUND) + .multiply_alpha(0.7), + ) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + }) + .style(|s| s.align_items(Some(AlignItems::Center)).flex_grow(1.0)), + empty() + .style(move |s| { + s.size_full() + .border_bottom(if editor_tab_active.get() == i.get() { + 2.0 + } else { + 0.0 + }) + .border_color(config.get().color(if is_focused() { + LapceColor::LAPCE_TAB_ACTIVE_UNDERLINE + } else { + LapceColor::LAPCE_TAB_INACTIVE_UNDERLINE + })) + }) + .style(|s| { + s.absolute() + .padding_horiz(3.0) + .size_full() + .pointer_events_none() + }) + .debug_name("Drop Indicator"), + empty() + .style(move |s| { + let i = i.get(); + let drag_over_left = drag_over_left.get(); + s.absolute() + .margin_left(if i == 0 { 0.0 } else { -2.0 }) + .height_full() + .width( + header_content_size.get().width as f32 + + if i == 0 { 1.0 } else { 3.0 }, + ) + .apply_if(drag_over_left.is_none(), |s| s.hide()) + .apply_if(drag_over_left.is_some(), |s| { + if let Some(drag_over_left) = drag_over_left { + if drag_over_left { + s.border_left(3.0) + } else { + s.border_right(3.0) + } + } else { + s + } + }) + .border_color( + config + .get() + .color(LapceColor::LAPCE_TAB_ACTIVE_UNDERLINE) + .multiply_alpha(0.5), + ) + }) + .debug_name("Active Tab Indicator"), + )) + .on_resize(move |rect| { + layout_rect.set(rect); + }) + .style(move |s| { + let config = config.get(); + s.height_full() + .flex_col() + .items_center() + .justify_center() + .cursor(CursorStyle::Pointer) + .hover(|s| s.background(config.color(LapceColor::HOVER_BACKGROUND))) + }) + .debug_name("Tab and Active Indicator") + .on_event_stop(EventListener::DragOver, move |event| { + if dragging.with_untracked(|dragging| dragging.is_some()) { + if let Event::PointerMove(pointer_event) = event { + let new_left = pointer_event.pos.x + < header_content_size.get_untracked().width / 2.0; + if drag_over_left.get_untracked() != Some(new_left) { + drag_over_left.set(Some(new_left)); + } + } + } + }) + .on_event(EventListener::Drop, move |event| { + if let Some((from_index, from_editor_tab_id)) = dragging.get_untracked() + { + drag_over_left.set(None); + if let Event::PointerUp(pointer_event) = event { + let left = pointer_event.pos.x + < header_content_size.get_untracked().width / 2.0; + let index = i.get_untracked(); + let new_index = if left { index } else { index + 1 }; + main_split.move_editor_tab_child( + from_editor_tab_id, + editor_tab_id, + from_index.get_untracked(), + new_index, + ); + } + EventPropagation::Stop + } else { + EventPropagation::Continue + } + }) + .on_event_stop(EventListener::DragLeave, move |_| { + drag_over_left.set(None); + }) + }; + + let content_size = create_rw_signal(Size::ZERO); + let scroll_offset = create_rw_signal(Rect::ZERO); + stack(( + stack({ + let size = create_rw_signal(Size::ZERO); + ( + clip(empty().style(move |s| { + let config = config.get(); + s.absolute() + .height_full() + .width(size.get().width as f32) + .background(config.color(LapceColor::PANEL_BACKGROUND)) + .box_shadow_blur(3.0) + .box_shadow_color( + config.color(LapceColor::LAPCE_DROPDOWN_SHADOW), + ) + })) + .style(move |s| { + let scroll_offset = scroll_offset.get(); + s.absolute() + .width(size.get().width as f32 + 30.0) + .height_full() + .apply_if(scroll_offset.x0 == 0.0, |s| s.hide()) + }), + stack(( + clickable_icon( + || LapceIcons::TAB_PREVIOUS, + move || { + workbench_command + .send(LapceWorkbenchCommand::PreviousEditorTab); + }, + || false, + || false, + || "Previous Tab", + config, + ) + .style(|s| s.margin_horiz(6.0).margin_vert(7.0)), + clickable_icon( + || LapceIcons::TAB_NEXT, + move || { + workbench_command + .send(LapceWorkbenchCommand::NextEditorTab); + }, + || false, + || false, + || "Next Tab", + config, + ) + .style(|s| s.margin_right(6.0)), + )) + .on_resize(move |rect| { + size.set(rect.size()); + }) + .debug_name("Next/Previoius Tab Buttons") + .style(move |s| s.items_center()), + ) + }) + .style(|s| s.flex_shrink(0.)), + container( + scroll({ + dyn_stack(items, key, view_fn) + .on_resize(move |rect| { + let size = rect.size(); + if content_size.get_untracked() != size { + content_size.set(size); + } + }) + .debug_name("Horizontal Tab Stack") + .style(|s| s.height_full().items_center()) + }) + .on_scroll(move |rect| { + scroll_offset.set(rect); + }) + .ensure_visible(move || { + let active = editor_tab_active.get(); + editor_tab + .with_untracked(|editor_tab| editor_tab.children[active].1) + .get_untracked() + }) + .scroll_style(|s| s.hide_bars(true)) + .style(|s| { + s.set(VerticalScrollAsHorizontal, true) + .absolute() + .size_full() + }), + ) + .style(|s| s.height_full().flex_grow(1.0).flex_basis(0.).min_width(10.)) + .debug_name("Tab scroll"), + stack({ + let size = create_rw_signal(Size::ZERO); + ( + clip({ + empty().style(move |s| { + let config = config.get(); + s.absolute() + .height_full() + .margin_left(30.0) + .width(size.get().width as f32) + .background(config.color(LapceColor::PANEL_BACKGROUND)) + .box_shadow_blur(3.0) + .box_shadow_color( + config.color(LapceColor::LAPCE_DROPDOWN_SHADOW), + ) + }) + }) + .style(move |s| { + let content_size = content_size.get(); + let scroll_offset = scroll_offset.get(); + s.absolute() + .margin_left(-30.0) + .width(size.get().width as f32 + 30.0) + .height_full() + .apply_if(scroll_offset.x1 >= content_size.width, |s| { + s.hide() + }) + }), + stack(( + clickable_icon( + || LapceIcons::SPLIT_HORIZONTAL, + move || { + let editor_tab_id = + editor_tab.with_untracked(|t| t.editor_tab_id); + internal_command.send(InternalCommand::Split { + direction: SplitDirection::Vertical, + editor_tab_id, + }); + }, + || false, + || false, + || "Split Horizontally", + config, + ) + .style(|s| s.margin_left(6.0)), + clickable_icon( + || LapceIcons::CLOSE, + move || { + let editor_tab_id = + editor_tab.with_untracked(|t| t.editor_tab_id); + internal_command.send(InternalCommand::EditorTabClose { + editor_tab_id, + }); + }, + || false, + || false, + || "Close All", + config, + ) + .style(|s| s.margin_horiz(6.0)), + )) + .on_resize(move |rect| { + size.set(rect.size()); + }) + .style(|s| s.items_center().height_full()), + ) + }) + .debug_name("Split/Close Panel Buttons") + .style(move |s| { + let content_size = content_size.get(); + let scroll_offset = scroll_offset.get(); + s.height_full() + .flex_shrink(0.) + .margin_left(PxPctAuto::Auto) + .apply_if(scroll_offset.x1 < content_size.width, |s| { + s.margin_left(0.) + }) + }), + )) + .style(move |s| { + let config = config.get(); + s.items_center() + .max_width_full() + .border_bottom(1.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .background(config.color(LapceColor::PANEL_BACKGROUND)) + .height(config.ui.header_height() as i32) + }) + .debug_name("Editor Tab Header") +} + +fn editor_tab_content( + window_tab_data: Rc, + plugin: PluginData, + active_editor_tab: ReadSignal>, + editor_tab: RwSignal, +) -> impl View { + let main_split = window_tab_data.main_split.clone(); + let common = main_split.common.clone(); + let workspace = common.workspace.clone(); + let editors = main_split.editors; + let diff_editors = main_split.diff_editors; + let config = common.config; + let focus = common.focus; + let items = move || { + editor_tab + .get() + .children + .into_iter() + .map(|(_, _, child)| child) + }; + let key = |child: &EditorTabChild| child.id(); + let view_fn = move |child| { + let common = common.clone(); + let child = match child { + EditorTabChild::Editor(editor_id) => { + if let Some(editor_data) = editors.editor_untracked(editor_id) { + let editor_scope = editor_data.scope; + let editor_tab_id = editor_data.editor_tab_id; + let is_active = move |tracked: bool| { + editor_scope.track(); + let focus = if tracked { + focus.get() + } else { + focus.get_untracked() + }; + if let Focus::Workbench = focus { + let active_editor_tab = if tracked { + active_editor_tab.get() + } else { + active_editor_tab.get_untracked() + }; + let editor_tab = if tracked { + editor_tab_id.get() + } else { + editor_tab_id.get_untracked() + }; + editor_tab.is_some() && editor_tab == active_editor_tab + } else { + false + } + }; + let editor_data = create_rw_signal(editor_data); + editor_container_view( + window_tab_data.clone(), + workspace.clone(), + is_active, + editor_data, + ) + .into_any() + } else { + text("empty editor").into_any() + } + } + EditorTabChild::DiffEditor(diff_editor_id) => { + let diff_editor_data = diff_editors.with_untracked(|diff_editors| { + diff_editors.get(&diff_editor_id).cloned() + }); + if let Some(diff_editor_data) = diff_editor_data { + let focus_right = diff_editor_data.focus_right; + let diff_editor_tab_id = diff_editor_data.editor_tab_id; + let diff_editor_scope = diff_editor_data.scope; + let is_active = move |tracked: bool| { + let focus = if tracked { + focus.get() + } else { + focus.get_untracked() + }; + if let Focus::Workbench = focus { + let active_editor_tab = if tracked { + active_editor_tab.get() + } else { + active_editor_tab.get_untracked() + }; + let diff_editor_tab_id = if tracked { + diff_editor_tab_id.get() + } else { + diff_editor_tab_id.get_untracked() + }; + Some(diff_editor_tab_id) == active_editor_tab + } else { + false + } + }; + let left_viewport = diff_editor_data.left.viewport(); + let left_scroll_to = diff_editor_data.left.scroll_to(); + let right_viewport = diff_editor_data.right.viewport(); + let right_scroll_to = diff_editor_data.right.scroll_to(); + create_effect(move |_| { + let left_viewport = left_viewport.get(); + if right_viewport.get_untracked() != left_viewport { + right_scroll_to + .set(Some(left_viewport.origin().to_vec2())); + } + }); + create_effect(move |_| { + let right_viewport = right_viewport.get(); + if left_viewport.get_untracked() != right_viewport { + left_scroll_to + .set(Some(right_viewport.origin().to_vec2())); + } + }); + let left_editor = + create_rw_signal(diff_editor_data.left.clone()); + let right_editor = + create_rw_signal(diff_editor_data.right.clone()); + stack(( + container( + editor_container_view( + window_tab_data.clone(), + workspace.clone(), + move |track| { + is_active(track) + && if track { + !focus_right.get() + } else { + !focus_right.get_untracked() + } + }, + left_editor, + ) + .debug_name("Left Editor"), + ) + .on_event_cont(EventListener::PointerDown, move |_| { + focus_right.set(false); + }) + .style(move |s| { + s.height_full() + .flex_grow(1.0) + .flex_basis(0.0) + .border_right(1.0) + .border_color( + config.get().color(LapceColor::LAPCE_BORDER), + ) + }), + container( + editor_container_view( + window_tab_data.clone(), + workspace.clone(), + move |track| { + is_active(track) + && if track { + focus_right.get() + } else { + focus_right.get_untracked() + } + }, + right_editor, + ) + .debug_name("Right Editor"), + ) + .on_event_cont(EventListener::PointerDown, move |_| { + focus_right.set(true); + }) + .style(|s| s.height_full().flex_grow(1.0).flex_basis(0.0)), + diff_show_more_section_view( + &diff_editor_data.left, + &diff_editor_data.right, + ), + )) + .style(|s: Style| s.size_full()) + .on_cleanup(move || { + diff_editor_scope.dispose(); + }) + .into_any() + } else { + text("empty diff editor").into_any() + } + } + EditorTabChild::Settings(_) => { + settings_view(plugin.installed, editors, common).into_any() + } + EditorTabChild::ThemeColorSettings(_) => { + theme_color_settings_view(editors, common).into_any() + } + EditorTabChild::Keymap(_) => keymap_view(editors, common).into_any(), + EditorTabChild::Volt(_, id) => { + plugin_info_view(plugin.clone(), id).into_any() + } + }; + child.style(|s| s.size_full()) + }; + let active = move || editor_tab.with(|t| t.active); + + tab(active, items, key, view_fn) + .style(|s| s.size_full()) + .debug_name("Editor Tab Content") +} + +#[derive(Clone, Copy, PartialEq, Eq)] +enum DragOverPosition { + Top, + Bottom, + Left, + Right, + Middle, +} + +fn editor_tab( + window_tab_data: Rc, + plugin: PluginData, + active_editor_tab: ReadSignal>, + editor_tab: RwSignal, + dragging: RwSignal, EditorTabId)>>, +) -> impl View { + let main_split = window_tab_data.main_split.clone(); + let common = main_split.common.clone(); + let editor_tabs = main_split.editor_tabs; + let editor_tab_id = + editor_tab.with_untracked(|editor_tab| editor_tab.editor_tab_id); + let config = common.config; + let focus = common.focus; + let internal_command = main_split.common.internal_command; + let tab_size = create_rw_signal(Size::ZERO); + let drag_over: RwSignal> = create_rw_signal(None); + stack(( + editor_tab_header( + window_tab_data.clone(), + active_editor_tab, + editor_tab, + dragging, + ), + stack(( + editor_tab_content( + window_tab_data.clone(), + plugin.clone(), + active_editor_tab, + editor_tab, + ), + empty() + .style(move |s| { + let pos = drag_over.get(); + let width = match pos { + Some(pos) => match pos { + DragOverPosition::Top => 100.0, + DragOverPosition::Bottom => 100.0, + DragOverPosition::Left => 50.0, + DragOverPosition::Right => 50.0, + DragOverPosition::Middle => 100.0, + }, + None => 100.0, + }; + let height = match pos { + Some(pos) => match pos { + DragOverPosition::Top => 50.0, + DragOverPosition::Bottom => 50.0, + DragOverPosition::Left => 100.0, + DragOverPosition::Right => 100.0, + DragOverPosition::Middle => 100.0, + }, + None => 100.0, + }; + let size = tab_size.get_untracked(); + let margin_left = match pos { + Some(pos) => match pos { + DragOverPosition::Top => 0.0, + DragOverPosition::Bottom => 0.0, + DragOverPosition::Left => 0.0, + DragOverPosition::Right => size.width / 2.0, + DragOverPosition::Middle => 0.0, + }, + None => 0.0, + }; + let margin_top = match pos { + Some(pos) => match pos { + DragOverPosition::Top => 0.0, + DragOverPosition::Bottom => size.height / 2.0, + DragOverPosition::Left => 0.0, + DragOverPosition::Right => 0.0, + DragOverPosition::Middle => 0.0, + }, + None => 0.0, + }; + s.absolute() + .size_pct(width, height) + .margin_top(margin_top as f32) + .margin_left(margin_left as f32) + .apply_if(pos.is_none(), |s| s.hide()) + .background( + config + .get() + .color(LapceColor::EDITOR_DRAG_DROP_BACKGROUND), + ) + }) + .debug_name("Drag Over Handle"), + empty() + .on_event_stop(EventListener::DragOver, move |event| { + if dragging.with_untracked(|dragging| dragging.is_some()) { + if let Event::PointerMove(pointer_event) = event { + let size = tab_size.get_untracked(); + let pos = pointer_event.pos; + let new_drag_over = if pos.x < size.width / 4.0 { + DragOverPosition::Left + } else if pos.x > size.width * 3.0 / 4.0 { + DragOverPosition::Right + } else if pos.y < size.height / 4.0 { + DragOverPosition::Top + } else if pos.y > size.height * 3.0 / 4.0 { + DragOverPosition::Bottom + } else { + DragOverPosition::Middle + }; + if drag_over.get_untracked() != Some(new_drag_over) { + drag_over.set(Some(new_drag_over)); + } + } + } + }) + .on_event_stop(EventListener::DragLeave, move |_| { + drag_over.set(None); + }) + .on_event(EventListener::Drop, move |_| { + if let Some((from_index, from_editor_tab_id)) = + dragging.get_untracked() + { + if let Some(pos) = drag_over.get_untracked() { + match pos { + DragOverPosition::Top => { + main_split.move_editor_tab_child_to_new_split( + from_editor_tab_id, + from_index.get_untracked(), + editor_tab_id, + SplitMoveDirection::Up, + ); + } + DragOverPosition::Bottom => { + main_split.move_editor_tab_child_to_new_split( + from_editor_tab_id, + from_index.get_untracked(), + editor_tab_id, + SplitMoveDirection::Down, + ); + } + DragOverPosition::Left => { + main_split.move_editor_tab_child_to_new_split( + from_editor_tab_id, + from_index.get_untracked(), + editor_tab_id, + SplitMoveDirection::Left, + ); + } + DragOverPosition::Right => { + main_split.move_editor_tab_child_to_new_split( + from_editor_tab_id, + from_index.get_untracked(), + editor_tab_id, + SplitMoveDirection::Right, + ); + } + DragOverPosition::Middle => { + main_split.move_editor_tab_child( + from_editor_tab_id, + editor_tab_id, + from_index.get_untracked(), + editor_tab.with_untracked(|editor_tab| { + editor_tab.active + 1 + }), + ); + } + } + } + drag_over.set(None); + EventPropagation::Stop + } else { + EventPropagation::Continue + } + }) + .on_resize(move |rect| { + tab_size.set(rect.size()); + }) + .style(move |s| { + s.absolute() + .size_full() + .apply_if(dragging.get().is_none(), |s| { + s.pointer_events_none() + }) + }), + )) + .debug_name("Editor Content and Drag Over") + .style(|s| s.size_full()), + )) + .on_event_cont(EventListener::PointerDown, move |_| { + if focus.get_untracked() != Focus::Workbench { + focus.set(Focus::Workbench); + } + let editor_tab_id = editor_tab.with_untracked(|t| t.editor_tab_id); + internal_command.send(InternalCommand::FocusEditorTab { editor_tab_id }); + }) + .on_cleanup(move || { + if editor_tabs + .with_untracked(|editor_tabs| editor_tabs.contains_key(&editor_tab_id)) + { + return; + } + editor_tab + .with_untracked(|editor_tab| editor_tab.scope) + .dispose(); + }) + .style(|s| s.flex_col().size_full()) + .debug_name("Editor Tab (Content + Header)") +} + +fn split_resize_border( + splits: ReadSignal>>, + editor_tabs: ReadSignal>>, + split: ReadSignal, + config: ReadSignal>, +) -> impl View { + let content_rect = move |content: &SplitContent, tracked: bool| { + if tracked { + match content { + SplitContent::EditorTab(editor_tab_id) => { + let editor_tab_data = + editor_tabs.with(|tabs| tabs.get(editor_tab_id).cloned()); + if let Some(editor_tab_data) = editor_tab_data { + editor_tab_data.with(|editor_tab| editor_tab.layout_rect) + } else { + Rect::ZERO + } + } + SplitContent::Split(split_id) => { + if let Some(split) = + splits.with(|splits| splits.get(split_id).cloned()) + { + split.with(|split| split.layout_rect) + } else { + Rect::ZERO + } + } + } + } else { + match content { + SplitContent::EditorTab(editor_tab_id) => { + let editor_tab_data = editor_tabs + .with_untracked(|tabs| tabs.get(editor_tab_id).cloned()); + if let Some(editor_tab_data) = editor_tab_data { + editor_tab_data + .with_untracked(|editor_tab| editor_tab.layout_rect) + } else { + Rect::ZERO + } + } + SplitContent::Split(split_id) => { + if let Some(split) = + splits.with_untracked(|splits| splits.get(split_id).cloned()) + { + split.with_untracked(|split| split.layout_rect) + } else { + Rect::ZERO + } + } + } + } + }; + let direction = move |tracked: bool| { + if tracked { + split.with(|split| split.direction) + } else { + split.with_untracked(|split| split.direction) + } + }; + dyn_stack( + move || { + let data = split.get(); + data.children.into_iter().enumerate().skip(1) + }, + |(index, (_, content))| (*index, content.id()), + move |(index, (_, content))| { + let drag_start: RwSignal> = create_rw_signal(None); + let view = empty(); + let view_id = view.id(); + view.on_event_stop(EventListener::PointerDown, move |event| { + view_id.request_active(); + if let Event::PointerDown(pointer_event) = event { + drag_start.set(Some(pointer_event.pos)); + } + }) + .on_event_stop(EventListener::PointerUp, move |_| { + drag_start.set(None); + }) + .on_event_stop(EventListener::PointerMove, move |event| { + if let Event::PointerMove(pointer_event) = event { + if let Some(drag_start_point) = drag_start.get_untracked() { + let rects = split.with_untracked(|split| { + split + .children + .iter() + .map(|(_, c)| content_rect(c, false)) + .collect::>() + }); + let direction = direction(false); + match direction { + SplitDirection::Vertical => { + let left = rects[index - 1].width(); + let right = rects[index].width(); + let shift = pointer_event.pos.x - drag_start_point.x; + let left = left + shift; + let right = right - shift; + let total_width = + rects.iter().map(|r| r.width()).sum::(); + split.with_untracked(|split| { + for (i, (size, _)) in + split.children.iter().enumerate() + { + if i == index - 1 { + size.set(left / total_width); + } else if i == index { + size.set(right / total_width); + } else { + size.set(rects[i].width() / total_width); + } + } + }) + } + SplitDirection::Horizontal => { + let up = rects[index - 1].height(); + let down = rects[index].height(); + let shift = pointer_event.pos.y - drag_start_point.y; + let up = up + shift; + let down = down - shift; + let total_height = + rects.iter().map(|r| r.height()).sum::(); + split.with_untracked(|split| { + for (i, (size, _)) in + split.children.iter().enumerate() + { + if i == index - 1 { + size.set(up / total_height); + } else if i == index { + size.set(down / total_height); + } else { + size.set( + rects[i].height() / total_height, + ); + } + } + }) + } + } + } + } + }) + .style(move |s| { + let rect = content_rect(&content, true); + let is_dragging = drag_start.get().is_some(); + let direction = direction(true); + s.position(Position::Absolute) + .apply_if(direction == SplitDirection::Vertical, |style| { + style.margin_left(rect.x0 as f32 - 0.0) + }) + .apply_if(direction == SplitDirection::Horizontal, |style| { + style.margin_top(rect.y0 as f32 - 0.0) + }) + .width(match direction { + SplitDirection::Vertical => PxPctAuto::Px(4.0), + SplitDirection::Horizontal => PxPctAuto::Pct(100.0), + }) + .height(match direction { + SplitDirection::Vertical => PxPctAuto::Pct(100.0), + SplitDirection::Horizontal => PxPctAuto::Px(4.0), + }) + .flex_direction(match direction { + SplitDirection::Vertical => FlexDirection::Row, + SplitDirection::Horizontal => FlexDirection::Column, + }) + .apply_if(is_dragging, |s| { + s.cursor(match direction { + SplitDirection::Vertical => CursorStyle::ColResize, + SplitDirection::Horizontal => CursorStyle::RowResize, + }) + .background(config.get().color(LapceColor::EDITOR_CARET)) + }) + .hover(|s| { + s.cursor(match direction { + SplitDirection::Vertical => CursorStyle::ColResize, + SplitDirection::Horizontal => CursorStyle::RowResize, + }) + .background(config.get().color(LapceColor::EDITOR_CARET)) + }) + .pointer_events_auto() + }) + }, + ) + .style(|s| { + s.position(Position::Absolute) + .size_full() + .pointer_events_none() + }) + .debug_name("Split Resize Border") +} + +fn split_border( + splits: ReadSignal>>, + editor_tabs: ReadSignal>>, + split: ReadSignal, + config: ReadSignal>, +) -> impl View { + let direction = move || split.with(|split| split.direction); + dyn_stack( + move || split.get().children.into_iter().skip(1), + |(_, content)| content.id(), + move |(_, content)| { + container(empty().style(move |s| { + let direction = direction(); + s.width(match direction { + SplitDirection::Vertical => PxPctAuto::Px(1.0), + SplitDirection::Horizontal => PxPctAuto::Pct(100.0), + }) + .height(match direction { + SplitDirection::Vertical => PxPctAuto::Pct(100.0), + SplitDirection::Horizontal => PxPctAuto::Px(1.0), + }) + .background(config.get().color(LapceColor::LAPCE_BORDER)) + })) + .style(move |s| { + let rect = match &content { + SplitContent::EditorTab(editor_tab_id) => { + let editor_tab_data = editor_tabs + .with(|tabs| tabs.get(editor_tab_id).cloned()); + if let Some(editor_tab_data) = editor_tab_data { + editor_tab_data.with(|editor_tab| editor_tab.layout_rect) + } else { + Rect::ZERO + } + } + SplitContent::Split(split_id) => { + if let Some(split) = + splits.with(|splits| splits.get(split_id).cloned()) + { + split.with(|split| split.layout_rect) + } else { + Rect::ZERO + } + } + }; + let direction = direction(); + s.position(Position::Absolute) + .apply_if(direction == SplitDirection::Vertical, |style| { + style.margin_left(rect.x0 as f32 - 2.0) + }) + .apply_if(direction == SplitDirection::Horizontal, |style| { + style.margin_top(rect.y0 as f32 - 2.0) + }) + .width(match direction { + SplitDirection::Vertical => PxPctAuto::Px(4.0), + SplitDirection::Horizontal => PxPctAuto::Pct(100.0), + }) + .height(match direction { + SplitDirection::Vertical => PxPctAuto::Pct(100.0), + SplitDirection::Horizontal => PxPctAuto::Px(4.0), + }) + .flex_direction(match direction { + SplitDirection::Vertical => FlexDirection::Row, + SplitDirection::Horizontal => FlexDirection::Column, + }) + .justify_content(Some(JustifyContent::Center)) + }) + }, + ) + .style(|s| { + s.position(Position::Absolute) + .size_full() + .pointer_events_none() + }) + .debug_name("Split Border") +} + +fn split_list( + split: ReadSignal, + window_tab_data: Rc, + plugin: PluginData, + dragging: RwSignal, EditorTabId)>>, +) -> impl View { + let main_split = window_tab_data.main_split.clone(); + let editor_tabs = main_split.editor_tabs.read_only(); + let active_editor_tab = main_split.active_editor_tab.read_only(); + let splits = main_split.splits.read_only(); + let config = main_split.common.config; + let split_id = split.with_untracked(|split| split.split_id); + + let direction = move || split.with(|split| split.direction); + let items = move || split.get().children.into_iter().enumerate(); + let key = |(_index, (_, content)): &(usize, (RwSignal, SplitContent))| { + content.id() + }; + let view_fn = { + let main_split = main_split.clone(); + let window_tab_data = window_tab_data.clone(); + move |(_index, (split_size, content)): ( + usize, + (RwSignal, SplitContent), + )| { + let plugin = plugin.clone(); + let child = match &content { + SplitContent::EditorTab(editor_tab_id) => { + let editor_tab_data = editor_tabs + .with_untracked(|tabs| tabs.get(editor_tab_id).cloned()); + if let Some(editor_tab_data) = editor_tab_data { + editor_tab( + window_tab_data.clone(), + plugin.clone(), + active_editor_tab, + editor_tab_data, + dragging, + ) + .into_any() + } else { + text("empty editor tab").into_any() + } + } + SplitContent::Split(split_id) => { + if let Some(split) = + splits.with(|splits| splits.get(split_id).cloned()) + { + split_list( + split.read_only(), + window_tab_data.clone(), + plugin.clone(), + dragging, + ) + .into_any() + } else { + text("empty split").into_any() + } + } + }; + let local_main_split = main_split.clone(); + let local_local_main_split = main_split.clone(); + child + .on_resize(move |rect| match &content { + SplitContent::EditorTab(editor_tab_id) => { + local_main_split.editor_tab_update_layout( + editor_tab_id, + None, + Some(rect), + ); + } + SplitContent::Split(split_id) => { + let split_data = + splits.with(|splits| splits.get(split_id).cloned()); + if let Some(split_data) = split_data { + split_data.update(|split| { + split.layout_rect = rect; + }); + } + } + }) + .on_move(move |point| match &content { + SplitContent::EditorTab(editor_tab_id) => { + local_local_main_split.editor_tab_update_layout( + editor_tab_id, + Some(point), + None, + ); + } + SplitContent::Split(split_id) => { + let split_data = + splits.with(|splits| splits.get(split_id).cloned()); + if let Some(split_data) = split_data { + split_data.update(|split| { + split.window_origin = point; + }); + } + } + }) + .style(move |s| s.flex_grow(split_size.get() as f32).flex_basis(0.0)) + } + }; + container( + stack(( + dyn_stack(items, key, view_fn).style(move |s| { + s.flex_direction(match direction() { + SplitDirection::Vertical => FlexDirection::Row, + SplitDirection::Horizontal => FlexDirection::Column, + }) + .size_full() + }), + split_border(splits, editor_tabs, split, config), + split_resize_border(splits, editor_tabs, split, config), + )) + .style(|s| s.size_full()), + ) + .on_cleanup(move || { + if splits.with_untracked(|splits| splits.contains_key(&split_id)) { + return; + } + split + .with_untracked(|split_data| split_data.scope) + .dispose(); + }) + .debug_name("Split List") +} + +fn main_split(window_tab_data: Rc) -> impl View { + let root_split = window_tab_data.main_split.root_split; + let root_split = window_tab_data + .main_split + .splits + .get_untracked() + .get(&root_split) + .unwrap() + .read_only(); + let config = window_tab_data.main_split.common.config; + let panel = window_tab_data.panel.clone(); + let plugin = window_tab_data.plugin.clone(); + let dragging: RwSignal, EditorTabId)>> = + create_rw_signal(None); + split_list( + root_split, + window_tab_data.clone(), + plugin.clone(), + dragging, + ) + .style(move |s| { + let config = config.get(); + let is_hidden = panel.panel_bottom_maximized(true) + && panel.is_container_shown(&PanelContainerPosition::Bottom, true); + s.border_color(config.color(LapceColor::LAPCE_BORDER)) + .background(config.color(LapceColor::EDITOR_BACKGROUND)) + .apply_if(is_hidden, |s| s.display(Display::None)) + .width_full() + .flex_grow(1.0) + .flex_basis(0.0) + }) + .debug_name("Main Split") +} + +pub fn not_clickable_icon( + icon: impl Fn() -> &'static str + 'static, + active_fn: impl Fn() -> bool + 'static, + disabled_fn: impl Fn() -> bool + 'static + Copy, + tooltip_: impl Fn() -> S + 'static + Clone, + config: ReadSignal>, +) -> impl View { + tooltip_label( + config, + clickable_icon_base( + icon, + None::>, + active_fn, + disabled_fn, + config, + ), + tooltip_, + ) + .debug_name("Not Clickable Icon") +} + +pub fn clickable_icon( + icon: impl Fn() -> &'static str + 'static, + on_click: impl Fn() + 'static, + active_fn: impl Fn() -> bool + 'static, + disabled_fn: impl Fn() -> bool + 'static + Copy, + tooltip_: impl Fn() -> S + 'static + Clone, + config: ReadSignal>, +) -> impl View { + tooltip_label( + config, + clickable_icon_base(icon, Some(on_click), active_fn, disabled_fn, config), + tooltip_, + ) +} + +pub fn clickable_icon_base( + icon: impl Fn() -> &'static str + 'static, + on_click: Option, + active_fn: impl Fn() -> bool + 'static, + disabled_fn: impl Fn() -> bool + 'static + Copy, + config: ReadSignal>, +) -> impl View { + let view = container( + svg(move || config.get().ui_svg(icon())) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.size(size, size) + .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + .disabled(|s| { + s.color(config.color(LapceColor::LAPCE_ICON_INACTIVE)) + .cursor(CursorStyle::Default) + }) + }) + .disabled(disabled_fn), + ) + .disabled(disabled_fn) + .style(move |s| { + let config = config.get(); + s.padding(4.0) + .border_radius(6.0) + .border(1.0) + .border_color(Color::TRANSPARENT) + .apply_if(active_fn(), |s| { + s.border_color(config.color(LapceColor::EDITOR_CARET)) + }) + .hover(|s| { + s.cursor(CursorStyle::Pointer) + .background(config.color(LapceColor::PANEL_HOVERED_BACKGROUND)) + }) + .active(|s| { + s.background( + config.color(LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND), + ) + }) + }); + + if let Some(on_click) = on_click { + view.on_click_stop(move |_| { + on_click(); + }) + } else { + view + } +} + +/// A tooltip with a label inside. +/// +/// When styling an element that has the tooltip, it will style the child rather than the tooltip +/// label. +pub fn tooltip_label( + config: ReadSignal>, + child: V, + text: impl Fn() -> S + 'static + Clone, +) -> impl View { + tooltip(child, move || { + tooltip_tip( + config, + label(text.clone()).style(move |s| s.selectable(false)), + ) + }) +} + +fn tooltip_tip( + config: ReadSignal>, + child: V, +) -> impl IntoView { + container(child).style(move |s| { + let config = config.get(); + s.padding_horiz(10.0) + .padding_vert(5.0) + .font_size(config.ui.font_size() as f32) + .font_family(config.ui.font_family.clone()) + .color(config.color(LapceColor::TOOLTIP_FOREGROUND)) + .background(config.color(LapceColor::TOOLTIP_BACKGROUND)) + .border(1) + .border_radius(6) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .box_shadow_blur(3.0) + .box_shadow_color(config.color(LapceColor::LAPCE_DROPDOWN_SHADOW)) + .margin_left(0.0) + .margin_top(4.0) + }) +} + +fn workbench(window_tab_data: Rc) -> impl View { + let workbench_size = window_tab_data.common.workbench_size; + let main_split_width = window_tab_data.main_split.width; + stack(( + panel_container_view(window_tab_data.clone(), PanelContainerPosition::Left), + { + let window_tab_data = window_tab_data.clone(); + stack(( + main_split(window_tab_data.clone()), + panel_container_view( + window_tab_data, + PanelContainerPosition::Bottom, + ), + )) + .on_resize(move |rect| { + let width = rect.size().width; + if main_split_width.get_untracked() != width { + main_split_width.set(width); + } + }) + .style(|s| s.flex_col().flex_grow(1.0)) + }, + panel_container_view(window_tab_data.clone(), PanelContainerPosition::Right), + window_message_view(window_tab_data.messages, window_tab_data.common.config), + )) + .on_resize(move |rect| { + let size = rect.size(); + if size != workbench_size.get_untracked() { + workbench_size.set(size); + } + }) + .style(move |s| s.size_full()) + .debug_name("Workbench") +} + +fn palette_item( + workspace: Arc, + i: usize, + item: PaletteItem, + index: ReadSignal, + palette_item_height: f64, + config: ReadSignal>, + keymap: Option<&KeyMap>, +) -> impl View + use<> { + match &item.content { + PaletteItemContent::File { path, .. } + | PaletteItemContent::Reference { path, .. } => { + let file_name = path + .file_name() + .unwrap_or_default() + .to_string_lossy() + .into_owned(); + // let (file_name, _) = create_signal(cx.scope, file_name); + let folder = path + .parent() + .unwrap_or("".as_ref()) + .to_string_lossy() + .into_owned(); + // let (folder, _) = create_signal(cx.scope, folder); + let folder_len = folder.len(); + + let file_name_indices = item + .indices + .iter() + .filter_map(|&i| { + if folder_len > 0 { + if i > folder_len { + Some(i - folder_len - 1) + } else { + None + } + } else { + Some(i) + } + }) + .collect::>(); + let folder_indices = item + .indices + .iter() + .filter_map(|&i| if i < folder_len { Some(i) } else { None }) + .collect::>(); + + let path = path.to_path_buf(); + let style_path = path.clone(); + container( + stack(( + svg(move || config.get().file_svg(&path).0).style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + let color = config.file_svg(&style_path).1; + s.min_width(size) + .size(size, size) + .margin_right(5.0) + .apply_opt(color, Style::color) + }), + focus_text( + move || file_name.clone(), + move || file_name_indices.clone(), + move || config.get().color(LapceColor::EDITOR_FOCUS), + ) + .style(|s| s.margin_right(6.0).max_width_full()), + focus_text( + move || folder.clone(), + move || folder_indices.clone(), + move || config.get().color(LapceColor::EDITOR_FOCUS), + ) + .style(move |s| { + s.color(config.get().color(LapceColor::EDITOR_DIM)) + .min_width(0.0) + .flex_grow(1.0) + .flex_basis(0.0) + }), + )) + .style(|s| s.align_items(Some(AlignItems::Center)).max_width_full()), + ) + } + PaletteItemContent::DocumentSymbol { + kind, + name, + container_name, + .. + } => { + let kind = *kind; + let text = name.to_string(); + let hint = container_name.clone().unwrap_or_default(); + let text_indices: Vec = item + .indices + .iter() + .filter_map(|i| { + let i = *i; + if i < text.len() { Some(i) } else { None } + }) + .collect(); + let hint_indices: Vec = item + .indices + .iter() + .filter_map(|i| { + let i = *i; + if i >= text.len() { + Some(i - text.len()) + } else { + None + } + }) + .collect(); + container( + stack(( + svg(move || { + let config = config.get(); + config + .symbol_svg(&kind) + .unwrap_or_else(|| config.ui_svg(LapceIcons::FILE)) + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.min_width(size).size(size, size).margin_right(5.0).color( + config.symbol_color(&kind).unwrap_or_else(|| { + config.color(LapceColor::LAPCE_ICON_ACTIVE) + }), + ) + }), + focus_text( + move || text.clone(), + move || text_indices.clone(), + move || config.get().color(LapceColor::EDITOR_FOCUS), + ) + .style(|s| s.margin_right(6.0).max_width_full()), + focus_text( + move || hint.clone(), + move || hint_indices.clone(), + move || config.get().color(LapceColor::EDITOR_FOCUS), + ) + .style(move |s| { + s.color(config.get().color(LapceColor::EDITOR_DIM)) + .min_width(0.0) + .flex_grow(1.0) + .flex_basis(0.0) + }), + )) + .style(|s| s.align_items(Some(AlignItems::Center)).max_width_full()), + ) + } + PaletteItemContent::WorkspaceSymbol { + kind, + name, + location, + .. + } => { + let text = name.to_string(); + let kind = *kind; + + let path = location.path.clone(); + let full_path = location.path.clone(); + let path = if let Some(workspace_path) = workspace.path.as_ref() { + path.strip_prefix(workspace_path) + .unwrap_or(&full_path) + .to_path_buf() + } else { + path + }; + + let hint = path.to_string_lossy().to_string(); + let text_indices: Vec = item + .indices + .iter() + .filter_map(|i| { + let i = *i; + if i < text.len() { Some(i) } else { None } + }) + .collect(); + let hint_indices: Vec = item + .indices + .iter() + .filter_map(|i| { + let i = *i; + if i >= text.len() { + Some(i - text.len()) + } else { + None + } + }) + .collect(); + container( + stack(( + svg(move || { + let config = config.get(); + config + .symbol_svg(&kind) + .unwrap_or_else(|| config.ui_svg(LapceIcons::FILE)) + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.min_width(size) + .size(size, size) + .margin_right(5.0) + .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + }), + focus_text( + move || text.clone(), + move || text_indices.clone(), + move || config.get().color(LapceColor::EDITOR_FOCUS), + ) + .style(|s| s.margin_right(6.0).max_width_full()), + focus_text( + move || hint.clone(), + move || hint_indices.clone(), + move || config.get().color(LapceColor::EDITOR_FOCUS), + ) + .style(move |s| { + s.color(config.get().color(LapceColor::EDITOR_DIM)) + .min_width(0.0) + .flex_grow(1.0) + .flex_basis(0.0) + }), + )) + .style(|s| s.align_items(Some(AlignItems::Center)).max_width_full()), + ) + } + PaletteItemContent::RunAndDebug { + mode, + config: run_config, + } => { + let mode = *mode; + let text = format!("{mode} {}", run_config.name); + let hint = format!( + "{} {}", + run_config.program, + run_config.args.clone().unwrap_or_default().join(" ") + ); + let text_indices: Vec = item + .indices + .iter() + .filter_map(|i| { + let i = *i; + if i < text.len() { Some(i) } else { None } + }) + .collect(); + let hint_indices: Vec = item + .indices + .iter() + .filter_map(|i| { + let i = *i; + if i >= text.len() { + Some(i - text.len()) + } else { + None + } + }) + .collect(); + container( + stack(( + svg(move || { + let config = config.get(); + match mode { + RunDebugMode::Run => config.ui_svg(LapceIcons::START), + RunDebugMode::Debug => config.ui_svg(LapceIcons::DEBUG), + } + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.min_width(size) + .size(size, size) + .margin_right(5.0) + .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + }), + focus_text( + move || text.clone(), + move || text_indices.clone(), + move || config.get().color(LapceColor::EDITOR_FOCUS), + ) + .style(|s| s.margin_right(6.0).max_width_full()), + focus_text( + move || hint.clone(), + move || hint_indices.clone(), + move || config.get().color(LapceColor::EDITOR_FOCUS), + ) + .style(move |s| { + s.color(config.get().color(LapceColor::EDITOR_DIM)) + .min_width(0.0) + .flex_grow(1.0) + .flex_basis(0.0) + }), + )) + .style(|s| s.align_items(Some(AlignItems::Center)).max_width_full()), + ) + } + PaletteItemContent::PaletteHelp { .. } + | PaletteItemContent::Command { .. } => { + let text = item.filter_text; + let indices = item.indices; + let keys = if let Some(keymap) = keymap { + keymap + .key + .iter() + .map(|key| key.label().trim().to_string()) + .filter(|l| !l.is_empty()) + .collect() + } else { + vec![] + }; + container( + stack(( + focus_text( + move || text.clone(), + move || indices.clone(), + move || config.get().color(LapceColor::EDITOR_FOCUS), + ) + .style(|s| { + s.flex_row() + .flex_grow(1.0) + .align_items(Some(AlignItems::Center)) + }), + stack((dyn_stack( + move || keys.clone(), + |k| k.clone(), + move |key| { + label(move || key.clone()).style(move |s| { + s.padding_horiz(5.0) + .padding_vert(1.0) + .margin_right(5.0) + .border(1.0) + .border_radius(3.0) + .border_color( + config.get().color(LapceColor::LAPCE_BORDER), + ) + .selectable(false) + }) + }, + ),)), + )) + .style(|s| s.width_full().items_center()), + ) + } + PaletteItemContent::Line { .. } + | PaletteItemContent::Workspace { .. } + | PaletteItemContent::SshHost { .. } + | PaletteItemContent::Language { .. } + | PaletteItemContent::LineEnding { .. } + | PaletteItemContent::ColorTheme { .. } + | PaletteItemContent::SCMReference { .. } + | PaletteItemContent::TerminalProfile { .. } + | PaletteItemContent::IconTheme { .. } => { + let text = item.filter_text; + let indices = item.indices; + container( + focus_text( + move || text.clone(), + move || indices.clone(), + move || config.get().color(LapceColor::EDITOR_FOCUS), + ) + .style(|s| s.align_items(Some(AlignItems::Center)).max_width_full()), + ) + } + #[cfg(windows)] + PaletteItemContent::WslHost { .. } => { + let text = item.filter_text; + let indices = item.indices; + container( + focus_text( + move || text.clone(), + move || indices.clone(), + move || config.get().color(LapceColor::EDITOR_FOCUS), + ) + .style(|s| s.align_items(Some(AlignItems::Center)).max_width_full()), + ) + } + } + .style(move |s| { + s.width_full() + .height(palette_item_height as f32) + .padding_horiz(10.0) + .apply_if(index.get() == i, |style| { + style.background( + config.get().color(LapceColor::PALETTE_CURRENT_BACKGROUND), + ) + }) + }) +} + +fn palette_input(window_tab_data: Rc) -> impl View { + let editor = window_tab_data.palette.input_editor.clone(); + let config = window_tab_data.common.config; + let focus = window_tab_data.common.focus; + let is_focused = move || focus.get() == Focus::Palette; + + let input = TextInputBuilder::new() + .is_focused(is_focused) + .build_editor(editor) + .placeholder(move || window_tab_data.palette.placeholder_text().to_owned()) + .style(|s| s.width_full()); + + container(container(input).style(move |s| { + let config = config.get(); + s.width_full() + .height(25.0) + .items_center() + .border_bottom(1.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .background(config.color(LapceColor::EDITOR_BACKGROUND)) + })) + .style(|s| s.padding_bottom(5.0)) +} + +struct PaletteItems(im::Vector); + +impl VirtualVector<(usize, PaletteItem)> for PaletteItems { + fn total_len(&self) -> usize { + self.0.len() + } + + fn slice( + &mut self, + range: Range, + ) -> impl Iterator { + let start = range.start; + Box::new( + self.0 + .slice(range) + .into_iter() + .enumerate() + .map(move |(i, item)| (i + start, item)), + ) + } +} + +fn palette_content( + window_tab_data: Rc, + layout_rect: ReadSignal, +) -> impl View { + let items = window_tab_data.palette.filtered_items; + let keymaps = window_tab_data + .palette + .keypress + .get_untracked() + .command_keymaps; + let index = window_tab_data.palette.index.read_only(); + let clicked_index = window_tab_data.palette.clicked_index.write_only(); + let config = window_tab_data.common.config; + let run_id = window_tab_data.palette.run_id; + let input = window_tab_data.palette.input.read_only(); + let palette_item_height = 25.0; + let workspace = window_tab_data.workspace.clone(); + stack(( + scroll({ + let workspace = workspace.clone(); + virtual_stack( + move || PaletteItems(items.get()), + move |(i, _item)| { + (run_id.get_untracked(), *i, input.get_untracked().input) + }, + move |(i, item)| { + let workspace = workspace.clone(); + let keymap = { + let cmd_kind = match &item.content { + PaletteItemContent::PaletteHelp { cmd } => { + Some(CommandKind::Workbench(cmd.clone())) + } + PaletteItemContent::Command { + cmd: LapceCommand { kind, .. }, + } => Some(kind.clone()), + _ => None, + }; + + cmd_kind + .and_then(|kind| keymaps.get(kind.str())) + .and_then(|maps| maps.first()) + }; + container(palette_item( + workspace, + i, + item, + index, + palette_item_height, + config, + keymap, + )) + .on_click_stop(move |_| { + clicked_index.set(Some(i)); + }) + .style(move |s| { + s.width_full().cursor(CursorStyle::Pointer).hover(|s| { + s.background( + config + .get() + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + }) + }) + }, + ) + .item_size_fixed(move || palette_item_height) + .style(|s| s.width_full().flex_col()) + }) + .ensure_visible(move || { + Size::new(1.0, palette_item_height) + .to_rect() + .with_origin(Point::new( + 0.0, + index.get() as f64 * palette_item_height, + )) + }) + .style(|s| { + s.width_full() + .min_height(0.0) + .set(PropagatePointerWheel, false) + }), + text("No matching results").style(move |s| { + s.display(if items.with(|items| items.is_empty()) { + Display::Flex + } else { + Display::None + }) + .padding_horiz(10.0) + .align_items(Some(AlignItems::Center)) + .height(palette_item_height as f32) + }), + )) + .style(move |s| { + s.flex_col() + .width_full() + .min_height(0.0) + .max_height((layout_rect.get().height() * 0.45 - 36.0).round() as f32) + .padding_bottom(5.0) + .padding_bottom(5.0) + }) +} + +fn palette_preview(window_tab_data: Rc) -> impl View { + let palette_data = window_tab_data.palette.clone(); + let workspace = palette_data.workspace.clone(); + let preview_editor = palette_data.preview_editor; + let has_preview = palette_data.has_preview; + let config = palette_data.common.config; + let preview_editor = create_rw_signal(preview_editor); + container( + container(editor_container_view( + window_tab_data, + workspace, + |_tracked: bool| true, + preview_editor, + )) + .style(move |s| { + let config = config.get(); + s.position(Position::Absolute) + .border_top(1.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .size_full() + .background(config.color(LapceColor::EDITOR_BACKGROUND)) + }), + ) + .style(move |s| { + s.display(if has_preview.get() { + Display::Flex + } else { + Display::None + }) + .flex_grow(1.0) + }) +} + +fn palette(window_tab_data: Rc) -> impl View { + let layout_rect = window_tab_data.layout_rect.read_only(); + let palette_data = window_tab_data.palette.clone(); + let status = palette_data.status.read_only(); + let config = palette_data.common.config; + let has_preview = palette_data.has_preview.read_only(); + container( + stack(( + palette_input(window_tab_data.clone()), + palette_content(window_tab_data.clone(), layout_rect), + palette_preview(window_tab_data.clone()), + )) + .on_event_stop(EventListener::PointerDown, move |_| {}) + .style(move |s| { + let config = config.get(); + s.width(config.ui.palette_width() as f64) + .max_width_full() + .max_height(if has_preview.get() { + PxPctAuto::Auto + } else { + PxPctAuto::Pct(100.0) + }) + .height(if has_preview.get() { + PxPctAuto::Px(layout_rect.get().height() - 10.0) + } else { + PxPctAuto::Auto + }) + .margin_top(4.0) + .border(1.0) + .border_radius(6.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .flex_col() + .background(config.color(LapceColor::PALETTE_BACKGROUND)) + .pointer_events_auto() + }), + ) + .style(move |s| { + s.display(if status.get() == PaletteStatus::Inactive { + Display::None + } else { + Display::Flex + }) + .position(Position::Absolute) + .size_full() + .flex_col() + .items_center() + .pointer_events_none() + }) + .debug_name("Palette Layer") +} + +fn window_message_view( + messages: RwSignal>, + config: ReadSignal>, +) -> impl View { + let view_fn = + move |(i, (title, message)): (usize, (String, ShowMessageParams))| { + stack(( + svg(move || { + if let MessageType::ERROR = message.typ { + config.get().ui_svg(LapceIcons::ERROR) + } else { + config.get().ui_svg(LapceIcons::WARNING) + } + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + let color = if let MessageType::ERROR = message.typ { + config.color(LapceColor::LAPCE_ERROR) + } else { + config.color(LapceColor::LAPCE_WARN) + }; + s.min_width(size) + .size(size, size) + .margin_right(10.0) + .margin_top(4.0) + .color(color) + }), + stack(( + text(title.clone()).style(|s| { + s.min_width(0.0).line_height(1.8).font_weight(Weight::BOLD) + }), + text(message.message.clone()).style(|s| { + s.min_width(0.0).line_height(1.8).margin_top(5.0) + }), + )) + .style(move |s| { + s.flex_col().min_width(0.0).flex_basis(0.0).flex_grow(1.0) + }), + clickable_icon( + || LapceIcons::CLOSE, + move || { + messages.update(|messages| { + messages.remove(i); + }); + }, + || false, + || false, + || "Close", + config, + ) + .style(|s| s.margin_left(6.0)), + )) + .on_double_click_stop(move |_| { + messages.update(|messages| { + messages.remove(i); + }); + }) + .on_secondary_click_stop({ + let message = message.message.clone(); + move |_| { + let mut clipboard = SystemClipboard::new(); + if !message.is_empty() { + clipboard.put_string(&message); + } + } + }) + .on_event_stop(EventListener::PointerDown, |_| {}) + .style(move |s| { + let config = config.get(); + s.width_full() + .items_start() + .padding(10.0) + .border(1.0) + .border_radius(6.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .background(config.color(LapceColor::PANEL_BACKGROUND)) + .apply_if(i > 0, |s| s.margin_top(10.0)) + }) + }; + + let id = AtomicU64::new(0); + container( + container( + container( + scroll( + dyn_stack( + move || messages.get().into_iter().enumerate(), + move |_| { + id.fetch_add(1, std::sync::atomic::Ordering::Relaxed) + }, + view_fn, + ) + .style(|s| s.flex_col().width_full()), + ) + .style(|s| { + s.absolute() + .pointer_events_auto() + .width_full() + .min_height(0.0) + .max_height_full() + .set(PropagatePointerWheel, false) + }), + ) + .style(|s| s.size_full()), + ) + .style(|s| { + s.width(360.0) + .max_width_pct(80.0) + .padding(10.0) + .height_full() + }), + ) + .style(|s| s.absolute().size_full().justify_end().pointer_events_none()) + .debug_name("Window Message View") +} + +struct VectorItems(im::Vector); + +impl VirtualVector<(usize, V)> for VectorItems { + fn total_len(&self) -> usize { + self.0.len() + } + + fn slice(&mut self, range: Range) -> impl Iterator { + let start = range.start; + self.0 + .slice(range) + .into_iter() + .enumerate() + .map(move |(i, item)| (i + start, item)) + } +} + +fn completion_kind_to_str(kind: CompletionItemKind) -> &'static str { + match kind { + CompletionItemKind::METHOD => "f", + CompletionItemKind::FUNCTION => "f", + CompletionItemKind::CLASS => "c", + CompletionItemKind::STRUCT => "s", + CompletionItemKind::VARIABLE => "v", + CompletionItemKind::INTERFACE => "i", + CompletionItemKind::ENUM => "e", + CompletionItemKind::ENUM_MEMBER => "e", + CompletionItemKind::FIELD => "v", + CompletionItemKind::PROPERTY => "p", + CompletionItemKind::CONSTANT => "d", + CompletionItemKind::MODULE => "m", + CompletionItemKind::KEYWORD => "k", + CompletionItemKind::SNIPPET => "n", + _ => "t", + } +} + +fn hover(window_tab_data: Rc) -> impl View { + let hover_data = window_tab_data.common.hover.clone(); + let config = window_tab_data.common.config; + let id = AtomicU64::new(0); + let layout_rect = window_tab_data.common.hover.layout_rect; + + scroll( + dyn_stack( + move || hover_data.content.get(), + move |_| id.fetch_add(1, std::sync::atomic::Ordering::Relaxed), + move |content| match content { + MarkdownContent::Text(text_layout) => container( + rich_text(move || text_layout.clone()) + .style(|s| s.max_width(600.0)), + ) + .style(|s| s.max_width_full()), + MarkdownContent::Image { .. } => container(empty()), + MarkdownContent::Separator => container(empty().style(move |s| { + s.width_full() + .margin_vert(5.0) + .height(1.0) + .background(config.get().color(LapceColor::LAPCE_BORDER)) + })), + }, + ) + .style(|s| s.flex_col().padding_horiz(10.0).padding_vert(5.0)), + ) + .on_resize(move |rect| { + layout_rect.set(rect); + }) + .on_event_stop(EventListener::PointerMove, |_| {}) + .on_event_stop(EventListener::PointerDown, |_| {}) + .style(move |s| { + let active = window_tab_data.common.hover.active.get(); + if !active { + s.hide() + } else { + let config = config.get(); + if let Some(origin) = window_tab_data.hover_origin() { + s.absolute() + .margin_left(origin.x as f32) + .margin_top(origin.y as f32) + .max_height(300.0) + .border(1.0) + .border_radius(6.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .background(config.color(LapceColor::PANEL_BACKGROUND)) + .set(PropagatePointerWheel, false) + } else { + s.hide() + } + } + }) + .debug_name("Hover Layer") +} + +fn completion(window_tab_data: Rc) -> impl View { + let completion_data = window_tab_data.common.completion; + let active_editor = window_tab_data.main_split.active_editor; + let config = window_tab_data.common.config; + let active = completion_data.with_untracked(|c| c.active); + let request_id = + move || completion_data.with_untracked(|c| (c.request_id, c.input_id)); + scroll( + virtual_stack( + move || completion_data.with(|c| VectorItems(c.filtered_items.clone())), + move |(i, _item)| (request_id(), *i), + move |(i, item)| { + stack(( + container( + text( + item.item.kind.map(completion_kind_to_str).unwrap_or(""), + ) + .style(move |s| { + s.width_full() + .justify_content(Some(JustifyContent::Center)) + }), + ) + .style(move |s| { + let config = config.get(); + let width = config.editor.line_height() as f32; + s.width(width) + .min_width(width) + .height_full() + .align_items(Some(AlignItems::Center)) + .font_weight(Weight::BOLD) + .apply_opt( + config.completion_color(item.item.kind), + |s, c| s.color(c).background(c.multiply_alpha(0.3)), + ) + }), + focus_text( + move || { + if config.get().editor.completion_item_show_detail { + item.item + .detail + .clone() + .unwrap_or(item.item.label.clone()) + } else { + item.item.label.clone() + } + }, + move || item.indices.clone(), + move || config.get().color(LapceColor::EDITOR_FOCUS), + ) + .on_click_stop(move |_| { + active.set(i); + if let Some(editor) = active_editor.get_untracked() { + editor.select_completion(); + } + }) + .on_event_stop(EventListener::PointerDown, |_| {}) + .style(move |s| { + let config = config.get(); + s.padding_horiz(5.0) + .min_width(0.0) + .align_items(Some(AlignItems::Center)) + .size_full() + .cursor(CursorStyle::Pointer) + .apply_if(active.get() == i, |s| { + s.background( + config.color(LapceColor::COMPLETION_CURRENT), + ) + }) + .hover(move |s| { + s.background( + config + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + }) + }), + )) + .style(move |s| { + s.align_items(Some(AlignItems::Center)) + .width_full() + .height(config.get().editor.line_height() as f32) + }) + }, + ) + .item_size_fixed(move || config.get().editor.line_height() as f64) + .style(|s| { + s.align_items(Some(AlignItems::Center)) + .width_full() + .flex_col() + }), + ) + .ensure_visible(move || { + let config = config.get(); + let active = active.get(); + Size::new(1.0, config.editor.line_height() as f64) + .to_rect() + .with_origin(Point::new( + 0.0, + active as f64 * config.editor.line_height() as f64, + )) + }) + .on_resize(move |rect| { + completion_data.update(|c| { + c.layout_rect = rect; + }); + }) + .on_event_stop(EventListener::PointerMove, |_| {}) + .style(move |s| { + let config = config.get(); + let origin = window_tab_data.completion_origin(); + s.position(Position::Absolute) + .width(config.editor.completion_width as i32) + .max_height(400.0) + .margin_left(origin.x as f32) + .margin_top(origin.y as f32) + .background(config.color(LapceColor::COMPLETION_BACKGROUND)) + .font_family(config.editor.font_family.clone()) + .font_size(config.editor.font_size() as f32) + .border_radius(6.0) + }) + .debug_name("Completion Layer") +} + +fn code_action(window_tab_data: Rc) -> impl View { + let config = window_tab_data.common.config; + let code_action = window_tab_data.code_action; + let (status, active) = code_action + .with_untracked(|code_action| (code_action.status, code_action.active)); + let request_id = + move || code_action.with_untracked(|code_action| code_action.request_id); + scroll( + container( + dyn_stack( + move || { + code_action.with(|code_action| { + code_action.filtered_items.clone().into_iter().enumerate() + }) + }, + move |(i, _item)| (request_id(), *i), + move |(i, item)| { + container( + text(item.title().replace('\n', " ")) + .style(|s| s.text_ellipsis().min_width(0.0)), + ) + .on_click_stop(move |_| { + let code_action = code_action.get_untracked(); + code_action.active.set(i); + code_action.select(); + }) + .on_event_stop(EventListener::PointerDown, |_| {}) + .style(move |s| { + let config = config.get(); + s.padding_horiz(10.0) + .align_items(Some(AlignItems::Center)) + .min_width(0.0) + .width_full() + .line_height(1.8) + .border_radius(6.0) + .cursor(CursorStyle::Pointer) + .apply_if(active.get() == i, |s| { + s.background( + config.color(LapceColor::COMPLETION_CURRENT), + ) + }) + .hover(move |s| { + s.background( + config + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + }) + }) + }, + ) + .style(|s| s.width_full().flex_col()), + ) + .style(|s| s.width_full().padding_vert(4.0)), + ) + .ensure_visible(move || { + let config = config.get(); + let active = active.get(); + Size::new(1.0, config.editor.line_height() as f64) + .to_rect() + .with_origin(Point::new( + 0.0, + active as f64 * config.editor.line_height() as f64, + )) + }) + .on_resize(move |rect| { + code_action.update(|c| { + c.layout_rect = rect; + }); + }) + .on_event_stop(EventListener::PointerMove, |_| {}) + .style(move |s| { + let origin = window_tab_data.code_action_origin(); + s.display(match status.get() { + CodeActionStatus::Inactive => Display::None, + CodeActionStatus::Active => Display::Flex, + }) + .position(Position::Absolute) + .width(400.0) + .max_height(400.0) + .margin_left(origin.x as f32) + .margin_top(origin.y as f32) + .background(config.get().color(LapceColor::COMPLETION_BACKGROUND)) + .border_radius(6.0) + }) + .debug_name("Code Action Layer") +} + +fn rename(window_tab_data: Rc) -> impl View { + let editor = window_tab_data.rename.editor.clone(); + let active = window_tab_data.rename.active; + let layout_rect = window_tab_data.rename.layout_rect; + let config = window_tab_data.common.config; + + container( + container( + TextInputBuilder::new() + .is_focused(move || active.get()) + .build_editor(editor) + .style(|s| s.width(150.0)), + ) + .style(move |s| { + let config = config.get(); + s.font_family(config.editor.font_family.clone()) + .font_size(config.editor.font_size() as f32) + .border(1.0) + .border_radius(6.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .background(config.color(LapceColor::EDITOR_BACKGROUND)) + }), + ) + .on_resize(move |rect| { + layout_rect.set(rect); + }) + .on_event_stop(EventListener::PointerMove, |_| {}) + .on_event_stop(EventListener::PointerDown, |_| {}) + .style(move |s| { + let origin = window_tab_data.rename_origin(); + s.position(Position::Absolute) + .apply_if(!active.get(), |s| s.hide()) + .margin_left(origin.x as f32) + .margin_top(origin.y as f32) + .background(config.get().color(LapceColor::PANEL_BACKGROUND)) + .border_radius(6.0) + .padding(6.0) + }) + .debug_name("Rename Layer") +} + +fn window_tab(window_tab_data: Rc) -> impl View { + let source_control = window_tab_data.source_control.clone(); + let window_origin = window_tab_data.common.window_origin; + let layout_rect = window_tab_data.layout_rect; + let config = window_tab_data.common.config; + let workbench_command = window_tab_data.common.workbench_command; + let window_tab_scope = window_tab_data.scope; + let hover_active = window_tab_data.common.hover.active; + let status_height = window_tab_data.status_height; + + let view = stack(( + stack(( + title(window_tab_data.clone()), + workbench(window_tab_data.clone()), + status( + window_tab_data.clone(), + source_control, + workbench_command, + status_height, + config, + ), + )) + .on_resize(move |rect| { + layout_rect.set(rect); + }) + .on_move(move |point| { + window_origin.set(point); + }) + .style(|s| s.size_full().flex_col()) + .debug_name("Base Layer"), + completion(window_tab_data.clone()), + hover(window_tab_data.clone()), + code_action(window_tab_data.clone()), + rename(window_tab_data.clone()), + palette(window_tab_data.clone()), + about::about_popup(window_tab_data.clone()), + alert::alert_box(window_tab_data.alert_data.clone()), + )) + .on_cleanup(move || { + window_tab_scope.dispose(); + }) + .on_event_cont(EventListener::PointerMove, move |_| { + if hover_active.get_untracked() { + hover_active.set(false); + } + }) + .style(move |s| { + let config = config.get(); + s.size_full() + .color(config.color(LapceColor::EDITOR_FOREGROUND)) + .background(config.color(LapceColor::EDITOR_BACKGROUND)) + .font_size(config.ui.font_size() as f32) + .apply_if(!config.ui.font_family.is_empty(), |s| { + s.font_family(config.ui.font_family.clone()) + }) + .class(floem::views::scroll::Handle, |s| { + s.background(config.color(LapceColor::LAPCE_SCROLL_BAR)) + }) + }) + .debug_name("Window Tab"); + + let view_id = view.id(); + window_tab_data.common.view_id.set(view_id); + view +} + +fn workspace_title(workspace: &LapceWorkspace) -> Option { + let p = workspace.path.as_ref()?; + let dir = p.file_name().unwrap_or(p.as_os_str()).to_string_lossy(); + Some(match &workspace.kind { + LapceWorkspaceType::Local => format!("{dir}"), + LapceWorkspaceType::RemoteSSH(remote) => format!("{dir} [{remote}]"), + #[cfg(windows)] + LapceWorkspaceType::RemoteWSL(remote) => format!("{dir} [{remote}]"), + }) +} + +fn workspace_tab_header(window_data: WindowData) -> impl View { + let tabs = window_data.window_tabs; + let active = window_data.active; + let config = window_data.config; + let window_tab_header_height = window_data.common.window_tab_header_height; + let available_width = create_rw_signal(0.0); + let add_icon_width = create_rw_signal(0.0); + let window_control_width = create_rw_signal(0.0); + let window_maximized = window_data.common.window_maximized; + let num_window_tabs = window_data.num_window_tabs; + let window_command = window_data.common.window_command; + + let tab_width = create_memo(move |_| { + let window_control_width = if !cfg!(target_os = "macos") + && config.get_untracked().core.custom_titlebar + { + window_control_width.get() + } else { + 0.0 + }; + let available_width = available_width.get() + - add_icon_width.get() + - if cfg!(target_os = "macos") { 75.0 } else { 0.0 } + - window_control_width + - 30.0; + let tabs_len = tabs.with(|tabs| tabs.len()); + if tabs_len > 0 { + (available_width / tabs_len as f64).min(200.0) + } else { + available_width + } + }); + + let local_window_data = window_data.clone(); + let dragging_index: RwSignal>> = create_rw_signal(None); + let view_fn = move |(index, tab): (RwSignal, Rc)| { + let drag_over_left = create_rw_signal(None); + let window_data = local_window_data.clone(); + stack(( + container({ + stack(( + stack(( + text( + workspace_title(&tab.workspace) + .unwrap_or_else(|| String::from("New Tab")), + ) + .style(|s| { + s.margin_left(10.0) + .min_width(0.0) + .flex_basis(0.0) + .flex_grow(1.0) + .selectable(false) + .text_ellipsis() + }), + { + let window_data = local_window_data.clone(); + clickable_icon( + || LapceIcons::WINDOW_CLOSE, + move || { + window_data.run_window_command( + WindowCommand::CloseWorkspaceTab { + index: Some(index.get_untracked()), + }, + ); + }, + || false, + || false, + || "Close", + config.read_only(), + ) + .style(|s| s.margin_horiz(6.0)) + }, + )) + .on_event_stop(EventListener::DragOver, move |event| { + if dragging_index.get_untracked().is_some() { + if let Event::PointerMove(pointer_event) = event { + let left = pointer_event.pos.x + < tab_width.get_untracked() / 2.0; + if drag_over_left.get_untracked() != Some(left) { + drag_over_left.set(Some(left)); + } + } + } + }) + .on_event(EventListener::Drop, move |event| { + if dragging_index.get_untracked().is_some() { + drag_over_left.set(None); + if let Event::PointerUp(pointer_event) = event { + let left = pointer_event.pos.x + < tab_width.get_untracked() / 2.0; + let index = index.get_untracked(); + let new_index = if left { index } else { index + 1 }; + if let Some(from_index) = + dragging_index.get_untracked() + { + window_data.move_tab( + from_index.get_untracked(), + new_index, + ); + } + dragging_index.set(None); + } + EventPropagation::Stop + } else { + EventPropagation::Continue + } + }) + .on_event_stop(EventListener::DragLeave, move |_| { + drag_over_left.set(None); + }) + .style(move |s| { + let config = config.get(); + s.width_full() + .min_width(0.0) + .items_center() + .border_right(1.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .apply_if( + cfg!(target_os = "macos") && index.get() == 0, + |s| s.border_left(1.0), + ) + }), + container(empty().style(move |s| { + s.size_full() + .apply_if(active.get() == index.get(), |s| { + s.border_bottom(2.0) + }) + .border_color( + config + .get() + .color(LapceColor::LAPCE_TAB_ACTIVE_UNDERLINE), + ) + })) + .style(move |s| { + s.position(Position::Absolute) + .padding_horiz(3.0) + .size_full() + .pointer_events_none() + }), + )) + .style(move |s| s.size_full().items_center()) + }) + .draggable() + .on_event_stop(EventListener::DragStart, move |_| { + dragging_index.set(Some(index)); + }) + .on_event_stop(EventListener::DragEnd, move |_| { + dragging_index.set(None); + }) + .dragging_style(move |s| { + let config = config.get(); + s.border(1.0) + .border_radius(6.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .color( + config + .color(LapceColor::EDITOR_FOREGROUND) + .multiply_alpha(0.7), + ) + .background( + config + .color(LapceColor::PANEL_BACKGROUND) + .multiply_alpha(0.7), + ) + }) + .on_click_stop(move |_| { + active.set(index.get_untracked()); + }) + .style(move |s| s.size_full()), + empty().style(move |s| { + let index = index.get(); + s.absolute() + .margin_left(if index == 0 { 0.0 } else { -2.0 }) + .width( + tab_width.get() as f32 + if index == 0 { 1.0 } else { 3.0 }, + ) + .height_full() + .border_color( + config.get().color(LapceColor::LAPCE_TAB_ACTIVE_UNDERLINE), + ) + .apply_if(drag_over_left.get().is_some(), move |s| { + let drag_over_left = drag_over_left.get_untracked().unwrap(); + if drag_over_left { + s.border_left(3.0) + } else { + s.border_right(3.0) + } + }) + .apply_if(drag_over_left.get().is_none(), move |s| s.hide()) + }), + )) + .style(move |s| s.height_full().width(tab_width.get() as f32)) + }; + + stack(( + empty().style(move |s| { + let is_macos = cfg!(target_os = "macos"); + s.min_width(75.0) + .width(75.0) + .apply_if(!is_macos, |s| s.hide()) + }), + dyn_stack( + move || { + let tabs = tabs.get(); + for (i, (index, _)) in tabs.iter().enumerate() { + if index.get_untracked() != i { + index.set(i); + } + } + tabs + }, + |(_, tab)| tab.window_tab_id, + view_fn, + ) + .style(|s| s.height_full()), + container(clickable_icon( + || LapceIcons::ADD, + move || { + window_data.run_window_command(WindowCommand::NewWorkspaceTab { + workspace: LapceWorkspace::default(), + end: true, + }); + }, + || false, + || false, + || "New Workspace Tab", + config.read_only(), + )) + .on_resize(move |rect| { + let current = add_icon_width.get_untracked(); + if rect.width() != current { + add_icon_width.set(rect.width()); + } + }) + .style(|s| { + s.height_full() + .padding_left(10.0) + .padding_right(10.0) + .items_center() + }), + drag_window_area(empty()) + .style(|s| s.height_full().flex_basis(0.0).flex_grow(1.0)), + window_controls_view( + window_command, + false, + num_window_tabs, + window_maximized, + config.read_only(), + ) + .on_resize(move |rect| { + let width = rect.width(); + if window_control_width.get_untracked() != width { + window_control_width.set(width); + } + }), + )) + .on_resize(move |rect| { + let current = available_width.get_untracked(); + if rect.width() != current { + available_width.set(rect.width()); + } + window_tab_header_height.set(rect.height()); + }) + .style(move |s| { + let config = config.get(); + s.border_bottom(1.0) + .width_full() + .height(37.0) + .font_size(config.ui.font_size() as f32) + .apply_if(!config.ui.font_family.is_empty(), |s| { + s.font_family(config.ui.font_family.clone()) + }) + .apply_if(tabs.with(|tabs| tabs.len() < 2), |s| s.hide()) + .color(config.color(LapceColor::EDITOR_FOREGROUND)) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .background(config.color(LapceColor::PANEL_BACKGROUND)) + .items_center() + }) + .debug_name("Workspace Tab Header") +} + +fn window(window_data: WindowData) -> impl View { + let window_tabs = window_data.window_tabs.read_only(); + let active = window_data.active.read_only(); + let items = move || window_tabs.get(); + let key = |(_, window_tab): &(RwSignal, Rc)| { + window_tab.window_tab_id + }; + let active = move || active.get(); + let window_focus = create_rw_signal(false); + let ime_enabled = window_data.ime_enabled; + let window_maximized = window_data.common.window_maximized; + + tab(active, items, key, |(_, window_tab_data)| { + window_tab(window_tab_data) + }) + .window_title(move || { + let active = active(); + let window_tabs = window_tabs.get(); + let workspace = window_tabs + .get(active) + .or_else(|| window_tabs.last()) + .and_then(|(_, window_tab)| window_tab.workspace.display()); + match workspace { + Some(workspace) => format!("{workspace} - Lapce"), + None => "Lapce".to_string(), + } + }) + .on_event_stop(EventListener::ImeEnabled, move |_| { + ime_enabled.set(true); + }) + .on_event_stop(EventListener::ImeDisabled, move |_| { + ime_enabled.set(false); + }) + .on_event_cont(EventListener::WindowGotFocus, move |_| { + window_focus.set(true); + }) + .on_event_cont(EventListener::WindowMaximizeChanged, move |event| { + if let Event::WindowMaximizeChanged(maximized) = event { + window_maximized.set(*maximized); + } + }) + .window_menu(move || { + window_focus.track(); + let active = active(); + let window_tabs = window_tabs.get(); + let window_tab = window_tabs.get(active).or_else(|| window_tabs.last()); + if let Some((_, window_tab)) = window_tab { + window_tab.common.keypress.track(); + let workbench_command = window_tab.common.workbench_command; + let lapce_command = window_tab.common.lapce_command; + window_menu(lapce_command, workbench_command) + } else { + Menu::new("Lapce") + } + }) + .style(|s| s.size_full()) + .debug_name("Window") +} + +pub fn launch() { + let cli = Cli::parse(); + + if !cli.wait { + logging::panic_hook(); + } + + let (reload_handle, _guard) = logging::logging(); + trace!(TraceLevel::INFO, "Starting up Lapce.."); + + #[cfg(feature = "vendored-fonts")] + { + use floem::text::{FONT_SYSTEM, fontdb::Source}; + + const FONT_DEJAVU_SANS_REGULAR: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/../extra/fonts/DejaVu/DejaVuSans.ttf" + )); + const FONT_DEJAVU_SANS_MONO_REGULAR: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/../extra/fonts/DejaVu/DejaVuSansMono.ttf" + )); + + FONT_SYSTEM + .lock() + .db_mut() + .load_font_source(Source::Binary(Arc::new(FONT_DEJAVU_SANS_REGULAR))); + FONT_SYSTEM + .lock() + .db_mut() + .load_font_source(Source::Binary(Arc::new( + FONT_DEJAVU_SANS_MONO_REGULAR, + ))); + } + + let stdin = std::io::stdin(); + if !stdin.is_terminal() { + trace!(TraceLevel::INFO, "Loading custom environment from shell"); + load_shell_env(); + } + + // small hack to unblock terminal if launched from it + // launch it as a separate process that waits + if !cli.wait { + let mut args = std::env::args().collect::>(); + args.push("--wait".to_string()); + let mut cmd = std::process::Command::new(&args[0]); + #[cfg(target_os = "windows")] + cmd.creation_flags(windows::Win32::System::Threading::CREATE_NO_WINDOW); + + let stderr_file_path = + Directory::logs_directory().unwrap().join("stderr.log"); + let stderr_file = std::fs::OpenOptions::new() + .write(true) + .truncate(true) + .create(true) + .read(true) + .open(stderr_file_path) + .unwrap(); + let stderr = Stdio::from(stderr_file); + + let stdout_file_path = + Directory::logs_directory().unwrap().join("stdout.log"); + let stdout_file = std::fs::OpenOptions::new() + .write(true) + .truncate(true) + .create(true) + .read(true) + .open(stdout_file_path) + .unwrap(); + let stdout = Stdio::from(stdout_file); + + if let Err(why) = cmd + .args(&args[1..]) + .stderr(stderr) + .stdout(stdout) + .env("LAPCE_LOG", "lapce_app::app=error,off") + .spawn() + { + eprintln!("Failed to launch lapce: {why}"); + std::process::exit(1); + }; + return; + } + + // If the cli is not requesting a new window, and we're not developing a plugin, we try to open + // in the existing Lapce process + if !cli.new { + match get_socket() { + Ok(socket) => { + if let Err(e) = try_open_in_existing_process(socket, &cli.paths) { + trace!(TraceLevel::ERROR, "failed to open path(s): {e}"); + }; + return; + } + Err(err) => { + tracing::error!("{:?}", err); + } + } + } + + #[cfg(feature = "updater")] + crate::update::cleanup(); + + if let Err(err) = lapce_proxy::register_lapce_path() { + tracing::error!("{:?}", err); + } + let db = match LapceDb::new() { + Ok(db) => Arc::new(db), + Err(e) => { + #[cfg(windows)] + logging::error_modal("Error", &format!("Failed to create LapceDb: {e}")); + + trace!(TraceLevel::ERROR, "Failed to create LapceDb: {e}"); + std::process::exit(1); + } + }; + let scope = Scope::new(); + provide_context(db.clone()); + + let window_scale = scope.create_rw_signal(1.0); + let latest_release = scope.create_rw_signal(Arc::new(None)); + let app_command = Listener::new_empty(scope); + + let plugin_paths = Arc::new(cli.plugin_path); + + let (tx, rx) = channel(); + let mut watcher = notify::recommended_watcher(ConfigWatcher::new(tx)) + .context("Failed to spawn file watcher") + .unwrap(); + if let Some(path) = LapceConfig::settings_file() { + if let Err(err) = watcher.watch(&path, notify::RecursiveMode::Recursive) { + tracing::error!("{:?}", err); + } + } + if let Some(path) = Directory::themes_directory() { + if let Err(err) = watcher.watch(&path, notify::RecursiveMode::Recursive) { + tracing::error!("{:?}", err); + } + } + if let Some(path) = LapceConfig::keymaps_file() { + if let Err(err) = watcher.watch(&path, notify::RecursiveMode::Recursive) { + tracing::error!("{:?}", err); + } + } + if let Some(path) = Directory::plugins_directory() { + if let Err(err) = watcher.watch(&path, notify::RecursiveMode::Recursive) { + tracing::error!("{:?}", err); + } + } + + let windows = scope.create_rw_signal(im::HashMap::new()); + let config = LapceConfig::load(&LapceWorkspace::default(), &[], &plugin_paths); + + // Restore scale from config + window_scale.set(config.ui.scale()); + + let config = scope.create_rw_signal(Arc::new(config)); + let app_data = AppData { + windows, + active_window: scope.create_rw_signal(WindowId::from_raw(0)), + window_scale, + app_terminated: scope.create_rw_signal(false), + watcher: Arc::new(watcher), + latest_release, + app_command, + tracing_handle: reload_handle, + config, + plugin_paths, + }; + + let app = app_data.create_windows(db.clone(), cli.paths); + + { + let app_data = app_data.clone(); + let notification = create_signal_from_channel(rx); + create_effect(move |_| { + if notification.get().is_some() { + tracing::debug!("notification reload_config"); + app_data.reload_config(); + } + }); + } + + { + let cx = Scope::new(); + let app_data = app_data.clone(); + let send = create_ext_action(cx, move |updated| { + if updated { + trace!( + TraceLevel::INFO, + "grammar or query got updated, reset highlight configs" + ); + reset_highlight_configs(); + for (_, window) in app_data.windows.get_untracked() { + for (_, tab) in window.window_tabs.get_untracked() { + for (_, doc) in tab.main_split.docs.get_untracked() { + doc.syntax.update(|syntax| { + *syntax = Syntax::from_language(syntax.language); + }); + doc.trigger_syntax_change(None); + } + } + } + } + }); + std::thread::Builder::new() + .name("FindGrammar".to_owned()) + .spawn(move || { + use self::grammars::*; + let updated = match find_grammar_release() { + Ok(release) => { + let mut updated = false; + match fetch_grammars(&release) { + Err(e) => { + trace!( + TraceLevel::ERROR, + "failed to fetch grammars: {e}" + ); + } + Ok(u) => updated |= u, + } + match fetch_queries(&release) { + Err(e) => { + trace!( + TraceLevel::ERROR, + "failed to fetch grammars: {e}" + ); + } + Ok(u) => updated |= u, + } + updated + } + Err(e) => { + trace!( + TraceLevel::ERROR, + "failed to obtain release info: {e}" + ); + false + } + }; + send(updated); + }) + .unwrap(); + } + + #[cfg(feature = "updater")] + { + let (tx, rx) = sync_channel(1); + let notification = create_signal_from_channel(rx); + let latest_release = app_data.latest_release; + create_effect(move |_| { + if let Some(release) = notification.get() { + latest_release.set(Arc::new(Some(release))); + } + }); + std::thread::Builder::new() + .name("LapceUpdater".to_owned()) + .spawn(move || { + loop { + if let Ok(release) = crate::update::get_latest_release() { + if let Err(err) = tx.send(release) { + tracing::error!("{:?}", err); + } + } + std::thread::sleep(std::time::Duration::from_secs(60 * 60)); + } + }) + .unwrap(); + } + + { + let (tx, rx) = sync_channel(1); + let notification = create_signal_from_channel(rx); + let app_data = app_data.clone(); + create_effect(move |_| { + if let Some(CoreNotification::OpenPaths { paths }) = notification.get() { + if let Some(window_tab) = app_data.active_window_tab() { + window_tab.open_paths(&paths); + // focus window after open doc + floem::action::focus_window(); + } + } + }); + std::thread::Builder::new() + .name("ListenLocalSocket".to_owned()) + .spawn(move || { + if let Err(err) = listen_local_socket(tx) { + tracing::error!("{:?}", err); + } + }) + .unwrap(); + } + + { + let app_data = app_data.clone(); + app_data.app_command.listen(move |command| { + app_data.run_app_command(command); + }); + } + + app.on_event(move |event| match event { + floem::AppEvent::WillTerminate => { + app_data.app_terminated.set(true); + if let Err(err) = db.insert_app(app_data.clone()) { + tracing::error!("{:?}", err); + } + } + floem::AppEvent::Reopen { + has_visible_windows, + } => { + if !has_visible_windows { + app_data.new_window(None); + } + } + }) + .run(); +} + +/// Uses a login shell to load the correct shell environment for the current user. +pub fn load_shell_env() { + use std::process::Command; + + use tracing::warn; + + #[cfg(not(windows))] + let shell = match std::env::var("SHELL") { + Ok(s) => s, + Err(error) => { + // Shell variable is not set, so we can't determine the correct shell executable. + trace!( + TraceLevel::ERROR, + "Failed to obtain shell environment: {error}" + ); + return; + } + }; + + #[cfg(windows)] + let shell = "powershell"; + + let mut command = Command::new(shell); + + #[cfg(not(windows))] + command.args(["--login", "-c", "printenv"]); + + #[cfg(windows)] + command.args([ + "-Command", + "Get-ChildItem env: | ForEach-Object { \"{0}={1}\" -f $_.Name, $_.Value }", + ]); + + #[cfg(windows)] + command.creation_flags(windows::Win32::System::Threading::CREATE_NO_WINDOW); + + let env = match command.output() { + Ok(output) => String::from_utf8(output.stdout).unwrap_or_default(), + + Err(error) => { + trace!( + TraceLevel::ERROR, + "Failed to obtain shell environment: {error}" + ); + return; + } + }; + + env.split('\n') + .filter_map(|line| line.split_once('=')) + .for_each(|(key, value)| unsafe { + let value = value.trim_matches('\r'); + if let Ok(v) = std::env::var(key) { + if v != value { + warn!("Overwriting '{key}', previous value: '{v}', new value '{value}'"); + } + }; + std::env::set_var(key, value); + }) +} + +pub fn get_socket() -> Result { + let local_socket = Directory::local_socket() + .ok_or_else(|| anyhow!("can't get local socket folder"))?; + let socket = + interprocess::local_socket::LocalSocketStream::connect(local_socket)?; + Ok(socket) +} + +pub fn try_open_in_existing_process( + mut socket: interprocess::local_socket::LocalSocketStream, + paths: &[PathObject], +) -> Result<()> { + let msg: CoreMessage = RpcMessage::Notification(CoreNotification::OpenPaths { + paths: paths.to_vec(), + }); + lapce_rpc::stdio::write_msg(&mut socket, msg)?; + + let (tx, rx) = crossbeam_channel::bounded(1); + std::thread::spawn(move || { + let mut buf = [0; 100]; + let received = if let Ok(n) = socket.read(&mut buf) { + &buf[..n] == b"received" + } else { + false + }; + tx.send(received) + }); + + let received = rx.recv_timeout(std::time::Duration::from_millis(500))?; + if !received { + return Err(anyhow!("didn't receive response")); + } + + Ok(()) +} + +fn listen_local_socket(tx: SyncSender) -> Result<()> { + let local_socket = Directory::local_socket() + .ok_or_else(|| anyhow!("can't get local socket folder"))?; + if local_socket.exists() { + if let Err(err) = std::fs::remove_file(&local_socket) { + tracing::error!("{:?}", err); + } + } + let socket = + interprocess::local_socket::LocalSocketListener::bind(local_socket)?; + + for stream in socket.incoming().flatten() { + let tx = tx.clone(); + std::thread::spawn(move || -> Result<()> { + let mut reader = BufReader::new(stream); + loop { + let msg: Option = + lapce_rpc::stdio::read_msg(&mut reader)?; + + if let Some(RpcMessage::Notification(msg)) = msg { + tx.send(msg)?; + } else { + trace!(TraceLevel::ERROR, "Unhandled message: {msg:?}"); + } + + let stream_ref = reader.get_mut(); + if let Err(err) = stream_ref.write_all(b"received") { + tracing::error!("{:?}", err); + } + if let Err(err) = stream_ref.flush() { + tracing::error!("{:?}", err); + } + } + }); + } + Ok(()) +} + +pub fn window_menu( + lapce_command: Listener, + workbench_command: Listener, +) -> Menu { + Menu::new("Lapce") + .entry({ + let mut menu = Menu::new("Lapce") + .entry(MenuItem::new("About Lapce").action(move || { + workbench_command.send(LapceWorkbenchCommand::ShowAbout) + })) + .separator() + .entry( + Menu::new("Settings...") + .entry(MenuItem::new("Open Settings").action(move || { + workbench_command + .send(LapceWorkbenchCommand::OpenSettings); + })) + .entry(MenuItem::new("Open Keyboard Shortcuts").action( + move || { + workbench_command.send( + LapceWorkbenchCommand::OpenKeyboardShortcuts, + ); + }, + )), + ) + .separator() + .entry(MenuItem::new("Quit Lapce").action(move || { + workbench_command.send(LapceWorkbenchCommand::Quit); + })); + if cfg!(target_os = "macos") { + menu = menu + .separator() + .entry(MenuItem::new("Hide Lapce")) + .entry(MenuItem::new("Hide Others")) + .entry(MenuItem::new("Show All")) + } + menu + }) + .separator() + .entry( + Menu::new("File") + .entry(MenuItem::new("New File").action(move || { + workbench_command.send(LapceWorkbenchCommand::NewFile); + })) + .separator() + .entry(MenuItem::new("Open").action(move || { + workbench_command.send(LapceWorkbenchCommand::OpenFile); + })) + .entry(MenuItem::new("Open Folder").action(move || { + workbench_command.send(LapceWorkbenchCommand::OpenFolder); + })) + .separator() + .entry(MenuItem::new("Save").action(move || { + lapce_command.send(LapceCommand { + kind: CommandKind::Focus(FocusCommand::Save), + data: None, + }); + })) + .entry(MenuItem::new("Save All").action(move || { + workbench_command.send(LapceWorkbenchCommand::SaveAll); + })) + .separator() + .entry(MenuItem::new("Close Folder").action(move || { + workbench_command.send(LapceWorkbenchCommand::CloseFolder); + })) + .entry(MenuItem::new("Close Window").action(move || { + workbench_command.send(LapceWorkbenchCommand::CloseWindow); + })), + ) + .entry( + Menu::new("Edit") + .entry(MenuItem::new("Cut").action(move || { + lapce_command.send(LapceCommand { + kind: CommandKind::Edit(EditCommand::ClipboardCut), + data: None, + }); + })) + .entry(MenuItem::new("Copy").action(move || { + lapce_command.send(LapceCommand { + kind: CommandKind::Edit(EditCommand::ClipboardCopy), + data: None, + }); + })) + .entry(MenuItem::new("Paste").action(move || { + lapce_command.send(LapceCommand { + kind: CommandKind::Edit(EditCommand::ClipboardPaste), + data: None, + }); + })) + .separator() + .entry(MenuItem::new("Undo").action(move || { + lapce_command.send(LapceCommand { + kind: CommandKind::Edit(EditCommand::Undo), + data: None, + }); + })) + .entry(MenuItem::new("Redo").action(move || { + lapce_command.send(LapceCommand { + kind: CommandKind::Edit(EditCommand::Redo), + data: None, + }); + })) + .separator() + .entry(MenuItem::new("Find").action(move || { + lapce_command.send(LapceCommand { + kind: CommandKind::Focus(FocusCommand::Search), + data: None, + }); + })), + ) +} +fn tab_secondary_click( + internal_command: Listener, + editor_tab_id: EditorTabId, + child: EditorTabChild, +) { + let mut menu = Menu::new(""); + let child_other = child.clone(); + let child_right = child.clone(); + let child_left = child.clone(); + menu = menu + .entry(MenuItem::new("Close").action(move || { + internal_command.send(InternalCommand::EditorTabChildClose { + editor_tab_id, + child: child.clone(), + }); + })) + .entry(MenuItem::new("Close Other Tabs").action(move || { + internal_command.send(InternalCommand::EditorTabCloseByKind { + editor_tab_id, + child: child_other.clone(), + kind: TabCloseKind::CloseOther, + }); + })) + .entry(MenuItem::new("Close All Tabs").action(move || { + internal_command.send(InternalCommand::EditorTabClose { editor_tab_id }); + })) + .entry(MenuItem::new("Close Tabs to the Right").action(move || { + internal_command.send(InternalCommand::EditorTabCloseByKind { + editor_tab_id, + child: child_right.clone(), + kind: TabCloseKind::CloseToRight, + }); + })) + .entry(MenuItem::new("Close Tabs to the Left").action(move || { + internal_command.send(InternalCommand::EditorTabCloseByKind { + editor_tab_id, + child: child_left.clone(), + kind: TabCloseKind::CloseToLeft, + }); + })); + show_context_menu(menu, None); +} diff --git a/lapce-app/src/app/grammars.rs b/lapce-app/src/app/grammars.rs new file mode 100644 index 0000000..511ecde --- /dev/null +++ b/lapce-app/src/app/grammars.rs @@ -0,0 +1,141 @@ +use std::{ + env, + fs::{self}, + path::PathBuf, +}; + +use anyhow::{Context, Result, anyhow}; +use lapce_core::directory::Directory; + +use crate::{tracing::*, update::ReleaseInfo}; + +fn get_github_api(url: &str) -> Result { + let user_agent = format!("Lapce/{}", lapce_core::meta::VERSION); + let resp = lapce_proxy::get_url(url, Some(user_agent.as_str()))?; + if !resp.status().is_success() { + return Err(anyhow!("get release info failed {}", resp.text()?)); + } + + Ok(resp.text()?) +} + +pub fn find_grammar_release() -> Result { + let releases: Vec = serde_json::from_str(&get_github_api( + "https://api.github.com/repos/lapce/tree-sitter-grammars/releases?per_page=100", + ).context("Failed to retrieve releases for tree-sitter-grammars")?)?; + + use lapce_core::meta::{RELEASE, ReleaseType, VERSION}; + + let releases = releases + .into_iter() + .filter_map(|f| { + if matches!(RELEASE, ReleaseType::Debug | ReleaseType::Nightly) { + return Some(f); + } + + let tag_name = if f.tag_name.starts_with('v') { + f.tag_name.trim_start_matches('v') + } else { + f.tag_name.as_str() + }; + + use std::cmp::Ordering; + + use semver::Version; + + let sv = Version::parse(tag_name).ok()?; + let version = Version::parse(VERSION).ok()?; + + if matches!(sv.cmp_precedence(&version), Ordering::Equal) { + Some(f) + } else { + None + } + }) + .collect::>(); + + let Some(release) = releases.first() else { + return Err(anyhow!("Couldn't find any release")); + }; + + Ok(release.to_owned()) +} + +pub fn fetch_grammars(release: &ReleaseInfo) -> Result { + let dir = Directory::grammars_directory() + .ok_or_else(|| anyhow!("can't get grammars directory"))?; + + let file_name = format!("grammars-{}-{}", env::consts::OS, env::consts::ARCH); + + let updated = download_release(dir, release, &file_name)?; + + trace!(TraceLevel::INFO, "Successfully downloaded grammars"); + + Ok(updated) +} + +pub fn fetch_queries(release: &ReleaseInfo) -> Result { + let dir = Directory::queries_directory() + .ok_or_else(|| anyhow!("can't get queries directory"))?; + + let file_name = "queries"; + + let updated = download_release(dir, release, file_name)?; + + trace!(TraceLevel::INFO, "Successfully downloaded queries"); + + Ok(updated) +} + +fn download_release( + dir: PathBuf, + release: &ReleaseInfo, + file_name: &str, +) -> Result { + if !dir.exists() { + fs::create_dir(&dir)?; + } + + let current_version = + fs::read_to_string(dir.join("version")).unwrap_or_default(); + let release_version = if release.tag_name == "nightly" { + format!("nightly-{}", &release.target_commitish[..7]) + } else { + release.tag_name.clone() + }; + + if release_version == current_version { + return Ok(false); + } + + for asset in &release.assets { + if asset.name.starts_with(file_name) { + let mut resp = lapce_proxy::get_url(&asset.browser_download_url, None)?; + if !resp.status().is_success() { + return Err(anyhow!("download file error {}", resp.text()?)); + } + + let file = tempfile::tempfile()?; + + { + use std::io::{Seek, Write}; + let file = &mut &file; + resp.copy_to(file)?; + file.flush()?; + file.rewind()?; + } + + if asset.name.ends_with(".zip") { + let mut archive = zip::ZipArchive::new(file)?; + archive.extract(&dir)?; + } else if asset.name.ends_with(".tar.zst") { + let mut archive = + tar::Archive::new(zstd::stream::read::Decoder::new(file)?); + archive.unpack(&dir)?; + } + + fs::write(dir.join("version"), &release_version)?; + } + } + Ok(true) +} diff --git a/lapce-app/src/app/logging.rs b/lapce-app/src/app/logging.rs new file mode 100644 index 0000000..bbc0586 --- /dev/null +++ b/lapce-app/src/app/logging.rs @@ -0,0 +1,153 @@ +use lapce_core::directory::Directory; +use tracing::level_filters::LevelFilter; +use tracing_appender::non_blocking::WorkerGuard; +use tracing_subscriber::{filter::Targets, reload::Handle}; + +use crate::tracing::*; + +#[inline(always)] +pub(super) fn logging() -> (Handle, Option) { + use tracing_subscriber::{filter, fmt, prelude::*, reload}; + + let (log_file, guard) = match Directory::logs_directory() + .and_then(|dir| { + tracing_appender::rolling::Builder::new() + .max_log_files(10) + .rotation(tracing_appender::rolling::Rotation::DAILY) + .filename_prefix("lapce") + .filename_suffix("log") + .build(dir) + .ok() + }) + .map(tracing_appender::non_blocking) + { + Some((log_file, guard)) => (Some(log_file), Some(guard)), + None => (None, None), + }; + + let log_file_filter_targets = filter::Targets::new() + .with_target("lapce_app", LevelFilter::DEBUG) + .with_target("lapce_proxy", LevelFilter::DEBUG) + .with_target("lapce_core", LevelFilter::DEBUG) + .with_default(LevelFilter::from_level(TraceLevel::INFO)); + let (log_file_filter, reload_handle) = + reload::Subscriber::new(log_file_filter_targets); + + let console_filter_targets = std::env::var("LAPCE_LOG") + .unwrap_or_default() + .parse::() + .unwrap_or_default(); + + let registry = tracing_subscriber::registry(); + if let Some(log_file) = log_file { + let file_layer = tracing_subscriber::fmt::subscriber() + .with_ansi(false) + .with_writer(log_file) + .with_filter(log_file_filter); + registry + .with(file_layer) + .with( + fmt::Subscriber::default() + .with_line_number(true) + .with_target(true) + .with_thread_names(true) + .with_filter(console_filter_targets), + ) + .init(); + } else { + registry + .with(fmt::Subscriber::default().with_filter(console_filter_targets)) + .init(); + }; + + (reload_handle, guard) +} + +pub(super) fn panic_hook() { + std::panic::set_hook(Box::new(move |info| { + let thread = std::thread::current(); + let thread = thread.name().unwrap_or("main"); + let backtrace = backtrace::Backtrace::new(); + + let payload = if let Some(s) = info.payload().downcast_ref::<&str>() { + s + } else { + "" + }; + + match info.location() { + Some(loc) => { + trace!( + target: "lapce_app::panic_hook", + TraceLevel::ERROR, + "thread {thread} panicked at {} | file://./{}:{}:{}\n{:?}", + payload, + loc.file(), loc.line(), loc.column(), + backtrace, + ); + } + None => { + trace!( + target: "lapce_app::panic_hook", + TraceLevel::ERROR, + "thread {thread} panicked at {}\n{:?}", + payload, + backtrace, + ); + } + } + + #[cfg(windows)] + error_modal("Error", &info.to_string()); + + #[cfg(unix)] + error_notification("Error", &info.to_string()); + })) +} + +#[cfg(windows)] +pub(super) fn error_modal(title: &str, msg: &str) -> i32 { + use std::{ffi::OsStr, iter::once, mem, os::windows::prelude::OsStrExt}; + + use windows::Win32::UI::WindowsAndMessaging::{ + MB_ICONERROR, MB_SYSTEMMODAL, MessageBoxW, + }; + + let result: i32; + + let title = OsStr::new(title) + .encode_wide() + .chain(once(0u16)) + .collect::>(); + let msg = OsStr::new(msg) + .encode_wide() + .chain(once(0u16)) + .collect::>(); + unsafe { + result = MessageBoxW( + mem::zeroed(), + msg.as_ptr(), + title.as_ptr(), + MB_ICONERROR | MB_SYSTEMMODAL, + ); + } + + result +} + +#[cfg(unix)] +pub fn error_notification(title: &str, msg: &str) { + let res = std::process::Command::new("notify-send") + .args([ + "-a", + "dev.lapce.lapce", + "-w", + "-n", + "dev.lapce.lapce", + "-c", + "error", + title, + msg, + ]) + .spawn(); +} diff --git a/lapce-app/src/bin/lapce.rs b/lapce-app/src/bin/lapce.rs new file mode 100644 index 0000000..2efd77d --- /dev/null +++ b/lapce-app/src/bin/lapce.rs @@ -0,0 +1,7 @@ +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] + +use lapce_app::app; + +pub fn main() { + app::launch(); +} diff --git a/lapce-app/src/code_action.rs b/lapce-app/src/code_action.rs new file mode 100644 index 0000000..eca5285 --- /dev/null +++ b/lapce-app/src/code_action.rs @@ -0,0 +1,233 @@ +use std::rc::Rc; + +use floem::{ + keyboard::Modifiers, + peniko::kurbo::Rect, + reactive::{RwSignal, Scope, SignalGet, SignalUpdate}, +}; +use lapce_core::{command::FocusCommand, mode::Mode, movement::Movement}; +use lapce_rpc::plugin::PluginId; +use lsp_types::CodeActionOrCommand; + +use crate::{ + command::{CommandExecuted, CommandKind, InternalCommand}, + keypress::{KeyPressFocus, condition::Condition}, + window_tab::{CommonData, Focus}, +}; + +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum CodeActionStatus { + Inactive, + Active, +} + +#[derive(Clone, Debug, PartialEq)] +pub struct ScoredCodeActionItem { + pub item: CodeActionOrCommand, + pub plugin_id: PluginId, + pub score: i64, + pub indices: Vec, +} + +impl ScoredCodeActionItem { + pub fn title(&self) -> &str { + match &self.item { + CodeActionOrCommand::Command(c) => &c.title, + CodeActionOrCommand::CodeAction(c) => &c.title, + } + } +} + +#[derive(Clone, Debug)] +pub struct CodeActionData { + pub status: RwSignal, + pub active: RwSignal, + pub request_id: usize, + pub input_id: usize, + pub offset: usize, + pub items: im::Vector, + pub filtered_items: im::Vector, + pub layout_rect: Rect, + pub mouse_click: bool, + pub common: Rc, +} + +impl KeyPressFocus for CodeActionData { + fn get_mode(&self) -> Mode { + Mode::Insert + } + + fn check_condition(&self, condition: Condition) -> bool { + matches!(condition, Condition::ListFocus | Condition::ModalFocus) + } + + fn run_command( + &self, + command: &crate::command::LapceCommand, + _count: Option, + _mods: Modifiers, + ) -> crate::command::CommandExecuted { + match &command.kind { + CommandKind::Workbench(_) => {} + CommandKind::Edit(_) => {} + CommandKind::Move(_) => {} + CommandKind::Scroll(_) => {} + CommandKind::Focus(cmd) => { + self.run_focus_command(cmd); + } + CommandKind::MotionMode(_) => {} + CommandKind::MultiSelection(_) => {} + } + CommandExecuted::Yes + } + + fn receive_char(&self, _c: &str) {} +} + +impl CodeActionData { + pub fn new(cx: Scope, common: Rc) -> Self { + let status = cx.create_rw_signal(CodeActionStatus::Inactive); + let active = cx.create_rw_signal(0); + + let code_action = Self { + status, + active, + request_id: 0, + input_id: 0, + offset: 0, + items: im::Vector::new(), + filtered_items: im::Vector::new(), + layout_rect: Rect::ZERO, + mouse_click: false, + common, + }; + + { + let code_action = code_action.clone(); + cx.create_effect(move |_| { + let focus = code_action.common.focus.get(); + if focus != Focus::CodeAction + && code_action.status.get_untracked() + != CodeActionStatus::Inactive + { + code_action.cancel(); + } + }) + } + + code_action + } + + pub fn next(&self) { + let active = self.active.get_untracked(); + let new = + Movement::Down.update_index(active, self.filtered_items.len(), 1, true); + self.active.set(new); + } + + pub fn previous(&self) { + let active = self.active.get_untracked(); + let new = + Movement::Up.update_index(active, self.filtered_items.len(), 1, true); + self.active.set(new); + } + + pub fn next_page(&self) { + let config = self.common.config.get_untracked(); + let count = ((self.layout_rect.size().height + / config.editor.line_height() as f64) + .floor() as usize) + .saturating_sub(1); + let active = self.active.get_untracked(); + let new = Movement::Down.update_index( + active, + self.filtered_items.len(), + count, + false, + ); + self.active.set(new); + } + + pub fn previous_page(&self) { + let config = self.common.config.get_untracked(); + let count = ((self.layout_rect.size().height + / config.editor.line_height() as f64) + .floor() as usize) + .saturating_sub(1); + let active = self.active.get_untracked(); + let new = Movement::Up.update_index( + active, + self.filtered_items.len(), + count, + false, + ); + self.active.set(new); + } + + pub fn show( + &mut self, + plugin_id: PluginId, + code_actions: im::Vector, + offset: usize, + mouse_click: bool, + ) { + self.active.set(0); + self.status.set(CodeActionStatus::Active); + self.offset = offset; + self.mouse_click = mouse_click; + self.request_id += 1; + self.items = code_actions + .into_iter() + .map(|code_action| ScoredCodeActionItem { + item: code_action, + plugin_id, + score: 0, + indices: Vec::new(), + }) + .collect(); + self.filtered_items = self.items.clone(); + self.common.focus.set(Focus::CodeAction); + } + + fn cancel(&self) { + self.status.set(CodeActionStatus::Inactive); + self.common.focus.set(Focus::Workbench); + } + + pub fn select(&self) { + if let Some(item) = self.filtered_items.get(self.active.get_untracked()) { + self.common + .internal_command + .send(InternalCommand::RunCodeAction { + plugin_id: item.plugin_id, + action: item.item.clone(), + }); + } + self.cancel(); + } + + fn run_focus_command(&self, cmd: &FocusCommand) -> CommandExecuted { + match cmd { + FocusCommand::ModalClose => { + self.cancel(); + } + FocusCommand::ListNext => { + self.next(); + } + FocusCommand::ListNextPage => { + self.next_page(); + } + FocusCommand::ListPrevious => { + self.previous(); + } + FocusCommand::ListPreviousPage => { + self.previous_page(); + } + FocusCommand::ListSelect => { + self.select(); + } + _ => return CommandExecuted::No, + } + CommandExecuted::Yes + } +} diff --git a/lapce-app/src/code_lens.rs b/lapce-app/src/code_lens.rs new file mode 100644 index 0000000..960f938 --- /dev/null +++ b/lapce-app/src/code_lens.rs @@ -0,0 +1,100 @@ +use std::rc::Rc; + +use lapce_rpc::dap_types::{ConfigSource, RunDebugConfig}; +use serde::{Deserialize, Serialize}; +use serde_json::Value; + +use crate::{command::InternalCommand, debug::RunDebugMode, window_tab::CommonData}; + +#[derive(Serialize, Deserialize)] +struct CargoArgs { + #[serde(rename = "cargoArgs")] + pub cargo_args: Vec, + + #[serde(rename = "cargoExtraArgs")] + pub cargo_extra_args: Vec, + + #[serde(rename = "executableArgs")] + pub executable_args: Vec, +} + +#[derive(Serialize, Deserialize)] +struct RustArgs { + pub args: CargoArgs, + pub kind: String, + pub label: String, + pub location: lsp_types::LocationLink, +} + +#[derive(Clone)] +pub struct CodeLensData { + common: Rc, +} + +impl CodeLensData { + pub fn new(common: Rc) -> Self { + Self { common } + } + + pub fn run(&self, command: &str, args: Vec) { + match command { + "rust-analyzer.runSingle" | "rust-analyzer.debugSingle" => { + let mode = if command == "rust-analyzer.runSingle" { + RunDebugMode::Run + } else { + RunDebugMode::Debug + }; + if let Some(config) = self.get_rust_command_config(&args, mode) { + self.common + .internal_command + .send(InternalCommand::RunAndDebug { mode, config }); + } + } + _ => { + tracing::debug!("todo {:}", command); + } + } + } + + fn get_rust_command_config( + &self, + args: &[Value], + mode: RunDebugMode, + ) -> Option { + if let Some(args) = args.first() { + let Ok(mut cargo_args) = + serde_json::from_value::(args.clone()) + else { + tracing::error!("serde error"); + return None; + }; + cargo_args + .args + .cargo_args + .extend(cargo_args.args.cargo_extra_args); + if !cargo_args.args.executable_args.is_empty() { + cargo_args.args.cargo_args.push("--".to_string()); + cargo_args + .args + .cargo_args + .extend(cargo_args.args.executable_args); + } + Some(RunDebugConfig { + ty: None, + name: cargo_args.label, + program: cargo_args.kind, + args: Some(cargo_args.args.cargo_args), + cwd: None, + env: None, + prelaunch: None, + debug_command: None, + dap_id: Default::default(), + tracing_output: mode == RunDebugMode::Debug, + config_source: ConfigSource::CodeLens, + }) + } else { + tracing::error!("no args"); + None + } + } +} diff --git a/lapce-app/src/command.rs b/lapce-app/src/command.rs new file mode 100644 index 0000000..c0cc3b8 --- /dev/null +++ b/lapce-app/src/command.rs @@ -0,0 +1,818 @@ +use std::{path::PathBuf, rc::Rc}; + +pub use floem::views::editor::command::CommandExecuted; +use floem::{ + ViewId, keyboard::Modifiers, peniko::kurbo::Vec2, + views::editor::command::Command, +}; +use indexmap::IndexMap; +use lapce_core::command::{ + EditCommand, FocusCommand, MotionModeCommand, MoveCommand, + MultiSelectionCommand, ScrollCommand, +}; +use lapce_rpc::{ + dap_types::{DapId, RunDebugConfig}, + plugin::{PluginId, VoltID}, + proxy::ProxyStatus, + terminal::{TermId, TerminalProfile}, +}; +use lsp_types::{CodeActionOrCommand, Position, WorkspaceEdit}; +use serde_json::Value; +use strum::{EnumMessage, IntoEnumIterator}; +use strum_macros::{Display, EnumIter, EnumString, IntoStaticStr}; + +use crate::{ + alert::AlertButton, + debug::RunDebugMode, + doc::Doc, + editor::location::EditorLocation, + editor_tab::EditorTabChild, + id::EditorTabId, + main_split::{SplitDirection, SplitMoveDirection, TabCloseKind}, + workspace::LapceWorkspace, +}; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct LapceCommand { + pub kind: CommandKind, + pub data: Option, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum CommandKind { + Workbench(LapceWorkbenchCommand), + Edit(EditCommand), + Move(MoveCommand), + Scroll(ScrollCommand), + Focus(FocusCommand), + MotionMode(MotionModeCommand), + MultiSelection(MultiSelectionCommand), +} + +impl CommandKind { + pub fn desc(&self) -> Option<&'static str> { + match &self { + CommandKind::Workbench(cmd) => cmd.get_message(), + CommandKind::Edit(cmd) => cmd.get_message(), + CommandKind::Move(cmd) => cmd.get_message(), + CommandKind::Scroll(cmd) => cmd.get_message(), + CommandKind::Focus(cmd) => cmd.get_message(), + CommandKind::MotionMode(cmd) => cmd.get_message(), + CommandKind::MultiSelection(cmd) => cmd.get_message(), + } + } + + pub fn str(&self) -> &'static str { + match &self { + CommandKind::Workbench(cmd) => cmd.into(), + CommandKind::Edit(cmd) => cmd.into(), + CommandKind::Move(cmd) => cmd.into(), + CommandKind::Scroll(cmd) => cmd.into(), + CommandKind::Focus(cmd) => cmd.into(), + CommandKind::MotionMode(cmd) => cmd.into(), + CommandKind::MultiSelection(cmd) => cmd.into(), + } + } +} +impl From for CommandKind { + fn from(cmd: Command) -> Self { + use Command::*; + match cmd { + Edit(edit) => CommandKind::Edit(edit), + Move(movement) => CommandKind::Move(movement), + Scroll(scroll) => CommandKind::Scroll(scroll), + MotionMode(motion_mode) => CommandKind::MotionMode(motion_mode), + MultiSelection(multi_selection) => { + CommandKind::MultiSelection(multi_selection) + } + } + } +} + +pub fn lapce_internal_commands() -> IndexMap { + let mut commands = IndexMap::new(); + + for c in LapceWorkbenchCommand::iter() { + let command = LapceCommand { + kind: CommandKind::Workbench(c.clone()), + data: None, + }; + commands.insert(c.to_string(), command); + } + + for c in EditCommand::iter() { + let command = LapceCommand { + kind: CommandKind::Edit(c.clone()), + data: None, + }; + commands.insert(c.to_string(), command); + } + + for c in MoveCommand::iter() { + let command = LapceCommand { + kind: CommandKind::Move(c.clone()), + data: None, + }; + commands.insert(c.to_string(), command); + } + + for c in ScrollCommand::iter() { + let command = LapceCommand { + kind: CommandKind::Scroll(c.clone()), + data: None, + }; + commands.insert(c.to_string(), command); + } + + for c in FocusCommand::iter() { + let command = LapceCommand { + kind: CommandKind::Focus(c.clone()), + data: None, + }; + commands.insert(c.to_string(), command); + } + + for c in MotionModeCommand::iter() { + let command = LapceCommand { + kind: CommandKind::MotionMode(c.clone()), + data: None, + }; + commands.insert(c.to_string(), command); + } + + for c in MultiSelectionCommand::iter() { + let command = LapceCommand { + kind: CommandKind::MultiSelection(c.clone()), + data: None, + }; + commands.insert(c.to_string(), command); + } + + commands +} + +#[derive( + Display, + EnumString, + EnumIter, + Clone, + PartialEq, + Eq, + Debug, + EnumMessage, + IntoStaticStr, +)] +pub enum LapceWorkbenchCommand { + #[strum(serialize = "enable_modal_editing")] + #[strum(message = "Enable Modal Editing")] + EnableModal, + + #[strum(serialize = "disable_modal_editing")] + #[strum(message = "Disable Modal Editing")] + DisableModal, + + #[strum(serialize = "open_folder")] + #[strum(message = "Open Folder")] + OpenFolder, + + #[strum(serialize = "close_folder")] + #[strum(message = "Close Folder")] + CloseFolder, + + #[strum(serialize = "open_file")] + #[strum(message = "Open File")] + OpenFile, + + #[strum(serialize = "show_call_hierarchy")] + #[strum(message = "Show Call Hierarchy")] + ShowCallHierarchy, + + #[strum(serialize = "find_references")] + #[strum(message = "Find References")] + FindReferences, + + #[strum(serialize = "go_to_implementation")] + #[strum(message = "Go to Implementation")] + GoToImplementation, + + #[strum(serialize = "reveal_in_panel")] + #[strum(message = "Reveal in Panel")] + RevealInPanel, + + #[strum(serialize = "source_control_open_active_file_remote_url")] + #[strum(message = "Source Control: Open Remote File Url")] + SourceControlOpenActiveFileRemoteUrl, + + #[cfg(not(target_os = "macos"))] + #[strum(serialize = "reveal_in_file_explorer")] + #[strum(message = "Reveal in System File Explorer")] + RevealInFileExplorer, + + #[cfg(target_os = "macos")] + #[strum(serialize = "reveal_in_file_explorer")] + #[strum(message = "Reveal in Finder")] + RevealInFileExplorer, + + #[strum(serialize = "run_in_terminal")] + #[strum(message = "Run in Terminal")] + RunInTerminal, + + #[strum(serialize = "reveal_active_file_in_file_explorer")] + #[strum(message = "Reveal Active File in File Explorer")] + RevealActiveFileInFileExplorer, + + #[strum(serialize = "open_ui_inspector")] + #[strum(message = "Open Internal UI Inspector")] + OpenUIInspector, + + #[strum(serialize = "show_env")] + #[strum(message = "Show Environment")] + ShowEnvironment, + + #[strum(serialize = "change_color_theme")] + #[strum(message = "Change Color Theme")] + ChangeColorTheme, + + #[strum(serialize = "change_icon_theme")] + #[strum(message = "Change Icon Theme")] + ChangeIconTheme, + + #[strum(serialize = "open_settings")] + #[strum(message = "Open Settings")] + OpenSettings, + + #[strum(serialize = "open_settings_file")] + #[strum(message = "Open Settings File")] + OpenSettingsFile, + + #[strum(serialize = "open_settings_directory")] + #[strum(message = "Open Settings Directory")] + OpenSettingsDirectory, + + #[strum(serialize = "open_theme_color_settings")] + #[strum(message = "Open Theme Color Settings")] + OpenThemeColorSettings, + + #[strum(serialize = "open_keyboard_shortcuts")] + #[strum(message = "Open Keyboard Shortcuts")] + OpenKeyboardShortcuts, + + #[strum(serialize = "open_keyboard_shortcuts_file")] + #[strum(message = "Open Keyboard Shortcuts File")] + OpenKeyboardShortcutsFile, + + #[strum(serialize = "open_log_file")] + #[strum(message = "Open Log File")] + OpenLogFile, + + #[strum(serialize = "open_logs_directory")] + #[strum(message = "Open Logs Directory")] + OpenLogsDirectory, + + #[strum(serialize = "open_proxy_directory")] + #[strum(message = "Open Proxy Directory")] + OpenProxyDirectory, + + #[strum(serialize = "open_themes_directory")] + #[strum(message = "Open Themes Directory")] + OpenThemesDirectory, + + #[strum(serialize = "open_plugins_directory")] + #[strum(message = "Open Plugins Directory")] + OpenPluginsDirectory, + + #[strum(serialize = "open_grammars_directory")] + #[strum(message = "Open Grammars Directory")] + OpenGrammarsDirectory, + + #[strum(serialize = "open_queries_directory")] + #[strum(message = "Open Queries Directory")] + OpenQueriesDirectory, + + #[strum(serialize = "zoom_in")] + #[strum(message = "Zoom In")] + ZoomIn, + + #[strum(serialize = "zoom_out")] + #[strum(message = "Zoom Out")] + ZoomOut, + + #[strum(serialize = "zoom_reset")] + #[strum(message = "Reset Zoom")] + ZoomReset, + + #[strum(serialize = "close_window_tab")] + #[strum(message = "Close Current Window Tab")] + CloseWindowTab, + + #[strum(serialize = "new_window_tab")] + #[strum(message = "Create New Window Tab")] + NewWindowTab, + + #[strum(serialize = "new_terminal_tab")] + #[strum(message = "Create New Terminal Tab")] + NewTerminalTab, + + #[strum(serialize = "close_terminal_tab")] + #[strum(message = "Close Terminal Tab")] + CloseTerminalTab, + + #[strum(serialize = "next_terminal_tab")] + #[strum(message = "Next Terminal Tab")] + NextTerminalTab, + + #[strum(serialize = "previous_terminal_tab")] + #[strum(message = "Previous Terminal Tab")] + PreviousTerminalTab, + + #[strum(serialize = "next_window_tab")] + #[strum(message = "Go To Next Window Tab")] + NextWindowTab, + + #[strum(serialize = "previous_window_tab")] + #[strum(message = "Go To Previous Window Tab")] + PreviousWindowTab, + + #[strum(serialize = "reload_window")] + #[strum(message = "Reload Window")] + ReloadWindow, + + #[strum(message = "New Window")] + #[strum(serialize = "new_window")] + NewWindow, + + #[strum(message = "Close Window")] + #[strum(serialize = "close_window")] + CloseWindow, + + #[strum(message = "New File")] + #[strum(serialize = "new_file")] + NewFile, + + #[strum(serialize = "connect_ssh_host")] + #[strum(message = "Connect to SSH Host")] + ConnectSshHost, + + #[cfg(windows)] + #[strum(serialize = "connect_wsl_host")] + #[strum(message = "Connect to WSL Host")] + ConnectWslHost, + + #[strum(serialize = "disconnect_remote")] + #[strum(message = "Disconnect From Remote")] + DisconnectRemote, + + #[strum(message = "Go To Line")] + #[strum(serialize = "palette.line")] + PaletteLine, + + #[strum(serialize = "palette")] + #[strum(message = "Go to File")] + Palette, + + #[strum(message = "Go To Symbol In File")] + #[strum(serialize = "palette.symbol")] + PaletteSymbol, + + #[strum(message = "Go To Symbol In Workspace")] + #[strum(serialize = "palette.workspace_symbol")] + PaletteWorkspaceSymbol, + + #[strum(message = "Command Palette")] + #[strum(serialize = "palette.command")] + PaletteCommand, + + #[strum(message = "Open Recent Workspace")] + #[strum(serialize = "palette.workspace")] + PaletteWorkspace, + + #[strum(message = "Run and Debug")] + #[strum(serialize = "palette.run_and_debug")] + PaletteRunAndDebug, + + #[strum(message = "Source Control: Checkout")] + #[strum(serialize = "palette.scm_references")] + PaletteSCMReferences, + + #[strum(message = "List Palette Types")] + #[strum(serialize = "palette.palette_help")] + PaletteHelp, + + #[strum(message = "List Palette Types and Files")] + #[strum(serialize = "palette.palette_help_and_file")] + PaletteHelpAndFile, + + #[strum(message = "Run and Debug Restart Current Running")] + #[strum(serialize = "palette.run_and_debug_restart")] + RunAndDebugRestart, + + #[strum(message = "Run and Debug Stop Current Running")] + #[strum(serialize = "palette.run_and_debug_stop")] + RunAndDebugStop, + + #[strum(serialize = "source_control.checkout_reference")] + CheckoutReference, + + #[strum(serialize = "toggle_maximized_panel")] + ToggleMaximizedPanel, + + #[strum(serialize = "hide_panel")] + HidePanel, + + #[strum(serialize = "show_panel")] + ShowPanel, + + /// Toggles the panel passed in parameter. + #[strum(serialize = "toggle_panel_focus")] + TogglePanelFocus, + + /// Toggles the panel passed in parameter. + #[strum(serialize = "toggle_panel_visual")] + TogglePanelVisual, + + #[strum(message = "Toggle Left Panel")] + #[strum(serialize = "toggle_panel_left_visual")] + TogglePanelLeftVisual, + + #[strum(message = "Toggle Right Panel")] + #[strum(serialize = "toggle_panel_right_visual")] + TogglePanelRightVisual, + + #[strum(message = "Toggle Bottom Panel")] + #[strum(serialize = "toggle_panel_bottom_visual")] + TogglePanelBottomVisual, + + // Focus toggle commands + #[strum(message = "Toggle Terminal Focus")] + #[strum(serialize = "toggle_terminal_focus")] + ToggleTerminalFocus, + + #[strum(serialize = "toggle_source_control_focus")] + ToggleSourceControlFocus, + + #[strum(message = "Toggle Plugin Focus")] + #[strum(serialize = "toggle_plugin_focus")] + TogglePluginFocus, + + #[strum(message = "Toggle File Explorer Focus")] + #[strum(serialize = "toggle_file_explorer_focus")] + ToggleFileExplorerFocus, + + #[strum(message = "Toggle Problem Focus")] + #[strum(serialize = "toggle_problem_focus")] + ToggleProblemFocus, + + #[strum(message = "Toggle Search Focus")] + #[strum(serialize = "toggle_search_focus")] + ToggleSearchFocus, + + // Visual toggle commands + #[strum(serialize = "toggle_terminal_visual")] + ToggleTerminalVisual, + + #[strum(serialize = "toggle_source_control_visual")] + ToggleSourceControlVisual, + + #[strum(serialize = "toggle_plugin_visual")] + TogglePluginVisual, + + #[strum(serialize = "toggle_file_explorer_visual")] + ToggleFileExplorerVisual, + + #[strum(serialize = "toggle_problem_visual")] + ToggleProblemVisual, + + #[strum(serialize = "toggle_debug_visual")] + ToggleDebugVisual, + + #[strum(serialize = "toggle_search_visual")] + ToggleSearchVisual, + + #[strum(serialize = "focus_editor")] + FocusEditor, + + #[strum(serialize = "focus_terminal")] + FocusTerminal, + + #[strum(message = "Source Control: Init")] + #[strum(serialize = "source_control_init")] + SourceControlInit, + + #[strum(serialize = "source_control_commit")] + SourceControlCommit, + + #[strum(message = "Source Control: Copy Remote File Url")] + #[strum(serialize = "source_control_copy_active_file_remote_url")] + SourceControlCopyActiveFileRemoteUrl, + + #[strum(message = "Source Control: Discard File Changes")] + #[strum(serialize = "source_control_discard_active_file_changes")] + SourceControlDiscardActiveFileChanges, + + #[strum(serialize = "source_control_discard_target_file_changes")] + SourceControlDiscardTargetFileChanges, + + #[strum(message = "Source Control: Discard Workspace Changes")] + #[strum(serialize = "source_control_discard_workspace_changes")] + SourceControlDiscardWorkspaceChanges, + + #[strum(serialize = "export_current_theme_settings")] + #[strum(message = "Export current settings to a theme file")] + ExportCurrentThemeSettings, + + #[strum(serialize = "install_theme")] + #[strum(message = "Install current theme file")] + InstallTheme, + + #[strum(serialize = "change_file_language")] + #[strum(message = "Change current file language")] + ChangeFileLanguage, + + #[strum(serialize = "change_file_line_ending")] + #[strum(message = "Change current file line ending")] + ChangeFileLineEnding, + + #[strum(serialize = "next_editor_tab")] + #[strum(message = "Next Editor Tab")] + NextEditorTab, + + #[strum(serialize = "previous_editor_tab")] + #[strum(message = "Previous Editor Tab")] + PreviousEditorTab, + + #[strum(serialize = "toggle_inlay_hints")] + #[strum(message = "Toggle Inlay Hints")] + ToggleInlayHints, + + #[strum(serialize = "restart_to_update")] + RestartToUpdate, + + #[strum(serialize = "show_about")] + #[strum(message = "About Lapce")] + ShowAbout, + + #[strum(message = "Save All Files")] + #[strum(serialize = "save_all")] + SaveAll, + + #[cfg(target_os = "macos")] + #[strum(message = "Install Lapce to PATH")] + #[strum(serialize = "install_to_path")] + InstallToPATH, + + #[cfg(target_os = "macos")] + #[strum(message = "Uninstall Lapce from PATH")] + #[strum(serialize = "uninstall_from_path")] + UninstallFromPATH, + + #[strum(serialize = "jump_location_backward")] + JumpLocationBackward, + + #[strum(serialize = "jump_location_forward")] + JumpLocationForward, + + #[strum(serialize = "jump_location_backward_local")] + JumpLocationBackwardLocal, + + #[strum(serialize = "jump_location_forward_local")] + JumpLocationForwardLocal, + + #[strum(message = "Next Error in Workspace")] + #[strum(serialize = "next_error")] + NextError, + + #[strum(message = "Previous Error in Workspace")] + #[strum(serialize = "previous_error")] + PreviousError, + + #[strum(message = "Diff Files")] + #[strum(serialize = "diff_files")] + DiffFiles, + + #[strum(serialize = "quit")] + #[strum(message = "Quit Editor")] + Quit, + + #[strum(serialize = "go_to_location")] + #[strum(message = "Go to Location")] + GoToLocation, + + #[strum(serialize = "add_run_debug_config")] + #[strum(message = "Add Run Debug Config")] + AddRunDebugConfig, +} + +#[derive(Clone, Debug)] +pub enum InternalCommand { + ReloadConfig, + OpenFile { + path: PathBuf, + }, + OpenAndConfirmedFile { + path: PathBuf, + }, + OpenFileInNewTab { + path: PathBuf, + }, + MakeConfirmed, + OpenFileChanges { + path: PathBuf, + }, + ReloadFileExplorer, + /// Test whether a file/directory can be created at that path + TestPathCreation { + new_path: PathBuf, + }, + FinishRenamePath { + current_path: PathBuf, + new_path: PathBuf, + }, + FinishNewNode { + is_dir: bool, + path: PathBuf, + }, + FinishDuplicate { + source: PathBuf, + path: PathBuf, + }, + GoToLocation { + location: EditorLocation, + }, + JumpToLocation { + location: EditorLocation, + }, + PaletteReferences { + references: Vec, + }, + SaveJumpLocation { + path: PathBuf, + offset: usize, + scroll_offset: Vec2, + }, + Split { + direction: SplitDirection, + editor_tab_id: EditorTabId, + }, + SplitMove { + direction: SplitMoveDirection, + editor_tab_id: EditorTabId, + }, + SplitExchange { + editor_tab_id: EditorTabId, + }, + NewTerminal { + profile: Option, + }, + SplitTerminal { + term_id: TermId, + }, + SplitTerminalPrevious { + term_id: TermId, + }, + SplitTerminalNext { + term_id: TermId, + }, + SplitTerminalExchange { + term_id: TermId, + }, + EditorTabClose { + editor_tab_id: EditorTabId, + }, + EditorTabChildClose { + editor_tab_id: EditorTabId, + child: EditorTabChild, + }, + EditorTabCloseByKind { + editor_tab_id: EditorTabId, + child: EditorTabChild, + kind: TabCloseKind, + }, + ShowCodeActions { + offset: usize, + mouse_click: bool, + plugin_id: PluginId, + code_actions: im::Vector, + }, + RunCodeAction { + plugin_id: PluginId, + action: CodeActionOrCommand, + }, + ApplyWorkspaceEdit { + edit: WorkspaceEdit, + }, + RunAndDebug { + mode: RunDebugMode, + config: RunDebugConfig, + }, + StartRename { + path: PathBuf, + placeholder: String, + start: usize, + position: Position, + }, + Search { + pattern: Option, + }, + FindEditorReceiveChar { + s: String, + }, + ReplaceEditorReceiveChar { + s: String, + }, + FindEditorCommand { + command: LapceCommand, + count: Option, + mods: Modifiers, + }, + ReplaceEditorCommand { + command: LapceCommand, + count: Option, + mods: Modifiers, + }, + FocusEditorTab { + editor_tab_id: EditorTabId, + }, + + SetColorTheme { + name: String, + /// Whether to save the theme to the config file + save: bool, + }, + SetIconTheme { + name: String, + /// Whether to save the theme to the config file + save: bool, + }, + SetModal { + modal: bool, + }, + UpdateLogLevel { + level: tracing_subscriber::filter::LevelFilter, + }, + OpenWebUri { + uri: String, + }, + ShowAlert { + title: String, + msg: String, + buttons: Vec, + }, + HideAlert, + SaveScratchDoc { + doc: Rc, + }, + SaveScratchDoc2 { + doc: Rc, + }, + UpdateProxyStatus { + status: ProxyStatus, + }, + DapFrameScopes { + dap_id: DapId, + frame_id: usize, + }, + OpenVoltView { + volt_id: VoltID, + }, + ResetBlinkCursor, + OpenDiffFiles { + left_path: PathBuf, + right_path: PathBuf, + }, + ExecuteProcess { + program: String, + arguments: Vec, + }, + ClearTerminalBuffer { + view_id: ViewId, + tab_index: usize, + terminal_index: usize, + }, + CallHierarchyIncoming { + item_id: ViewId, + }, + StopTerminal { + term_id: TermId, + }, + RestartTerminal { + term_id: TermId, + }, +} + +#[derive(Clone)] +pub enum WindowCommand { + SetWorkspace { + workspace: LapceWorkspace, + }, + CloseWorkspaceTab { + index: Option, + }, + NewWorkspaceTab { + workspace: LapceWorkspace, + end: bool, + }, + NextWorkspaceTab, + PreviousWorkspaceTab, + NewWindow, + CloseWindow, +} diff --git a/lapce-app/src/completion.rs b/lapce-app/src/completion.rs new file mode 100644 index 0000000..2016126 --- /dev/null +++ b/lapce-app/src/completion.rs @@ -0,0 +1,417 @@ +use std::{borrow::Cow, path::PathBuf, str::FromStr, sync::Arc}; + +use floem::{ + peniko::kurbo::Rect, + reactive::{ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, + views::editor::{id::EditorId, text::Document}, +}; +use lapce_core::{ + buffer::rope_text::RopeText, movement::Movement, rope_text_pos::RopeTextPosition, +}; +use lapce_rpc::{plugin::PluginId, proxy::ProxyRpcHandler}; +use lsp_types::{ + CompletionItem, CompletionResponse, CompletionTextEdit, InsertTextFormat, + Position, +}; +use nucleo::Utf32Str; + +use crate::{config::LapceConfig, editor::EditorData, snippet::Snippet}; + +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum CompletionStatus { + Inactive, + Started, + Done, +} + +#[derive(Clone, PartialEq)] +pub struct ScoredCompletionItem { + pub item: CompletionItem, + pub plugin_id: PluginId, + pub score: u32, + pub label_score: u32, + pub indices: Vec, +} + +#[derive(Clone)] +pub struct CompletionData { + pub status: CompletionStatus, + /// The current request id. This is used to discard old requests. + pub request_id: usize, + /// An input id that is used for keeping track of whether the input has changed. + pub input_id: usize, + // TODO: A `PathBuf` has the issue that the proxy may not have the same format. + // TODO(minor): It might be nice to not require a path. LSPs cannot operate on scratch buffers + // as of now, but they might be allowed in the future. + pub path: PathBuf, + /// The offset that the completion is/was started at. Used for positioning the completion elem + pub offset: usize, + /// The active completion index in the list of filtered items + pub active: RwSignal, + /// The current input that the user has typed which is being sent for consideration by the LSP + pub input: String, + /// `(Input, CompletionItems)` + pub input_items: im::HashMap>, + /// The filtered items that are being displayed to the user + pub filtered_items: im::Vector, + /// The size of the completion element. + /// This is used for positioning the element. + /// As well, it is needed for some movement commands like page up/down that need to know the + /// height to compute how far to move. + pub layout_rect: Rect, + /// The editor id that was most recently used to trigger a completion. + pub latest_editor_id: Option, + /// Matcher for filtering the completion items + matcher: RwSignal, + config: ReadSignal>, +} + +impl CompletionData { + pub fn new(cx: Scope, config: ReadSignal>) -> Self { + let active = cx.create_rw_signal(0); + Self { + status: CompletionStatus::Inactive, + request_id: 0, + input_id: 0, + path: PathBuf::new(), + offset: 0, + active, + input: "".to_string(), + input_items: im::HashMap::new(), + filtered_items: im::Vector::new(), + layout_rect: Rect::ZERO, + matcher: cx + .create_rw_signal(nucleo::Matcher::new(nucleo::Config::DEFAULT)), + latest_editor_id: None, + config, + } + } + + /// Handle the response to a completion request. + pub fn receive( + &mut self, + request_id: usize, + input: &str, + resp: &CompletionResponse, + plugin_id: PluginId, + ) { + // If we've been canceled or the request id is old, ignore the response. + if self.status == CompletionStatus::Inactive || self.request_id != request_id + { + return; + } + + let items = match resp { + CompletionResponse::Array(items) => items, + // TODO: Possibly handle the 'is_incomplete' field on List. + CompletionResponse::List(list) => &list.items, + }; + let items: im::Vector = items + .iter() + .map(|i| ScoredCompletionItem { + item: i.to_owned(), + plugin_id, + score: 0, + label_score: 0, + indices: Vec::new(), + }) + .collect(); + self.input_items.insert(input.to_string(), items); + self.filter_items(); + } + + /// Request for completion items wit the current request id. + pub fn request( + &mut self, + editor_id: EditorId, + proxy_rpc: &ProxyRpcHandler, + path: PathBuf, + input: String, + position: Position, + ) { + self.latest_editor_id = Some(editor_id); + self.input_items.insert(input.clone(), im::Vector::new()); + proxy_rpc.completion(self.request_id, path, input, position); + } + + /// Close the completion, clearing all the data. + pub fn cancel(&mut self) { + if self.status == CompletionStatus::Inactive { + return; + } + self.status = CompletionStatus::Inactive; + self.input_id = 0; + self.latest_editor_id = None; + self.active.set(0); + self.input.clear(); + self.input_items.clear(); + self.filtered_items.clear(); + } + + pub fn update_input(&mut self, input: String) { + if self.status == CompletionStatus::Inactive { + return; + } + self.input = input; + // TODO: If the user types a letter that continues the current active item, we should + // try keeping that item active. Possibly give this a setting. + // ex: `p` has `print!` and `println!` has options. If you select the second, then type + // `r` then it should stay on `println!` even as the overall filtering of the list changes. + self.active.set(0); + self.filter_items(); + } + + fn all_items(&self) -> im::Vector { + self.input_items + .get(&self.input) + .cloned() + .filter(|items| !items.is_empty()) + .unwrap_or_else(move || { + self.input_items.get("").cloned().unwrap_or_default() + }) + } + + pub fn filter_items(&mut self) { + self.input_id += 1; + if self.input.is_empty() { + self.filtered_items = self.all_items(); + return; + } + + // Filter the items by the fuzzy matching with the input text. + let mut items: im::Vector = self + .matcher + .try_update(|matcher| { + let pattern = nucleo::pattern::Pattern::parse( + &self.input, + nucleo::pattern::CaseMatching::Ignore, + nucleo::pattern::Normalization::Smart, + ); + self.all_items() + .iter() + .filter_map(|i| { + let filter_text = + i.item.filter_text.as_ref().unwrap_or(&i.item.label); + let shift = i + .item + .label + .match_indices(filter_text) + .next() + .map(|(shift, _)| shift) + .unwrap_or(0); + let mut indices = Vec::new(); + let mut filter_text_buf = Vec::new(); + let filter_text = + Utf32Str::new(filter_text, &mut filter_text_buf); + if let Some(score) = + pattern.indices(filter_text, matcher, &mut indices) + { + if shift > 0 { + for idx in indices.iter_mut() { + *idx += shift as u32; + } + } + let mut item = i.clone(); + item.score = score; + item.label_score = score; + item.indices = + indices.into_iter().map(|i| i as usize).collect(); + + let mut label_buf = Vec::new(); + let label_text = + Utf32Str::new(&i.item.label, &mut label_buf); + if let Some(score) = pattern.score(label_text, matcher) { + item.label_score = score; + } + Some(item) + } else { + None + } + }) + .collect() + }) + .unwrap(); + // Sort all the items by their score, then their label score, then their length. + items.sort_by(|a, b| { + b.score + .cmp(&a.score) + .then_with(|| b.label_score.cmp(&a.label_score)) + .then_with(|| a.item.label.len().cmp(&b.item.label.len())) + }); + self.filtered_items = items; + } + + /// Move down in the list of items. + pub fn next(&mut self) { + let active = self.active.get_untracked(); + let new = + Movement::Down.update_index(active, self.filtered_items.len(), 1, true); + self.active.set(new); + } + + /// Move up in the list of items. + pub fn previous(&mut self) { + let active = self.active.get_untracked(); + let new = + Movement::Up.update_index(active, self.filtered_items.len(), 1, true); + self.active.set(new); + } + + /// The amount of items that can be displayed in the current layout. + fn display_count(&self) -> usize { + let config = self.config.get_untracked(); + ((self.layout_rect.size().height / config.editor.line_height() as f64) + .floor() as usize) + .saturating_sub(1) + } + + /// Move to the next page of items. + pub fn next_page(&mut self) { + let count = self.display_count(); + let active = self.active.get_untracked(); + let new = Movement::Down.update_index( + active, + self.filtered_items.len(), + count, + false, + ); + self.active.set(new); + } + + /// Move to the previous page of items. + pub fn previous_page(&mut self) { + let count = self.display_count(); + let active = self.active.get_untracked(); + let new = Movement::Up.update_index( + active, + self.filtered_items.len(), + count, + false, + ); + self.active.set(new); + } + + /// The currently selected/active item. + pub fn current_item(&self) -> Option<&ScoredCompletionItem> { + self.filtered_items.get(self.active.get_untracked()) + } + + /// Update the completion lens of the document with the active completion item. + pub fn update_document_completion( + &self, + editor_data: &EditorData, + cursor_offset: usize, + ) { + let doc = editor_data.doc(); + + if !doc.content.with_untracked(|content| content.is_file()) { + return; + } + + let config = self.config.get_untracked(); + + if !config.editor.enable_completion_lens { + doc.clear_completion_lens(); + return; + } + + let completion_lens = completion_lens_text( + doc.rope_text(), + cursor_offset, + self, + doc.completion_lens().as_deref(), + ); + match completion_lens { + Some(Some(lens)) => { + let offset = self.offset + self.input.len(); + // TODO: will need to be adjusted to use visual line. + // Could just store the offset in doc. + let (line, col) = editor_data.editor.offset_to_line_col(offset); + + doc.set_completion_lens(lens, line, col); + } + // Unchanged + Some(None) => {} + None => { + doc.clear_completion_lens(); + } + } + } +} + +/// Get the text of the completion lens for the given completion item. +/// Returns `None` if the completion lens should be hidden. +/// Returns `Some(None)` if the completion lens should be shown, but not changed. +/// Returns `Some(Some(text))` if the completion lens should be shown and changed to the given text. +fn completion_lens_text( + rope_text: impl RopeText, + cursor_offset: usize, + completion: &CompletionData, + current_completion: Option<&str>, +) -> Option> { + let item = &completion.current_item()?.item; + + let item: Cow = if let Some(edit) = &item.text_edit { + // A text edit is used, because that is what will actually be inserted. + + let text_format = item + .insert_text_format + .unwrap_or(InsertTextFormat::PLAIN_TEXT); + + // We don't display insert and replace + let CompletionTextEdit::Edit(edit) = edit else { + return None; + }; + // The completion offset can be different from the current cursor offset. + let completion_offset = completion.offset; + + let start_offset = rope_text.prev_code_boundary(cursor_offset); + let edit_start = rope_text.offset_of_position(&edit.range.start); + + // If the start of the edit isn't where the cursor currently is, + // and it is not at the start of the completion, then we ignore it. + // This captures most cases that we want, even if it skips over some + // displayable edits. + if start_offset != edit_start && completion_offset != edit_start { + return None; + } + + match text_format { + InsertTextFormat::PLAIN_TEXT => { + // This is not entirely correct because it assumes that the position is + // `{start,end}_offset` when it may not necessarily be. + Cow::Borrowed(&edit.new_text) + } + InsertTextFormat::SNIPPET => { + // Parse the snippet. Bail if it's invalid. + let snippet = Snippet::from_str(&edit.new_text).ok()?; + + let text = snippet.text(); + + Cow::Owned(text) + } + _ => { + // We don't know how to support this text format. + return None; + } + } + } else { + // There's no specific text edit, so we just use the label. + Cow::Borrowed(&item.label) + }; + // We strip the prefix of the current input from the label. + // So that, for example, `p` with a completion of `println` only sets the lens text to `rintln`. + // If the text does not include a prefix in the expected position, then we do not display it. + let item = item.as_ref().strip_prefix(&completion.input)?; + + // Get only the first line of text, because Lapce does not currently support + // multi-line phantom text. + let item = item.lines().next().unwrap_or(item); + + if Some(item) == current_completion { + // If the item is the same as the current completion, then we don't display it. + Some(None) + } else { + Some(Some(item.to_string())) + } +} diff --git a/lapce-app/src/config.rs b/lapce-app/src/config.rs new file mode 100644 index 0000000..1070577 --- /dev/null +++ b/lapce-app/src/config.rs @@ -0,0 +1,1020 @@ +use std::{ + collections::HashMap, + path::{Path, PathBuf}, + sync::Arc, +}; + +use ::core::slice; +use floem::{peniko::Color, prelude::palette::css}; +use itertools::Itertools; +use lapce_core::directory::Directory; +use lapce_proxy::plugin::wasi::find_all_volts; +use lapce_rpc::plugin::VoltID; +use lsp_types::{CompletionItemKind, SymbolKind}; +use once_cell::sync::Lazy; +use parking_lot::RwLock; +use serde::Deserialize; +use strum::VariantNames; +use tracing::error; + +use self::{ + color::LapceColor, + color_theme::{ColorThemeConfig, ThemeColor, ThemeColorPreference}, + core::CoreConfig, + editor::{EditorConfig, SCALE_OR_SIZE_LIMIT, WrapStyle}, + icon::LapceIcons, + icon_theme::IconThemeConfig, + svg::SvgStore, + terminal::TerminalConfig, + ui::UIConfig, +}; +use crate::workspace::{LapceWorkspace, LapceWorkspaceType}; + +pub mod color; +pub mod color_theme; +pub mod core; +pub mod editor; +pub mod icon; +pub mod icon_theme; +pub mod svg; +pub mod terminal; +pub mod ui; +pub mod watcher; + +pub const LOGO: &str = include_str!("../../extra/images/logo.svg"); +const DEFAULT_SETTINGS: &str = include_str!("../../defaults/settings.toml"); +const DEFAULT_LIGHT_THEME: &str = include_str!("../../defaults/light-theme.toml"); +const DEFAULT_DARK_THEME: &str = include_str!("../../defaults/dark-theme.toml"); +const DEFAULT_ICON_THEME: &str = include_str!("../../defaults/icon-theme.toml"); + +static DEFAULT_CONFIG: Lazy = Lazy::new(LapceConfig::default_config); +static DEFAULT_LAPCE_CONFIG: Lazy = + Lazy::new(LapceConfig::default_lapce_config); + +static DEFAULT_DARK_THEME_CONFIG: Lazy = Lazy::new(|| { + config::Config::builder() + .add_source(config::File::from_str( + DEFAULT_DARK_THEME, + config::FileFormat::Toml, + )) + .build() + .unwrap() +}); + +/// The default theme is the dark theme. +static DEFAULT_DARK_THEME_COLOR_CONFIG: Lazy = Lazy::new(|| { + let (_, theme) = + LapceConfig::load_color_theme_from_str(DEFAULT_DARK_THEME).unwrap(); + theme.get::("color-theme") + .expect("Failed to load default dark theme. This is likely due to a missing or misnamed field in dark-theme.toml") +}); + +static DEFAULT_ICON_THEME_CONFIG: Lazy = Lazy::new(|| { + config::Config::builder() + .add_source(config::File::from_str( + DEFAULT_ICON_THEME, + config::FileFormat::Toml, + )) + .build() + .unwrap() +}); +static DEFAULT_ICON_THEME_ICON_CONFIG: Lazy = Lazy::new(|| { + DEFAULT_ICON_THEME_CONFIG.get::("icon-theme") + .expect("Failed to load default icon theme. This is likely due to a missing or misnamed field in icon-theme.toml") +}); + +/// Used for creating a `DropdownData` for a setting +#[derive(Debug, Clone)] +pub struct DropdownInfo { + /// The currently selected item. + pub active_index: usize, + pub items: im::Vector, +} + +#[derive(Debug, Clone, Deserialize, Default)] +#[serde(rename_all = "kebab-case")] +pub struct LapceConfig { + #[serde(skip)] + pub id: u64, + pub core: CoreConfig, + pub ui: UIConfig, + pub editor: EditorConfig, + pub terminal: TerminalConfig, + #[serde(default)] + pub color_theme: ColorThemeConfig, + #[serde(default)] + pub icon_theme: IconThemeConfig, + #[serde(flatten)] + pub plugins: HashMap>, + #[serde(skip)] + pub color: ThemeColor, + #[serde(skip)] + pub available_color_themes: HashMap, + #[serde(skip)] + pub available_icon_themes: + HashMap)>, + // #[serde(skip)] + // tab_layout_info: Arc>>, + #[serde(skip)] + svg_store: Arc>, + /// A list of the themes that are available. This is primarily for populating + /// the theme picker, and serves as a cache. + #[serde(skip)] + color_theme_list: im::Vector, + #[serde(skip)] + icon_theme_list: im::Vector, + /// The couple names for the wrap style + #[serde(skip)] + wrap_style_list: im::Vector, +} + +impl LapceConfig { + pub fn load( + workspace: &LapceWorkspace, + disabled_volts: &[VoltID], + extra_plugin_paths: &[PathBuf], + ) -> Self { + let config = Self::merge_config(workspace, None, None); + let mut lapce_config: LapceConfig = match config.try_deserialize() { + Ok(config) => config, + Err(error) => { + error!("Failed to deserialize configuration file: {error}"); + DEFAULT_LAPCE_CONFIG.clone() + } + }; + + lapce_config.available_color_themes = + Self::load_color_themes(disabled_volts, extra_plugin_paths); + lapce_config.available_icon_themes = + Self::load_icon_themes(disabled_volts, extra_plugin_paths); + lapce_config.resolve_theme(workspace); + + lapce_config.color_theme_list = lapce_config + .available_color_themes + .values() + .map(|(name, _)| name.clone()) + .sorted() + .collect(); + lapce_config.color_theme_list.sort(); + + lapce_config.icon_theme_list = lapce_config + .available_icon_themes + .values() + .map(|(name, _, _)| name.clone()) + .sorted() + .collect(); + lapce_config.icon_theme_list.sort(); + + lapce_config.wrap_style_list = im::vector![ + WrapStyle::None.to_string(), + WrapStyle::EditorWidth.to_string(), + // TODO: WrapStyle::WrapColumn.to_string(), + WrapStyle::WrapWidth.to_string() + ]; + + lapce_config.terminal.get_indexed_colors(); + + lapce_config + } + + fn merge_config( + workspace: &LapceWorkspace, + color_theme_config: Option, + icon_theme_config: Option, + ) -> config::Config { + let mut config = DEFAULT_CONFIG.clone(); + + if let Some(theme) = color_theme_config { + // TODO: use different color theme basis if the theme declares its color preference + // differently + config = config::Config::builder() + .add_source(config.clone()) + .add_source(DEFAULT_DARK_THEME_CONFIG.clone()) + .add_source(theme) + .build() + .unwrap_or_else(|_| config.clone()); + } + + if let Some(theme) = icon_theme_config { + config = config::Config::builder() + .add_source(config.clone()) + .add_source(theme) + .build() + .unwrap_or_else(|_| config.clone()); + } + + if let Some(path) = Self::settings_file() { + config = config::Config::builder() + .add_source(config.clone()) + .add_source(config::File::from(path.as_path()).required(false)) + .build() + .unwrap_or_else(|_| config.clone()); + } + + match workspace.kind { + LapceWorkspaceType::Local => { + if let Some(path) = workspace.path.as_ref() { + let path = path.join("./.lapce/settings.toml"); + config = config::Config::builder() + .add_source(config.clone()) + .add_source( + config::File::from(path.as_path()).required(false), + ) + .build() + .unwrap_or_else(|_| config.clone()); + } + } + LapceWorkspaceType::RemoteSSH(_) => {} + #[cfg(windows)] + LapceWorkspaceType::RemoteWSL(_) => {} + } + + config + } + + fn update_id(&mut self) { + self.id = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .map(|d| d.as_millis() as u64) + .unwrap_or(0); + } + + fn default_config() -> config::Config { + config::Config::builder() + .add_source(config::File::from_str( + DEFAULT_SETTINGS, + config::FileFormat::Toml, + )) + .build() + .unwrap() + } + + fn default_lapce_config() -> LapceConfig { + let mut default_lapce_config: LapceConfig = + DEFAULT_CONFIG.clone().try_deserialize().expect("Failed to deserialize default config, this likely indicates a missing or misnamed field in settings.toml"); + default_lapce_config.color_theme = DEFAULT_DARK_THEME_COLOR_CONFIG.clone(); + default_lapce_config.icon_theme = DEFAULT_ICON_THEME_ICON_CONFIG.clone(); + default_lapce_config.resolve_colors(None); + default_lapce_config + } + + fn resolve_theme(&mut self, workspace: &LapceWorkspace) { + let default_lapce_config = DEFAULT_LAPCE_CONFIG.clone(); + + let color_theme_config = self + .available_color_themes + .get(&self.core.color_theme.to_lowercase()) + .map(|(_, config)| config) + .unwrap_or(&DEFAULT_DARK_THEME_CONFIG); + + let icon_theme_config = self + .available_icon_themes + .get(&self.core.icon_theme.to_lowercase()) + .map(|(_, config, _)| config) + .unwrap_or(&DEFAULT_ICON_THEME_CONFIG); + + let icon_theme_path = self + .available_icon_themes + .get(&self.core.icon_theme.to_lowercase()) + .map(|(_, _, path)| path); + + if let Ok(new) = Self::merge_config( + workspace, + Some(color_theme_config.clone()), + Some(icon_theme_config.clone()), + ) + .try_deserialize::() + { + self.core = new.core; + self.ui = new.ui; + self.editor = new.editor; + self.terminal = new.terminal; + self.terminal.get_indexed_colors(); + + self.color_theme = new.color_theme; + self.icon_theme = new.icon_theme; + if let Some(icon_theme_path) = icon_theme_path { + self.icon_theme.path = icon_theme_path.clone().unwrap_or_default(); + } + self.plugins = new.plugins; + } + self.resolve_colors(Some(&default_lapce_config)); + self.update_id(); + } + + fn load_color_themes( + disabled_volts: &[VoltID], + extra_plugin_paths: &[PathBuf], + ) -> HashMap { + let mut themes = Self::load_local_themes().unwrap_or_default(); + + for (key, theme) in + Self::load_plugin_color_themes(disabled_volts, extra_plugin_paths) + { + themes.insert(key, theme); + } + + let (name, theme) = + Self::load_color_theme_from_str(DEFAULT_LIGHT_THEME).unwrap(); + themes.insert(name.to_lowercase(), (name, theme)); + let (name, theme) = + Self::load_color_theme_from_str(DEFAULT_DARK_THEME).unwrap(); + themes.insert(name.to_lowercase(), (name, theme)); + + themes + } + + pub fn default_color_theme(&self) -> &ColorThemeConfig { + &DEFAULT_DARK_THEME_COLOR_CONFIG + } + + /// Set the active color theme. + /// Note that this does not save the config. + pub fn set_color_theme(&mut self, workspace: &LapceWorkspace, theme: &str) { + self.core.color_theme = theme.to_string(); + self.resolve_theme(workspace); + } + + /// Set the active icon theme. + /// Note that this does not save the config. + pub fn set_icon_theme(&mut self, workspace: &LapceWorkspace, theme: &str) { + self.core.icon_theme = theme.to_string(); + self.resolve_theme(workspace); + } + + pub fn set_modal(&mut self, _workspace: &LapceWorkspace, modal: bool) { + self.core.modal = modal; + } + + /// Get the color by the name from the current theme if it exists + /// Otherwise, get the color from the base them + /// # Panics + /// If the color was not able to be found in either theme, which may be indicative that + /// it is misspelled or needs to be added to the base-theme. + pub fn color(&self, name: &str) -> Color { + match self.color.ui.get(name) { + Some(c) => *c, + None => { + error!("Failed to find key: {name}"); + css::HOT_PINK + } + } + } + + /// Retrieve a color value whose key starts with "style." + pub fn style_color(&self, name: &str) -> Option { + self.color.syntax.get(name).copied() + } + + pub fn completion_color( + &self, + kind: Option, + ) -> Option { + let kind = kind?; + let theme_str = match kind { + CompletionItemKind::METHOD => "method", + CompletionItemKind::FUNCTION => "method", + CompletionItemKind::ENUM => "enum", + CompletionItemKind::ENUM_MEMBER => "enum-member", + CompletionItemKind::CLASS => "class", + CompletionItemKind::VARIABLE => "field", + CompletionItemKind::STRUCT => "structure", + CompletionItemKind::KEYWORD => "keyword", + CompletionItemKind::CONSTANT => "constant", + CompletionItemKind::PROPERTY => "property", + CompletionItemKind::FIELD => "field", + CompletionItemKind::INTERFACE => "interface", + CompletionItemKind::SNIPPET => "snippet", + CompletionItemKind::MODULE => "builtinType", + _ => "string", + }; + + self.style_color(theme_str) + } + + fn resolve_colors(&mut self, default_config: Option<&LapceConfig>) { + self.color.base = self + .color_theme + .base + .resolve(default_config.map(|c| &c.color_theme.base)); + self.color.ui = self + .color_theme + .resolve_ui_color(&self.color.base, default_config.map(|c| &c.color.ui)); + self.color.syntax = self.color_theme.resolve_syntax_color( + &self.color.base, + default_config.map(|c| &c.color.syntax), + ); + + let fg = self.color(LapceColor::EDITOR_FOREGROUND).to_rgba8(); + let bg = self.color(LapceColor::EDITOR_BACKGROUND).to_rgba8(); + let is_light = fg.r as u32 + fg.g as u32 + fg.b as u32 + > bg.r as u32 + bg.g as u32 + bg.b as u32; + let high_contrast = self.color_theme.high_contrast.unwrap_or(false); + self.color.color_preference = match (is_light, high_contrast) { + (true, true) => ThemeColorPreference::HighContrastLight, + (false, true) => ThemeColorPreference::HighContrastDark, + (true, false) => ThemeColorPreference::Light, + (false, false) => ThemeColorPreference::Dark, + }; + } + + fn load_local_themes() -> Option> { + let themes_folder = Directory::themes_directory()?; + let themes: HashMap = + std::fs::read_dir(themes_folder) + .ok()? + .filter_map(|entry| { + entry + .ok() + .and_then(|entry| Self::load_color_theme(&entry.path())) + }) + .collect(); + Some(themes) + } + + fn load_color_theme(path: &Path) -> Option<(String, (String, config::Config))> { + if !path.is_file() { + return None; + } + let config = config::Config::builder() + .add_source(config::File::from(path)) + .build() + .ok()?; + let table = config.get_table("color-theme").ok()?; + let name = table.get("name")?.to_string(); + Some((name.to_lowercase(), (name, config))) + } + + /// Load the given theme by its contents. + /// Returns `(name, theme fields)` + fn load_color_theme_from_str(s: &str) -> Option<(String, config::Config)> { + let config = config::Config::builder() + .add_source(config::File::from_str(s, config::FileFormat::Toml)) + .build() + .ok()?; + let table = config.get_table("color-theme").ok()?; + let name = table.get("name")?.to_string(); + Some((name, config)) + } + + fn load_icon_themes( + disabled_volts: &[VoltID], + extra_plugin_paths: &[PathBuf], + ) -> HashMap)> { + let mut themes = HashMap::new(); + + for (key, (name, theme, path)) in + Self::load_plugin_icon_themes(disabled_volts, extra_plugin_paths) + { + themes.insert(key, (name, theme, Some(path))); + } + + let (name, theme) = + Self::load_icon_theme_from_str(DEFAULT_ICON_THEME).unwrap(); + themes.insert(name.to_lowercase(), (name, theme, None)); + + themes + } + + fn load_icon_theme_from_str(s: &str) -> Option<(String, config::Config)> { + let config = config::Config::builder() + .add_source(config::File::from_str(s, config::FileFormat::Toml)) + .build() + .ok()?; + let table = config.get_table("icon-theme").ok()?; + let name = table.get("name")?.to_string(); + Some((name, config)) + } + + fn load_plugin_color_themes( + disabled_volts: &[VoltID], + extra_plugin_paths: &[PathBuf], + ) -> HashMap { + let mut themes: HashMap = HashMap::new(); + for meta in find_all_volts(extra_plugin_paths) { + if disabled_volts.contains(&meta.id()) { + continue; + } + if let Some(plugin_themes) = meta.color_themes.as_ref() { + for theme_path in plugin_themes { + if let Some((key, theme)) = + Self::load_color_theme(&PathBuf::from(theme_path)) + { + themes.insert(key, theme); + } + } + } + } + themes + } + + fn load_plugin_icon_themes( + disabled_volts: &[VoltID], + extra_plugin_paths: &[PathBuf], + ) -> HashMap { + let mut themes: HashMap = + HashMap::new(); + for meta in find_all_volts(extra_plugin_paths) { + if disabled_volts.contains(&meta.id()) { + continue; + } + if let Some(plugin_themes) = meta.icon_themes.as_ref() { + for theme_path in plugin_themes { + if let Some((key, theme)) = + Self::load_icon_theme(&PathBuf::from(theme_path)) + { + themes.insert(key, theme); + } + } + } + } + themes + } + + fn load_icon_theme( + path: &Path, + ) -> Option<(String, (String, config::Config, PathBuf))> { + if !path.is_file() { + return None; + } + let config = config::Config::builder() + .add_source(config::File::from(path)) + .build() + .ok()?; + let table = config.get_table("icon-theme").ok()?; + let name = table.get("name")?.to_string(); + Some(( + name.to_lowercase(), + (name, config, path.parent().unwrap().to_path_buf()), + )) + } + + pub fn export_theme(&self) -> String { + let mut table = toml::value::Table::new(); + let mut theme = self.color_theme.clone(); + theme.name = "".to_string(); + table.insert( + "color-theme".to_string(), + toml::Value::try_from(&theme).unwrap(), + ); + table.insert("ui".to_string(), toml::Value::try_from(&self.ui).unwrap()); + let value = toml::Value::Table(table); + toml::to_string_pretty(&value).unwrap() + } + + pub fn settings_file() -> Option { + let path = Directory::config_directory()?.join("settings.toml"); + + if !path.exists() { + if let Err(err) = std::fs::OpenOptions::new() + .create_new(true) + .write(true) + .open(&path) + { + tracing::error!("{:?}", err); + } + } + + Some(path) + } + + pub fn keymaps_file() -> Option { + let path = Directory::config_directory()?.join("keymaps.toml"); + + if !path.exists() { + if let Err(err) = std::fs::OpenOptions::new() + .create_new(true) + .write(true) + .open(&path) + { + tracing::error!("{:?}", err); + } + } + + Some(path) + } + + pub fn ui_svg(&self, icon: &'static str) -> String { + let svg = self.icon_theme.ui.get(icon).and_then(|path| { + let path = self.icon_theme.path.join(path); + self.svg_store.write().get_svg_on_disk(&path) + }); + + svg.unwrap_or_else(|| { + let name = DEFAULT_ICON_THEME_ICON_CONFIG.ui.get(icon).unwrap(); + self.svg_store.write().get_default_svg(name) + }) + } + + pub fn files_svg(&self, paths: &[&Path]) -> (String, Option) { + let svg = self + .icon_theme + .resolve_path_to_icon(paths) + .and_then(|p| self.svg_store.write().get_svg_on_disk(&p)); + + if let Some(svg) = svg { + let color = if self.icon_theme.use_editor_color.unwrap_or(false) { + Some(self.color(LapceColor::LAPCE_ICON_ACTIVE)) + } else { + None + }; + (svg, color) + } else { + ( + self.ui_svg(LapceIcons::FILE), + Some(self.color(LapceColor::LAPCE_ICON_ACTIVE)), + ) + } + } + + pub fn file_svg(&self, path: &Path) -> (String, Option) { + self.files_svg(slice::from_ref(&path)) + } + + pub fn symbol_svg(&self, kind: &SymbolKind) -> Option { + let kind_str = match *kind { + SymbolKind::ARRAY => LapceIcons::SYMBOL_KIND_ARRAY, + SymbolKind::BOOLEAN => LapceIcons::SYMBOL_KIND_BOOLEAN, + SymbolKind::CLASS => LapceIcons::SYMBOL_KIND_CLASS, + SymbolKind::CONSTANT => LapceIcons::SYMBOL_KIND_CONSTANT, + SymbolKind::ENUM_MEMBER => LapceIcons::SYMBOL_KIND_ENUM_MEMBER, + SymbolKind::ENUM => LapceIcons::SYMBOL_KIND_ENUM, + SymbolKind::EVENT => LapceIcons::SYMBOL_KIND_EVENT, + SymbolKind::FIELD => LapceIcons::SYMBOL_KIND_FIELD, + SymbolKind::FILE => LapceIcons::SYMBOL_KIND_FILE, + SymbolKind::INTERFACE => LapceIcons::SYMBOL_KIND_INTERFACE, + SymbolKind::KEY => LapceIcons::SYMBOL_KIND_KEY, + SymbolKind::FUNCTION => LapceIcons::SYMBOL_KIND_FUNCTION, + SymbolKind::METHOD => LapceIcons::SYMBOL_KIND_METHOD, + SymbolKind::OBJECT => LapceIcons::SYMBOL_KIND_OBJECT, + SymbolKind::NAMESPACE => LapceIcons::SYMBOL_KIND_NAMESPACE, + SymbolKind::NUMBER => LapceIcons::SYMBOL_KIND_NUMBER, + SymbolKind::OPERATOR => LapceIcons::SYMBOL_KIND_OPERATOR, + SymbolKind::TYPE_PARAMETER => LapceIcons::SYMBOL_KIND_TYPE_PARAMETER, + SymbolKind::PROPERTY => LapceIcons::SYMBOL_KIND_PROPERTY, + SymbolKind::STRING => LapceIcons::SYMBOL_KIND_STRING, + SymbolKind::STRUCT => LapceIcons::SYMBOL_KIND_STRUCT, + SymbolKind::VARIABLE => LapceIcons::SYMBOL_KIND_VARIABLE, + _ => return None, + }; + + Some(self.ui_svg(kind_str)) + } + + pub fn symbol_color(&self, kind: &SymbolKind) -> Option { + let theme_str = match *kind { + SymbolKind::METHOD => "method", + SymbolKind::FUNCTION => "method", + SymbolKind::ENUM => "enum", + SymbolKind::ENUM_MEMBER => "enum-member", + SymbolKind::CLASS => "class", + SymbolKind::VARIABLE => "field", + SymbolKind::STRUCT => "structure", + SymbolKind::CONSTANT => "constant", + SymbolKind::PROPERTY => "property", + SymbolKind::FIELD => "field", + SymbolKind::INTERFACE => "interface", + SymbolKind::ARRAY => "", + SymbolKind::BOOLEAN => "", + SymbolKind::EVENT => "", + SymbolKind::FILE => "", + SymbolKind::KEY => "", + SymbolKind::OBJECT => "", + SymbolKind::NAMESPACE => "", + SymbolKind::NUMBER => "number", + SymbolKind::OPERATOR => "", + SymbolKind::TYPE_PARAMETER => "", + SymbolKind::STRING => "string", + _ => return None, + }; + + self.style_color(theme_str) + } + + pub fn logo_svg(&self) -> String { + self.svg_store.read().logo_svg() + } + + /// List of the color themes that are available by their display names. + pub fn color_theme_list(&self) -> im::Vector { + self.color_theme_list.clone() + } + + /// List of the icon themes that are available by their display names. + pub fn icon_theme_list(&self) -> im::Vector { + self.icon_theme_list.clone() + } + + pub fn terminal_font_family(&self) -> &str { + if self.terminal.font_family.is_empty() { + self.editor.font_family.as_str() + } else { + self.terminal.font_family.as_str() + } + } + + pub fn terminal_font_size(&self) -> usize { + if self.terminal.font_size > 0 { + self.terminal.font_size + } else { + self.editor.font_size() + } + } + + pub fn terminal_line_height(&self) -> usize { + let font_size = self.terminal_font_size(); + + if self.terminal.line_height > 0.0 { + let line_height = if self.terminal.line_height < SCALE_OR_SIZE_LIMIT { + self.terminal.line_height * font_size as f64 + } else { + self.terminal.line_height + }; + + // Prevent overlapping lines + (line_height.round() as usize).max(font_size) + } else { + self.editor.line_height() + } + } + + pub fn terminal_get_color( + &self, + color: &alacritty_terminal::vte::ansi::Color, + colors: &alacritty_terminal::term::color::Colors, + ) -> Color { + match color { + alacritty_terminal::vte::ansi::Color::Named(color) => { + self.terminal_get_named_color(color) + } + alacritty_terminal::vte::ansi::Color::Spec(rgb) => { + Color::from_rgb8(rgb.r, rgb.g, rgb.b) + } + alacritty_terminal::vte::ansi::Color::Indexed(index) => { + if let Some(rgb) = colors[*index as usize] { + return Color::from_rgb8(rgb.r, rgb.g, rgb.b); + } + const NAMED_COLORS: [alacritty_terminal::vte::ansi::NamedColor; 16] = [ + alacritty_terminal::vte::ansi::NamedColor::Black, + alacritty_terminal::vte::ansi::NamedColor::Red, + alacritty_terminal::vte::ansi::NamedColor::Green, + alacritty_terminal::vte::ansi::NamedColor::Yellow, + alacritty_terminal::vte::ansi::NamedColor::Blue, + alacritty_terminal::vte::ansi::NamedColor::Magenta, + alacritty_terminal::vte::ansi::NamedColor::Cyan, + alacritty_terminal::vte::ansi::NamedColor::White, + alacritty_terminal::vte::ansi::NamedColor::BrightBlack, + alacritty_terminal::vte::ansi::NamedColor::BrightRed, + alacritty_terminal::vte::ansi::NamedColor::BrightGreen, + alacritty_terminal::vte::ansi::NamedColor::BrightYellow, + alacritty_terminal::vte::ansi::NamedColor::BrightBlue, + alacritty_terminal::vte::ansi::NamedColor::BrightMagenta, + alacritty_terminal::vte::ansi::NamedColor::BrightCyan, + alacritty_terminal::vte::ansi::NamedColor::BrightWhite, + ]; + if (*index as usize) < NAMED_COLORS.len() { + self.terminal_get_named_color(&NAMED_COLORS[*index as usize]) + } else { + self.terminal.indexed_colors.get(index).cloned().unwrap() + } + } + } + } + + fn terminal_get_named_color( + &self, + color: &alacritty_terminal::vte::ansi::NamedColor, + ) -> Color { + let (color, alpha) = match color { + alacritty_terminal::vte::ansi::NamedColor::Cursor => { + (LapceColor::TERMINAL_CURSOR, 1.0) + } + alacritty_terminal::vte::ansi::NamedColor::Foreground => { + (LapceColor::TERMINAL_FOREGROUND, 1.0) + } + alacritty_terminal::vte::ansi::NamedColor::Background => { + (LapceColor::TERMINAL_BACKGROUND, 1.0) + } + alacritty_terminal::vte::ansi::NamedColor::Blue => { + (LapceColor::TERMINAL_BLUE, 1.0) + } + alacritty_terminal::vte::ansi::NamedColor::Green => { + (LapceColor::TERMINAL_GREEN, 1.0) + } + alacritty_terminal::vte::ansi::NamedColor::Yellow => { + (LapceColor::TERMINAL_YELLOW, 1.0) + } + alacritty_terminal::vte::ansi::NamedColor::Red => { + (LapceColor::TERMINAL_RED, 1.0) + } + alacritty_terminal::vte::ansi::NamedColor::White => { + (LapceColor::TERMINAL_WHITE, 1.0) + } + alacritty_terminal::vte::ansi::NamedColor::Black => { + (LapceColor::TERMINAL_BLACK, 1.0) + } + alacritty_terminal::vte::ansi::NamedColor::Cyan => { + (LapceColor::TERMINAL_CYAN, 1.0) + } + alacritty_terminal::vte::ansi::NamedColor::Magenta => { + (LapceColor::TERMINAL_MAGENTA, 1.0) + } + alacritty_terminal::vte::ansi::NamedColor::BrightBlue => { + (LapceColor::TERMINAL_BRIGHT_BLUE, 1.0) + } + alacritty_terminal::vte::ansi::NamedColor::BrightGreen => { + (LapceColor::TERMINAL_BRIGHT_GREEN, 1.0) + } + alacritty_terminal::vte::ansi::NamedColor::BrightYellow => { + (LapceColor::TERMINAL_BRIGHT_YELLOW, 1.0) + } + alacritty_terminal::vte::ansi::NamedColor::BrightRed => { + (LapceColor::TERMINAL_BRIGHT_RED, 1.0) + } + alacritty_terminal::vte::ansi::NamedColor::BrightWhite => { + (LapceColor::TERMINAL_BRIGHT_WHITE, 1.0) + } + alacritty_terminal::vte::ansi::NamedColor::BrightBlack => { + (LapceColor::TERMINAL_BRIGHT_BLACK, 1.0) + } + alacritty_terminal::vte::ansi::NamedColor::BrightCyan => { + (LapceColor::TERMINAL_BRIGHT_CYAN, 1.0) + } + alacritty_terminal::vte::ansi::NamedColor::BrightMagenta => { + (LapceColor::TERMINAL_BRIGHT_MAGENTA, 1.0) + } + alacritty_terminal::vte::ansi::NamedColor::BrightForeground => { + (LapceColor::TERMINAL_FOREGROUND, 1.0) + } + alacritty_terminal::vte::ansi::NamedColor::DimBlack => { + (LapceColor::TERMINAL_BLACK, 0.66) + } + alacritty_terminal::vte::ansi::NamedColor::DimRed => { + (LapceColor::TERMINAL_RED, 0.66) + } + alacritty_terminal::vte::ansi::NamedColor::DimGreen => { + (LapceColor::TERMINAL_GREEN, 0.66) + } + alacritty_terminal::vte::ansi::NamedColor::DimYellow => { + (LapceColor::TERMINAL_YELLOW, 0.66) + } + alacritty_terminal::vte::ansi::NamedColor::DimBlue => { + (LapceColor::TERMINAL_BLUE, 0.66) + } + alacritty_terminal::vte::ansi::NamedColor::DimMagenta => { + (LapceColor::TERMINAL_MAGENTA, 0.66) + } + alacritty_terminal::vte::ansi::NamedColor::DimCyan => { + (LapceColor::TERMINAL_CYAN, 0.66) + } + alacritty_terminal::vte::ansi::NamedColor::DimWhite => { + (LapceColor::TERMINAL_WHITE, 0.66) + } + alacritty_terminal::vte::ansi::NamedColor::DimForeground => { + (LapceColor::TERMINAL_FOREGROUND, 0.66) + } + }; + self.color(color).multiply_alpha(alpha) + } + + /// Get the dropdown information for the specific setting, used for the settings UI. + /// This should aim to efficiently return the data, because it is used to determine whether to + /// update the dropdown items. + pub fn get_dropdown_info(&self, kind: &str, key: &str) -> Option { + match (kind, key) { + ("core", "color-theme") => Some(DropdownInfo { + active_index: self + .color_theme_list + .iter() + .position(|s| s == &self.color_theme.name) + .unwrap_or(0), + items: self.color_theme_list.clone(), + }), + ("core", "icon-theme") => Some(DropdownInfo { + active_index: self + .icon_theme_list + .iter() + .position(|s| s == &self.icon_theme.name) + .unwrap_or(0), + items: self.icon_theme_list.clone(), + }), + ("editor", "wrap-style") => Some(DropdownInfo { + // TODO: it would be better to have the text not be the default kebab-case when + // displayed in settings, but we would need to map back from the dropdown's value + // or index. + active_index: self + .wrap_style_list + .iter() + .flat_map(|w| WrapStyle::try_from_str(w)) + .position(|w| w == self.editor.wrap_style) + .unwrap_or(0), + items: self.wrap_style_list.clone(), + }), + ("ui", "tab-close-button") => Some(DropdownInfo { + active_index: self.ui.tab_close_button as usize, + items: ui::TabCloseButton::VARIANTS + .iter() + .map(|s| s.to_string()) + .sorted() + .collect(), + }), + ("ui", "tab-separator-height") => Some(DropdownInfo { + active_index: self.ui.tab_separator_height as usize, + items: ui::TabSeparatorHeight::VARIANTS + .iter() + .map(|s| s.to_string()) + .sorted() + .collect(), + }), + ("terminal", "default-profile") => Some(DropdownInfo { + active_index: self + .terminal + .profiles + .iter() + .position(|(profile_name, _)| { + profile_name + == self + .terminal + .default_profile + .get(std::env::consts::OS) + .unwrap_or(&String::from("default")) + }) + .unwrap_or(0), + items: self.terminal.profiles.clone().into_keys().collect(), + }), + _ => None, + } + } + + fn get_file_table() -> Option { + let path = Self::settings_file()?; + let content = std::fs::read_to_string(path).ok()?; + let document: toml_edit::Document = content.parse().ok()?; + Some(document) + } + + pub fn reset_setting(parent: &str, key: &str) -> Option<()> { + let mut main_table = Self::get_file_table().unwrap_or_default(); + + // Find the container table + let mut table = main_table.as_table_mut(); + for key in parent.split('.') { + if !table.contains_key(key) { + table.insert( + key, + toml_edit::Item::Table(toml_edit::Table::default()), + ); + } + table = table.get_mut(key)?.as_table_mut()?; + } + + table.remove(key); + + // Store + let path = Self::settings_file()?; + std::fs::write(path, main_table.to_string().as_bytes()).ok()?; + + Some(()) + } + + /// Update the config file with the given edit. + /// This should be called whenever the configuration is changed, so that it is persisted. + pub fn update_file( + parent: &str, + key: &str, + value: toml_edit::Value, + ) -> Option<()> { + // TODO: This is a hack to fix the fact that terminal default profile is saved in a + // different manner than other fields. As it is per-operating-system. + // Thus we have to instead set the terminal.default-profile.{OS} + // It would be better to not need a special hack. + let (parent, key) = if parent == "terminal" && key == "default-profile" { + ("terminal.default-profile", std::env::consts::OS) + } else { + (parent, key) + }; + + let mut main_table = Self::get_file_table().unwrap_or_default(); + + // Find the container table + let mut table = main_table.as_table_mut(); + for key in parent.split('.') { + if !table.contains_key(key) { + table.insert( + key, + toml_edit::Item::Table(toml_edit::Table::default()), + ); + } + table = table.get_mut(key)?.as_table_mut()?; + } + + // Update key + table.insert(key, toml_edit::Item::Value(value)); + + // Store + let path = Self::settings_file()?; + std::fs::write(path, main_table.to_string().as_bytes()).ok()?; + + Some(()) + } +} diff --git a/lapce-app/src/config/color.rs b/lapce-app/src/config/color.rs new file mode 100644 index 0000000..158fabf --- /dev/null +++ b/lapce-app/src/config/color.rs @@ -0,0 +1,182 @@ +use std::path::PathBuf; + +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum LoadThemeError { + #[error("themes folder not found, possibly it could not be created")] + ThemesFolderNotFound, + #[error("theme file ({theme_name}.toml) was not found in {themes_folder:?}")] + FileNotFound { + themes_folder: PathBuf, + theme_name: String, + }, + #[error("recursion limit reached for {variable_name}")] + RecursionLimitReached { variable_name: String }, + #[error("variable {variable_name} not found")] + VariableNotFound { variable_name: String }, + #[error("There was an error reading the theme file")] + Read(std::io::Error), +} + +pub struct LapceColor {} + +impl LapceColor { + pub const LAPCE_WARN: &'static str = "lapce.warn"; + pub const LAPCE_ERROR: &'static str = "lapce.error"; + pub const LAPCE_DROPDOWN_SHADOW: &'static str = "lapce.dropdown_shadow"; + pub const LAPCE_BORDER: &'static str = "lapce.border"; + pub const LAPCE_SCROLL_BAR: &'static str = "lapce.scroll_bar"; + + pub const LAPCE_BUTTON_PRIMARY_BACKGROUND: &'static str = + "lapce.button.primary.background"; + pub const LAPCE_BUTTON_PRIMARY_FOREGROUND: &'static str = + "lapce.button.primary.foreground"; + + pub const LAPCE_TAB_ACTIVE_BACKGROUND: &'static str = + "lapce.tab.active.background"; + pub const LAPCE_TAB_ACTIVE_FOREGROUND: &'static str = + "lapce.tab.active.foreground"; + pub const LAPCE_TAB_ACTIVE_UNDERLINE: &'static str = + "lapce.tab.active.underline"; + + pub const LAPCE_TAB_INACTIVE_BACKGROUND: &'static str = + "lapce.tab.inactive.background"; + pub const LAPCE_TAB_INACTIVE_FOREGROUND: &'static str = + "lapce.tab.inactive.foreground"; + pub const LAPCE_TAB_INACTIVE_UNDERLINE: &'static str = + "lapce.tab.inactive.underline"; + + pub const LAPCE_TAB_SEPARATOR: &'static str = "lapce.tab.separator"; + + pub const LAPCE_ICON_ACTIVE: &'static str = "lapce.icon.active"; + pub const LAPCE_ICON_INACTIVE: &'static str = "lapce.icon.inactive"; + + pub const LAPCE_REMOTE_ICON: &'static str = "lapce.remote.icon"; + pub const LAPCE_REMOTE_LOCAL: &'static str = "lapce.remote.local"; + pub const LAPCE_REMOTE_CONNECTED: &'static str = "lapce.remote.connected"; + pub const LAPCE_REMOTE_CONNECTING: &'static str = "lapce.remote.connecting"; + pub const LAPCE_REMOTE_DISCONNECTED: &'static str = "lapce.remote.disconnected"; + + pub const LAPCE_PLUGIN_NAME: &'static str = "lapce.plugin.name"; + pub const LAPCE_PLUGIN_DESCRIPTION: &'static str = "lapce.plugin.description"; + pub const LAPCE_PLUGIN_AUTHOR: &'static str = "lapce.plugin.author"; + + pub const EDITOR_BACKGROUND: &'static str = "editor.background"; + pub const EDITOR_FOREGROUND: &'static str = "editor.foreground"; + pub const EDITOR_DIM: &'static str = "editor.dim"; + pub const EDITOR_FOCUS: &'static str = "editor.focus"; + pub const EDITOR_CARET: &'static str = "editor.caret"; + pub const EDITOR_SELECTION: &'static str = "editor.selection"; + pub const EDITOR_DEBUG_BREAK_LINE: &'static str = "editor.debug_break_line"; + pub const EDITOR_CURRENT_LINE: &'static str = "editor.current_line"; + pub const EDITOR_LINK: &'static str = "editor.link"; + pub const EDITOR_VISIBLE_WHITESPACE: &'static str = "editor.visible_whitespace"; + pub const EDITOR_INDENT_GUIDE: &'static str = "editor.indent_guide"; + pub const EDITOR_DRAG_DROP_BACKGROUND: &'static str = + "editor.drag_drop_background"; + pub const EDITOR_STICKY_HEADER_BACKGROUND: &'static str = + "editor.sticky_header_background"; + pub const EDITOR_DRAG_DROP_TAB_BACKGROUND: &'static str = + "editor.drag_drop_tab_background"; + + pub const INLAY_HINT_FOREGROUND: &'static str = "inlay_hint.foreground"; + pub const INLAY_HINT_BACKGROUND: &'static str = "inlay_hint.background"; + + pub const ERROR_LENS_ERROR_FOREGROUND: &'static str = + "error_lens.error.foreground"; + pub const ERROR_LENS_ERROR_BACKGROUND: &'static str = + "error_lens.error.background"; + pub const ERROR_LENS_WARNING_FOREGROUND: &'static str = + "error_lens.warning.foreground"; + pub const ERROR_LENS_WARNING_BACKGROUND: &'static str = + "error_lens.warning.background"; + pub const ERROR_LENS_OTHER_FOREGROUND: &'static str = + "error_lens.other.foreground"; + pub const ERROR_LENS_OTHER_BACKGROUND: &'static str = + "error_lens.other.background"; + + pub const COMPLETION_LENS_FOREGROUND: &'static str = + "completion_lens.foreground"; + + pub const SOURCE_CONTROL_ADDED: &'static str = "source_control.added"; + pub const SOURCE_CONTROL_REMOVED: &'static str = "source_control.removed"; + pub const SOURCE_CONTROL_MODIFIED: &'static str = "source_control.modified"; + + pub const TERMINAL_CURSOR: &'static str = "terminal.cursor"; + pub const TERMINAL_BACKGROUND: &'static str = "terminal.background"; + pub const TERMINAL_FOREGROUND: &'static str = "terminal.foreground"; + pub const TERMINAL_RED: &'static str = "terminal.red"; + pub const TERMINAL_BLUE: &'static str = "terminal.blue"; + pub const TERMINAL_GREEN: &'static str = "terminal.green"; + pub const TERMINAL_YELLOW: &'static str = "terminal.yellow"; + pub const TERMINAL_BLACK: &'static str = "terminal.black"; + pub const TERMINAL_WHITE: &'static str = "terminal.white"; + pub const TERMINAL_CYAN: &'static str = "terminal.cyan"; + pub const TERMINAL_MAGENTA: &'static str = "terminal.magenta"; + + pub const TERMINAL_BRIGHT_RED: &'static str = "terminal.bright_red"; + pub const TERMINAL_BRIGHT_BLUE: &'static str = "terminal.bright_blue"; + pub const TERMINAL_BRIGHT_GREEN: &'static str = "terminal.bright_green"; + pub const TERMINAL_BRIGHT_YELLOW: &'static str = "terminal.bright_yellow"; + pub const TERMINAL_BRIGHT_BLACK: &'static str = "terminal.bright_black"; + pub const TERMINAL_BRIGHT_WHITE: &'static str = "terminal.bright_white"; + pub const TERMINAL_BRIGHT_CYAN: &'static str = "terminal.bright_cyan"; + pub const TERMINAL_BRIGHT_MAGENTA: &'static str = "terminal.bright_magenta"; + + pub const PALETTE_BACKGROUND: &'static str = "palette.background"; + pub const PALETTE_FOREGROUND: &'static str = "palette.foreground"; + pub const PALETTE_CURRENT_BACKGROUND: &'static str = + "palette.current.background"; + pub const PALETTE_CURRENT_FOREGROUND: &'static str = + "palette.current.foreground"; + + pub const COMPLETION_BACKGROUND: &'static str = "completion.background"; + pub const COMPLETION_CURRENT: &'static str = "completion.current"; + + pub const HOVER_BACKGROUND: &'static str = "hover.background"; + + pub const ACTIVITY_BACKGROUND: &'static str = "activity.background"; + pub const ACTIVITY_CURRENT: &'static str = "activity.current"; + + pub const DEBUG_BREAKPOINT: &'static str = "debug.breakpoint"; + pub const DEBUG_BREAKPOINT_HOVER: &'static str = "debug.breakpoint.hover"; + + pub const TOOLTIP_BACKGROUND: &'static str = "tooltip.background"; + pub const TOOLTIP_FOREGROUND: &'static str = "tooltip.foreground"; + + pub const PANEL_BACKGROUND: &'static str = "panel.background"; + pub const PANEL_FOREGROUND: &'static str = "panel.foreground"; + pub const PANEL_FOREGROUND_DIM: &'static str = "panel.foreground.dim"; + pub const PANEL_CURRENT_BACKGROUND: &'static str = "panel.current.background"; + pub const PANEL_CURRENT_FOREGROUND: &'static str = "panel.current.foreground"; + pub const PANEL_CURRENT_FOREGROUND_DIM: &'static str = + "panel.current.foreground.dim"; + pub const PANEL_HOVERED_BACKGROUND: &'static str = "panel.hovered.background"; + pub const PANEL_HOVERED_ACTIVE_BACKGROUND: &'static str = + "panel.hovered.active.background"; + pub const PANEL_HOVERED_FOREGROUND: &'static str = "panel.hovered.foreground"; + pub const PANEL_HOVERED_FOREGROUND_DIM: &'static str = + "panel.hovered.foreground.dim"; + + pub const STATUS_BACKGROUND: &'static str = "status.background"; + pub const STATUS_FOREGROUND: &'static str = "status.foreground"; + pub const STATUS_MODAL_NORMAL_BACKGROUND: &'static str = + "status.modal.normal.background"; + pub const STATUS_MODAL_NORMAL_FOREGROUND: &'static str = + "status.modal.normal.foreground"; + pub const STATUS_MODAL_INSERT_BACKGROUND: &'static str = + "status.modal.insert.background"; + pub const STATUS_MODAL_INSERT_FOREGROUND: &'static str = + "status.modal.insert.foreground"; + pub const STATUS_MODAL_VISUAL_BACKGROUND: &'static str = + "status.modal.visual.background"; + pub const STATUS_MODAL_VISUAL_FOREGROUND: &'static str = + "status.modal.visual.foreground"; + pub const STATUS_MODAL_TERMINAL_BACKGROUND: &'static str = + "status.modal.terminal.background"; + pub const STATUS_MODAL_TERMINAL_FOREGROUND: &'static str = + "status.modal.terminal.foreground"; + + pub const MARKDOWN_BLOCKQUOTE: &'static str = "markdown.blockquote"; +} diff --git a/lapce-app/src/config/color_theme.rs b/lapce-app/src/config/color_theme.rs new file mode 100644 index 0000000..b9c0d97 --- /dev/null +++ b/lapce-app/src/config/color_theme.rs @@ -0,0 +1,263 @@ +use std::{ + collections::{BTreeMap, HashMap}, + path::PathBuf, + str::FromStr, +}; + +use floem::{peniko::Color, prelude::palette::css}; +use serde::{Deserialize, Serialize}; + +use super::color::LoadThemeError; + +#[derive(Debug, Clone, Default)] +pub enum ThemeColorPreference { + #[default] + Light, + Dark, + HighContrastDark, + HighContrastLight, +} + +/// Holds all the resolved theme variables +#[derive(Debug, Clone, Default)] +pub struct ThemeBaseColor(HashMap); +impl ThemeBaseColor { + pub fn get(&self, name: &str) -> Option { + self.0.get(name).map(ToOwned::to_owned) + } +} + +pub const THEME_RECURSION_LIMIT: usize = 6; + +#[derive(Debug, Clone, Default)] +pub struct ThemeColor { + pub color_preference: ThemeColorPreference, + pub base: ThemeBaseColor, + pub syntax: HashMap, + pub ui: HashMap, +} + +#[derive(Debug, Clone, Deserialize, Serialize, Default)] +pub struct ThemeBaseConfig(pub BTreeMap); + +impl ThemeBaseConfig { + /// Resolve the variables in this theme base config into the actual colors. + /// The basic idea is just: `"field`: some value` does: + /// - If the value does not start with `$`, then it is a color and we return it + /// - If the value starts with `$` then it is a variable + /// - Look it up in the current theme + /// - If not found, look it up in the default theme + /// - If not found, return `Color::HOT_PINK` as a fallback + /// + /// Note that this applies even if the default theme colors have a variable. + /// This allows the default theme to have, for example, a `$uibg` variable that the current + /// them can override so that if there's ever a new ui element using that variable, the theme + /// does not have to be updated. + pub fn resolve(&self, default: Option<&ThemeBaseConfig>) -> ThemeBaseColor { + let default = default.cloned().unwrap_or_default(); + + let mut base = ThemeBaseColor(HashMap::new()); + + // We resolve all the variables to their values + for (key, value) in self.0.iter() { + match self.resolve_variable(&default, key, value, 0) { + Ok(Some(color)) => { + let color = Color::from_str(color) + .unwrap_or_else(|_| { + tracing::warn!( + "Failed to parse color theme variable for ({key}: {value})" + ); + css::HOT_PINK + }); + base.0.insert(key.to_string(), color); + } + Ok(None) => { + tracing::warn!( + "Failed to resolve color theme variable for ({key}: {value})" + ); + } + Err(err) => { + tracing::error!( + "Failed to resolve color theme variable ({key}: {value}): {err}" + ); + } + } + } + + base + } + + fn resolve_variable<'a>( + &'a self, + defaults: &'a ThemeBaseConfig, + key: &str, + value: &'a str, + i: usize, + ) -> Result, LoadThemeError> { + let Some(value) = value.strip_prefix('$') else { + return Ok(Some(value)); + }; + + if i > THEME_RECURSION_LIMIT { + return Err(LoadThemeError::RecursionLimitReached { + variable_name: key.to_string(), + }); + } + + let target = + self.get(value) + .or_else(|| defaults.get(value)) + .ok_or_else(|| LoadThemeError::VariableNotFound { + variable_name: key.to_string(), + })?; + + self.resolve_variable(defaults, value, target, i + 1) + } + + // Note: this returns an `&String` just to make it consistent with hashmap lookups that are + // also used via ui/syntax + pub fn get(&self, name: &str) -> Option<&String> { + self.0.get(name) + } + + pub fn key_values(&self) -> BTreeMap { + self.0.clone() + } +} + +#[derive(Debug, Clone, Deserialize, Serialize, Default)] +#[serde(rename_all = "kebab-case", default)] +pub struct ColorThemeConfig { + #[serde(skip)] + pub path: PathBuf, + pub name: String, + pub high_contrast: Option, + pub base: ThemeBaseConfig, + pub syntax: BTreeMap, + pub ui: BTreeMap, +} + +impl ColorThemeConfig { + fn resolve_color( + colors: &BTreeMap, + base: &ThemeBaseColor, + default: Option<&HashMap>, + ) -> HashMap { + colors + .iter() + .map(|(name, hex)| { + let color = if let Some(stripped) = hex.strip_prefix('$') { + base.get(stripped) + } else { + Color::from_str(hex).ok() + }; + + let color = color + .or_else(|| { + default.and_then(|default| default.get(name).cloned()) + }) + .unwrap_or(Color::from_rgb8(0, 0, 0)); + + (name.to_string(), color) + }) + .collect() + } + + pub(super) fn resolve_ui_color( + &self, + base: &ThemeBaseColor, + default: Option<&HashMap>, + ) -> HashMap { + Self::resolve_color(&self.ui, base, default) + } + + pub(super) fn resolve_syntax_color( + &self, + base: &ThemeBaseColor, + default: Option<&HashMap>, + ) -> HashMap { + Self::resolve_color(&self.syntax, base, default) + } +} + +#[cfg(test)] +mod tests { + use config::Config; + use floem::{peniko::Color, prelude::palette::css}; + + use crate::{config::LapceConfig, workspace::LapceWorkspace}; + + #[test] + fn test_resolve() { + // Mimicking load + let workspace = LapceWorkspace::default(); + + let config = LapceConfig::merge_config(&workspace, None, None); + let mut lapce_config: LapceConfig = config.try_deserialize().unwrap(); + + let test_theme_str = r##" +[color-theme] +name = "test" +color-preference = "dark" + +[ui] + +[color-theme.base] +"blah" = "#ff00ff" +"text" = "#000000" + +[color-theme.syntax] + +[color-theme.ui] +"lapce.error" = "#ffffff" +"editor.background" = "$blah" +"##; + println!("Test theme: {test_theme_str}"); + let test_theme_cfg = Config::builder() + .add_source(config::File::from_str( + test_theme_str, + config::FileFormat::Toml, + )) + .build() + .unwrap(); + + lapce_config.available_color_themes = + [("test".to_string(), ("test".to_string(), test_theme_cfg))] + .into_iter() + .collect(); + // lapce_config.available_icon_themes = Some(vec![]); + lapce_config.core.color_theme = "test".to_string(); + + lapce_config.resolve_theme(&workspace); + + println!("Hot Pink: {:?}", css::HOT_PINK); + // test basic override + assert_eq!( + lapce_config.color("lapce.error"), + Color::WHITE, + "Failed to get basic theme override" + ); + // test that it falls through to the dark theme for unspecified color + assert_eq!( + lapce_config.color("lapce.warn"), + Color::from_rgb8(0xE5, 0xC0, 0x7B), + "Failed to get from fallback dark theme" + ); // $yellow + // test that our custom variable worked + assert_eq!( + lapce_config.color("editor.background"), + Color::from_rgb8(0xFF, 0x00, 0xFF), + "Failed to get from custom variable" + ); + // test that for text it now uses our redeclared variable + assert_eq!( + lapce_config.color("editor.foreground"), + Color::BLACK, + "Failed to get from custom variable circle back around" + ); + + // don't bother filling color/icon theme list + // don't bother with wrap style list + // don't bother with terminal colors + } +} diff --git a/lapce-app/src/config/core.rs b/lapce-app/src/config/core.rs new file mode 100644 index 0000000..c230b9c --- /dev/null +++ b/lapce-app/src/config/core.rs @@ -0,0 +1,25 @@ +use serde::{Deserialize, Serialize}; +use structdesc::FieldNames; + +#[derive(FieldNames, Debug, Clone, Deserialize, Serialize, Default)] +#[serde(rename_all = "kebab-case")] +pub struct CoreConfig { + #[field_names(desc = "Enable modal editing (Vim like)")] + pub modal: bool, + #[field_names(desc = "Set the color theme of Lapce")] + pub color_theme: String, + #[field_names(desc = "Set the icon theme of Lapce")] + pub icon_theme: String, + #[field_names( + desc = "Enable customised titlebar and disable OS native one (Linux, BSD, Windows)" + )] + pub custom_titlebar: bool, + #[field_names( + desc = "Only allow double-click to open files in the file explorer" + )] + pub file_explorer_double_click: bool, + #[field_names( + desc = "Enable auto-reload for the plugin when its configuration changes." + )] + pub auto_reload_plugin: bool, +} diff --git a/lapce-app/src/config/editor.rs b/lapce-app/src/config/editor.rs new file mode 100644 index 0000000..5d6cb12 --- /dev/null +++ b/lapce-app/src/config/editor.rs @@ -0,0 +1,306 @@ +use floem::views::editor::text::RenderWhitespace; +use serde::{Deserialize, Serialize}; +use structdesc::FieldNames; + +pub const SCALE_OR_SIZE_LIMIT: f64 = 5.0; + +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +pub enum ClickMode { + #[default] + #[serde(rename = "single")] + SingleClick, + #[serde(rename = "file")] + DoubleClickFile, + #[serde(rename = "all")] + DoubleClickAll, +} + +#[derive(Debug, Clone, Copy, Serialize, Deserialize, Default, PartialEq)] +#[serde(rename_all = "kebab-case")] +pub enum WrapStyle { + /// No wrapping + None, + /// Wrap at the editor width + #[default] + EditorWidth, + // /// Wrap at the wrap-column + // WrapColumn, + /// Wrap at a specific width + WrapWidth, +} +impl WrapStyle { + pub fn as_str(&self) -> &'static str { + match self { + WrapStyle::None => "none", + WrapStyle::EditorWidth => "editor-width", + // WrapStyle::WrapColumn => "wrap-column", + WrapStyle::WrapWidth => "wrap-width", + } + } + + pub fn try_from_str(s: &str) -> Option { + match s { + "none" => Some(WrapStyle::None), + "editor-width" => Some(WrapStyle::EditorWidth), + // "wrap-column" => Some(WrapStyle::WrapColumn), + "wrap-width" => Some(WrapStyle::WrapWidth), + _ => None, + } + } +} + +impl std::fmt::Display for WrapStyle { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str())?; + + Ok(()) + } +} + +#[derive(FieldNames, Debug, Clone, Deserialize, Serialize, Default)] +#[serde(rename_all = "kebab-case")] +pub struct EditorConfig { + #[field_names(desc = "Set the editor font family")] + pub font_family: String, + #[field_names(desc = "Set the editor font size")] + font_size: usize, + #[field_names(desc = "Set the font size in the code glance")] + pub code_glance_font_size: usize, + #[field_names( + desc = "Set the editor line height. If less than 5.0, line height will be a multiple of the font size." + )] + line_height: f64, + #[field_names( + desc = "If enabled, when you input a tab character, it will insert indent that's detected based on your files." + )] + pub smart_tab: bool, + #[field_names(desc = "Set the tab width")] + pub tab_width: usize, + #[field_names(desc = "If opened editors are shown in a tab")] + pub show_tab: bool, + #[field_names(desc = "If navigation breadcrumbs are shown for the file")] + pub show_bread_crumbs: bool, + #[field_names(desc = "If the editor can scroll beyond the last line")] + pub scroll_beyond_last_line: bool, + #[field_names( + desc = "Set the minimum number of visible lines above and below the cursor" + )] + pub cursor_surrounding_lines: usize, + #[field_names(desc = "The kind of wrapping to perform")] + pub wrap_style: WrapStyle, + // #[field_names(desc = "The number of columns to wrap at")] + // pub wrap_column: usize, + #[field_names(desc = "The number of pixels to wrap at")] + pub wrap_width: usize, + #[field_names( + desc = "Show code context like functions and classes at the top of editor when scroll" + )] + pub sticky_header: bool, + #[field_names(desc = "The number of pixels to show completion")] + pub completion_width: usize, + #[field_names( + desc = "If the editor should show the documentation of the current completion item" + )] + pub completion_show_documentation: bool, + #[field_names( + desc = "Should the completion item use the `detail` field to replace the label `field`?" + )] + pub completion_item_show_detail: bool, + #[field_names( + desc = "If the editor should show the signature of the function as the parameters are being typed" + )] + pub show_signature: bool, + #[field_names( + desc = "If the signature view should put the codeblock into a label. This might not work nicely for LSPs which provide invalid code for their labels." + )] + pub signature_label_code_block: bool, + #[field_names( + desc = "Whether the editor should enable automatic closing of matching pairs" + )] + pub auto_closing_matching_pairs: bool, + #[field_names( + desc = "Whether the editor should automatically surround selected text when typing quotes or brackets" + )] + pub auto_surround: bool, + #[field_names( + desc = "How long (in ms) it should take before the hover information appears" + )] + pub hover_delay: u64, + #[field_names( + desc = "If modal mode should have relative line numbers (though, not in insert mode)" + )] + pub modal_mode_relative_line_numbers: bool, + #[field_names( + desc = "Whether it should format the document on save (if there is an available formatter)" + )] + pub format_on_save: bool, + + #[field_names( + desc = "Whether newlines should be automatically converted to the current line ending" + )] + pub normalize_line_endings: bool, + + #[field_names(desc = "If matching brackets are highlighted")] + pub highlight_matching_brackets: bool, + + #[field_names(desc = "If scope lines are highlighted")] + pub highlight_scope_lines: bool, + + #[field_names(desc = "If inlay hints should be displayed")] + pub enable_inlay_hints: bool, + + #[field_names( + desc = "Set the inlay hint font family. If empty, it uses the editor font family." + )] + pub inlay_hint_font_family: String, + #[field_names( + desc = "Set the inlay hint font size. If less than 5 or greater than editor font size, it uses the editor font size." + )] + pub inlay_hint_font_size: usize, + #[field_names(desc = "If diagnostics should be displayed inline")] + pub enable_error_lens: bool, + + #[field_names( + desc = "Only render the styling without displaying messages, provided that `Enable ErrorLens` is enabled" + )] + pub only_render_error_styling: bool, + #[field_names( + desc = "Whether error lens should go to the end of view line, or only to the end of the diagnostic" + )] + pub error_lens_end_of_line: bool, + #[field_names( + desc = "Whether error lens should extend over multiple lines. If false, it will have newlines stripped." + )] + pub error_lens_multiline: bool, + // TODO: Error lens but put entirely on the next line + // TODO: error lens with indentation matching. + #[field_names( + desc = "Set error lens font family. If empty, it uses the inlay hint font family." + )] + pub error_lens_font_family: String, + #[field_names( + desc = "Set the error lens font size. If 0 it uses the inlay hint font size." + )] + pub error_lens_font_size: usize, + #[field_names( + desc = "If the editor should display the completion item as phantom text" + )] + pub enable_completion_lens: bool, + #[field_names(desc = "If the editor should display inline completions")] + pub enable_inline_completion: bool, + #[field_names( + desc = "Set completion lens font family. If empty, it uses the inlay hint font family." + )] + pub completion_lens_font_family: String, + #[field_names( + desc = "Set the completion lens font size. If 0 it uses the inlay hint font size." + )] + pub completion_lens_font_size: usize, + #[field_names( + desc = "Set the cursor blink interval (in milliseconds). Set to 0 to completely disable." + )] + blink_interval: u64, + #[field_names( + desc = "Whether the multiple cursor selection is case sensitive." + )] + pub multicursor_case_sensitive: bool, + #[field_names( + desc = "Whether the multiple cursor selection only selects whole words." + )] + pub multicursor_whole_words: bool, + #[field_names( + desc = "How the editor should render whitespace characters.\nOptions: none, all, boundary, trailing." + )] + pub render_whitespace: RenderWhitespace, + #[field_names(desc = "Whether the editor show indent guide.")] + pub show_indent_guide: bool, + #[field_names( + desc = "Set the auto save delay (in milliseconds), Set to 0 to completely disable" + )] + pub autosave_interval: u64, + #[field_names( + desc = "Whether the document should be formatted when an autosave is triggered (required Format on Save)" + )] + pub format_on_autosave: bool, + #[field_names( + desc = "If enabled the cursor treats leading soft tabs as if they are hard tabs." + )] + pub atomic_soft_tabs: bool, + #[field_names( + desc = "Use a double click to interact with the file explorer.\nOptions: single (default), file or all." + )] + pub double_click: ClickMode, + #[field_names(desc = "Move the focus as you type in the global search box")] + pub move_focus_while_search: bool, + #[field_names( + desc = "Set the default number of visible lines above and below the diff block (-1 for infinite)" + )] + pub diff_context_lines: i32, + #[field_names(desc = "Whether the editor colorizes brackets")] + pub bracket_pair_colorization: bool, + #[field_names(desc = "Bracket colorization Limit")] + pub bracket_colorization_limit: u64, + #[field_names( + desc = "Glob patterns for excluding files and folders (in file explorer)" + )] + pub files_exclude: String, +} + +impl EditorConfig { + pub fn font_size(&self) -> usize { + self.font_size.clamp(6, 32) + } + + pub fn line_height(&self) -> usize { + let line_height = if self.line_height < SCALE_OR_SIZE_LIMIT { + self.line_height * self.font_size as f64 + } else { + self.line_height + }; + + // Prevent overlapping lines + (line_height.round() as usize).max(self.font_size) + } + + pub fn inlay_hint_font_size(&self) -> usize { + if self.inlay_hint_font_size < 5 + || self.inlay_hint_font_size > self.font_size + { + self.font_size() + } else { + self.inlay_hint_font_size + } + } + + pub fn error_lens_font_size(&self) -> usize { + if self.error_lens_font_size == 0 { + self.inlay_hint_font_size() + } else { + self.error_lens_font_size + } + } + + pub fn completion_lens_font_size(&self) -> usize { + if self.completion_lens_font_size == 0 { + self.inlay_hint_font_size() + } else { + self.completion_lens_font_size + } + } + + /// Returns the tab width if atomic soft tabs are enabled. + pub fn atomic_soft_tab_width(&self) -> Option { + if self.atomic_soft_tabs { + Some(self.tab_width) + } else { + None + } + } + + pub fn blink_interval(&self) -> u64 { + if self.blink_interval == 0 { + return 0; + } + self.blink_interval.max(200) + } +} diff --git a/lapce-app/src/config/icon.rs b/lapce-app/src/config/icon.rs new file mode 100644 index 0000000..9fdcbd2 --- /dev/null +++ b/lapce-app/src/config/icon.rs @@ -0,0 +1,171 @@ +pub struct LapceIcons {} + +impl LapceIcons { + pub const WINDOW_CLOSE: &'static str = "window.close"; + pub const WINDOW_RESTORE: &'static str = "window.restore"; + pub const WINDOW_MAXIMIZE: &'static str = "window.maximize"; + pub const WINDOW_MINIMIZE: &'static str = "window.minimize"; + + pub const LOGO: &'static str = "logo"; + pub const MENU: &'static str = "menu"; + pub const LINK: &'static str = "link"; + pub const ERROR: &'static str = "error"; + pub const ADD: &'static str = "add"; + pub const CLOSE: &'static str = "close"; + pub const REMOTE: &'static str = "remote"; + pub const PROBLEM: &'static str = "error"; + pub const DEBUG: &'static str = "debug"; + pub const DEBUG_ALT: &'static str = "debug_alt"; + pub const DEBUG_BREAKPOINT: &'static str = "debug_breakpoint"; + pub const DEBUG_SMALL: &'static str = "debug_small"; + pub const DEBUG_RESTART: &'static str = "debug_restart"; + pub const DEBUG_CONTINUE: &'static str = "debug_continue"; + pub const DEBUG_STEP_OVER: &'static str = "debug_step_over"; + pub const DEBUG_STEP_INTO: &'static str = "debug_step_into"; + pub const DEBUG_STEP_OUT: &'static str = "debug_step_out"; + pub const DEBUG_PAUSE: &'static str = "debug_pause"; + pub const DEBUG_STOP: &'static str = "debug_stop"; + pub const DEBUG_CONSOLE: &'static str = "debug_console"; + pub const DEBUG_DISCONNECT: &'static str = "debug_disconnect"; + pub const START: &'static str = "start"; + pub const RUN_ERRORS: &'static str = "run_errors"; + pub const UNSAVED: &'static str = "unsaved"; + pub const WARNING: &'static str = "warning"; + pub const TERMINAL: &'static str = "terminal"; + pub const SETTINGS: &'static str = "settings"; + pub const LIGHTBULB: &'static str = "lightbulb"; + pub const EXTENSIONS: &'static str = "extensions"; + pub const KEYBOARD: &'static str = "keyboard"; + pub const BREADCRUMB_SEPARATOR: &'static str = "breadcrumb_separator"; + pub const SYMBOL_COLOR: &'static str = "symbol_color"; + pub const TYPE_HIERARCHY: &'static str = "type_hierarchy"; + + pub const FILE: &'static str = "file"; + pub const FILE_EXPLORER: &'static str = "file_explorer"; + pub const FILE_PICKER_UP: &'static str = "file_picker_up"; + + pub const IMAGE_LOADING: &'static str = "image_loading"; + pub const IMAGE_ERROR: &'static str = "image_error"; + + pub const SCM: &'static str = "scm.icon"; + pub const SCM_DIFF_MODIFIED: &'static str = "scm.diff.modified"; + pub const SCM_DIFF_ADDED: &'static str = "scm.diff.added"; + pub const SCM_DIFF_REMOVED: &'static str = "scm.diff.removed"; + pub const SCM_DIFF_RENAMED: &'static str = "scm.diff.renamed"; + pub const SCM_CHANGE_ADD: &'static str = "scm.change.add"; + pub const SCM_CHANGE_REMOVE: &'static str = "scm.change.remove"; + + pub const FOLD: &'static str = "fold"; + pub const FOLD_UP: &'static str = "fold.up"; + pub const FOLD_DOWN: &'static str = "fold.down"; + + pub const PALETTE_MENU: &'static str = "palette.menu"; + + pub const DROPDOWN_ARROW: &'static str = "dropdown.arrow"; + + pub const PANEL_FOLD_UP: &'static str = "panel.fold-up"; + pub const PANEL_FOLD_DOWN: &'static str = "panel.fold-down"; + + pub const LOCATION_BACKWARD: &'static str = "location.backward"; + pub const LOCATION_FORWARD: &'static str = "location.forward"; + + pub const ITEM_OPENED: &'static str = "item.opened"; + pub const ITEM_CLOSED: &'static str = "item.closed"; + + pub const DIRECTORY_CLOSED: &'static str = "directory.closed"; + pub const DIRECTORY_OPENED: &'static str = "directory.opened"; + + pub const PANEL_RESTORE: &'static str = "panel.restore"; + pub const PANEL_MAXIMISE: &'static str = "panel.maximise"; + + pub const SPLIT_HORIZONTAL: &'static str = "split.horizontal"; + + pub const TAB_PREVIOUS: &'static str = "tab.previous"; + pub const TAB_NEXT: &'static str = "tab.next"; + + pub const SIDEBAR_LEFT: &'static str = "sidebar.left.on"; + pub const SIDEBAR_LEFT_OFF: &'static str = "sidebar.left.off"; + pub const SIDEBAR_RIGHT: &'static str = "sidebar.right.on"; + pub const SIDEBAR_RIGHT_OFF: &'static str = "sidebar.right.off"; + + pub const LAYOUT_PANEL: &'static str = "layout.panel.on"; + pub const LAYOUT_PANEL_OFF: &'static str = "layout.panel.off"; + + pub const SEARCH: &'static str = "search.icon"; + pub const SEARCH_CLEAR: &'static str = "search.clear"; + pub const SEARCH_FORWARD: &'static str = "search.forward"; + pub const SEARCH_BACKWARD: &'static str = "search.backward"; + pub const SEARCH_CASE_SENSITIVE: &'static str = "search.case_sensitive"; + pub const SEARCH_WHOLE_WORD: &'static str = "search.whole_word"; + pub const SEARCH_REGEX: &'static str = "search.regex"; + pub const SEARCH_REPLACE: &'static str = "search.replace"; + pub const SEARCH_REPLACE_ALL: &'static str = "search.replace_all"; + + pub const FILE_TYPE_CODE: &'static str = "file-code"; + pub const FILE_TYPE_MEDIA: &'static str = "file-media"; + pub const FILE_TYPE_BINARY: &'static str = "file-binary"; + pub const FILE_TYPE_ARCHIVE: &'static str = "file-zip"; + pub const FILE_TYPE_SUBMODULE: &'static str = "file-submodule"; + pub const FILE_TYPE_SYMLINK_FILE: &'static str = "file-symlink-file"; + pub const FILE_TYPE_SYMLINK_DIRECTORY: &'static str = "file-symlink-directory"; + + pub const DOCUMENT_SYMBOL: &'static str = "document_symbol"; + + pub const REFERENCES: &'static str = "references"; + + pub const IMPLEMENTATION: &'static str = "implementation"; + + pub const SYMBOL_KIND_ARRAY: &'static str = "symbol_kind.array"; + pub const SYMBOL_KIND_BOOLEAN: &'static str = "symbol_kind.boolean"; + pub const SYMBOL_KIND_CLASS: &'static str = "symbol_kind.class"; + pub const SYMBOL_KIND_CONSTANT: &'static str = "symbol_kind.constant"; + pub const SYMBOL_KIND_ENUM_MEMBER: &'static str = "symbol_kind.enum_member"; + pub const SYMBOL_KIND_ENUM: &'static str = "symbol_kind.enum"; + pub const SYMBOL_KIND_EVENT: &'static str = "symbol_kind.event"; + pub const SYMBOL_KIND_FIELD: &'static str = "symbol_kind.field"; + pub const SYMBOL_KIND_FILE: &'static str = "symbol_kind.file"; + pub const SYMBOL_KIND_FUNCTION: &'static str = "symbol_kind.function"; + pub const SYMBOL_KIND_INTERFACE: &'static str = "symbol_kind.interface"; + pub const SYMBOL_KIND_KEY: &'static str = "symbol_kind.key"; + pub const SYMBOL_KIND_METHOD: &'static str = "symbol_kind.method"; + pub const SYMBOL_KIND_NAMESPACE: &'static str = "symbol_kind.namespace"; + pub const SYMBOL_KIND_NUMBER: &'static str = "symbol_kind.number"; + pub const SYMBOL_KIND_OBJECT: &'static str = "symbol_kind.namespace"; + pub const SYMBOL_KIND_OPERATOR: &'static str = "symbol_kind.operator"; + pub const SYMBOL_KIND_PROPERTY: &'static str = "symbol_kind.property"; + pub const SYMBOL_KIND_STRING: &'static str = "symbol_kind.string"; + pub const SYMBOL_KIND_STRUCT: &'static str = "symbol_kind.struct"; + pub const SYMBOL_KIND_TYPE_PARAMETER: &'static str = + "symbol_kind.type_parameter"; + pub const SYMBOL_KIND_VARIABLE: &'static str = "symbol_kind.variable"; + + pub const COMPLETION_ITEM_KIND_CLASS: &'static str = + "completion_item_kind.class"; + pub const COMPLETION_ITEM_KIND_CONSTANT: &'static str = + "completion_item_kind.constant"; + pub const COMPLETION_ITEM_KIND_ENUM_MEMBER: &'static str = + "completion_item_kind.enum_member"; + pub const COMPLETION_ITEM_KIND_ENUM: &'static str = "completion_item_kind.enum"; + pub const COMPLETION_ITEM_KIND_FIELD: &'static str = + "completion_item_kind.field"; + pub const COMPLETION_ITEM_KIND_FUNCTION: &'static str = + "completion_item_kind.function"; + pub const COMPLETION_ITEM_KIND_INTERFACE: &'static str = + "completion_item_kind.interface"; + pub const COMPLETION_ITEM_KIND_KEYWORD: &'static str = + "completion_item_kind.keyword"; + pub const COMPLETION_ITEM_KIND_METHOD: &'static str = + "completion_item_kind.method"; + pub const COMPLETION_ITEM_KIND_MODULE: &'static str = + "completion_item_kind.module"; + pub const COMPLETION_ITEM_KIND_PROPERTY: &'static str = + "completion_item_kind.property"; + pub const COMPLETION_ITEM_KIND_SNIPPET: &'static str = + "completion_item_kind.snippet"; + pub const COMPLETION_ITEM_KIND_STRING: &'static str = + "completion_item_kind.string"; + pub const COMPLETION_ITEM_KIND_STRUCT: &'static str = + "completion_item_kind.struct"; + pub const COMPLETION_ITEM_KIND_VARIABLE: &'static str = + "completion_item_kind.variable"; +} diff --git a/lapce-app/src/config/icon_theme.rs b/lapce-app/src/config/icon_theme.rs new file mode 100644 index 0000000..262dffa --- /dev/null +++ b/lapce-app/src/config/icon_theme.rs @@ -0,0 +1,243 @@ +use std::{ + ffi::OsStr, + path::{Path, PathBuf}, +}; + +use indexmap::IndexMap; +use serde::{Deserialize, Serialize}; + +/// Returns the first item yielded from `items` if at least one item is yielded, all yielded items +/// are `Some`, and all yielded items compare equal, else returns `None`. +fn try_all_equal_value>>( + items: I, +) -> Option { + let mut items = items.into_iter(); + let first = items.next().flatten()?; + + items.try_fold(first, |initial_item, item| { + item.and_then(|item| (item == initial_item).then_some(initial_item)) + }) +} + +#[derive(Debug, Clone, Deserialize, Serialize, Default)] +#[serde(rename_all = "kebab-case", default)] +pub struct IconThemeConfig { + #[serde(skip)] + pub path: PathBuf, + pub name: String, + pub use_editor_color: Option, + pub ui: IndexMap, + pub foldername: IndexMap, + pub filename: IndexMap, + pub extension: IndexMap, +} + +impl IconThemeConfig { + /// If all paths in `paths` have the same file type (as determined by the file name or + /// extension), and there is an icon associated with that file type, returns the path of the + /// icon. + pub fn resolve_path_to_icon(&self, paths: &[&Path]) -> Option { + let file_names = paths + .iter() + .map(|path| path.file_name().and_then(OsStr::to_str)); + let file_name_icon = try_all_equal_value(file_names) + .and_then(|file_name| self.filename.get(file_name)); + + file_name_icon + .or_else(|| { + let extensions = paths + .iter() + .map(|path| path.extension().and_then(OsStr::to_str)); + + try_all_equal_value(extensions) + .and_then(|extension| self.extension.get(extension)) + }) + .map(|icon| self.path.join(icon)) + } +} + +#[cfg(test)] +mod tests { + use super::IconThemeConfig; + use crate::config::icon_theme::try_all_equal_value; + + #[test] + fn try_all_equal_value_empty_none() { + assert_eq!(Option::::None, try_all_equal_value([])); + } + + #[test] + fn try_all_equal_value_any_none_none() { + assert_eq!(Option::::None, try_all_equal_value([None])); + assert_eq!( + Option::::None, + try_all_equal_value([None, Some(1), Some(1)]) + ); + assert_eq!(Option::::None, try_all_equal_value([Some(0), None])); + assert_eq!( + Option::::None, + try_all_equal_value([Some(3), Some(3), None, Some(3)]) + ); + } + + #[test] + fn try_all_equal_value_any_different_none() { + assert_eq!(Option::::None, try_all_equal_value([Some(1), Some(2)])); + assert_eq!( + Option::::None, + try_all_equal_value([Some(1), Some(10), Some(1)]) + ); + assert_eq!( + Option::::None, + try_all_equal_value([Some(3), Some(3), Some(3), Some(3), Some(2)]) + ); + assert_eq!( + Option::::None, + try_all_equal_value([Some(5), Some(4), Some(4), Some(4), Some(4)]) + ); + assert_eq!( + Option::::None, + try_all_equal_value([Some(3), Some(0), Some(9), Some(20), Some(1)]) + ); + } + + #[test] + fn try_all_equal_value_all_same_some() { + assert_eq!(Option::::Some(1), try_all_equal_value([Some(1)])); + assert_eq!(Option::::Some(-2), try_all_equal_value([Some(-2); 2])); + assert_eq!(Option::::Some(0), try_all_equal_value([Some(0); 3])); + assert_eq!(Option::::Some(30), try_all_equal_value([Some(30); 57])); + } + + fn get_icon_theme_config() -> IconThemeConfig { + IconThemeConfig { + path: "icons".to_owned().into(), + filename: [("Makefile", "makefile.svg"), ("special.rs", "special.svg")] + .map(|(k, v)| (k.to_owned(), v.to_owned())) + .into(), + extension: [("rs", "rust.svg"), ("c", "c.svg"), ("py", "python.svg")] + .map(|(k, v)| (k.to_owned(), v.to_owned())) + .into(), + ..Default::default() + } + } + + #[test] + fn resolve_path_to_icon_no_paths_none() { + let icon_theme_config = get_icon_theme_config(); + + assert_eq!(None, icon_theme_config.resolve_path_to_icon(&[])); + } + + #[test] + fn resolve_path_to_icon_different_none() { + let icon_theme_config = get_icon_theme_config(); + + assert_eq!( + None, + icon_theme_config + .resolve_path_to_icon(&["foo.rs", "bar.c"].map(AsRef::as_ref)) + ); + assert_eq!( + None, + icon_theme_config.resolve_path_to_icon( + &["/some/path/main.py", "other/path.py", "dir1/./dir2/file.rs"] + .map(AsRef::as_ref) + ) + ); + assert_eq!( + None, + icon_theme_config.resolve_path_to_icon( + &["/root/Makefile", "dir/dir/special.rs", "../../main.rs"] + .map(AsRef::as_ref) + ) + ); + assert_eq!( + None, + icon_theme_config + .resolve_path_to_icon(&["main.c", "foo.txt"].map(AsRef::as_ref)) + ); + } + + #[test] + fn resolve_path_to_icon_no_match_none() { + let icon_theme_config = get_icon_theme_config(); + + assert_eq!( + None, + icon_theme_config.resolve_path_to_icon(&["foo"].map(AsRef::as_ref)) + ); + assert_eq!( + None, + icon_theme_config.resolve_path_to_icon( + &["/some/path/file.txt", "other/path.txt"].map(AsRef::as_ref) + ) + ); + assert_eq!( + None, + icon_theme_config.resolve_path_to_icon( + &["folder/file", "/home/user/file", "../../file"].map(AsRef::as_ref) + ) + ); + assert_eq!( + None, + icon_theme_config.resolve_path_to_icon(&[".."].map(AsRef::as_ref)) + ); + assert_eq!( + None, + icon_theme_config.resolve_path_to_icon(&["."].map(AsRef::as_ref)) + ); + } + + #[test] + fn resolve_path_to_icon_file_name_match_some() { + let icon_theme_config = get_icon_theme_config(); + + assert_eq!( + Some("icons/makefile.svg".to_owned().into()), + icon_theme_config.resolve_path_to_icon(&["Makefile"].map(AsRef::as_ref)) + ); + assert_eq!( + Some("icons/makefile.svg".to_owned().into()), + icon_theme_config.resolve_path_to_icon( + &[ + "baz/Makefile", + "/foo/bar/dir/Makefile", + ".././/././Makefile" + ] + .map(AsRef::as_ref) + ) + ); + assert_eq!( + Some("icons/special.svg".to_owned().into()), + icon_theme_config.resolve_path_to_icon( + &["dir/special.rs", "/dir1/dir2/..//./special.rs"] + .map(AsRef::as_ref) + ) + ); + } + + #[test] + fn resolve_path_to_icon_extension_match_some() { + let icon_theme_config = get_icon_theme_config(); + + assert_eq!( + Some("icons/python.svg".to_owned().into()), + icon_theme_config + .resolve_path_to_icon(&["source.py"].map(AsRef::as_ref)) + ); + assert_eq!( + Some("icons/rust.svg".to_owned().into()), + icon_theme_config.resolve_path_to_icon( + &["/home/user/main.rs", "../../special.rs.rs", "special.rs"] + .map(AsRef::as_ref) + ) + ); + assert_eq!( + Some("icons/c.svg".to_owned().into()), + icon_theme_config.resolve_path_to_icon( + &["/dir1/Makefile.c", "../main.c"].map(AsRef::as_ref) + ) + ); + } +} diff --git a/lapce-app/src/config/svg.rs b/lapce-app/src/config/svg.rs new file mode 100644 index 0000000..5a8ac83 --- /dev/null +++ b/lapce-app/src/config/svg.rs @@ -0,0 +1,65 @@ +use std::{ + collections::HashMap, + fs, + path::{Path, PathBuf}, +}; + +use include_dir::{Dir, include_dir}; + +use crate::config::LOGO; + +const CODICONS_ICONS_DIR: Dir = + include_dir!("$CARGO_MANIFEST_DIR/../icons/codicons"); +const LAPCE_ICONS_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/../icons/lapce"); + +#[derive(Debug, Clone)] +pub struct SvgStore { + svgs: HashMap, + svgs_on_disk: HashMap>, +} + +impl Default for SvgStore { + fn default() -> Self { + Self::new() + } +} + +impl SvgStore { + fn new() -> Self { + let mut svgs = HashMap::new(); + svgs.insert("lapce_logo".to_string(), LOGO.to_string()); + + Self { + svgs, + svgs_on_disk: HashMap::new(), + } + } + + pub fn logo_svg(&self) -> String { + self.svgs.get("lapce_logo").unwrap().clone() + } + + pub fn get_default_svg(&mut self, name: &str) -> String { + if !self.svgs.contains_key(name) { + let file = if name == "lapce_remote.svg" || name == "lapce_logo.svg" { + LAPCE_ICONS_DIR.get_file(name).unwrap() + } else { + CODICONS_ICONS_DIR + .get_file(name) + .unwrap_or_else(|| panic!("Failed to unwrap {name}")) + }; + let content = file.contents_utf8().unwrap(); + self.svgs.insert(name.to_string(), content.to_string()); + } + self.svgs.get(name).unwrap().clone() + } + + pub fn get_svg_on_disk(&mut self, path: &Path) -> Option { + if !self.svgs_on_disk.contains_key(path) { + let svg = fs::read_to_string(path).ok(); + self.svgs_on_disk.insert(path.to_path_buf(), svg); + } + + self.svgs_on_disk.get(path).unwrap().clone() + } +} diff --git a/lapce-app/src/config/terminal.rs b/lapce-app/src/config/terminal.rs new file mode 100644 index 0000000..2f151b4 --- /dev/null +++ b/lapce-app/src/config/terminal.rs @@ -0,0 +1,101 @@ +use std::{collections::HashMap, sync::Arc}; + +use floem::peniko::Color; +use serde::{Deserialize, Serialize}; +use structdesc::FieldNames; + +#[derive(FieldNames, Debug, Clone, Deserialize, Serialize, Default)] +#[serde(rename_all = "kebab-case")] +pub struct TerminalConfig { + #[field_names( + desc = "Set the terminal font family. If empty, it uses editor font family." + )] + pub font_family: String, + #[field_names( + desc = "Set the terminal font size, If 0, it uses editor font size." + )] + pub font_size: usize, + #[field_names( + desc = "Set the terminal line height, If 0, it uses editor line height" + )] + pub line_height: f64, + + #[field_names(skip)] + pub profiles: HashMap, + #[field_names(skip)] + pub default_profile: HashMap, + + #[serde(skip)] + #[field_names(skip)] + pub indexed_colors: Arc>, +} + +#[derive(FieldNames, Debug, Clone, Deserialize, Serialize, Default)] +#[serde(rename_all = "kebab-case")] +pub struct TerminalProfile { + #[field_names(desc = "Command to execute when launching terminal")] + pub command: Option, + #[field_names(desc = "Arguments passed to command")] + pub arguments: Option>, + #[field_names(desc = "Command to execute when launching terminal")] + pub workdir: Option, + #[field_names(desc = "Arguments passed to command")] + pub environment: Option>, +} + +impl TerminalConfig { + pub fn get_indexed_colors(&mut self) { + let mut indexed_colors = HashMap::new(); + // Build colors. + for r in 0..6 { + for g in 0..6 { + for b in 0..6 { + // Override colors 16..232 with the config (if present). + let index = 16 + r * 36 + g * 6 + b; + let color = Color::from_rgb8( + if r == 0 { 0 } else { r * 40 + 55 }, + if g == 0 { 0 } else { g * 40 + 55 }, + if b == 0 { 0 } else { b * 40 + 55 }, + ); + indexed_colors.insert(index, color); + } + } + } + + let index: u8 = 232; + + for i in 0..24 { + // Override colors 232..256 with the config (if present). + + let value = i * 10 + 8; + indexed_colors.insert(index + i, Color::from_rgb8(value, value, value)); + } + + self.indexed_colors = Arc::new(indexed_colors); + } + + pub fn get_default_profile( + &self, + ) -> Option { + let profile = self.profiles.get( + self.default_profile + .get(std::env::consts::OS) + .unwrap_or(&String::from("default")), + )?; + let workdir = if let Some(workdir) = &profile.workdir { + url::Url::parse(&workdir.display().to_string()).ok() + } else { + None + }; + + let profile = profile.clone(); + + Some(lapce_rpc::terminal::TerminalProfile { + name: std::env::consts::OS.to_string(), + command: profile.command, + arguments: profile.arguments, + workdir, + environment: profile.environment, + }) + } +} diff --git a/lapce-app/src/config/ui.rs b/lapce-app/src/config/ui.rs new file mode 100644 index 0000000..79b427b --- /dev/null +++ b/lapce-app/src/config/ui.rs @@ -0,0 +1,144 @@ +use floem::text::FamilyOwned; +use serde::{Deserialize, Serialize}; +use structdesc::FieldNames; + +#[derive(FieldNames, Debug, Clone, Deserialize, Serialize, Default)] +#[serde(rename_all = "kebab-case")] +pub struct UIConfig { + #[field_names(desc = "Set the UI scale. Defaults to 1.0")] + scale: f64, + + #[field_names( + desc = "Set the UI font family. If empty, it uses system default." + )] + pub font_family: String, + + #[field_names(desc = "Set the UI base font size")] + font_size: usize, + + #[field_names(desc = "Set the icon size in the UI")] + icon_size: usize, + + #[field_names( + desc = "Set the header height for panel header and editor tab header" + )] + header_height: usize, + + #[field_names(desc = "Set the height for status line")] + status_height: usize, + + #[field_names(desc = "Set the minimum width for editor tab")] + tab_min_width: usize, + + #[field_names( + desc = "Set whether the editor tab separator should be full height or the height of the content" + )] + pub tab_separator_height: TabSeparatorHeight, + + #[field_names(desc = "Set the width for scroll bar")] + scroll_width: usize, + + #[field_names(desc = "Controls the width of drop shadow in the UI")] + drop_shadow_width: usize, + + #[field_names(desc = "Controls the width of the command palette")] + palette_width: usize, + + #[field_names( + desc = "Set the hover font family. If empty, it uses the UI font family" + )] + hover_font_family: String, + #[field_names(desc = "Set the hover font size. If 0, uses the UI font size")] + hover_font_size: usize, + + #[field_names(desc = "Trim whitespace from search results")] + pub trim_search_results_whitespace: bool, + + #[field_names(desc = "Set the line height for list items")] + list_line_height: usize, + + #[field_names(desc = "Set position of the close button in editor tabs")] + pub tab_close_button: TabCloseButton, + + #[field_names(desc = "Display the Open Editors section in the explorer")] + pub open_editors_visible: bool, +} + +#[derive( + Debug, + Clone, + Copy, + Deserialize, + Serialize, + Default, + PartialEq, + Eq, + PartialOrd, + Ord, + strum_macros::VariantNames, +)] +pub enum TabCloseButton { + Left, + #[default] + Right, + Off, +} + +#[derive( + Debug, + Clone, + Copy, + Deserialize, + Serialize, + Default, + PartialEq, + Eq, + PartialOrd, + Ord, + strum_macros::VariantNames, +)] +pub enum TabSeparatorHeight { + #[default] + Content, + Full, +} + +impl UIConfig { + pub fn scale(&self) -> f64 { + self.scale.clamp(0.1, 4.0) + } + + pub fn font_size(&self) -> usize { + self.font_size.clamp(6, 32) + } + + pub fn font_family(&self) -> Vec { + FamilyOwned::parse_list(&self.font_family).collect() + } + + pub fn header_height(&self) -> usize { + let font_size = self.font_size(); + self.header_height.max(font_size) + } + + pub fn icon_size(&self) -> usize { + if self.icon_size == 0 { + self.font_size() + } else { + self.icon_size.clamp(6, 32) + } + } + + pub fn status_height(&self) -> usize { + let font_size = self.font_size(); + self.status_height.max(font_size) + } + + pub fn palette_width(&self) -> usize { + if self.palette_width == 0 { + 500 + } else { + self.palette_width.max(100) + } + } +} diff --git a/lapce-app/src/config/watcher.rs b/lapce-app/src/config/watcher.rs new file mode 100644 index 0000000..668c7b0 --- /dev/null +++ b/lapce-app/src/config/watcher.rs @@ -0,0 +1,55 @@ +use std::sync::{Arc, atomic::AtomicBool, mpsc::Sender}; + +pub struct ConfigWatcher { + tx: Sender<()>, + delay_handler: Arc, +} + +impl notify::EventHandler for ConfigWatcher { + fn handle_event(&mut self, event: notify::Result) { + match event { + Ok(event) => match event.kind { + notify::EventKind::Create(_) + | notify::EventKind::Modify(_) + | notify::EventKind::Remove(_) => { + if self + .delay_handler + .compare_exchange( + false, + true, + std::sync::atomic::Ordering::Relaxed, + std::sync::atomic::Ordering::Relaxed, + ) + .is_ok() + { + let config_mutex = self.delay_handler.clone(); + let tx = self.tx.clone(); + std::thread::spawn(move || { + std::thread::sleep(std::time::Duration::from_millis( + 500, + )); + if let Err(err) = tx.send(()) { + tracing::error!("{:?}", err); + } + config_mutex + .store(false, std::sync::atomic::Ordering::Relaxed); + }); + } + } + _ => {} + }, + Err(err) => { + tracing::error!("{:?}", err); + } + } + } +} + +impl ConfigWatcher { + pub fn new(tx: Sender<()>) -> Self { + Self { + tx, + delay_handler: Arc::new(AtomicBool::new(false)), + } + } +} diff --git a/lapce-app/src/db.rs b/lapce-app/src/db.rs new file mode 100644 index 0000000..fd56b05 --- /dev/null +++ b/lapce-app/src/db.rs @@ -0,0 +1,452 @@ +use std::{ + path::{Path, PathBuf}, + rc::Rc, + sync::Arc, +}; + +use anyhow::{Result, anyhow}; +use crossbeam_channel::{Sender, unbounded}; +use floem::{peniko::kurbo::Vec2, reactive::SignalGet}; +use lapce_core::directory::Directory; +use lapce_rpc::plugin::VoltID; +use sha2::{Digest, Sha256}; + +use crate::{ + app::{AppData, AppInfo}, + doc::DocInfo, + panel::{data::PanelOrder, kind::PanelKind}, + window::{WindowData, WindowInfo}, + window_tab::WindowTabData, + workspace::{LapceWorkspace, WorkspaceInfo}, +}; + +const APP: &str = "app"; +const WINDOW: &str = "window"; +const WORKSPACE_INFO: &str = "workspace_info"; +const WORKSPACE_FILES: &str = "workspace_files"; +const PANEL_ORDERS: &str = "panel_orders"; +const DISABLED_VOLTS: &str = "disabled_volts"; +const RECENT_WORKSPACES: &str = "recent_workspaces"; + +pub enum SaveEvent { + App(AppInfo), + Workspace(LapceWorkspace, WorkspaceInfo), + RecentWorkspace(LapceWorkspace), + Doc(DocInfo), + DisabledVolts(Vec), + WorkspaceDisabledVolts(Arc, Vec), + PanelOrder(PanelOrder), +} + +#[derive(Clone)] +pub struct LapceDb { + folder: PathBuf, + workspace_folder: PathBuf, + save_tx: Sender, +} + +impl LapceDb { + pub fn new() -> Result { + let folder = Directory::config_directory() + .ok_or_else(|| anyhow!("can't get config directory"))? + .join("db"); + let workspace_folder = folder.join("workspaces"); + if let Err(err) = std::fs::create_dir_all(&workspace_folder) { + tracing::error!("{:?}", err); + } + + let (save_tx, save_rx) = unbounded(); + + let db = Self { + save_tx, + workspace_folder, + folder, + }; + let local_db = db.clone(); + std::thread::Builder::new() + .name("SaveEventHandler".to_owned()) + .spawn(move || -> Result<()> { + loop { + let event = save_rx.recv()?; + match event { + SaveEvent::App(info) => { + if let Err(err) = local_db.insert_app_info(info) { + tracing::error!("{:?}", err); + } + } + SaveEvent::Workspace(workspace, info) => { + if let Err(err) = + local_db.insert_workspace(&workspace, &info) + { + tracing::error!("{:?}", err); + } + } + SaveEvent::RecentWorkspace(workspace) => { + if let Err(err) = + local_db.insert_recent_workspace(workspace) + { + tracing::error!("{:?}", err); + } + } + SaveEvent::Doc(info) => { + if let Err(err) = local_db.insert_doc(&info) { + tracing::error!("{:?}", err); + } + } + SaveEvent::DisabledVolts(volts) => { + if let Err(err) = local_db.insert_disabled_volts(volts) { + tracing::error!("{:?}", err); + } + } + SaveEvent::WorkspaceDisabledVolts(workspace, volts) => { + if let Err(err) = local_db + .insert_workspace_disabled_volts(workspace, volts) + { + tracing::error!("{:?}", err); + } + } + SaveEvent::PanelOrder(order) => { + if let Err(err) = local_db.insert_panel_orders(&order) { + tracing::error!("{:?}", err); + } + } + } + } + }) + .unwrap(); + Ok(db) + } + + pub fn get_disabled_volts(&self) -> Result> { + let volts = std::fs::read_to_string(self.folder.join(DISABLED_VOLTS))?; + let volts: Vec = serde_json::from_str(&volts)?; + Ok(volts) + } + + pub fn save_disabled_volts(&self, volts: Vec) { + if let Err(err) = self.save_tx.send(SaveEvent::DisabledVolts(volts)) { + tracing::error!("{:?}", err); + } + } + + pub fn save_workspace_disabled_volts( + &self, + workspace: Arc, + volts: Vec, + ) { + if let Err(err) = self + .save_tx + .send(SaveEvent::WorkspaceDisabledVolts(workspace, volts)) + { + tracing::error!("{:?}", err); + } + } + + pub fn insert_disabled_volts(&self, volts: Vec) -> Result<()> { + let volts = serde_json::to_string_pretty(&volts)?; + std::fs::write(self.folder.join(DISABLED_VOLTS), volts)?; + Ok(()) + } + + pub fn insert_workspace_disabled_volts( + &self, + workspace: Arc, + volts: Vec, + ) -> Result<()> { + let folder = self + .workspace_folder + .join(workspace_folder_name(&workspace)); + if let Err(err) = std::fs::create_dir_all(&folder) { + tracing::error!("{:?}", err); + } + + let volts = serde_json::to_string_pretty(&volts)?; + std::fs::write(folder.join(DISABLED_VOLTS), volts)?; + Ok(()) + } + + pub fn get_workspace_disabled_volts( + &self, + workspace: &LapceWorkspace, + ) -> Result> { + let folder = self.workspace_folder.join(workspace_folder_name(workspace)); + let volts = std::fs::read_to_string(folder.join(DISABLED_VOLTS))?; + let volts: Vec = serde_json::from_str(&volts)?; + Ok(volts) + } + + pub fn recent_workspaces(&self) -> Result> { + let workspaces = + std::fs::read_to_string(self.folder.join(RECENT_WORKSPACES))?; + let workspaces: Vec = serde_json::from_str(&workspaces)?; + Ok(workspaces) + } + + pub fn update_recent_workspace(&self, workspace: &LapceWorkspace) -> Result<()> { + if workspace.path.is_none() { + return Ok(()); + } + self.save_tx + .send(SaveEvent::RecentWorkspace(workspace.clone()))?; + Ok(()) + } + + fn insert_recent_workspace(&self, workspace: LapceWorkspace) -> Result<()> { + let mut workspaces = self.recent_workspaces().unwrap_or_default(); + + let mut exits = false; + for w in workspaces.iter_mut() { + if w.path == workspace.path && w.kind == workspace.kind { + w.last_open = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_secs(); + exits = true; + break; + } + } + if !exits { + let mut workspace = workspace; + workspace.last_open = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_secs(); + workspaces.push(workspace); + } + workspaces.sort_by_key(|w| -(w.last_open as i64)); + let workspaces = serde_json::to_string_pretty(&workspaces)?; + std::fs::write(self.folder.join(RECENT_WORKSPACES), workspaces)?; + + Ok(()) + } + + pub fn save_window_tab(&self, data: Rc) -> Result<()> { + let workspace = (*data.workspace).clone(); + let workspace_info = data.workspace_info(); + + self.save_tx + .send(SaveEvent::Workspace(workspace, workspace_info))?; + // self.insert_unsaved_buffer(main_split)?; + + Ok(()) + } + + pub fn get_workspace_info( + &self, + workspace: &LapceWorkspace, + ) -> Result { + let info = std::fs::read_to_string( + self.workspace_folder + .join(workspace_folder_name(workspace)) + .join(WORKSPACE_INFO), + )?; + let info: WorkspaceInfo = serde_json::from_str(&info)?; + Ok(info) + } + + fn insert_workspace( + &self, + workspace: &LapceWorkspace, + info: &WorkspaceInfo, + ) -> Result<()> { + let folder = self.workspace_folder.join(workspace_folder_name(workspace)); + if let Err(err) = std::fs::create_dir_all(&folder) { + tracing::error!("{:?}", err); + } + let workspace_info = serde_json::to_string_pretty(info)?; + std::fs::write(folder.join(WORKSPACE_INFO), workspace_info)?; + Ok(()) + } + + pub fn save_app(&self, data: &AppData) -> Result<()> { + let windows = data.windows.get_untracked(); + for (_, window) in &windows { + if let Err(err) = self.save_window(window.clone()) { + tracing::error!("{:?}", err); + } + } + + let info = AppInfo { + windows: windows + .iter() + .map(|(_, window_data)| window_data.info()) + .collect(), + }; + if info.windows.is_empty() { + return Ok(()); + } + + self.save_tx.send(SaveEvent::App(info))?; + + Ok(()) + } + + pub fn insert_app_info(&self, info: AppInfo) -> Result<()> { + let info = serde_json::to_string_pretty(&info)?; + std::fs::write(self.folder.join(APP), info)?; + Ok(()) + } + + pub fn insert_app(&self, data: AppData) -> Result<()> { + let windows = data.windows.get_untracked(); + if windows.is_empty() { + // insert_app is called after window is closed, so we don't want to store it + return Ok(()); + } + for (_, window) in &windows { + if let Err(err) = self.insert_window(window.clone()) { + tracing::error!("{:?}", err); + } + } + let info = AppInfo { + windows: windows + .iter() + .map(|(_, window_data)| window_data.info()) + .collect(), + }; + self.insert_app_info(info)?; + Ok(()) + } + + pub fn get_app(&self) -> Result { + let info = std::fs::read_to_string(self.folder.join(APP))?; + let mut info: AppInfo = serde_json::from_str(&info)?; + for window in info.windows.iter_mut() { + if window.size.width < 10.0 { + window.size.width = 800.0; + } + if window.size.height < 10.0 { + window.size.height = 600.0; + } + } + Ok(info) + } + + pub fn get_window(&self) -> Result { + let info = std::fs::read_to_string(self.folder.join(WINDOW))?; + let mut info: WindowInfo = serde_json::from_str(&info)?; + if info.size.width < 10.0 { + info.size.width = 800.0; + } + if info.size.height < 10.0 { + info.size.height = 600.0; + } + Ok(info) + } + + pub fn save_window(&self, data: WindowData) -> Result<()> { + for (_, window_tab) in data.window_tabs.get_untracked().into_iter() { + if let Err(err) = self.save_window_tab(window_tab) { + tracing::error!("{:?}", err); + } + } + Ok(()) + } + + pub fn insert_window(&self, data: WindowData) -> Result<()> { + for (_, window_tab) in data.window_tabs.get_untracked().into_iter() { + if let Err(err) = self.insert_window_tab(window_tab) { + tracing::error!("{:?}", err); + } + } + let info = data.info(); + let info = serde_json::to_string_pretty(&info)?; + std::fs::write(self.folder.join(WINDOW), info)?; + Ok(()) + } + + pub fn insert_window_tab(&self, data: Rc) -> Result<()> { + let workspace = (*data.workspace).clone(); + let workspace_info = data.workspace_info(); + + self.insert_workspace(&workspace, &workspace_info)?; + // self.insert_unsaved_buffer(main_split)?; + + Ok(()) + } + + pub fn get_panel_orders(&self) -> Result { + let panel_orders = std::fs::read_to_string(self.folder.join(PANEL_ORDERS))?; + let mut panel_orders: PanelOrder = serde_json::from_str(&panel_orders)?; + + use strum::IntoEnumIterator; + for kind in PanelKind::iter() { + if kind.position(&panel_orders).is_none() { + let panels = + panel_orders.entry(kind.default_position()).or_default(); + panels.push_back(kind); + } + } + + Ok(panel_orders) + } + + pub fn save_panel_orders(&self, order: PanelOrder) { + if let Err(err) = self.save_tx.send(SaveEvent::PanelOrder(order)) { + tracing::error!("{:?}", err); + } + } + + fn insert_panel_orders(&self, order: &PanelOrder) -> Result<()> { + let info = serde_json::to_string_pretty(order)?; + std::fs::write(self.folder.join(PANEL_ORDERS), info)?; + Ok(()) + } + + pub fn save_doc_position( + &self, + workspace: &LapceWorkspace, + path: PathBuf, + cursor_offset: usize, + scroll_offset: Vec2, + ) { + let info = DocInfo { + workspace: workspace.clone(), + path, + scroll_offset: (scroll_offset.x, scroll_offset.y), + cursor_offset, + }; + if let Err(err) = self.save_tx.send(SaveEvent::Doc(info)) { + tracing::error!("{:?}", err); + } + } + + fn insert_doc(&self, info: &DocInfo) -> Result<()> { + let folder = self + .workspace_folder + .join(workspace_folder_name(&info.workspace)) + .join(WORKSPACE_FILES); + if let Err(err) = std::fs::create_dir_all(&folder) { + tracing::error!("{:?}", err); + } + let contents = serde_json::to_string_pretty(info)?; + std::fs::write(folder.join(doc_path_name(&info.path)), contents)?; + Ok(()) + } + + pub fn get_doc_info( + &self, + workspace: &LapceWorkspace, + path: &Path, + ) -> Result { + let folder = self + .workspace_folder + .join(workspace_folder_name(workspace)) + .join(WORKSPACE_FILES); + let info = std::fs::read_to_string(folder.join(doc_path_name(path)))?; + let info: DocInfo = serde_json::from_str(&info)?; + Ok(info) + } +} + +fn workspace_folder_name(workspace: &LapceWorkspace) -> String { + url::form_urlencoded::Serializer::new(String::new()) + .append_key_only(&workspace.to_string()) + .finish() +} + +fn doc_path_name(path: &Path) -> String { + let mut hasher = Sha256::new(); + hasher.update(path.to_string_lossy().as_bytes()); + format!("{:x}", hasher.finalize()) +} diff --git a/lapce-app/src/debug.rs b/lapce-app/src/debug.rs new file mode 100644 index 0000000..4ecf75d --- /dev/null +++ b/lapce-app/src/debug.rs @@ -0,0 +1,640 @@ +use std::{ + collections::{BTreeMap, HashMap}, + fmt::Display, + path::PathBuf, + rc::Rc, + time::Instant, +}; + +use floem::{ + ext_event::create_ext_action, + reactive::{Memo, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, + views::VirtualVector, +}; +use lapce_rpc::{ + dap_types::{ + self, DapId, RunDebugConfig, SourceBreakpoint, StackFrame, Stopped, + ThreadId, Variable, + }, + proxy::ProxyResponse, + terminal::TermId, +}; +use serde::{Deserialize, Serialize}; + +use crate::{ + command::InternalCommand, + editor::location::{EditorLocation, EditorPosition}, + window_tab::CommonData, +}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum RunDebugMode { + Run, + Debug, +} + +impl Display for RunDebugMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let s = match self { + RunDebugMode::Run => "Run", + RunDebugMode::Debug => "Debug", + }; + f.write_str(s) + } +} + +#[derive(Clone)] +pub struct RunDebugProcess { + pub mode: RunDebugMode, + pub config: RunDebugConfig, + pub stopped: bool, + pub created: Instant, + pub is_prelaunch: bool, +} + +#[derive(Deserialize, Serialize)] +pub struct RunDebugConfigs { + pub configs: Vec, +} + +#[derive(Clone)] +pub struct RunDebugData { + pub active_term: RwSignal>, + pub daps: RwSignal>, + pub breakpoints: RwSignal>>, +} + +impl RunDebugData { + pub fn new( + cx: Scope, + breakpoints: RwSignal>>, + ) -> Self { + let active_term: RwSignal> = cx.create_rw_signal(None); + let daps: RwSignal> = + cx.create_rw_signal(im::HashMap::new()); + + Self { + active_term, + daps, + breakpoints, + } + } + + pub fn source_breakpoints(&self) -> HashMap> { + self.breakpoints + .get_untracked() + .iter() + .map(|(path, breakpoints)| { + ( + path.to_path_buf(), + breakpoints + .iter() + .filter_map(|(_, b)| { + if b.active { + Some(SourceBreakpoint { + line: b.line + 1, + column: None, + condition: None, + hit_condition: None, + log_message: None, + }) + } else { + None + } + }) + .collect(), + ) + }) + .collect() + } +} + +#[derive(Clone, PartialEq)] +pub struct StackTraceData { + pub expanded: RwSignal, + pub frames: RwSignal>, + pub frames_shown: usize, +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct LapceBreakpoint { + pub id: Option, + pub verified: bool, + pub message: Option, + pub line: usize, + pub offset: usize, + pub dap_line: Option, + pub active: bool, +} + +#[derive(Clone, PartialEq, Eq)] +#[allow(clippy::large_enum_variant)] +pub enum ScopeOrVar { + Scope(dap_types::Scope), + Var(dap_types::Variable), +} + +impl Default for ScopeOrVar { + fn default() -> Self { + ScopeOrVar::Scope(dap_types::Scope::default()) + } +} + +impl ScopeOrVar { + pub fn name(&self) -> &str { + match self { + ScopeOrVar::Scope(scope) => &scope.name, + ScopeOrVar::Var(var) => &var.name, + } + } + + pub fn value(&self) -> Option<&str> { + match self { + ScopeOrVar::Scope(_) => None, + ScopeOrVar::Var(var) => Some(&var.value), + } + } + + pub fn ty(&self) -> Option<&str> { + match self { + ScopeOrVar::Scope(_) => None, + ScopeOrVar::Var(var) => var.ty.as_deref(), + } + } + + pub fn reference(&self) -> usize { + match self { + ScopeOrVar::Scope(scope) => scope.variables_reference, + ScopeOrVar::Var(var) => var.variables_reference, + } + } +} + +#[derive(Clone, Default)] +pub struct DapVariable { + pub item: ScopeOrVar, + pub parent: Vec, + pub expanded: bool, + pub read: bool, + pub children: Vec, + pub children_expanded_count: usize, +} + +#[derive(Clone)] +pub struct DapData { + pub term_id: TermId, + pub dap_id: DapId, + pub stopped: RwSignal, + pub thread_id: RwSignal>, + pub stack_traces: RwSignal>, + pub variables_id: RwSignal, + pub variables: RwSignal, + pub breakline: Memo>, + pub common: Rc, +} + +impl DapData { + pub fn new( + cx: Scope, + dap_id: DapId, + term_id: TermId, + common: Rc, + ) -> Self { + let stopped = cx.create_rw_signal(false); + let thread_id = cx.create_rw_signal(None); + let stack_traces: RwSignal> = + cx.create_rw_signal(BTreeMap::new()); + let breakline = cx.create_memo(move |_| { + let thread_id = thread_id.get(); + if let Some(thread_id) = thread_id { + let trace = stack_traces + .with(|stack_traces| stack_traces.get(&thread_id).cloned()); + + if let Some(trace) = trace { + let breakline = trace.frames.with(|f| { + f.get(0) + .and_then(|f| { + f.source + .as_ref() + .map(|s| (f.line.saturating_sub(1), s)) + }) + .and_then(|(line, s)| s.path.clone().map(|p| (line, p))) + }); + return breakline; + } + None + } else { + None + } + }); + Self { + term_id, + dap_id, + stopped, + thread_id, + stack_traces, + variables_id: cx.create_rw_signal(0), + variables: cx.create_rw_signal(DapVariable { + item: ScopeOrVar::Scope(dap_types::Scope::default()), + parent: Vec::new(), + expanded: true, + read: true, + children: Vec::new(), + children_expanded_count: 0, + }), + breakline, + common, + } + } + + pub fn stopped( + &self, + cx: Scope, + stopped: &Stopped, + stack_traces: &HashMap>, + variables: &[(dap_types::Scope, Vec)], + ) { + self.stopped.set(true); + self.thread_id.update(|thread_id| { + *thread_id = Some(stopped.thread_id.unwrap_or_default()); + }); + + let main_thread_id = self.thread_id.get_untracked(); + let mut current_stack_traces = self.stack_traces.get_untracked(); + current_stack_traces.retain(|t, _| stack_traces.contains_key(t)); + for (thread_id, frames) in stack_traces { + let is_main_thread = main_thread_id.as_ref() == Some(thread_id); + if is_main_thread { + if let Some(frame) = frames.first() { + if let Some(path) = + frame.source.as_ref().and_then(|source| source.path.clone()) + { + self.common.internal_command.send( + InternalCommand::JumpToLocation { + location: EditorLocation { + path, + position: Some(EditorPosition::Line( + frame.line.saturating_sub(1), + )), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }, + }, + ); + } + } + } + if let Some(current) = current_stack_traces.get_mut(thread_id) { + current.frames.set(frames.into()); + if is_main_thread { + current.expanded.set(true); + } + } else { + current_stack_traces.insert( + *thread_id, + StackTraceData { + expanded: cx.create_rw_signal(is_main_thread), + frames: cx.create_rw_signal(frames.into()), + frames_shown: 20, + }, + ); + } + } + self.stack_traces.set(current_stack_traces); + self.variables.update(|dap_var| { + dap_var.children = variables + .iter() + .enumerate() + .map(|(i, (scope, vars))| DapVariable { + item: ScopeOrVar::Scope(scope.to_owned()), + parent: Vec::new(), + expanded: i == 0, + read: true, + children: vars + .iter() + .map(|var| DapVariable { + item: ScopeOrVar::Var(var.to_owned()), + parent: vec![scope.variables_reference], + expanded: false, + read: false, + children: Vec::new(), + children_expanded_count: 0, + }) + .collect(), + children_expanded_count: if i == 0 { vars.len() } else { 0 }, + }) + .collect(); + dap_var.children_expanded_count = dap_var + .children + .iter() + .map(|v| v.children_expanded_count + 1) + .sum::(); + }); + } + + pub fn toggle_expand(&self, parent: Vec, reference: usize) { + self.variables_id.update(|id| { + *id += 1; + }); + self.variables.update(|variables| { + if let Some(var) = variables.get_var_mut(&parent, reference) { + if var.expanded { + var.expanded = false; + variables.update_count_recursive(&parent, reference); + } else { + var.expanded = true; + if !var.read { + var.read = true; + self.read_var_children(&parent, reference); + } else { + variables.update_count_recursive(&parent, reference); + } + } + } + }); + } + + fn read_var_children(&self, parent: &[usize], reference: usize) { + let root = self.variables; + let parent = parent.to_vec(); + let variables_id = self.variables_id; + + let send = create_ext_action(self.common.scope, move |result| { + if let Ok(ProxyResponse::DapVariableResponse { variables }) = result { + variables_id.update(|id| { + *id += 1; + }); + root.update(|root| { + if let Some(var) = root.get_var_mut(&parent, reference) { + let mut new_parent = parent.clone(); + new_parent.push(reference); + var.read = true; + var.children = variables + .into_iter() + .map(|v| DapVariable { + item: ScopeOrVar::Var(v), + parent: new_parent.clone(), + expanded: false, + read: false, + children: Vec::new(), + children_expanded_count: 0, + }) + .collect(); + root.update_count_recursive(&parent, reference); + } + }); + } + }); + self.common + .proxy + .dap_variable(self.dap_id, reference, move |result| { + send(result); + }); + } +} + +pub struct DapVariableViewdata { + pub item: ScopeOrVar, + pub parent: Vec, + pub expanded: bool, + pub level: usize, +} + +impl VirtualVector for DapVariable { + fn total_len(&self) -> usize { + self.children_expanded_count + } + + fn slice( + &mut self, + range: std::ops::Range, + ) -> impl Iterator { + let min = range.start; + let max = range.end; + let mut i = 0; + let mut view_items = Vec::new(); + for item in self.children.iter() { + i = item.append_view_slice(&mut view_items, min, max, i + 1, 0); + if i > max { + return view_items.into_iter(); + } + } + + view_items.into_iter() + } +} + +impl DapVariable { + pub fn append_view_slice( + &self, + view_items: &mut Vec, + min: usize, + max: usize, + current: usize, + level: usize, + ) -> usize { + if current > max { + return current; + } + if current + self.children_expanded_count < min { + return current + self.children_expanded_count; + } + + let mut i = current; + if current >= min { + view_items.push(DapVariableViewdata { + item: self.item.clone(), + parent: self.parent.clone(), + expanded: self.expanded, + level, + }); + } + + if self.expanded { + for item in self.children.iter() { + i = item.append_view_slice(view_items, min, max, i + 1, level + 1); + if i > max { + return i; + } + } + } + i + } + + pub fn get_var_mut( + &mut self, + parent: &[usize], + reference: usize, + ) -> Option<&mut DapVariable> { + let parent = if parent.is_empty() { + self + } else { + parent.iter().try_fold(self, |item, parent| { + item.children + .iter_mut() + .find(|c| c.item.reference() == *parent) + })? + }; + parent + .children + .iter_mut() + .find(|c| c.item.reference() == reference) + } + + pub fn update_count_recursive(&mut self, parent: &[usize], reference: usize) { + let mut parent = parent.to_vec(); + self.update_count(&parent, reference); + while let Some(reference) = parent.pop() { + self.update_count(&parent, reference); + } + self.children_expanded_count = self + .children + .iter() + .map(|item| item.children_expanded_count + 1) + .sum::(); + } + + pub fn update_count( + &mut self, + parent: &[usize], + reference: usize, + ) -> Option<()> { + let var = self.get_var_mut(parent, reference)?; + var.children_expanded_count = if var.expanded { + var.children + .iter() + .map(|item| item.children_expanded_count + 1) + .sum::() + } else { + 0 + }; + Some(()) + } +} + +#[cfg(test)] +mod tests { + use lapce_rpc::dap_types::{Scope, Variable}; + + use super::{DapVariable, ScopeOrVar}; + + #[test] + fn test_update_count() { + let variables = [ + ( + Scope { + variables_reference: 0, + ..Default::default() + }, + vec![ + Variable { + variables_reference: 3, + ..Default::default() + }, + Variable { + variables_reference: 4, + ..Default::default() + }, + ], + ), + ( + Scope { + variables_reference: 1, + ..Default::default() + }, + vec![ + Variable { + variables_reference: 5, + ..Default::default() + }, + Variable { + variables_reference: 6, + ..Default::default() + }, + ], + ), + ( + Scope { + variables_reference: 2, + ..Default::default() + }, + vec![ + Variable { + variables_reference: 7, + ..Default::default() + }, + Variable { + variables_reference: 8, + ..Default::default() + }, + ], + ), + ]; + + let mut root = DapVariable { + item: ScopeOrVar::Scope(Scope::default()), + parent: Vec::new(), + expanded: true, + read: true, + children: variables + .iter() + .map(|(scope, vars)| DapVariable { + item: ScopeOrVar::Scope(scope.to_owned()), + parent: Vec::new(), + expanded: true, + read: true, + children: vars + .iter() + .map(|var| DapVariable { + item: ScopeOrVar::Var(var.to_owned()), + parent: vec![scope.variables_reference], + expanded: false, + read: false, + children: Vec::new(), + children_expanded_count: 0, + }) + .collect(), + children_expanded_count: vars.len(), + }) + .collect(), + children_expanded_count: 0, + }; + root.children_expanded_count = root + .children + .iter() + .map(|v| v.children_expanded_count + 1) + .sum::(); + assert_eq!(root.children_expanded_count, 9); + + let var = root.get_var_mut(&[0], 3).unwrap(); + var.expanded = true; + var.read = true; + var.children = [ + Variable { + variables_reference: 9, + ..Default::default() + }, + Variable { + variables_reference: 10, + ..Default::default() + }, + ] + .iter() + .map(|var| DapVariable { + item: ScopeOrVar::Var(var.to_owned()), + parent: vec![0, 3], + expanded: false, + read: false, + children: Vec::new(), + children_expanded_count: 0, + }) + .collect(); + root.update_count_recursive(&[0], 3); + let var = root.get_var_mut(&[0], 3).unwrap(); + assert_eq!(var.children_expanded_count, 2); + let var = root.get_var_mut(&[], 0).unwrap(); + assert_eq!(var.children_expanded_count, 4); + assert_eq!(root.children_expanded_count, 11); + } +} diff --git a/lapce-app/src/doc.rs b/lapce-app/src/doc.rs new file mode 100644 index 0000000..f70e308 --- /dev/null +++ b/lapce-app/src/doc.rs @@ -0,0 +1,2239 @@ +use std::{ + borrow::Cow, + cell::RefCell, + collections::HashMap, + ops::Range, + path::{Path, PathBuf}, + rc::Rc, + sync::{ + Arc, + atomic::{self, AtomicUsize}, + }, + time::Duration, +}; + +use floem::{ + ViewId, + action::exec_after, + ext_event::create_ext_action, + keyboard::Modifiers, + peniko::Color, + reactive::{ + ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith, batch, + }, + text::{Attrs, AttrsList, FamilyOwned, TextLayout}, + views::editor::{ + CursorInfo, Editor, EditorStyle, + actions::CommonAction, + command::{Command, CommandExecuted}, + id::EditorId, + layout::{LineExtraStyle, TextLayoutLine}, + phantom_text::{PhantomText, PhantomTextKind, PhantomTextLine}, + text::{Document, DocumentPhantom, PreeditData, Styling, SystemClipboard}, + view::{ScreenLines, ScreenLinesBase}, + }, +}; +use itertools::Itertools; +use lapce_core::{ + buffer::{ + Buffer, InvalLines, + diff::{DiffLines, rope_diff}, + rope_text::RopeText, + }, + char_buffer::CharBuffer, + command::EditCommand, + cursor::{Cursor, CursorAffinity}, + editor::{Action, EditConf, EditType}, + indent::IndentStyle, + language::LapceLanguage, + line_ending::LineEnding, + mode::MotionMode, + register::Register, + rope_text_pos::RopeTextPosition, + selection::{InsertDrift, Selection}, + style::line_styles, + syntax::{BracketParser, Syntax, edit::SyntaxEdit}, + word::{CharClassification, WordCursor, get_char_property}, +}; +use lapce_rpc::{ + buffer::BufferId, + plugin::PluginId, + proxy::ProxyResponse, + style::{LineStyle, LineStyles, Style}, +}; +use lapce_xi_rope::{ + Interval, Rope, RopeDelta, Transformer, + spans::{Spans, SpansBuilder}, +}; +use lsp_types::{ + CodeActionOrCommand, CodeLens, Diagnostic, DiagnosticSeverity, + DocumentSymbolResponse, InlayHint, InlayHintLabel, TextEdit, +}; +use serde::{Deserialize, Serialize}; +use smallvec::SmallVec; + +use crate::{ + command::{CommandKind, LapceCommand}, + config::{LapceConfig, color::LapceColor}, + editor::{EditorData, compute_screen_lines, gutter::FoldingRanges}, + find::{Find, FindProgress, FindResult}, + history::DocumentHistory, + keypress::KeyPressFocus, + main_split::Editors, + panel::{ + document_symbol::{SymbolData, SymbolInformationItemData}, + kind::PanelKind, + }, + window_tab::{CommonData, Focus}, + workspace::LapceWorkspace, +}; + +#[derive(Clone, Debug)] +pub struct DiagnosticData { + pub expanded: RwSignal, + pub diagnostics: RwSignal>, + pub diagnostics_span: RwSignal>, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct EditorDiagnostic { + pub range: Option<(usize, usize)>, + pub diagnostic: Diagnostic, +} + +#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] +pub struct DocHistory { + pub path: PathBuf, + pub version: String, +} + +#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] +pub enum DocContent { + /// A file at some location. This can be a remote path. + File { path: PathBuf, read_only: bool }, + /// A local document, which doesn't need to be sync to the disk. + Local, + /// A document of an old version in the source control + History(DocHistory), + /// A new file which doesn't exist in the file system + Scratch { id: BufferId, name: String }, +} + +impl DocContent { + pub fn is_local(&self) -> bool { + matches!(self, DocContent::Local) + } + + pub fn is_file(&self) -> bool { + matches!(self, DocContent::File { .. }) + } + + pub fn read_only(&self) -> bool { + match self { + DocContent::File { read_only, .. } => *read_only, + DocContent::Local => false, + DocContent::History(_) => true, + DocContent::Scratch { .. } => false, + } + } + + pub fn path(&self) -> Option<&PathBuf> { + match self { + DocContent::File { path, .. } => Some(path), + DocContent::Local => None, + DocContent::History(_) => None, + DocContent::Scratch { .. } => None, + } + } +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct DocInfo { + pub workspace: LapceWorkspace, + pub path: PathBuf, + pub scroll_offset: (f64, f64), + pub cursor_offset: usize, +} + +/// (Offset -> (Plugin the code actions are from, Code Actions)) +pub type CodeActions = + im::HashMap)>; + +pub type AllCodeLens = im::HashMap)>; + +#[derive(Clone)] +pub struct Doc { + pub scope: Scope, + pub buffer_id: BufferId, + pub content: RwSignal, + pub cache_rev: RwSignal, + /// Whether the buffer's content has been loaded/initialized into the buffer. + pub loaded: RwSignal, + pub buffer: RwSignal, + pub syntax: RwSignal, + semantic_styles: RwSignal>>, + /// Inlay hints for the document + pub inlay_hints: RwSignal>>, + /// Current completion lens text, if any. + /// This will be displayed even on views that are not focused. + pub completion_lens: RwSignal>, + /// (line, col) + pub completion_pos: RwSignal<(usize, usize)>, + + /// Current inline completion text, if any. + /// This will be displayed even on views that are not focused. + pub inline_completion: RwSignal>, + /// (line, col) + pub inline_completion_pos: RwSignal<(usize, usize)>, + + /// (Offset -> (Plugin the code actions are from, Code Actions)) + pub code_actions: RwSignal, + + pub code_lens: RwSignal, + + pub folding_ranges: RwSignal, + + /// Stores information about different versions of the document from source control. + histories: RwSignal>, + pub head_changes: RwSignal>, + + line_styles: Rc>, + pub parser: Rc>, + + /// A cache for the sticky headers which maps a line to the lines it should show in the header. + pub sticky_headers: Rc>>>>, + + pub preedit: PreeditData, + + pub find_result: FindResult, + + /// The diagnostics for the document + pub diagnostics: DiagnosticData, + + editors: Editors, + pub common: Rc, + + pub document_symbol_data: RwSignal>, +} +impl Doc { + pub fn new( + cx: Scope, + path: PathBuf, + diagnostics: DiagnosticData, + editors: Editors, + common: Rc, + ) -> Self { + let syntax = Syntax::init(&path); + let config = common.config.get_untracked(); + Doc { + scope: cx, + buffer_id: BufferId::next(), + buffer: cx.create_rw_signal(Buffer::new("")), + syntax: cx.create_rw_signal(syntax), + line_styles: Rc::new(RefCell::new(HashMap::new())), + parser: Rc::new(RefCell::new(BracketParser::new( + String::new(), + config.editor.bracket_pair_colorization, + config.editor.bracket_colorization_limit, + ))), + semantic_styles: cx.create_rw_signal(None), + inlay_hints: cx.create_rw_signal(None), + diagnostics, + completion_lens: cx.create_rw_signal(None), + completion_pos: cx.create_rw_signal((0, 0)), + inline_completion: cx.create_rw_signal(None), + inline_completion_pos: cx.create_rw_signal((0, 0)), + cache_rev: cx.create_rw_signal(0), + content: cx.create_rw_signal(DocContent::File { + path, + read_only: false, + }), + loaded: cx.create_rw_signal(false), + histories: cx.create_rw_signal(im::HashMap::new()), + head_changes: cx.create_rw_signal(im::Vector::new()), + sticky_headers: Rc::new(RefCell::new(HashMap::new())), + code_actions: cx.create_rw_signal(im::HashMap::new()), + find_result: FindResult::new(cx), + preedit: PreeditData::new(cx), + editors, + common, + code_lens: cx.create_rw_signal(im::HashMap::new()), + document_symbol_data: cx.create_rw_signal(None), + folding_ranges: cx.create_rw_signal(FoldingRanges::default()), + } + } + + pub fn new_local(cx: Scope, editors: Editors, common: Rc) -> Doc { + Self::new_content(cx, DocContent::Local, editors, common) + } + + pub fn new_content( + cx: Scope, + content: DocContent, + editors: Editors, + common: Rc, + ) -> Doc { + let cx = cx.create_child(); + let config = common.config.get_untracked(); + Self { + scope: cx, + buffer_id: BufferId::next(), + buffer: cx.create_rw_signal(Buffer::new("")), + syntax: cx.create_rw_signal(Syntax::plaintext()), + line_styles: Rc::new(RefCell::new(HashMap::new())), + parser: Rc::new(RefCell::new(BracketParser::new( + String::new(), + config.editor.bracket_pair_colorization, + config.editor.bracket_colorization_limit, + ))), + semantic_styles: cx.create_rw_signal(None), + inlay_hints: cx.create_rw_signal(None), + diagnostics: DiagnosticData { + expanded: cx.create_rw_signal(true), + diagnostics: cx.create_rw_signal(im::Vector::new()), + diagnostics_span: cx.create_rw_signal(SpansBuilder::new(0).build()), + }, + completion_lens: cx.create_rw_signal(None), + completion_pos: cx.create_rw_signal((0, 0)), + inline_completion: cx.create_rw_signal(None), + inline_completion_pos: cx.create_rw_signal((0, 0)), + cache_rev: cx.create_rw_signal(0), + content: cx.create_rw_signal(content), + histories: cx.create_rw_signal(im::HashMap::new()), + head_changes: cx.create_rw_signal(im::Vector::new()), + sticky_headers: Rc::new(RefCell::new(HashMap::new())), + loaded: cx.create_rw_signal(true), + find_result: FindResult::new(cx), + code_actions: cx.create_rw_signal(im::HashMap::new()), + preedit: PreeditData::new(cx), + editors, + common, + code_lens: cx.create_rw_signal(im::HashMap::new()), + document_symbol_data: cx.create_rw_signal(None), + folding_ranges: cx.create_rw_signal(FoldingRanges::default()), + } + } + + pub fn new_history( + cx: Scope, + content: DocContent, + editors: Editors, + common: Rc, + ) -> Doc { + let config = common.config.get_untracked(); + let syntax = if let DocContent::History(history) = &content { + Syntax::init(&history.path) + } else { + Syntax::plaintext() + }; + Self { + scope: cx, + buffer_id: BufferId::next(), + buffer: cx.create_rw_signal(Buffer::new("")), + syntax: cx.create_rw_signal(syntax), + line_styles: Rc::new(RefCell::new(HashMap::new())), + parser: Rc::new(RefCell::new(BracketParser::new( + String::new(), + config.editor.bracket_pair_colorization, + config.editor.bracket_colorization_limit, + ))), + semantic_styles: cx.create_rw_signal(None), + inlay_hints: cx.create_rw_signal(None), + diagnostics: DiagnosticData { + expanded: cx.create_rw_signal(true), + diagnostics: cx.create_rw_signal(im::Vector::new()), + diagnostics_span: cx.create_rw_signal(SpansBuilder::new(0).build()), + }, + completion_lens: cx.create_rw_signal(None), + completion_pos: cx.create_rw_signal((0, 0)), + inline_completion: cx.create_rw_signal(None), + inline_completion_pos: cx.create_rw_signal((0, 0)), + cache_rev: cx.create_rw_signal(0), + content: cx.create_rw_signal(content), + sticky_headers: Rc::new(RefCell::new(HashMap::new())), + loaded: cx.create_rw_signal(true), + histories: cx.create_rw_signal(im::HashMap::new()), + head_changes: cx.create_rw_signal(im::Vector::new()), + code_actions: cx.create_rw_signal(im::HashMap::new()), + find_result: FindResult::new(cx), + preedit: PreeditData::new(cx), + editors, + common, + code_lens: cx.create_rw_signal(im::HashMap::new()), + document_symbol_data: cx.create_rw_signal(None), + folding_ranges: cx.create_rw_signal(FoldingRanges::default()), + } + } + + /// Create a styling instance for this doc + pub fn styling(self: &Rc) -> Rc { + Rc::new(DocStyling { + config: self.common.config, + doc: self.clone(), + }) + } + + /// Create an [`Editor`] instance from this [`Doc`]. Note that this needs to be registered + /// appropriately to create the [`EditorData`] and such. + pub fn create_editor( + self: &Rc, + cx: Scope, + id: EditorId, + is_local: bool, + ) -> Editor { + let common = &self.common; + let config = common.config.get_untracked(); + let modal = config.core.modal && !is_local; + + let register = common.register; + // TODO: we could have these Rcs created once and stored somewhere, maybe on + // common, to avoid recreating them everytime. + let cursor_info = CursorInfo { + blink_interval: Rc::new(move || config.editor.blink_interval()), + blink_timer: common.window_common.cursor_blink_timer, + hidden: common.window_common.hide_cursor, + should_blink: Rc::new(should_blink(common.focus, common.keyboard_focus)), + }; + let mut editor = + Editor::new_direct(cx, id, self.clone(), self.styling(), modal); + + editor.register = register; + editor.cursor_info = cursor_info; + editor.ime_allowed = common.window_common.ime_allowed; + + editor.recreate_view_effects(); + + editor + } + + fn editor_data(&self, id: EditorId) -> Option { + self.editors.editor_untracked(id) + } + + pub fn syntax(&self) -> ReadSignal { + self.syntax.read_only() + } + + pub fn set_syntax(&self, syntax: Syntax) { + batch(|| { + self.syntax.set(syntax); + if self.semantic_styles.with_untracked(|s| s.is_none()) { + self.clear_style_cache(); + } + self.clear_sticky_headers_cache(); + }); + } + + /// Set the syntax highlighting this document should use. + pub fn set_language(&self, language: LapceLanguage) { + self.syntax.set(Syntax::from_language(language)); + } + + pub fn find(&self) -> &Find { + &self.common.find + } + + /// Whether or not the underlying buffer is loaded + pub fn loaded(&self) -> bool { + self.loaded.get_untracked() + } + + //// Initialize the content with some text, this marks the document as loaded. + pub fn init_content(&self, content: Rope) { + batch(|| { + self.syntax.with_untracked(|syntax| { + self.buffer.update(|buffer| { + buffer.init_content(content); + buffer.detect_indent(|| { + IndentStyle::from_str(syntax.language.indent_unit()) + }); + }); + }); + self.loaded.set(true); + self.on_update(None); + self.init_parser(); + self.init_diagnostics(); + self.retrieve_head(); + }); + } + + fn init_parser(&self) { + let code = self.buffer.get_untracked().to_string(); + self.syntax.with_untracked(|syntax| { + if syntax.styles.is_some() { + self.parser.borrow_mut().update_code( + code, + &self.buffer.get_untracked(), + Some(syntax), + ); + } else { + self.parser.borrow_mut().update_code( + code, + &self.buffer.get_untracked(), + None, + ); + } + }); + } + + /// Reload the document's content, and is what you should typically use when you want to *set* + /// an existing document's content. + pub fn reload(&self, content: Rope, set_pristine: bool) { + // self.code_actions.clear(); + // self.inlay_hints = None; + let delta = self + .buffer + .try_update(|buffer| buffer.reload(content, set_pristine)) + .unwrap(); + self.apply_deltas(&[delta]); + } + + pub fn handle_file_changed(&self, content: Rope) { + if self.is_pristine() { + self.reload(content, true); + } + } + + pub fn do_insert( + &self, + cursor: &mut Cursor, + s: &str, + config: &LapceConfig, + ) -> Vec<(Rope, RopeDelta, InvalLines)> { + if self.content.with_untracked(|c| c.read_only()) { + return Vec::new(); + } + + let old_cursor = cursor.mode.clone(); + let deltas = self.syntax.with_untracked(|syntax| { + self.buffer + .try_update(|buffer| { + Action::insert( + cursor, + buffer, + s, + &|buffer, c, offset| { + syntax_prev_unmatched(buffer, syntax, c, offset) + }, + config.editor.auto_closing_matching_pairs, + config.editor.auto_surround, + ) + }) + .unwrap() + }); + // Keep track of the change in the cursor mode for undo/redo + self.buffer.update(|buffer| { + buffer.set_cursor_before(old_cursor); + buffer.set_cursor_after(cursor.mode.clone()); + }); + self.apply_deltas(&deltas); + deltas + } + + pub fn do_raw_edit( + &self, + edits: &[(impl AsRef, &str)], + edit_type: EditType, + ) -> Option<(Rope, RopeDelta, InvalLines)> { + if self.content.with_untracked(|c| c.read_only()) { + return None; + } + + let (text, delta, inval_lines) = self + .buffer + .try_update(|buffer| buffer.edit(edits, edit_type)) + .unwrap(); + self.apply_deltas(&[(text.clone(), delta.clone(), inval_lines.clone())]); + Some((text, delta, inval_lines)) + } + + pub fn do_edit( + &self, + cursor: &mut Cursor, + cmd: &EditCommand, + modal: bool, + register: &mut Register, + smart_tab: bool, + ) -> Vec<(Rope, RopeDelta, InvalLines)> { + if self.content.with_untracked(|c| c.read_only()) + && !cmd.not_changing_buffer() + { + return Vec::new(); + } + + let mut clipboard = SystemClipboard::new(); + let old_cursor = cursor.mode.clone(); + let deltas = self.syntax.with_untracked(|syntax| { + self.buffer + .try_update(|buffer| { + Action::do_edit( + cursor, + buffer, + cmd, + &mut clipboard, + register, + EditConf { + comment_token: syntax.language.comment_token(), + modal, + smart_tab, + keep_indent: true, + auto_indent: true, + }, + ) + }) + .unwrap() + }); + + if !deltas.is_empty() { + self.buffer.update(|buffer| { + buffer.set_cursor_before(old_cursor); + buffer.set_cursor_after(cursor.mode.clone()); + }); + self.apply_deltas(&deltas); + } + + deltas + } + + pub fn apply_deltas(&self, deltas: &[(Rope, RopeDelta, InvalLines)]) { + let rev = self.rev() - deltas.len() as u64; + batch(|| { + for (i, (_, delta, inval)) in deltas.iter().enumerate() { + self.update_styles(delta); + self.update_inlay_hints(delta); + self.update_diagnostics(delta); + self.update_completion_lens(delta); + self.update_find_result(delta); + if let DocContent::File { path, .. } = self.content.get_untracked() { + self.update_breakpoints(delta, &path, &inval.old_text); + self.common.proxy.update( + path, + delta.clone(), + rev + i as u64 + 1, + ); + } + } + }); + + // TODO(minor): We could avoid this potential allocation since most apply_delta callers are actually using a Vec + // which we could reuse. + // We use a smallvec because there is unlikely to be more than a couple of deltas + let edits: SmallVec<[SyntaxEdit; 3]> = deltas + .iter() + .map(|(before_text, delta, _)| { + SyntaxEdit::from_delta(before_text, delta.clone()) + }) + .collect(); + self.on_update(Some(edits)); + } + + pub fn is_pristine(&self) -> bool { + self.buffer.with_untracked(|b| b.is_pristine()) + } + + /// Get the buffer's current revision. This is used to track whether the buffer has changed. + pub fn rev(&self) -> u64 { + self.buffer.with_untracked(|b| b.rev()) + } + + /// Get the buffer's line-ending. + /// Note: this may not be the same as what the actual line endings in the file are, rather this + /// is what the line-ending is set to (and what it will be saved as). + pub fn line_ending(&self) -> LineEnding { + self.buffer.with_untracked(|b| b.line_ending()) + } + + fn on_update(&self, edits: Option>) { + batch(|| { + self.trigger_syntax_change(edits); + self.trigger_head_change(); + self.check_auto_save(); + self.get_inlay_hints(); + self.find_result.reset(); + self.get_semantic_styles(); + self.do_bracket_colorization(); + self.clear_code_actions(); + self.clear_style_cache(); + self.get_code_lens(); + self.get_document_symbol(); + self.get_folding_range(); + }); + } + + fn do_bracket_colorization(&self) { + if self.parser.borrow().active { + self.syntax.with_untracked(|syntax| { + if syntax.rev == self.rev() && syntax.styles.is_some() { + self.parser.borrow_mut().update_code( + self.buffer.get_untracked().to_string(), + &self.buffer.get_untracked(), + Some(syntax), + ); + } else { + self.parser.borrow_mut().update_code( + self.buffer.get_untracked().to_string(), + &self.buffer.get_untracked(), + None, + ); + } + }) + } + } + + pub fn do_text_edit(&self, edits: &[TextEdit]) { + let edits = self.buffer.with_untracked(|buffer| { + edits + .iter() + .map(|edit| { + let selection = lapce_core::selection::Selection::region( + buffer.offset_of_position(&edit.range.start), + buffer.offset_of_position(&edit.range.end), + ); + (selection, edit.new_text.as_str()) + }) + .collect::>() + }); + self.do_raw_edit(&edits, EditType::Completion); + } + + fn check_auto_save(&self) { + let config = self.common.config.get_untracked(); + if config.editor.autosave_interval > 0 { + let Some(path) = self.content.with_untracked(|c| c.path().cloned()) + else { + return; + }; + let rev = self.rev(); + let doc = self.clone(); + let scope = self.scope; + let proxy = self.common.proxy.clone(); + let format = config.editor.format_on_save; + exec_after( + Duration::from_millis(config.editor.autosave_interval), + move |_| { + let current_rev = match doc + .buffer + .try_with_untracked(|b| b.as_ref().map(|b| b.rev())) + { + Some(rev) => rev, + None => return, + }; + + if current_rev != rev || doc.is_pristine() { + return; + } + + if format { + let send = create_ext_action(scope, move |result| { + let current_rev = doc.rev(); + if current_rev != rev { + return; + } + if let Ok(ProxyResponse::GetDocumentFormatting { + edits, + }) = result + { + doc.do_text_edit(&edits); + } + doc.save(|| {}); + }); + proxy.get_document_formatting(path, move |result| { + send(result); + }); + } else { + doc.save(|| {}); + } + }, + ); + } + } + + /// Update the styles after an edit, so the highlights are at the correct positions. + /// This does not do a reparse of the document itself. + fn update_styles(&self, delta: &RopeDelta) { + batch(|| { + self.semantic_styles.update(|styles| { + if let Some(styles) = styles.as_mut() { + styles.apply_shape(delta); + } + }); + self.syntax.update(|syntax| { + if let Some(styles) = syntax.styles.as_mut() { + styles.apply_shape(delta); + } + syntax.lens.apply_delta(delta); + }); + }); + } + + /// Update the inlay hints so their positions are correct after an edit. + fn update_inlay_hints(&self, delta: &RopeDelta) { + self.inlay_hints.update(|inlay_hints| { + if let Some(hints) = inlay_hints.as_mut() { + hints.apply_shape(delta); + } + }); + } + + pub fn trigger_syntax_change(&self, edits: Option>) { + let (rev, text) = + self.buffer.with_untracked(|b| (b.rev(), b.text().clone())); + + let doc = self.clone(); + let send = create_ext_action(self.scope, move |syntax| { + if doc.buffer.with_untracked(|b| b.rev()) == rev { + doc.syntax.set(syntax); + doc.do_bracket_colorization(); + doc.clear_style_cache(); + doc.clear_sticky_headers_cache(); + } + }); + + self.syntax.update(|syntax| { + syntax.cancel_flag.store(1, atomic::Ordering::Relaxed); + syntax.cancel_flag = Arc::new(AtomicUsize::new(0)); + }); + let mut syntax = self.syntax.get_untracked(); + rayon::spawn(move || { + syntax.parse(rev, text, edits.as_deref()); + send(syntax); + }); + } + + fn clear_style_cache(&self) { + self.line_styles.borrow_mut().clear(); + self.clear_text_cache(); + } + + fn clear_code_actions(&self) { + self.code_actions.update(|c| { + c.clear(); + }); + } + + /// Inform any dependents on this document that they should clear any cached text. + pub fn clear_text_cache(&self) { + self.cache_rev.try_update(|cache_rev| { + *cache_rev += 1; + + // TODO: ??? + // Update the text layouts within the callback so that those alerted to cache rev + // will see the now empty layouts. + // self.text_layouts.borrow_mut().clear(*cache_rev, None); + }); + } + + fn clear_sticky_headers_cache(&self) { + self.sticky_headers.borrow_mut().clear(); + } + + /// Get the active style information, either the semantic styles or the + /// tree-sitter syntax styles. + fn styles(&self) -> Option> { + if let Some(semantic_styles) = self.semantic_styles.get_untracked() { + Some(semantic_styles) + } else { + self.syntax.with_untracked(|syntax| syntax.styles.clone()) + } + } + + /// Get the style information for the particular line from semantic/syntax highlighting. + /// This caches the result if possible. + pub fn line_style(&self, line: usize) -> Arc> { + if self.line_styles.borrow().get(&line).is_none() { + let styles = self.styles(); + + let line_styles = styles + .map(|styles| { + let text = + self.buffer.with_untracked(|buffer| buffer.text().clone()); + line_styles(&text, line, &styles) + }) + .unwrap_or_default(); + self.line_styles + .borrow_mut() + .insert(line, Arc::new(line_styles)); + } + self.line_styles.borrow().get(&line).cloned().unwrap() + } + + /// Request semantic styles for the buffer from the LSP through the proxy. + pub fn get_semantic_styles(&self) { + if !self.loaded() { + return; + } + + let path = + if let DocContent::File { path, .. } = self.content.get_untracked() { + path + } else { + return; + }; + + let (atomic_rev, rev, len) = self + .buffer + .with_untracked(|b| (b.atomic_rev(), b.rev(), b.len())); + + let doc = self.clone(); + let send = create_ext_action(self.scope, move |styles| { + if let Some(styles) = styles { + if doc.buffer.with_untracked(|b| b.rev()) == rev { + doc.semantic_styles.set(Some(styles)); + doc.clear_style_cache(); + } + } + }); + + self.common.proxy.get_semantic_tokens(path, move |result| { + if let Ok(ProxyResponse::GetSemanticTokens { styles }) = result { + if styles.styles.is_empty() { + send(None); + return; + } + if atomic_rev.load(atomic::Ordering::Acquire) != rev { + send(None); + return; + } + std::thread::spawn(move || { + let mut styles_span = SpansBuilder::new(len); + for style in styles.styles { + if atomic_rev.load(atomic::Ordering::Acquire) != rev { + send(None); + return; + } + styles_span.add_span( + Interval::new(style.start, style.end), + style.style, + ); + } + + let styles = styles_span.build(); + send(Some(styles)); + }); + } else { + send(None); + } + }); + } + + pub fn get_code_lens(&self) { + let cx = self.scope; + let doc = self.clone(); + self.code_lens.update(|code_lens| { + code_lens.clear(); + }); + let rev = self.rev(); + if let DocContent::File { path, .. } = doc.content.get_untracked() { + let send = create_ext_action(cx, move |result| { + if rev != doc.rev() { + return; + } + if let Ok(ProxyResponse::GetCodeLensResponse { plugin_id, resp }) = + result + { + let Some(codelens) = resp else { + return; + }; + doc.code_lens.update(|code_lens| { + for codelens in codelens { + if codelens.command.is_none() { + continue; + } + let entry = code_lens + .entry(codelens.range.start.line as usize) + .or_insert_with(|| { + ( + plugin_id, + doc.buffer.with_untracked(|b| { + b.offset_of_line( + codelens.range.start.line as usize, + ) + }), + im::Vector::new(), + ) + }); + entry.2.push_back(codelens); + } + }); + } + }); + self.common.proxy.get_code_lens(path, move |result| { + send(result); + }); + } + } + + pub fn get_document_symbol(&self) { + let cx = self.scope; + let doc = self.clone(); + let rev = self.rev(); + if let DocContent::File { path, .. } = doc.content.get_untracked() { + let send = create_ext_action(cx, { + let path = path.clone(); + move |result| { + if rev != doc.rev() { + return; + } + if let Ok(ProxyResponse::GetDocumentSymbols { resp }) = result { + let items: Vec> = + match resp { + DocumentSymbolResponse::Flat(_symbols) => { + Vec::with_capacity(0) + } + DocumentSymbolResponse::Nested(symbols) => symbols + .into_iter() + .map(|x| { + cx.create_rw_signal( + SymbolInformationItemData::from((x, cx)), + ) + }) + .collect(), + }; + let symbol_new = Some(SymbolData::new(items, path, cx)); + doc.document_symbol_data.update(|symbol| { + *symbol = symbol_new; + }); + } + } + }); + + self.common.proxy.get_document_symbols(path, move |result| { + send(result); + }); + } + } + + /// Request inlay hints for the buffer from the LSP through the proxy. + pub fn get_inlay_hints(&self) { + if !self.loaded() { + return; + } + + let path = + if let DocContent::File { path, .. } = self.content.get_untracked() { + path + } else { + return; + }; + + let (buffer, rev, len) = self + .buffer + .with_untracked(|b| (b.clone(), b.rev(), b.len())); + + let doc = self.clone(); + let send = create_ext_action(self.scope, move |hints| { + if doc.buffer.with_untracked(|b| b.rev()) == rev { + doc.inlay_hints.set(Some(hints)); + doc.clear_text_cache(); + } + }); + + self.common.proxy.get_inlay_hints(path, move |result| { + if let Ok(ProxyResponse::GetInlayHints { mut hints }) = result { + // Sort the inlay hints by their position, as the LSP does not guarantee that it will + // provide them in the order that they are in within the file + // as well, Spans does not iterate in the order that they appear + hints.sort_by(|left, right| left.position.cmp(&right.position)); + + let mut hints_span = SpansBuilder::new(len); + for hint in hints { + let offset = buffer.offset_of_position(&hint.position).min(len); + hints_span.add_span( + Interval::new(offset, (offset + 1).min(len)), + hint, + ); + } + let hints = hints_span.build(); + send(hints); + } + }); + } + + pub fn diagnostics(&self) -> &DiagnosticData { + &self.diagnostics + } + + /// Update the diagnostics' positions after an edit so that they appear in the correct place. + fn update_diagnostics(&self, delta: &RopeDelta) { + if self + .diagnostics + .diagnostics + .with_untracked(|d| d.is_empty()) + { + return; + } + + self.diagnostics.diagnostics_span.update(|diagnostics| { + diagnostics.apply_shape(delta); + }); + } + + /// init diagnostics offset ranges from lsp positions + pub fn init_diagnostics(&self) { + let len = self.buffer.with_untracked(|b| b.len()); + let diagnostics = self.diagnostics.diagnostics.get_untracked(); + + let span = self.buffer.with_untracked(|buffer| { + let mut span = SpansBuilder::new(len); + for diag in diagnostics.iter() { + let start = buffer.offset_of_position(&diag.range.start); + let end = buffer.offset_of_position(&diag.range.end); + span.add_span(Interval::new(start, end), diag.to_owned()); + } + span.build() + }); + self.diagnostics.diagnostics_span.set(span); + + self.clear_text_cache(); + self.clear_code_actions(); + } + + pub fn get_folding_range(&self) { + // let cx = self.scope; + // let doc = self.clone(); + // let rev = self.rev(); + // if let DocContent::File { path, .. } = doc.content.get_untracked() { + // let send = create_ext_action(cx, { + // move |result| { + // if rev != doc.rev() { + // return; + // } + // if let Ok(ProxyResponse::LspFoldingRangeResponse { + // resp, .. + // }) = result + // { + // let folding = resp + // .unwrap_or_default() + // .into_iter() + // .map(|x| { + // crate::editor::gutter::FoldingRange::from_lsp(x) + // }) + // .sorted_by(|x, y| x.start.line.cmp(&y.start.line)) + // .collect(); + // doc.folding_ranges.update(|symbol| { + // symbol.0 = folding; + // }); + // } + // } + // }); + + // self.common + // .proxy + // .get_lsp_folding_range(path, move |result| { + // send(result); + // }); + // } + } + + /// Get the current completion lens text + pub fn completion_lens(&self) -> Option { + self.completion_lens.get_untracked() + } + + pub fn set_completion_lens( + &self, + completion_lens: String, + line: usize, + col: usize, + ) { + // TODO: more granular invalidation + self.completion_lens.set(Some(completion_lens)); + self.completion_pos.set((line, col)); + self.clear_text_cache(); + } + + pub fn clear_completion_lens(&self) { + // TODO: more granular invalidation + if self.completion_lens.get_untracked().is_some() { + self.completion_lens.set(None); + self.clear_text_cache(); + } + } + + fn update_breakpoints(&self, delta: &RopeDelta, path: &Path, old_text: &Rope) { + if self + .common + .breakpoints + .with_untracked(|breakpoints| breakpoints.contains_key(path)) + { + self.common.breakpoints.update(|breakpoints| { + if let Some(path_breakpoints) = breakpoints.get_mut(path) { + let mut transformer = Transformer::new(delta); + self.buffer.with_untracked(|buffer| { + *path_breakpoints = path_breakpoints + .clone() + .into_values() + .map(|mut b| { + let offset = old_text.offset_of_line(b.line); + let offset = transformer.transform(offset, false); + let line = buffer.line_of_offset(offset); + b.line = line; + b.offset = offset; + (b.line, b) + }) + .collect(); + }); + } + }); + } + } + + /// Update the completion lens position after an edit so that it appears in the correct place. + pub fn update_completion_lens(&self, delta: &RopeDelta) { + let Some(completion) = self.completion_lens.get_untracked() else { + return; + }; + + let (line, col) = self.completion_pos.get_untracked(); + let offset = self + .buffer + .with_untracked(|b| b.offset_of_line_col(line, col)); + + // If the edit is easily checkable + updateable from, then we alter the lens' text. + // In normal typing, if we didn't do this, then the text would jitter forward and then + // backwards as the completion lens is updated. + // TODO: this could also handle simple deletion, but we don't currently keep track of + // the past completion lens string content in the field. + if delta.as_simple_insert().is_some() { + let (iv, new_len) = delta.summary(); + if iv.start() == iv.end() + && iv.start() == offset + && new_len <= completion.len() + { + // Remove the # of newly inserted characters + // These aren't necessarily the same as the characters literally in the + // text, but the completion will be updated when the completion widget + // receives the update event, and it will fix this if needed. + // TODO: this could be smarter and use the insert's content + self.completion_lens + .set(Some(completion[new_len..].to_string())); + } + } + + // Shift the position by the rope delta + let mut transformer = Transformer::new(delta); + + let new_offset = transformer.transform(offset, true); + let new_pos = self + .buffer + .with_untracked(|b| b.offset_to_line_col(new_offset)); + + self.completion_pos.set(new_pos); + } + + fn update_find_result(&self, delta: &RopeDelta) { + self.find_result.occurrences.update(|s| { + *s = s.apply_delta(delta, true, InsertDrift::Default); + }) + } + + pub fn update_find(&self) { + let find_rev = self.common.find.rev.get_untracked(); + if self.find_result.find_rev.get_untracked() != find_rev { + if self + .common + .find + .search_string + .with_untracked(|search_string| { + search_string + .as_ref() + .map(|s| s.content.is_empty()) + .unwrap_or(true) + }) + { + self.find_result.occurrences.set(Selection::new()); + } + self.find_result.reset(); + self.find_result.find_rev.set(find_rev); + } + + if self.find_result.progress.get_untracked() != FindProgress::Started { + return; + } + + let search = self.common.find.search_string.get_untracked(); + let search = match search { + Some(search) => search, + None => return, + }; + if search.content.is_empty() { + return; + } + + self.find_result + .progress + .set(FindProgress::InProgress(Selection::new())); + + let find_result = self.find_result.clone(); + let send = create_ext_action(self.scope, move |occurrences: Selection| { + find_result.occurrences.set(occurrences); + find_result.progress.set(FindProgress::Ready); + }); + + let text = self.buffer.with_untracked(|b| b.text().clone()); + let case_matching = self.common.find.case_matching.get_untracked(); + let whole_words = self.common.find.whole_words.get_untracked(); + rayon::spawn(move || { + let mut occurrences = Selection::new(); + Find::find( + &text, + &search, + 0, + text.len(), + case_matching, + whole_words, + true, + &mut occurrences, + ); + send(occurrences); + }); + } + + /// Get the sticky headers for a particular line, creating them if necessary. + pub fn sticky_headers(&self, line: usize) -> Option> { + if let Some(lines) = self.sticky_headers.borrow().get(&line) { + return lines.clone(); + } + let lines = self.buffer.with_untracked(|buffer| { + let offset = buffer.offset_of_line(line + 1); + self.syntax.with_untracked(|syntax| { + syntax.sticky_headers(offset).map(|offsets| { + offsets + .iter() + .filter_map(|offset| { + let l = buffer.line_of_offset(*offset); + if l <= line { Some(l) } else { None } + }) + .dedup() + .sorted() + .collect() + }) + }) + }); + self.sticky_headers.borrow_mut().insert(line, lines.clone()); + lines + } + + pub fn head_changes(&self) -> RwSignal> { + self.head_changes + } + + /// Retrieve the `head` version of the buffer + pub fn retrieve_head(&self) { + if let DocContent::File { path, .. } = self.content.get_untracked() { + let histories = self.histories; + + let send = { + let path = path.clone(); + let doc = self.clone(); + create_ext_action(self.scope, move |result| { + if let Ok(ProxyResponse::BufferHeadResponse { + content, .. + }) = result + { + let history = DocumentHistory::new( + path.clone(), + "head".to_string(), + &content, + ); + histories.update(|histories| { + histories.insert("head".to_string(), history); + }); + + doc.trigger_head_change(); + } + }) + }; + + let path = path.clone(); + let proxy = self.common.proxy.clone(); + std::thread::spawn(move || { + proxy.get_buffer_head(path, move |result| { + send(result); + }); + }); + } + } + + pub fn trigger_head_change(&self) { + let history = if let Some(text) = + self.histories.with_untracked(|histories| { + histories + .get("head") + .map(|history| history.buffer.text().clone()) + }) { + text + } else { + return; + }; + + let rev = self.rev(); + let left_rope = history; + let (atomic_rev, right_rope) = self + .buffer + .with_untracked(|b| (b.atomic_rev(), b.text().clone())); + + let send = { + let atomic_rev = atomic_rev.clone(); + let head_changes = self.head_changes; + create_ext_action(self.scope, move |changes| { + let changes = if let Some(changes) = changes { + changes + } else { + return; + }; + + if atomic_rev.load(atomic::Ordering::Acquire) != rev { + return; + } + + head_changes.set(changes); + }) + }; + + rayon::spawn(move || { + let changes = + rope_diff(left_rope, right_rope, rev, atomic_rev.clone(), None); + send(changes.map(im::Vector::from)); + }); + } + + pub fn save(&self, after_action: impl FnOnce() + 'static) { + let content = self.content.get_untracked(); + if let DocContent::File { path, .. } = content { + let rev = self.rev(); + let buffer = self.buffer; + let send = create_ext_action(self.scope, move |result| { + if let Ok(ProxyResponse::SaveResponse {}) = result { + let current_rev = buffer.with_untracked(|buffer| buffer.rev()); + if current_rev == rev { + buffer.update(|buffer| { + buffer.set_pristine(); + }); + after_action(); + } + } + }); + + self.common.proxy.save(rev, path, true, move |result| { + send(result); + }) + } + } + + pub fn set_inline_completion( + &self, + inline_completion: String, + line: usize, + col: usize, + ) { + // TODO: more granular invalidation + batch(|| { + self.inline_completion.set(Some(inline_completion)); + self.inline_completion_pos.set((line, col)); + self.clear_text_cache(); + }); + } + + pub fn clear_inline_completion(&self) { + if self.inline_completion.with_untracked(Option::is_some) { + self.inline_completion.set(None); + self.clear_text_cache(); + } + } + + pub fn update_inline_completion(&self, delta: &RopeDelta) { + let Some(completion) = self.inline_completion.get_untracked() else { + return; + }; + + let (line, col) = self.completion_pos.get_untracked(); + let offset = self + .buffer + .with_untracked(|b| b.offset_of_line_col(line, col)); + + // If the edit is easily checkable + updateable from, then we alter the text. + // In normal typing, if we didn't do this, then the text would jitter forward and then + // backwards as the completion is updated. + // TODO: this could also handle simple deletion, but we don't currently keep track of + // the past completion string content in the field. + if delta.as_simple_insert().is_some() { + let (iv, new_len) = delta.summary(); + if iv.start() == iv.end() + && iv.start() == offset + && new_len <= completion.len() + { + // Remove the # of newly inserted characters + // These aren't necessarily the same as the characters literally in the + // text, but the completion will be updated when the completion widget + // receives the update event, and it will fix this if needed. + self.inline_completion + .set(Some(completion[new_len..].to_string())); + } + } + + // Shift the position by the rope delta + let mut transformer = Transformer::new(delta); + + let new_offset = transformer.transform(offset, true); + let new_pos = self + .buffer + .with_untracked(|b| b.offset_to_line_col(new_offset)); + + self.inline_completion_pos.set(new_pos); + } + + pub fn code_actions(&self) -> RwSignal { + self.code_actions + } + + /// Returns the offsets of the brackets enclosing the given offset. + /// Uses a language aware algorithm if syntax support is available for the current language, + /// else falls back to a language unaware algorithm. + pub fn find_enclosing_brackets(&self, offset: usize) -> Option<(usize, usize)> { + let rev = self.rev(); + self.syntax + .with_untracked(|syntax| { + (!syntax.text.is_empty() && syntax.rev == rev) + .then(|| syntax.find_enclosing_pair(offset)) + }) + // If syntax.text is empty, either the buffer is empty or we don't have syntax support + // for the current language. + // Try a language unaware search for enclosing brackets in case it is the latter. + .unwrap_or_else(|| { + self.buffer.with_untracked(|buffer| { + WordCursor::new(buffer.text(), offset).find_enclosing_pair() + }) + }) + } +} +impl Document for Doc { + fn text(&self) -> Rope { + self.buffer.with_untracked(|buffer| buffer.text().clone()) + } + + fn cache_rev(&self) -> RwSignal { + self.cache_rev + } + + fn find_unmatched(&self, offset: usize, previous: bool, ch: char) -> usize { + self.syntax().with_untracked(|syntax| { + if syntax.layers.is_some() { + syntax + .find_tag(offset, previous, &CharBuffer::from(ch)) + .unwrap_or(offset) + } else { + let text = self.text(); + let mut cursor = WordCursor::new(&text, offset); + let new_offset = if previous { + cursor.previous_unmatched(ch) + } else { + cursor.next_unmatched(ch) + }; + + new_offset.unwrap_or(offset) + } + }) + } + + fn find_matching_pair(&self, offset: usize) -> usize { + self.syntax().with_untracked(|syntax| { + if syntax.layers.is_some() { + syntax.find_matching_pair(offset).unwrap_or(offset) + } else { + let text = self.text(); + WordCursor::new(&text, offset) + .match_pairs() + .unwrap_or(offset) + } + }) + } + + fn preedit(&self) -> PreeditData { + self.preedit.clone() + } + + fn compute_screen_lines( + &self, + editor: &Editor, + base: RwSignal, + ) -> ScreenLines { + let Some(editor_data) = self.editor_data(editor.id()) else { + return ScreenLines { + lines: Default::default(), + info: Default::default(), + diff_sections: Default::default(), + base, + }; + }; + + compute_screen_lines( + self.common.config, + base, + editor_data.kind.read_only(), + &editor_data.doc_signal().get(), + editor.lines(), + editor.text_prov(), + editor.config_id(), + ) + } + + fn run_command( + &self, + ed: &Editor, + cmd: &Command, + count: Option, + modifiers: Modifiers, + ) -> CommandExecuted { + let Some(editor_data) = self.editor_data(ed.id()) else { + return CommandExecuted::No; + }; + + let cmd = CommandKind::from(cmd.clone()); + let cmd = LapceCommand { + kind: cmd, + data: None, + }; + editor_data.run_command(&cmd, count, modifiers) + } + + fn receive_char(&self, ed: &Editor, c: &str) { + let Some(editor_data) = self.editor_data(ed.id()) else { + return; + }; + + editor_data.receive_char(c); + } + + fn edit( + &self, + iter: &mut dyn Iterator, + edit_type: EditType, + ) { + let delta = self + .buffer + .try_update(|buffer| buffer.edit(iter, edit_type)) + .unwrap(); + self.apply_deltas(&[delta]); + } +} + +impl DocumentPhantom for Doc { + fn phantom_text( + &self, + _: EditorId, + _: &EditorStyle, + line: usize, + ) -> PhantomTextLine { + let config = &self.common.config.get_untracked(); + + let (start_offset, end_offset) = self.buffer.with_untracked(|buffer| { + (buffer.offset_of_line(line), buffer.offset_of_line(line + 1)) + }); + + let inlay_hints = self.inlay_hints.get_untracked(); + // If hints are enabled, and the hints field is filled, then get the hints for this line + // and convert them into PhantomText instances + let hints = config + .editor + .enable_inlay_hints + .then_some(()) + .and(inlay_hints.as_ref()) + .map(|hints| hints.iter_chunks(start_offset..end_offset)) + .into_iter() + .flatten() + .filter(|(interval, _)| { + interval.start >= start_offset && interval.start < end_offset + }) + .map(|(interval, inlay_hint)| { + let (col, affinity) = self.buffer.with_untracked(|b| { + let mut cursor = + lapce_xi_rope::Cursor::new(b.text(), interval.start); + + let next_char = cursor.peek_next_codepoint(); + let prev_char = cursor.prev_codepoint(); + + let mut affinity = None; + if let Some(prev_char) = prev_char { + let c = get_char_property(prev_char); + if c == CharClassification::Other { + affinity = Some(CursorAffinity::Backward) + } else if matches!( + c, + CharClassification::Lf + | CharClassification::Cr + | CharClassification::Space + ) { + affinity = Some(CursorAffinity::Forward) + } + }; + if affinity.is_none() { + if let Some(next_char) = next_char { + let c = get_char_property(next_char); + if c == CharClassification::Other { + affinity = Some(CursorAffinity::Forward) + } else if matches!( + c, + CharClassification::Lf + | CharClassification::Cr + | CharClassification::Space + ) { + affinity = Some(CursorAffinity::Backward) + } + } + } + + let (_, col) = b.offset_to_line_col(interval.start); + (col, affinity) + }); + let text = match &inlay_hint.label { + InlayHintLabel::String(label) => label.to_string(), + InlayHintLabel::LabelParts(parts) => { + parts.iter().map(|p| &p.value).join("") + } + }; + PhantomText { + kind: PhantomTextKind::InlayHint, + col, + text, + affinity, + fg: Some(config.color(LapceColor::INLAY_HINT_FOREGROUND)), + // font_family: Some(config.editor.inlay_hint_font_family()), + font_size: Some(config.editor.inlay_hint_font_size()), + bg: Some(config.color(LapceColor::INLAY_HINT_BACKGROUND)), + under_line: None, + } + }); + // You're quite unlikely to have more than six hints on a single line + // this later has the diagnostics added onto it, but that's still likely to be below six + // overall. + let mut text: SmallVec<[PhantomText; 6]> = hints.collect(); + + // If error lens is enabled, and the diagnostics field is filled, then get the diagnostics + // that end on this line which have a severity worse than HINT and convert them into + // PhantomText instances + + let mut diag_text: SmallVec<[PhantomText; 6]> = + self.buffer.with_untracked(|buffer| { + config + .editor + .enable_error_lens + .then_some(()) + .map(|_| self.diagnostics.diagnostics_span.get_untracked()) + .map(|diags| { + diags + .iter_chunks(start_offset..end_offset) + .filter_map(|(iv, diag)| { + let end = iv.end(); + let end_line = buffer.line_of_offset(end); + if end_line == line + && diag.severity < Some(DiagnosticSeverity::HINT) + { + let fg = { + let severity = diag + .severity + .unwrap_or(DiagnosticSeverity::WARNING); + let theme_prop = if severity + == DiagnosticSeverity::ERROR + { + LapceColor::ERROR_LENS_ERROR_FOREGROUND + } else if severity + == DiagnosticSeverity::WARNING + { + LapceColor::ERROR_LENS_WARNING_FOREGROUND + } else { + // information + hint (if we keep that) + things without a severity + LapceColor::ERROR_LENS_OTHER_FOREGROUND + }; + + config.color(theme_prop) + }; + + let text = + if config.editor.only_render_error_styling { + "".to_string() + } else if config.editor.error_lens_multiline + { + format!(" {}", diag.message) + } else { + format!( + " {}", + diag.message.lines().join(" ") + ) + }; + Some(PhantomText { + kind: PhantomTextKind::Diagnostic, + col: end_offset - start_offset, + affinity: Some(CursorAffinity::Backward), + text, + fg: Some(fg), + font_size: Some( + config.editor.error_lens_font_size(), + ), + bg: None, + under_line: None, + }) + } else { + None + } + }) + .collect::>() + }) + .unwrap_or_default() + }); + + text.append(&mut diag_text); + + let (completion_line, completion_col) = self.completion_pos.get_untracked(); + let completion_text = config + .editor + .enable_completion_lens + .then_some(()) + .and(self.completion_lens.get_untracked()) + // TODO: We're probably missing on various useful completion things to include here! + .filter(|_| line == completion_line) + .map(|completion| PhantomText { + kind: PhantomTextKind::Completion, + col: completion_col, + text: completion.clone(), + fg: Some(config.color(LapceColor::COMPLETION_LENS_FOREGROUND)), + font_size: Some(config.editor.completion_lens_font_size()), + affinity: Some(CursorAffinity::Backward), + // font_family: Some(config.editor.completion_lens_font_family()), + bg: None, + under_line: None, + // TODO: italics? + }); + if let Some(completion_text) = completion_text { + text.push(completion_text); + } + + // TODO: don't display completion lens and inline completion at the same time + // and/or merge them so that they can be shifted between like multiple inline completions + // can + let (inline_completion_line, inline_completion_col) = + self.inline_completion_pos.get_untracked(); + let inline_completion_text = config + .editor + .enable_inline_completion + .then_some(()) + .and(self.inline_completion.get_untracked()) + .filter(|_| line == inline_completion_line) + .map(|completion| PhantomText { + kind: PhantomTextKind::Completion, + col: inline_completion_col, + text: completion.clone(), + affinity: Some(CursorAffinity::Backward), + fg: Some(config.color(LapceColor::COMPLETION_LENS_FOREGROUND)), + font_size: Some(config.editor.completion_lens_font_size()), + // font_family: Some(config.editor.completion_lens_font_family()), + bg: None, + under_line: None, + // TODO: italics? + }); + if let Some(inline_completion_text) = inline_completion_text { + text.push(inline_completion_text); + } + + if let Some(preedit) = self + .preedit_phantom(Some(config.color(LapceColor::EDITOR_FOREGROUND)), line) + { + text.push(preedit) + } + + text.sort_by(|a, b| { + if a.col == b.col { + a.kind.cmp(&b.kind) + } else { + a.col.cmp(&b.col) + } + }); + + PhantomTextLine { text } + } + + fn has_multiline_phantom(&self, _: EditorId, _: &EditorStyle) -> bool { + // TODO: actually check + true + } +} +impl CommonAction for Doc { + fn exec_motion_mode( + &self, + _ed: &Editor, + cursor: &mut Cursor, + motion_mode: MotionMode, + range: Range, + is_vertical: bool, + register: &mut Register, + ) { + let deltas = self + .buffer + .try_update(move |buffer| { + Action::execute_motion_mode( + cursor, + buffer, + motion_mode, + range, + is_vertical, + register, + ) + }) + .unwrap(); + self.apply_deltas(&deltas); + } + + fn do_edit( + &self, + _ed: &Editor, + cursor: &mut Cursor, + cmd: &EditCommand, + modal: bool, + register: &mut Register, + smart_tab: bool, + ) -> bool { + let deltas = Doc::do_edit(self, cursor, cmd, modal, register, smart_tab); + !deltas.is_empty() + } +} + +#[derive(Clone)] +pub struct DocStyling { + config: ReadSignal>, + doc: Rc, +} +impl DocStyling { + fn apply_colorization( + &self, + edid: EditorId, + style: &EditorStyle, + line: usize, + attrs: &Attrs, + attrs_list: &mut AttrsList, + ) { + let config = self.config.get_untracked(); + let phantom_text = self.doc.phantom_text(edid, style, line); + if let Some(bracket_styles) = self.doc.parser.borrow().bracket_pos.get(&line) + { + for bracket_style in bracket_styles.iter() { + if let Some(fg_color) = bracket_style.style.fg_color.as_ref() { + if let Some(fg_color) = config.style_color(fg_color) { + let start = phantom_text.col_at(bracket_style.start); + let end = phantom_text.col_at(bracket_style.end); + attrs_list + .add_span(start..end, attrs.clone().color(fg_color)); + } + } + } + } + } +} +impl Styling for DocStyling { + fn id(&self) -> u64 { + self.config.with_untracked(|config| config.id) + } + + fn font_size(&self, _: EditorId, _line: usize) -> usize { + self.config + .with_untracked(|config| config.editor.font_size()) + } + + fn line_height(&self, _: EditorId, _line: usize) -> f32 { + self.config + .with_untracked(|config| config.editor.line_height()) as f32 + } + + fn font_family( + &self, + _: EditorId, + _line: usize, + ) -> std::borrow::Cow<'_, [floem::text::FamilyOwned]> { + // TODO: cache this + Cow::Owned(self.config.with_untracked(|config| { + FamilyOwned::parse_list(&config.editor.font_family).collect() + })) + } + + fn weight(&self, _: EditorId, _line: usize) -> floem::text::Weight { + floem::text::Weight::NORMAL + } + + fn italic_style(&self, _: EditorId, _line: usize) -> floem::text::Style { + floem::text::Style::Normal + } + + fn stretch(&self, _: EditorId, _line: usize) -> floem::text::Stretch { + floem::text::Stretch::Normal + } + + fn indent_line(&self, _: EditorId, line: usize, line_content: &str) -> usize { + if line_content.trim().is_empty() { + let text = self.doc.rope_text(); + let offset = text.offset_of_line(line); + if let Some(offset) = + self.doc.syntax.with_untracked(|s| s.parent_offset(offset)) + { + return text.line_of_offset(offset); + } + } + + line + } + + fn tab_width(&self, _: EditorId, _line: usize) -> usize { + self.config.with_untracked(|config| config.editor.tab_width) + } + + fn atomic_soft_tabs(&self, _: EditorId, _line: usize) -> bool { + self.config + .with_untracked(|config| config.editor.atomic_soft_tabs) + } + + fn apply_attr_styles( + &self, + edid: EditorId, + style: &EditorStyle, + line: usize, + default: Attrs, + attrs_list: &mut AttrsList, + ) { + let config = self.doc.common.config.get_untracked(); + + self.apply_colorization(edid, style, line, &default, attrs_list); + + let phantom_text = self.doc.phantom_text(edid, style, line); + for line_style in self.doc.line_style(line).iter() { + if let Some(fg_color) = line_style.style.fg_color.as_ref() { + if let Some(fg_color) = config.style_color(fg_color) { + let start = phantom_text.col_at(line_style.start); + let end = phantom_text.col_at(line_style.end); + attrs_list.add_span(start..end, default.clone().color(fg_color)); + } + } + } + } + + fn apply_layout_styles( + &self, + edid: EditorId, + style: &EditorStyle, + line: usize, + layout_line: &mut TextLayoutLine, + ) { + let doc = &self.doc; + let config = doc.common.config.get_untracked(); + + layout_line.extra_style.clear(); + let layout = &layout_line.text; + + let phantom_text = doc.phantom_text(edid, style, line); + + let phantom_styles = phantom_text + .offset_size_iter() + .filter(move |(_, _, _, p)| p.bg.is_some() || p.under_line.is_some()) + .flat_map(move |(col_shift, size, col, phantom)| { + let start = col + col_shift; + let end = start + size; + + extra_styles_for_range( + layout, + start, + end, + phantom.bg, + phantom.under_line, + None, + ) + }); + layout_line.extra_style.extend(phantom_styles); + + let (start_offset, end_offset) = doc.buffer.with_untracked(|buffer| { + (buffer.offset_of_line(line), buffer.offset_of_line(line + 1)) + }); + + let mut max_severity: Option = None; + doc.diagnostics.diagnostics_span.with_untracked(|diags| { + diags + .iter_chunks(start_offset..end_offset) + .for_each(|(iv, diag)| { + let start = iv.start(); + let end = iv.end(); + + if start <= end_offset + && end >= start_offset + && diag.severity < Some(DiagnosticSeverity::HINT) + { + let start = start.saturating_sub(start_offset); + let end = end - start_offset; + let start = phantom_text.col_after(start, true); + let end = phantom_text.col_after(end, false); + + match (diag.severity, max_severity) { + (Some(severity), Some(max)) => { + if severity < max { + max_severity = Some(severity); + } + } + (Some(severity), None) => { + max_severity = Some(severity); + } + _ => {} + } + + let color_name = match diag.severity { + Some(DiagnosticSeverity::ERROR) => { + LapceColor::LAPCE_ERROR + } + _ => LapceColor::LAPCE_WARN, + }; + let color = config.color(color_name); + let styles = extra_styles_for_range( + layout, + start, + end, + None, + None, + Some(color), + ); + layout_line.extra_style.extend(styles); + } + }); + }); + + // Add the styling for the diagnostic severity, if applicable + if let Some(max_severity) = max_severity { + let theme_prop = if max_severity == DiagnosticSeverity::ERROR { + LapceColor::ERROR_LENS_ERROR_BACKGROUND + } else if max_severity == DiagnosticSeverity::WARNING { + LapceColor::ERROR_LENS_WARNING_BACKGROUND + } else { + LapceColor::ERROR_LENS_OTHER_BACKGROUND + }; + + let size = layout.size(); + let x1 = if !config.editor.error_lens_end_of_line { + let error_end_x = size.width; + Some(error_end_x.max(size.width)) + } else { + None + }; + + // TODO(minor): Should we show the background only on wrapped lines that have the + // diagnostic actually on that line? + // That would make it more obvious where it is from and matches other editors. + layout_line.extra_style.push(LineExtraStyle { + x: 0.0, + y: 0.0, + width: x1, + height: size.height, + bg_color: Some(config.color(theme_prop)), + under_line: None, + wave_line: None, + }); + } + } + + fn paint_caret(&self, edid: EditorId, _line: usize) -> bool { + let Some(e_data) = self.doc.editor_data(edid) else { + return true; + }; + + // If the find is active, then we don't want to paint the caret + !e_data.find_focus.get_untracked() + } +} + +impl std::fmt::Debug for Doc { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&format!("Document {:?}", self.buffer_id)) + } +} + +/// Get the previous unmatched character `c` from the `offset` using `syntax` if applicable +fn syntax_prev_unmatched( + buffer: &Buffer, + syntax: &Syntax, + c: char, + offset: usize, +) -> Option { + if syntax.layers.is_some() { + syntax.find_tag(offset, true, &CharBuffer::new(c)) + } else { + WordCursor::new(buffer.text(), offset).previous_unmatched(c) + } +} + +fn should_blink( + focus: RwSignal, + keyboard_focus: RwSignal>, +) -> impl Fn() -> bool { + move || { + let Some(focus) = focus.try_get_untracked() else { + return false; + }; + if matches!( + focus, + Focus::Workbench + | Focus::Palette + | Focus::Panel(PanelKind::Plugin) + | Focus::Panel(PanelKind::Search) + | Focus::Panel(PanelKind::SourceControl) + ) { + return true; + } + + if keyboard_focus.get_untracked().is_some() { + return true; + } + false + } +} + +fn extra_styles_for_range( + text_layout: &TextLayout, + start: usize, + end: usize, + bg_color: Option, + under_line: Option, + wave_line: Option, +) -> impl Iterator + '_ { + let start_hit = text_layout.hit_position(start); + let end_hit = text_layout.hit_position(end); + + text_layout + .layout_runs() + .enumerate() + .filter_map(move |(current_line, run)| { + if current_line < start_hit.line || current_line > end_hit.line { + return None; + } + + let x = if current_line == start_hit.line { + start_hit.point.x + } else { + run.glyphs.first().map(|g| g.x).unwrap_or(0.0) as f64 + }; + let end_x = if current_line == end_hit.line { + end_hit.point.x + } else { + run.glyphs.last().map(|g| g.x + g.w).unwrap_or(0.0) as f64 + }; + let width = end_x - x; + + if width == 0.0 { + return None; + } + + let height = (run.max_ascent + run.max_descent) as f64; + let y = run.line_y as f64 - run.max_ascent as f64; + + Some(LineExtraStyle { + x, + y, + width: Some(width), + height, + bg_color, + under_line, + wave_line, + }) + }) +} diff --git a/lapce-app/src/editor.rs b/lapce-app/src/editor.rs new file mode 100644 index 0000000..9e30c6a --- /dev/null +++ b/lapce-app/src/editor.rs @@ -0,0 +1,3926 @@ +use std::{ + collections::{HashMap, HashSet}, + rc::Rc, + str::FromStr, + sync::Arc, + time::Duration, +}; + +use floem::{ + ViewId, + action::{TimerToken, exec_after, show_context_menu}, + ext_event::create_ext_action, + keyboard::Modifiers, + kurbo::{Point, Rect, Vec2}, + menu::{Menu, MenuItem}, + pointer::{MouseButton, PointerInputEvent, PointerMoveEvent}, + prelude::SignalTrack, + reactive::{ + ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith, batch, + use_context, + }, + views::editor::{ + Editor, + command::CommandExecuted, + id::EditorId, + movement, + text::Document, + view::{ + DiffSection, DiffSectionKind, LineInfo, ScreenLines, ScreenLinesBase, + }, + visual_line::{ConfigId, Lines, TextLayoutProvider, VLine, VLineInfo}, + }, +}; +use itertools::Itertools; +use lapce_core::{ + buffer::{ + InvalLines, + diff::DiffLines, + rope_text::{RopeText, RopeTextVal}, + }, + command::{ + EditCommand, FocusCommand, MotionModeCommand, MultiSelectionCommand, + ScrollCommand, + }, + cursor::{Cursor, CursorMode}, + editor::EditType, + mode::{Mode, MotionMode}, + rope_text_pos::RopeTextPosition, + selection::{InsertDrift, SelRegion, Selection}, +}; +use lapce_rpc::{buffer::BufferId, plugin::PluginId, proxy::ProxyResponse}; +use lapce_xi_rope::{Rope, RopeDelta, Transformer}; +use lsp_types::{ + CodeActionResponse, CompletionItem, CompletionTextEdit, GotoDefinitionResponse, + HoverContents, InlayHint, InlayHintLabel, InlineCompletionTriggerKind, Location, + MarkedString, MarkupKind, Range, TextEdit, +}; +use nucleo::Utf32Str; +use serde::{Deserialize, Serialize}; +use view::StickyHeaderInfo; + +use self::{ + diff::DiffInfo, + location::{EditorLocation, EditorPosition}, +}; +use crate::{ + command::{CommandKind, InternalCommand, LapceCommand, LapceWorkbenchCommand}, + completion::CompletionStatus, + config::LapceConfig, + db::LapceDb, + doc::{Doc, DocContent}, + editor_tab::EditorTabChild, + id::{DiffEditorId, EditorTabId}, + inline_completion::{InlineCompletionItem, InlineCompletionStatus}, + keypress::{KeyPressFocus, condition::Condition}, + lsp::path_from_url, + main_split::{Editors, MainSplitData, SplitDirection, SplitMoveDirection}, + markdown::{ + MarkdownContent, from_marked_string, from_plaintext, parse_markdown, + }, + panel::{ + call_hierarchy_view::CallHierarchyItemData, + implementation_view::{init_implementation_root, map_to_location}, + kind::PanelKind, + }, + snippet::Snippet, + tracing::*, + window_tab::{CommonData, Focus, WindowTabData}, +}; + +pub mod diff; +pub mod gutter; +pub mod location; +pub mod view; + +#[derive(Clone, Debug)] +pub enum InlineFindDirection { + Left, + Right, +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct EditorInfo { + pub content: DocContent, + pub unsaved: Option, + pub offset: usize, + pub scroll_offset: (f64, f64), +} + +impl EditorInfo { + pub fn to_data( + &self, + data: MainSplitData, + editor_tab_id: EditorTabId, + ) -> EditorId { + let editors = &data.editors; + let common = data.common.clone(); + match &self.content { + DocContent::File { path, .. } => { + let (doc, new_doc) = + data.get_doc(path.clone(), self.unsaved.clone()); + let editor = editors.make_from_doc( + data.scope, + doc, + Some(editor_tab_id), + None, + None, + common, + ); + editor.go_to_location( + EditorLocation { + path: path.clone(), + position: Some(EditorPosition::Offset(self.offset)), + scroll_offset: Some(Vec2::new( + self.scroll_offset.0, + self.scroll_offset.1, + )), + ignore_unconfirmed: false, + same_editor_tab: false, + }, + new_doc, + None, + ); + + editor.id() + } + DocContent::Local => editors.new_local(data.scope, common), + DocContent::History(_) => editors.new_local(data.scope, common), + DocContent::Scratch { name, .. } => { + let doc = data + .scratch_docs + .try_update(|scratch_docs| { + if let Some(doc) = scratch_docs.get(name) { + return doc.clone(); + } + let content = DocContent::Scratch { + id: BufferId::next(), + name: name.to_string(), + }; + let doc = Doc::new_content( + data.scope, + content, + data.editors, + data.common.clone(), + ); + let doc = Rc::new(doc); + if let Some(unsaved) = &self.unsaved { + doc.reload(Rope::from(unsaved), false); + } + scratch_docs.insert(name.to_string(), doc.clone()); + doc + }) + .unwrap(); + + editors.new_from_doc( + data.scope, + doc, + Some(editor_tab_id), + None, + None, + common, + ) + } + } + } +} + +#[derive(Clone)] +pub enum EditorViewKind { + Normal, + Diff(DiffInfo), +} + +impl EditorViewKind { + pub fn is_normal(&self) -> bool { + matches!(self, EditorViewKind::Normal) + } +} + +#[derive(Clone)] +pub struct OnScreenFind { + pub active: bool, + pub pattern: String, + pub regions: Vec, +} + +pub type SnippetIndex = Vec<(usize, (usize, usize))>; + +/// Shares data between cloned instances as long as the signals aren't swapped out. +#[derive(Clone, Debug)] +pub struct EditorData { + pub scope: Scope, + pub editor_tab_id: RwSignal>, + pub diff_editor_id: RwSignal>, + pub confirmed: RwSignal, + pub snippet: RwSignal>, + pub inline_find: RwSignal>, + pub on_screen_find: RwSignal, + pub last_inline_find: RwSignal>, + pub find_focus: RwSignal, + pub editor: Rc, + pub kind: RwSignal, + pub sticky_header_height: RwSignal, + pub common: Rc, + pub sticky_header_info: RwSignal, +} + +impl PartialEq for EditorData { + fn eq(&self, other: &Self) -> bool { + self.id() == other.id() + } +} + +impl EditorData { + fn new( + cx: Scope, + editor: Editor, + editor_tab_id: Option, + diff_editor_id: Option<(EditorTabId, DiffEditorId)>, + confirmed: Option>, + common: Rc, + ) -> Self { + let cx = cx.create_child(); + + let confirmed = confirmed.unwrap_or_else(|| cx.create_rw_signal(false)); + EditorData { + scope: cx, + editor_tab_id: cx.create_rw_signal(editor_tab_id), + diff_editor_id: cx.create_rw_signal(diff_editor_id), + confirmed, + snippet: cx.create_rw_signal(None), + inline_find: cx.create_rw_signal(None), + on_screen_find: cx.create_rw_signal(OnScreenFind { + active: false, + pattern: "".to_string(), + regions: Vec::new(), + }), + last_inline_find: cx.create_rw_signal(None), + find_focus: cx.create_rw_signal(false), + editor: Rc::new(editor), + kind: cx.create_rw_signal(EditorViewKind::Normal), + sticky_header_height: cx.create_rw_signal(0.0), + common, + sticky_header_info: cx.create_rw_signal(StickyHeaderInfo::default()), + } + } + + /// Create a new local editor. + /// + /// You should prefer calling [`Editors::make_local`] / [`Editors::new_local`] instead to + /// register the editor. + pub fn new_local(cx: Scope, editors: Editors, common: Rc) -> Self { + Self::new_local_id(cx, EditorId::next(), editors, common) + } + + /// Create a new local editor with the given id. + /// + /// You should prefer calling [`Editors::make_local`] / [`Editors::new_local`] instead to + /// register the editor. + pub fn new_local_id( + cx: Scope, + editor_id: EditorId, + editors: Editors, + common: Rc, + ) -> Self { + let cx = cx.create_child(); + let doc = Rc::new(Doc::new_local(cx, editors, common.clone())); + let editor = doc.create_editor(cx, editor_id, true); + Self::new(cx, editor, None, None, None, common) + } + + /// Create a new editor with a specific doc. + /// + /// You should prefer calling [`Editors::new_editor_doc`] / [`Editors::make_from_doc`] instead. + pub fn new_doc( + cx: Scope, + doc: Rc, + editor_tab_id: Option, + diff_editor_id: Option<(EditorTabId, DiffEditorId)>, + confirmed: Option>, + common: Rc, + ) -> Self { + let editor = doc.create_editor(cx, EditorId::next(), false); + Self::new(cx, editor, editor_tab_id, diff_editor_id, confirmed, common) + } + + /// Swap out the document this editor is for + pub fn update_doc(&self, doc: Rc) { + let style = doc.styling(); + self.editor.update_doc(doc, Some(style)); + } + + /// Create a new editor using the same underlying [`Doc`] + pub fn copy( + &self, + cx: Scope, + editor_tab_id: Option, + diff_editor_id: Option<(EditorTabId, DiffEditorId)>, + confirmed: Option>, + ) -> Self { + let cx = cx.create_child(); + + let confirmed = confirmed.unwrap_or_else(|| cx.create_rw_signal(true)); + + let editor = Self::new_doc( + cx, + self.doc(), + editor_tab_id, + diff_editor_id, + Some(confirmed), + self.common.clone(), + ); + editor.editor.cursor.set(self.editor.cursor.get_untracked()); + editor + .editor + .viewport + .set(self.editor.viewport.get_untracked()); + editor.editor.scroll_to.set(Some( + self.editor.viewport.get_untracked().origin().to_vec2(), + )); + editor + .editor + .last_movement + .set(self.editor.last_movement.get_untracked()); + + editor + } + + pub fn id(&self) -> EditorId { + self.editor.id() + } + + pub fn editor_info(&self, _data: &WindowTabData) -> EditorInfo { + let offset = self.cursor().get_untracked().offset(); + let scroll_offset = self.viewport().get_untracked().origin(); + let doc = self.doc(); + let is_pristine = doc.is_pristine(); + let unsaved = if is_pristine { + None + } else { + Some(doc.buffer.with_untracked(|b| b.to_string())) + }; + EditorInfo { + content: self.doc().content.get_untracked(), + unsaved, + offset, + scroll_offset: (scroll_offset.x, scroll_offset.y), + } + } + + pub fn cursor(&self) -> RwSignal { + self.editor.cursor + } + + pub fn viewport(&self) -> RwSignal { + self.editor.viewport + } + + pub fn window_origin(&self) -> RwSignal { + self.editor.window_origin + } + + pub fn scroll_delta(&self) -> RwSignal { + self.editor.scroll_delta + } + + pub fn scroll_to(&self) -> RwSignal> { + self.editor.scroll_to + } + + pub fn active(&self) -> RwSignal { + self.editor.active + } + + /// Get the line information for lines on the screen. + pub fn screen_lines(&self) -> RwSignal { + self.editor.screen_lines + } + + pub fn doc(&self) -> Rc { + let doc = self.editor.doc(); + let Ok(doc) = (doc as Rc).downcast() else { + panic!("doc is not Rc"); + }; + + doc + } + + /// The signal for the editor's document. + pub fn doc_signal(&self) -> DocSignal { + DocSignal { + inner: self.editor.doc_signal(), + } + } + + pub fn text(&self) -> Rope { + self.editor.text() + } + + pub fn rope_text(&self) -> RopeTextVal { + self.editor.rope_text() + } + + fn run_edit_command(&self, cmd: &EditCommand) -> CommandExecuted { + let doc = self.doc(); + let text = self.editor.rope_text(); + let is_local = doc.content.with_untracked(|content| content.is_local()); + let modal = self.editor.es.with_untracked(|s| s.modal()) && !is_local; + let smart_tab = self + .common + .config + .with_untracked(|config| config.editor.smart_tab); + let doc_before_edit = text.text().clone(); + let mut cursor = self.editor.cursor.get_untracked(); + let mut register = self.common.register.get_untracked(); + + let yank_data = + if let lapce_core::cursor::CursorMode::Visual { .. } = &cursor.mode { + Some(cursor.yank(&text)) + } else { + None + }; + + let deltas = + batch(|| doc.do_edit(&mut cursor, cmd, modal, &mut register, smart_tab)); + + if !deltas.is_empty() { + if let Some(data) = yank_data { + register.add_delete(data); + } + } + + self.editor.cursor.set(cursor); + self.editor.register.set(register); + + if show_completion(cmd, &doc_before_edit, &deltas) { + self.update_completion(false); + } else { + self.cancel_completion(); + } + + if *cmd == EditCommand::InsertNewLine { + // Cancel so that there's no flickering + self.cancel_inline_completion(); + self.update_inline_completion(InlineCompletionTriggerKind::Automatic); + self.quit_on_screen_find(); + } else if show_inline_completion(cmd) { + self.update_inline_completion(InlineCompletionTriggerKind::Automatic); + } else { + self.cancel_inline_completion(); + } + + self.apply_deltas(&deltas); + if let EditCommand::NormalMode = cmd { + self.snippet.set(None); + self.quit_on_screen_find(); + } + + CommandExecuted::Yes + } + + fn run_motion_mode_command( + &self, + cmd: &MotionModeCommand, + count: Option, + ) -> CommandExecuted { + let count = count.unwrap_or(1); + let motion_mode = match cmd { + MotionModeCommand::MotionModeDelete => MotionMode::Delete { count }, + MotionModeCommand::MotionModeIndent => MotionMode::Indent, + MotionModeCommand::MotionModeOutdent => MotionMode::Outdent, + MotionModeCommand::MotionModeYank => MotionMode::Yank { count }, + }; + let mut cursor = self.editor.cursor.get_untracked(); + let mut register = self.common.register.get_untracked(); + + movement::do_motion_mode( + &self.editor, + &*self.doc(), + &mut cursor, + motion_mode, + &mut register, + ); + + self.editor.cursor.set(cursor); + self.common.register.set(register); + + CommandExecuted::Yes + } + + fn run_multi_selection_command( + &self, + cmd: &MultiSelectionCommand, + ) -> CommandExecuted { + let mut cursor = self.editor.cursor.get_untracked(); + let rope_text = self.rope_text(); + let doc = self.doc(); + let config = self.common.config.get_untracked(); + + // This is currently special-cased in Lapce because floem editor does not have 'find' + match cmd { + MultiSelectionCommand::SelectAllCurrent => { + if let CursorMode::Insert(mut selection) = cursor.mode.clone() { + if !selection.is_empty() { + let find = doc.find(); + + let first = selection.first().unwrap(); + let (start, end) = if first.is_caret() { + rope_text.select_word(first.start) + } else { + (first.min(), first.max()) + }; + let search_str = rope_text.slice_to_cow(start..end); + let case_sensitive = find.case_sensitive(false); + let multicursor_case_sensitive = + config.editor.multicursor_case_sensitive; + let case_sensitive = + multicursor_case_sensitive || case_sensitive; + // let search_whole_word = config.editor.multicursor_whole_words; + find.set_case_sensitive(case_sensitive); + find.set_find(&search_str); + let mut offset = 0; + while let Some((start, end)) = + find.next(rope_text.text(), offset, false, false) + { + offset = end; + selection.add_region(SelRegion::new(start, end, None)); + } + } + cursor.set_insert(selection); + } + } + MultiSelectionCommand::SelectNextCurrent => { + if let CursorMode::Insert(mut selection) = cursor.mode.clone() { + if !selection.is_empty() { + let mut had_caret = false; + for region in selection.regions_mut() { + if region.is_caret() { + had_caret = true; + let (start, end) = + rope_text.select_word(region.start); + region.start = start; + region.end = end; + } + } + if !had_caret { + let find = doc.find(); + + let r = selection.last_inserted().unwrap(); + let search_str = + rope_text.slice_to_cow(r.min()..r.max()); + let case_sensitive = find.case_sensitive(false); + let case_sensitive = + config.editor.multicursor_case_sensitive + || case_sensitive; + // let search_whole_word = + // config.editor.multicursor_whole_words; + find.set_case_sensitive(case_sensitive); + find.set_find(&search_str); + let mut offset = r.max(); + let mut seen = HashSet::new(); + while let Some((start, end)) = + find.next(rope_text.text(), offset, false, true) + { + if !selection + .regions() + .iter() + .any(|r| r.min() == start && r.max() == end) + { + selection.add_region(SelRegion::new( + start, end, None, + )); + break; + } + if seen.contains(&end) { + break; + } + offset = end; + seen.insert(offset); + } + } + } + cursor.set_insert(selection); + } + } + MultiSelectionCommand::SelectSkipCurrent => { + if let CursorMode::Insert(mut selection) = cursor.mode.clone() { + if !selection.is_empty() { + let r = selection.last_inserted().unwrap(); + if r.is_caret() { + let (start, end) = rope_text.select_word(r.start); + selection.replace_last_inserted_region(SelRegion::new( + start, end, None, + )); + } else { + let find = doc.find(); + + let search_str = + rope_text.slice_to_cow(r.min()..r.max()); + find.set_find(&search_str); + let mut offset = r.max(); + let mut seen = HashSet::new(); + while let Some((start, end)) = + find.next(rope_text.text(), offset, false, true) + { + if !selection + .regions() + .iter() + .any(|r| r.min() == start && r.max() == end) + { + selection.replace_last_inserted_region( + SelRegion::new(start, end, None), + ); + break; + } + if seen.contains(&end) { + break; + } + offset = end; + seen.insert(offset); + } + } + } + cursor.set_insert(selection); + } + } + _ => movement::do_multi_selection(&self.editor, &mut cursor, cmd), + }; + + self.editor.cursor.set(cursor); + // self.cancel_signature(); + self.cancel_completion(); + self.cancel_inline_completion(); + CommandExecuted::Yes + } + + fn run_move_command( + &self, + movement: &lapce_core::movement::Movement, + count: Option, + mods: Modifiers, + ) -> CommandExecuted { + self.common.hover.active.set(false); + if movement.is_jump() + && movement != &self.editor.last_movement.get_untracked() + { + let path = self + .doc() + .content + .with_untracked(|content| content.path().cloned()); + if let Some(path) = path { + let offset = self.cursor().with_untracked(|c| c.offset()); + let scroll_offset = + self.viewport().get_untracked().origin().to_vec2(); + self.common.internal_command.send( + InternalCommand::SaveJumpLocation { + path, + offset, + scroll_offset, + }, + ); + } + } + self.editor.last_movement.set(movement.clone()); + + let mut cursor = self.cursor().get_untracked(); + self.common.register.update(|register| { + movement::move_cursor( + &self.editor, + &*self.doc(), + &mut cursor, + movement, + count.unwrap_or(1), + mods.shift(), + register, + ) + }); + + self.editor.cursor.set(cursor); + + if self.snippet.with_untracked(|s| s.is_some()) { + self.snippet.update(|snippet| { + let offset = self.editor.cursor.get_untracked().offset(); + let mut within_region = false; + for (_, (start, end)) in snippet.as_mut().unwrap() { + if offset >= *start && offset <= *end { + within_region = true; + break; + } + } + if !within_region { + *snippet = None; + } + }) + } + self.cancel_completion(); + CommandExecuted::Yes + } + + pub fn run_scroll_command( + &self, + cmd: &ScrollCommand, + count: Option, + mods: Modifiers, + ) -> CommandExecuted { + let prev_completion_index = self + .common + .completion + .with_untracked(|c| c.active.get_untracked()); + + match cmd { + ScrollCommand::PageUp => { + self.editor.page_move(false, mods); + } + ScrollCommand::PageDown => { + self.editor.page_move(true, mods); + } + ScrollCommand::ScrollUp => { + self.scroll(false, count.unwrap_or(1), mods); + } + ScrollCommand::ScrollDown => { + self.scroll(true, count.unwrap_or(1), mods); + } + // TODO: + ScrollCommand::CenterOfWindow => {} + ScrollCommand::TopOfWindow => {} + ScrollCommand::BottomOfWindow => {} + } + + let current_completion_index = self + .common + .completion + .with_untracked(|c| c.active.get_untracked()); + + if prev_completion_index != current_completion_index { + self.common.completion.with_untracked(|c| { + let cursor_offset = self.cursor().with_untracked(|c| c.offset()); + c.update_document_completion(self, cursor_offset); + }); + } + + CommandExecuted::Yes + } + + pub fn run_focus_command( + &self, + cmd: &FocusCommand, + _count: Option, + mods: Modifiers, + ) -> CommandExecuted { + // TODO(minor): Evaluate whether we should split this into subenums, + // such as actions specific to the actual editor pane, movement, and list movement. + let prev_completion_index = self + .common + .completion + .with_untracked(|c| c.active.get_untracked()); + + match cmd { + FocusCommand::ModalClose => { + self.cancel_completion(); + } + FocusCommand::SplitVertical => { + if let Some(editor_tab_id) = + self.editor_tab_id.read_only().get_untracked() + { + self.common.internal_command.send(InternalCommand::Split { + direction: SplitDirection::Vertical, + editor_tab_id, + }); + } else if let Some((editor_tab_id, _)) = + self.diff_editor_id.get_untracked() + { + self.common.internal_command.send(InternalCommand::Split { + direction: SplitDirection::Vertical, + editor_tab_id, + }); + } else { + return CommandExecuted::No; + } + } + FocusCommand::SplitHorizontal => { + if let Some(editor_tab_id) = self.editor_tab_id.get_untracked() { + self.common.internal_command.send(InternalCommand::Split { + direction: SplitDirection::Horizontal, + editor_tab_id, + }); + } else if let Some((editor_tab_id, _)) = + self.diff_editor_id.get_untracked() + { + self.common.internal_command.send(InternalCommand::Split { + direction: SplitDirection::Horizontal, + editor_tab_id, + }); + } else { + return CommandExecuted::No; + } + } + FocusCommand::SplitRight => { + if let Some(editor_tab_id) = self.editor_tab_id.get_untracked() { + self.common + .internal_command + .send(InternalCommand::SplitMove { + direction: SplitMoveDirection::Right, + editor_tab_id, + }); + } else if let Some((editor_tab_id, _)) = + self.diff_editor_id.get_untracked() + { + self.common + .internal_command + .send(InternalCommand::SplitMove { + direction: SplitMoveDirection::Right, + editor_tab_id, + }); + } else { + return CommandExecuted::No; + } + } + FocusCommand::SplitLeft => { + if let Some(editor_tab_id) = self.editor_tab_id.get_untracked() { + self.common + .internal_command + .send(InternalCommand::SplitMove { + direction: SplitMoveDirection::Left, + editor_tab_id, + }); + } else if let Some((editor_tab_id, _)) = + self.diff_editor_id.get_untracked() + { + self.common + .internal_command + .send(InternalCommand::SplitMove { + direction: SplitMoveDirection::Left, + editor_tab_id, + }); + } else { + return CommandExecuted::No; + } + } + FocusCommand::SplitUp => { + if let Some(editor_tab_id) = self.editor_tab_id.get_untracked() { + self.common + .internal_command + .send(InternalCommand::SplitMove { + direction: SplitMoveDirection::Up, + editor_tab_id, + }); + } else if let Some((editor_tab_id, _)) = + self.diff_editor_id.get_untracked() + { + self.common + .internal_command + .send(InternalCommand::SplitMove { + direction: SplitMoveDirection::Up, + editor_tab_id, + }); + } else { + return CommandExecuted::No; + } + } + FocusCommand::SplitDown => { + if let Some(editor_tab_id) = self.editor_tab_id.get_untracked() { + self.common + .internal_command + .send(InternalCommand::SplitMove { + direction: SplitMoveDirection::Down, + editor_tab_id, + }); + } else if let Some((editor_tab_id, _)) = + self.diff_editor_id.get_untracked() + { + self.common + .internal_command + .send(InternalCommand::SplitMove { + direction: SplitMoveDirection::Down, + editor_tab_id, + }); + } else { + return CommandExecuted::No; + } + } + FocusCommand::SplitExchange => { + if let Some(editor_tab_id) = self.editor_tab_id.get_untracked() { + self.common + .internal_command + .send(InternalCommand::SplitExchange { editor_tab_id }); + } else if let Some((editor_tab_id, _)) = + self.diff_editor_id.get_untracked() + { + self.common + .internal_command + .send(InternalCommand::SplitExchange { editor_tab_id }); + } else { + return CommandExecuted::No; + } + } + FocusCommand::SplitClose => { + if let Some(editor_tab_id) = self.editor_tab_id.get_untracked() { + self.common.internal_command.send( + InternalCommand::EditorTabChildClose { + editor_tab_id, + child: EditorTabChild::Editor(self.id()), + }, + ); + } else if let Some((editor_tab_id, diff_editor_id)) = + self.diff_editor_id.get_untracked() + { + self.common.internal_command.send( + InternalCommand::EditorTabChildClose { + editor_tab_id, + child: EditorTabChild::DiffEditor(diff_editor_id), + }, + ); + } else { + return CommandExecuted::No; + } + } + FocusCommand::ListNext => { + self.common.completion.update(|c| { + c.next(); + }); + } + FocusCommand::ListPrevious => { + self.common.completion.update(|c| { + c.previous(); + }); + } + FocusCommand::ListNextPage => { + self.common.completion.update(|c| { + c.next_page(); + }); + } + FocusCommand::ListPreviousPage => { + self.common.completion.update(|c| { + c.previous_page(); + }); + } + FocusCommand::ListSelect => { + self.select_completion(); + self.cancel_inline_completion(); + } + FocusCommand::JumpToNextSnippetPlaceholder => { + self.snippet.update(|snippet| { + if let Some(snippet_mut) = snippet.as_mut() { + let mut current = 0; + let offset = self.cursor().get_untracked().offset(); + for (i, (_, (start, end))) in snippet_mut.iter().enumerate() + { + if *start <= offset && offset <= *end { + current = i; + break; + } + } + + let last_placeholder = current + 1 >= snippet_mut.len() - 1; + + if let Some((_, (start, end))) = snippet_mut.get(current + 1) + { + let mut selection = + lapce_core::selection::Selection::new(); + let region = lapce_core::selection::SelRegion::new( + *start, *end, None, + ); + selection.add_region(region); + self.cursor().update(|cursor| { + cursor.set_insert(selection); + }); + } + + if last_placeholder { + *snippet = None; + } + // self.update_signature(); + self.cancel_completion(); + self.cancel_inline_completion(); + } + }); + } + FocusCommand::JumpToPrevSnippetPlaceholder => { + self.snippet.update(|snippet| { + if let Some(snippet_mut) = snippet.as_mut() { + let mut current = 0; + let offset = self.cursor().get_untracked().offset(); + for (i, (_, (start, end))) in snippet_mut.iter().enumerate() + { + if *start <= offset && offset <= *end { + current = i; + break; + } + } + + if current > 0 { + if let Some((_, (start, end))) = + snippet_mut.get(current - 1) + { + let mut selection = + lapce_core::selection::Selection::new(); + let region = lapce_core::selection::SelRegion::new( + *start, *end, None, + ); + selection.add_region(region); + self.cursor().update(|cursor| { + cursor.set_insert(selection); + }); + } + // self.update_signature(); + self.cancel_completion(); + self.cancel_inline_completion(); + } + } + }); + } + FocusCommand::GotoDefinition => { + self.go_to_definition(); + } + FocusCommand::ShowCodeActions => { + self.show_code_actions(false); + } + FocusCommand::SearchWholeWordForward => { + self.search_whole_word_forward(mods); + } + FocusCommand::SearchForward => { + self.search_forward(mods); + } + FocusCommand::SearchBackward => { + self.search_backward(mods); + } + FocusCommand::Save => { + self.save(true, || {}); + } + FocusCommand::SaveWithoutFormatting => { + self.save(false, || {}); + } + FocusCommand::FormatDocument => { + self.format(); + } + FocusCommand::InlineFindLeft => { + self.inline_find.set(Some(InlineFindDirection::Left)); + } + FocusCommand::InlineFindRight => { + self.inline_find.set(Some(InlineFindDirection::Right)); + } + FocusCommand::OnScreenFind => { + self.on_screen_find.update(|find| { + find.active = true; + find.pattern.clear(); + find.regions.clear(); + }); + } + FocusCommand::RepeatLastInlineFind => { + if let Some((direction, c)) = self.last_inline_find.get_untracked() { + self.inline_find(direction, &c); + } + } + FocusCommand::Rename => { + self.rename(); + } + FocusCommand::ClearSearch => { + self.clear_search(); + } + FocusCommand::Search => { + self.search(); + } + FocusCommand::FocusFindEditor => { + self.common.find.replace_focus.set(false); + } + FocusCommand::FocusReplaceEditor => { + if self.common.find.replace_active.get_untracked() { + self.common.find.replace_focus.set(true); + } + } + FocusCommand::InlineCompletionSelect => { + self.select_inline_completion(); + } + FocusCommand::InlineCompletionNext => { + self.next_inline_completion(); + } + FocusCommand::InlineCompletionPrevious => { + self.previous_inline_completion(); + } + FocusCommand::InlineCompletionCancel => { + self.cancel_inline_completion(); + } + FocusCommand::InlineCompletionInvoke => { + self.update_inline_completion(InlineCompletionTriggerKind::Invoked); + } + FocusCommand::ShowHover => { + let start_offset = self.doc().buffer.with_untracked(|b| { + b.prev_code_boundary(self.cursor().get_untracked().offset()) + }); + self.update_hover(start_offset); + } + _ => {} + } + + let current_completion_index = self + .common + .completion + .with_untracked(|c| c.active.get_untracked()); + + if prev_completion_index != current_completion_index { + self.common.completion.with_untracked(|c| { + let cursor_offset = self.cursor().with_untracked(|c| c.offset()); + c.update_document_completion(self, cursor_offset); + }); + } + + CommandExecuted::Yes + } + + /// Jump to the next/previous column on the line which matches the given text + fn inline_find(&self, direction: InlineFindDirection, c: &str) { + let offset = self.cursor().with_untracked(|c| c.offset()); + let doc = self.doc(); + let (line_content, line_start_offset) = + doc.buffer.with_untracked(|buffer| { + let line = buffer.line_of_offset(offset); + let line_content = buffer.line_content(line); + let line_start_offset = buffer.offset_of_line(line); + (line_content.to_string(), line_start_offset) + }); + let index = offset - line_start_offset; + if let Some(new_index) = match direction { + InlineFindDirection::Left => line_content[..index].rfind(c), + InlineFindDirection::Right => { + if index + 1 >= line_content.len() { + None + } else { + let index = index + + doc.buffer.with_untracked(|buffer| { + buffer.next_grapheme_offset( + offset, + 1, + buffer.offset_line_end(offset, false), + ) + }) + - offset; + line_content[index..].find(c).map(|i| i + index) + } + } + } { + self.run_move_command( + &lapce_core::movement::Movement::Offset( + new_index + line_start_offset, + ), + None, + Modifiers::empty(), + ); + } + } + + fn quit_on_screen_find(&self) { + if self.on_screen_find.with_untracked(|s| s.active) { + self.on_screen_find.update(|f| { + f.active = false; + f.pattern.clear(); + f.regions.clear(); + }) + } + } + + fn on_screen_find(&self, pattern: &str) -> Vec { + let screen_lines = self.screen_lines().get_untracked(); + let lines: HashSet = + screen_lines.lines.iter().map(|l| l.line).collect(); + + let mut matcher = nucleo::Matcher::new(nucleo::Config::DEFAULT); + let pattern = nucleo::pattern::Pattern::parse( + pattern, + nucleo::pattern::CaseMatching::Ignore, + nucleo::pattern::Normalization::Smart, + ); + let mut indices = Vec::new(); + let mut filter_text_buf = Vec::new(); + let mut items = Vec::new(); + + let buffer = self.doc().buffer; + + for line in lines { + filter_text_buf.clear(); + indices.clear(); + + buffer.with_untracked(|buffer| { + let start = buffer.offset_of_line(line); + let end = buffer.offset_of_line(line + 1); + let text = buffer.text().slice_to_cow(start..end); + let filter_text = Utf32Str::new(&text, &mut filter_text_buf); + + if let Some(score) = + pattern.indices(filter_text, &mut matcher, &mut indices) + { + indices.sort(); + let left = + start + indices.first().copied().unwrap_or(0) as usize; + let right = + start + indices.last().copied().unwrap_or(0) as usize + 1; + let right = if right == left { left + 1 } else { right }; + items.push((score, left, right)); + } + }); + } + + items.sort_by_key(|(score, _, _)| -(*score as i64)); + if let Some((_, offset, _)) = items.first().copied() { + self.run_move_command( + &lapce_core::movement::Movement::Offset(offset), + None, + Modifiers::empty(), + ); + } + + items + .into_iter() + .map(|(_, start, end)| SelRegion::new(start, end, None)) + .collect() + } + + fn go_to_definition(&self) { + let doc = self.doc(); + let path = match if doc.loaded() { + doc.content.with_untracked(|c| c.path().cloned()) + } else { + None + } { + Some(path) => path, + None => return, + }; + + let offset = self.cursor().with_untracked(|c| c.offset()); + let (start_position, position) = doc.buffer.with_untracked(|buffer| { + let start_offset = buffer.prev_code_boundary(offset); + let start_position = buffer.offset_to_position(start_offset); + let position = buffer.offset_to_position(offset); + (start_position, position) + }); + + enum DefinitionOrReference { + Location(EditorLocation), + References(Vec), + } + + let internal_command = self.common.internal_command; + let cursor = self.cursor().read_only(); + let send = create_ext_action(self.scope, move |d| { + let current_offset = cursor.with_untracked(|c| c.offset()); + if current_offset != offset { + return; + } + + match d { + DefinitionOrReference::Location(location) => { + internal_command + .send(InternalCommand::JumpToLocation { location }); + } + DefinitionOrReference::References(locations) => { + internal_command.send(InternalCommand::PaletteReferences { + references: locations + .into_iter() + .map(|l| EditorLocation { + path: path_from_url(&l.uri), + position: Some(EditorPosition::Position( + l.range.start, + )), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }) + .collect(), + }); + } + } + }); + let proxy = self.common.proxy.clone(); + self.common.proxy.get_definition( + offset, + path.clone(), + position, + move |result| { + if let Ok(ProxyResponse::GetDefinitionResponse { + definition, .. + }) = result + { + if let Some(location) = match definition { + GotoDefinitionResponse::Scalar(location) => Some(location), + GotoDefinitionResponse::Array(locations) => { + if !locations.is_empty() { + Some(locations[0].clone()) + } else { + None + } + } + GotoDefinitionResponse::Link(location_links) => { + let location_link = location_links[0].clone(); + Some(Location { + uri: location_link.target_uri, + range: location_link.target_selection_range, + }) + } + } { + if location.range.start == start_position { + proxy.get_references( + path.clone(), + position, + move |result| { + if let Ok( + ProxyResponse::GetReferencesResponse { + references, + }, + ) = result + { + if references.is_empty() { + return; + } + if references.len() == 1 { + let location = &references[0]; + send(DefinitionOrReference::Location( + EditorLocation { + path: path_from_url( + &location.uri, + ), + position: Some( + EditorPosition::Position( + location.range.start, + ), + ), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }, + )); + } else { + send(DefinitionOrReference::References( + references, + )); + } + } + }, + ); + } else { + let path = path_from_url(&location.uri); + send(DefinitionOrReference::Location(EditorLocation { + path, + position: Some(EditorPosition::Position( + location.range.start, + )), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + })); + } + } + } + }, + ); + } + + pub fn call_hierarchy(&self, window_tab_data: WindowTabData) { + let doc = self.doc(); + let path = match if doc.loaded() { + doc.content.with_untracked(|c| c.path().cloned()) + } else { + None + } { + Some(path) => path, + None => return, + }; + + let offset = self.cursor().with_untracked(|c| c.offset()); + let (_start_position, position) = doc.buffer.with_untracked(|buffer| { + let start_offset = buffer.prev_code_boundary(offset); + let start_position = buffer.offset_to_position(start_offset); + let position = buffer.offset_to_position(offset); + (start_position, position) + }); + let scope = window_tab_data.scope; + let range = Range { + start: _start_position, + end: position, + }; + self.common.proxy.show_call_hierarchy( + path, + position, + create_ext_action(self.scope, move |result| { + if let Ok(ProxyResponse::ShowCallHierarchyResponse { + items, .. + }) = result + { + if let Some(item) = items.and_then(|x| x.into_iter().next()) { + let root = scope.create_rw_signal(CallHierarchyItemData { + view_id: ViewId::new(), + item: Rc::new(item), + from_range: range, + init: false, + open: scope.create_rw_signal(true), + children: scope.create_rw_signal(Vec::with_capacity(0)), + }); + let item = root; + window_tab_data.call_hierarchy_data.root.update(|x| { + *x = Some(root); + }); + window_tab_data.show_panel(PanelKind::CallHierarchy); + window_tab_data.common.internal_command.send( + InternalCommand::CallHierarchyIncoming { + item_id: item.get_untracked().view_id, + }, + ); + } + } + }), + ); + } + + pub fn find_reference(&self, window_tab_data: WindowTabData) { + let doc = self.doc(); + let path = match if doc.loaded() { + doc.content.with_untracked(|c| c.path().cloned()) + } else { + None + } { + Some(path) => path, + None => return, + }; + + let offset = self.cursor().with_untracked(|c| c.offset()); + let (_start_position, position) = doc.buffer.with_untracked(|buffer| { + let start_offset = buffer.prev_code_boundary(offset); + let start_position = buffer.offset_to_position(start_offset); + let position = buffer.offset_to_position(offset); + (start_position, position) + }); + let scope = window_tab_data.scope; + let update_implementation = create_ext_action(self.scope, { + let window_tab_data = window_tab_data.clone(); + move |result| { + if let Ok(ProxyResponse::ReferencesResolveResponse { items }) = + result + { + window_tab_data + .main_split + .references + .update(|x| *x = init_implementation_root(items, scope)); + window_tab_data.show_panel(PanelKind::References); + } + } + }); + let proxy = self.common.proxy.clone(); + self.common.proxy.get_references( + path, + position, + create_ext_action(self.scope, move |result| { + if let Ok(ProxyResponse::GetReferencesResponse { references }) = + result + { + { + if !references.is_empty() { + proxy.references_resolve( + references, + update_implementation, + ); + } else { + window_tab_data.show_panel(PanelKind::References); + } + } + } + }), + ); + } + + pub fn go_to_implementation(&self, window_tab_data: WindowTabData) { + let doc = self.doc(); + let path = match if doc.loaded() { + doc.content.with_untracked(|c| c.path().cloned()) + } else { + None + } { + Some(path) => path, + None => return, + }; + + let offset = self.cursor().with_untracked(|c| c.offset()); + let (_start_position, position) = doc.buffer.with_untracked(|buffer| { + let start_offset = buffer.prev_code_boundary(offset); + let start_position = buffer.offset_to_position(start_offset); + let position = buffer.offset_to_position(offset); + (start_position, position) + }); + let scope = window_tab_data.scope; + let update_implementation = create_ext_action(self.scope, { + let window_tab_data = window_tab_data.clone(); + move |result| { + if let Ok(ProxyResponse::ReferencesResolveResponse { items }) = + result + { + window_tab_data + .main_split + .implementations + .update(|x| *x = init_implementation_root(items, scope)); + window_tab_data.show_panel(PanelKind::Implementation); + } + } + }); + let proxy = self.common.proxy.clone(); + self.common.proxy.go_to_implementation( + path, + position, + create_ext_action(self.scope, { + move |result| { + if let Ok(ProxyResponse::GotoImplementationResponse { + resp, + .. + }) = result + { + let locations = map_to_location(resp); + if !locations.is_empty() { + proxy.references_resolve( + locations, + update_implementation, + ); + } else { + window_tab_data.show_panel(PanelKind::Implementation); + } + } + } + }), + ); + } + + fn scroll(&self, down: bool, count: usize, mods: Modifiers) { + self.editor.scroll( + self.sticky_header_height.get_untracked(), + down, + count, + mods, + ) + } + + fn select_inline_completion(&self) { + if self + .common + .inline_completion + .with_untracked(|c| c.status == InlineCompletionStatus::Inactive) + { + return; + } + + let data = self + .common + .inline_completion + .with_untracked(|c| (c.current_item().cloned(), c.start_offset)); + self.cancel_inline_completion(); + + let (Some(item), start_offset) = data else { + return; + }; + + if let Err(err) = item.apply(self, start_offset) { + tracing::error!("{:?}", err); + } + } + + fn next_inline_completion(&self) { + if self + .common + .inline_completion + .with_untracked(|c| c.status == InlineCompletionStatus::Inactive) + { + return; + } + + self.common.inline_completion.update(|c| { + c.next(); + }); + } + + fn previous_inline_completion(&self) { + if self + .common + .inline_completion + .with_untracked(|c| c.status == InlineCompletionStatus::Inactive) + { + return; + } + + self.common.inline_completion.update(|c| { + c.previous(); + }); + } + + pub fn cancel_inline_completion(&self) { + if self + .common + .inline_completion + .with_untracked(|c| c.status == InlineCompletionStatus::Inactive) + { + return; + } + + self.common.inline_completion.update(|c| { + c.cancel(); + }); + + self.doc().clear_inline_completion(); + } + + /// Update the current inline completion + fn update_inline_completion(&self, trigger_kind: InlineCompletionTriggerKind) { + if self.get_mode() != Mode::Insert { + self.cancel_inline_completion(); + return; + } + + let doc = self.doc(); + let path = match if doc.loaded() { + doc.content.with_untracked(|c| c.path().cloned()) + } else { + None + } { + Some(path) => path, + None => return, + }; + + let offset = self.cursor().with_untracked(|c| c.offset()); + let line = doc + .buffer + .with_untracked(|buffer| buffer.line_of_offset(offset)); + let position = doc + .buffer + .with_untracked(|buffer| buffer.offset_to_position(offset)); + + let inline_completion = self.common.inline_completion; + let doc = self.doc(); + + // Update the inline completion's text if it's already active to avoid flickering + let has_relevant = inline_completion.with_untracked(|completion| { + let c_line = doc.buffer.with_untracked(|buffer| { + buffer.line_of_offset(completion.start_offset) + }); + completion.status != InlineCompletionStatus::Inactive + && line == c_line + && completion.path == path + }); + if has_relevant { + let config = self.common.config.get_untracked(); + inline_completion.update(|completion| { + completion.update_inline_completion(&config, &doc, offset); + }); + } + + let path2 = path.clone(); + let send = create_ext_action( + self.scope, + move |items: Vec| { + let items = doc.buffer.with_untracked(|buffer| { + items + .into_iter() + .map(|item| InlineCompletionItem::from_lsp(buffer, item)) + .collect() + }); + inline_completion.update(|c| { + c.set_items(items, offset, path2); + c.update_doc(&doc, offset); + }); + }, + ); + + inline_completion.update(|c| c.status = InlineCompletionStatus::Started); + + self.common.proxy.get_inline_completions( + path, + position, + trigger_kind, + move |res| { + if let Ok(ProxyResponse::GetInlineCompletions { + completions: items, + }) = res + { + let items = match items { + lsp_types::InlineCompletionResponse::Array(items) => items, + // Currently does not have any relevant extra fields + lsp_types::InlineCompletionResponse::List(items) => { + items.items + } + }; + send(items); + } + }, + ); + } + + /// Check if there are inline completions that are being rendered + fn has_inline_completions(&self) -> bool { + self.common.inline_completion.with_untracked(|completion| { + completion.status != InlineCompletionStatus::Inactive + && !completion.items.is_empty() + }) + } + + pub fn select_completion(&self) { + let item = self + .common + .completion + .with_untracked(|c| c.current_item().cloned()); + self.cancel_completion(); + let doc = self.doc(); + if let Some(item) = item { + if item.item.data.is_some() { + let editor = self.clone(); + let rev = doc.buffer.with_untracked(|buffer| buffer.rev()); + let path = doc.content.with_untracked(|c| c.path().cloned()); + let offset = self.cursor().with_untracked(|c| c.offset()); + let buffer = doc.buffer; + let content = doc.content; + let send = create_ext_action(self.scope, move |item| { + if editor.cursor().with_untracked(|c| c.offset() != offset) { + return; + } + if buffer.with_untracked(|b| b.rev()) != rev + || content.with_untracked(|content| { + content.path() != path.as_ref() + }) + { + return; + } + if let Err(err) = editor.apply_completion_item(&item) { + tracing::error!("{:?}", err); + } + }); + self.common.proxy.completion_resolve( + item.plugin_id, + item.item.clone(), + move |result| { + let item = + if let Ok(ProxyResponse::CompletionResolveResponse { + item, + }) = result + { + *item + } else { + item.item.clone() + }; + send(item); + }, + ); + } else if let Err(err) = self.apply_completion_item(&item.item) { + tracing::error!("{:?}", err); + } + } + } + + pub fn cancel_completion(&self) { + if self.common.completion.with_untracked(|c| c.status) + == CompletionStatus::Inactive + { + return; + } + self.common.completion.update(|c| { + c.cancel(); + }); + + self.doc().clear_completion_lens() + } + + /// Update the displayed autocompletion box + /// Sends a request to the LSP for completion information + fn update_completion(&self, display_if_empty_input: bool) { + if self.get_mode() != Mode::Insert { + self.cancel_completion(); + return; + } + + let doc = self.doc(); + let path = match if doc.loaded() { + doc.content.with_untracked(|c| c.path().cloned()) + } else { + None + } { + Some(path) => path, + None => return, + }; + + let offset = self.cursor().with_untracked(|c| c.offset()); + let (start_offset, input, char) = doc.buffer.with_untracked(|buffer| { + let start_offset = buffer.prev_code_boundary(offset); + let end_offset = buffer.next_code_boundary(offset); + let input = buffer.slice_to_cow(start_offset..end_offset).to_string(); + let char = if start_offset == 0 { + "".to_string() + } else { + buffer + .slice_to_cow(start_offset - 1..start_offset) + .to_string() + }; + (start_offset, input, char) + }); + if !display_if_empty_input && input.is_empty() && char != "." && char != ":" + { + self.cancel_completion(); + return; + } + + if self.common.completion.with_untracked(|completion| { + completion.status != CompletionStatus::Inactive + && completion.offset == start_offset + && completion.path == path + }) { + self.common.completion.update(|completion| { + completion.update_input(input.clone()); + + if !completion.input_items.contains_key("") { + let start_pos = doc.buffer.with_untracked(|buffer| { + buffer.offset_to_position(start_offset) + }); + completion.request( + self.id(), + &self.common.proxy, + path.clone(), + "".to_string(), + start_pos, + ); + } + + if !completion.input_items.contains_key(&input) { + let position = doc + .buffer + .with_untracked(|buffer| buffer.offset_to_position(offset)); + completion.request( + self.id(), + &self.common.proxy, + path, + input, + position, + ); + } + }); + let cursor_offset = self.cursor().with_untracked(|c| c.offset()); + self.common + .completion + .get_untracked() + .update_document_completion(self, cursor_offset); + + return; + } + + let doc = self.doc(); + self.common.completion.update(|completion| { + completion.path.clone_from(&path); + completion.offset = start_offset; + completion.input.clone_from(&input); + completion.status = CompletionStatus::Started; + completion.input_items.clear(); + completion.request_id += 1; + let start_pos = doc + .buffer + .with_untracked(|buffer| buffer.offset_to_position(start_offset)); + completion.request( + self.id(), + &self.common.proxy, + path.clone(), + "".to_string(), + start_pos, + ); + + if !input.is_empty() { + let position = doc + .buffer + .with_untracked(|buffer| buffer.offset_to_position(offset)); + completion.request( + self.id(), + &self.common.proxy, + path, + input, + position, + ); + } + }); + } + + /// Check if there are completions that are being rendered + fn has_completions(&self) -> bool { + self.common.completion.with_untracked(|completion| { + completion.status != CompletionStatus::Inactive + && !completion.filtered_items.is_empty() + }) + } + + fn apply_completion_item(&self, item: &CompletionItem) -> anyhow::Result<()> { + let doc = self.doc(); + let buffer = doc.buffer.get_untracked(); + let cursor = self.cursor().get_untracked(); + // Get all the edits which would be applied in places other than right where the cursor is + let additional_edit: Vec<_> = item + .additional_text_edits + .as_ref() + .into_iter() + .flatten() + .map(|edit| { + let selection = lapce_core::selection::Selection::region( + buffer.offset_of_position(&edit.range.start), + buffer.offset_of_position(&edit.range.end), + ); + (selection, edit.new_text.as_str()) + }) + .collect::>(); + + let text_format = item + .insert_text_format + .unwrap_or(lsp_types::InsertTextFormat::PLAIN_TEXT); + if let Some(edit) = &item.text_edit { + match edit { + CompletionTextEdit::Edit(edit) => { + let offset = cursor.offset(); + let start_offset = buffer.prev_code_boundary(offset); + let end_offset = buffer.next_code_boundary(offset); + let edit_start = buffer.offset_of_position(&edit.range.start); + let edit_end = buffer.offset_of_position(&edit.range.end); + + let selection = lapce_core::selection::Selection::region( + start_offset.min(edit_start), + end_offset.max(edit_end), + ); + match text_format { + lsp_types::InsertTextFormat::PLAIN_TEXT => { + self.do_edit( + &selection, + &[ + &[(selection.clone(), edit.new_text.as_str())][..], + &additional_edit[..], + ] + .concat(), + ); + return Ok(()); + } + lsp_types::InsertTextFormat::SNIPPET => { + self.completion_apply_snippet( + &edit.new_text, + &selection, + additional_edit, + start_offset, + )?; + return Ok(()); + } + _ => {} + } + } + CompletionTextEdit::InsertAndReplace(_) => (), + } + } + + let offset = cursor.offset(); + let start_offset = buffer.prev_code_boundary(offset); + let end_offset = buffer.next_code_boundary(offset); + let selection = Selection::region(start_offset, end_offset); + + self.do_edit( + &selection, + &[ + &[( + selection.clone(), + item.insert_text.as_deref().unwrap_or(item.label.as_str()), + )][..], + &additional_edit[..], + ] + .concat(), + ); + Ok(()) + } + + pub fn completion_apply_snippet( + &self, + snippet: &str, + selection: &Selection, + additional_edit: Vec<(Selection, &str)>, + start_offset: usize, + ) -> anyhow::Result<()> { + let snippet = Snippet::from_str(snippet)?; + let text = snippet.text(); + let mut cursor = self.cursor().get_untracked(); + let old_cursor = cursor.mode.clone(); + let (b_text, delta, inval_lines) = self + .doc() + .do_raw_edit( + &[ + &[(selection.clone(), text.as_str())][..], + &additional_edit[..], + ] + .concat(), + EditType::Completion, + ) + .ok_or_else(|| anyhow::anyhow!("not edited"))?; + + let selection = selection.apply_delta(&delta, true, InsertDrift::Default); + + let mut transformer = Transformer::new(&delta); + let offset = transformer.transform(start_offset, false); + let snippet_tabs = snippet.tabs(offset); + + let doc = self.doc(); + if snippet_tabs.is_empty() { + doc.buffer.update(|buffer| { + cursor.update_selection(buffer, selection); + buffer.set_cursor_before(old_cursor); + buffer.set_cursor_after(cursor.mode.clone()); + }); + self.cursor().set(cursor); + self.apply_deltas(&[(b_text, delta, inval_lines)]); + return Ok(()); + } + + let mut selection = lapce_core::selection::Selection::new(); + let (_tab, (start, end)) = &snippet_tabs[0]; + let region = lapce_core::selection::SelRegion::new(*start, *end, None); + selection.add_region(region); + cursor.set_insert(selection); + + doc.buffer.update(|buffer| { + buffer.set_cursor_before(old_cursor); + buffer.set_cursor_after(cursor.mode.clone()); + }); + self.cursor().set(cursor); + self.apply_deltas(&[(b_text, delta, inval_lines)]); + self.add_snippet_placeholders(snippet_tabs); + Ok(()) + } + + fn add_snippet_placeholders( + &self, + new_placeholders: Vec<(usize, (usize, usize))>, + ) { + self.snippet.update(|snippet| { + if snippet.is_none() { + if new_placeholders.len() > 1 { + *snippet = Some(new_placeholders); + } + return; + } + + let placeholders = snippet.as_mut().unwrap(); + + let mut current = 0; + let offset = self.cursor().get_untracked().offset(); + for (i, (_, (start, end))) in placeholders.iter().enumerate() { + if *start <= offset && offset <= *end { + current = i; + break; + } + } + + let v = placeholders.split_off(current); + placeholders.extend_from_slice(&new_placeholders); + placeholders.extend_from_slice(&v[1..]); + }); + } + + pub fn do_edit( + &self, + selection: &Selection, + edits: &[(impl AsRef, &str)], + ) { + let mut cursor = self.cursor().get_untracked(); + let doc = self.doc(); + let (text, delta, inval_lines) = + match doc.do_raw_edit(edits, EditType::Completion) { + Some(e) => e, + None => return, + }; + let selection = selection.apply_delta(&delta, true, InsertDrift::Default); + let old_cursor = cursor.mode.clone(); + doc.buffer.update(|buffer| { + cursor.update_selection(buffer, selection); + buffer.set_cursor_before(old_cursor); + buffer.set_cursor_after(cursor.mode.clone()); + }); + self.cursor().set(cursor); + + self.apply_deltas(&[(text, delta, inval_lines)]); + } + + pub fn do_text_edit(&self, edits: &[TextEdit]) { + let (selection, edits) = self.doc().buffer.with_untracked(|buffer| { + let selection = self.cursor().get_untracked().edit_selection(buffer); + let edits = edits + .iter() + .map(|edit| { + let selection = lapce_core::selection::Selection::region( + buffer.offset_of_position(&edit.range.start), + buffer.offset_of_position(&edit.range.end), + ); + (selection, edit.new_text.as_str()) + }) + .collect::>(); + (selection, edits) + }); + + self.do_edit(&selection, &edits); + } + + fn apply_deltas(&self, deltas: &[(Rope, RopeDelta, InvalLines)]) { + if !deltas.is_empty() && !self.confirmed.get_untracked() { + self.confirmed.set(true); + } + for (_, delta, _) in deltas { + // self.inactive_apply_delta(delta); + self.update_snippet_offset(delta); + // self.update_breakpoints(delta); + } + // self.update_signature(); + } + + fn update_snippet_offset(&self, delta: &RopeDelta) { + if self.snippet.with_untracked(|s| s.is_some()) { + self.snippet.update(|snippet| { + let mut transformer = Transformer::new(delta); + *snippet = Some( + snippet + .as_ref() + .unwrap() + .iter() + .map(|(tab, (start, end))| { + ( + *tab, + ( + transformer.transform(*start, false), + transformer.transform(*end, true), + ), + ) + }) + .collect(), + ); + }); + } + } + + fn do_go_to_location( + &self, + location: EditorLocation, + edits: Option>, + ) { + if let Some(position) = location.position { + self.go_to_position(position, location.scroll_offset, edits); + } else if let Some(edits) = edits.as_ref() { + self.do_text_edit(edits); + } else { + let db: Arc = use_context().unwrap(); + if let Ok(info) = db.get_doc_info(&self.common.workspace, &location.path) + { + self.go_to_position( + EditorPosition::Offset(info.cursor_offset), + Some(Vec2::new(info.scroll_offset.0, info.scroll_offset.1)), + edits, + ); + } + } + } + + pub fn go_to_location( + &self, + location: EditorLocation, + new_doc: bool, + edits: Option>, + ) { + if !new_doc { + self.do_go_to_location(location, edits); + } else { + let loaded = self.doc().loaded; + let editor = self.clone(); + self.scope.create_effect(move |prev_loaded| { + if prev_loaded == Some(true) { + return true; + } + + let loaded = loaded.get(); + if loaded { + editor.do_go_to_location(location.clone(), edits.clone()); + } + loaded + }); + } + } + + pub fn go_to_position( + &self, + position: EditorPosition, + scroll_offset: Option, + edits: Option>, + ) { + let offset = self + .doc() + .buffer + .with_untracked(|buffer| position.to_offset(buffer)); + let config = self.common.config.get_untracked(); + self.cursor().set(if config.core.modal { + Cursor::new(CursorMode::Normal(offset), None, None) + } else { + Cursor::new(CursorMode::Insert(Selection::caret(offset)), None, None) + }); + if let Some(scroll_offset) = scroll_offset { + self.editor.scroll_to.set(Some(scroll_offset)); + } + if let Some(edits) = edits.as_ref() { + self.do_text_edit(edits); + } + } + + pub fn get_code_actions(&self) { + let doc = self.doc(); + let path = match if doc.loaded() { + doc.content.with_untracked(|c| c.path().cloned()) + } else { + None + } { + Some(path) => path, + None => return, + }; + + let offset = self.cursor().with_untracked(|c| c.offset()); + let exists = doc + .code_actions() + .with_untracked(|c| c.contains_key(&offset)); + + if exists { + return; + } + + // insert some empty data, so that we won't make the request again + doc.code_actions().update(|c| { + c.insert(offset, (PluginId(0), im::Vector::new())); + }); + + let (position, rev, diagnostics) = doc.buffer.with_untracked(|buffer| { + let position = buffer.offset_to_position(offset); + let rev = doc.rev(); + + // Get the diagnostics for the current line, which the LSP might use to inform + // what code actions are available (such as fixes for the diagnostics). + let diagnostics = doc + .diagnostics() + .diagnostics_span + .get_untracked() + .iter_chunks(offset..offset) + .filter(|(iv, _diag)| iv.start <= offset && iv.end >= offset) + .map(|(_iv, diag)| diag) + .cloned() + .collect(); + + (position, rev, diagnostics) + }); + + let send = create_ext_action( + self.scope, + move |resp: (PluginId, CodeActionResponse)| { + if doc.rev() == rev { + doc.code_actions().update(|c| { + c.insert(offset, (resp.0, resp.1.into())); + }); + } + }, + ); + + self.common.proxy.get_code_actions( + path, + position, + diagnostics, + move |result| { + if let Ok(ProxyResponse::GetCodeActionsResponse { + plugin_id, + resp, + }) = result + { + send((plugin_id, resp)) + } + }, + ); + } + + pub fn show_code_actions(&self, mouse_click: bool) { + let offset = self.cursor().with_untracked(|c| c.offset()); + let doc = self.doc(); + let code_actions = doc + .code_actions() + .with_untracked(|c| c.get(&offset).cloned()); + if let Some((plugin_id, code_actions)) = code_actions { + if !code_actions.is_empty() { + self.common.internal_command.send( + InternalCommand::ShowCodeActions { + offset, + mouse_click, + plugin_id, + code_actions, + }, + ); + } + } + } + + fn do_save(&self, after_action: impl FnOnce() + 'static) { + self.doc().save(after_action); + } + + pub fn save( + &self, + allow_formatting: bool, + after_action: impl FnOnce() + 'static, + ) { + let doc = self.doc(); + let is_pristine = doc.is_pristine(); + let content = doc.content.get_untracked(); + + if let DocContent::Scratch { .. } = &content { + self.common + .internal_command + .send(InternalCommand::SaveScratchDoc2 { doc }); + return; + } + + if content.path().is_some() && is_pristine { + return; + } + + let config = self.common.config.get_untracked(); + let DocContent::File { path, .. } = content else { + return; + }; + + // If we are disallowing formatting (such as due to a manual save without formatting), + // then we skip normalizing line endings as a common reason for that is large files. + // (but if the save is typical, even if config format_on_save is false, we normalize) + if allow_formatting && config.editor.normalize_line_endings { + self.run_edit_command(&EditCommand::NormalizeLineEndings); + } + + let rev = doc.rev(); + let format_on_save = allow_formatting && config.editor.format_on_save; + if format_on_save { + let editor = self.clone(); + let send = create_ext_action(self.scope, move |result| { + if let Ok(Ok(ProxyResponse::GetDocumentFormatting { edits })) = + result + { + let current_rev = editor.doc().rev(); + if current_rev == rev { + editor.do_text_edit(&edits); + } + } + editor.do_save(after_action); + }); + + let (tx, rx) = crossbeam_channel::bounded(1); + let proxy = self.common.proxy.clone(); + std::thread::spawn(move || { + proxy.get_document_formatting(path, move |result| { + if let Err(err) = tx.send(result) { + tracing::error!("{:?}", err); + } + }); + let result = rx.recv_timeout(std::time::Duration::from_secs(1)); + send(result); + }); + } else { + self.do_save(after_action); + } + } + + pub fn format(&self) { + let doc = self.doc(); + let rev = doc.rev(); + let content = doc.content.get_untracked(); + + if let DocContent::File { path, .. } = content { + let editor = self.clone(); + let send = create_ext_action(self.scope, move |result| { + if let Ok(Ok(ProxyResponse::GetDocumentFormatting { edits })) = + result + { + let current_rev = editor.doc().rev(); + if current_rev == rev { + editor.do_text_edit(&edits); + } + } + }); + + let (tx, rx) = crossbeam_channel::bounded(1); + let proxy = self.common.proxy.clone(); + std::thread::spawn(move || { + proxy.get_document_formatting(path, move |result| { + if let Err(err) = tx.send(result) { + tracing::error!("{:?}", err); + } + }); + let result = rx.recv_timeout(std::time::Duration::from_secs(1)); + send(result); + }); + } + } + + fn search_whole_word_forward(&self, mods: Modifiers) { + let offset = self.cursor().with_untracked(|c| c.offset()); + let (word, buffer) = self.doc().buffer.with_untracked(|buffer| { + let (start, end) = buffer.select_word(offset); + (buffer.slice_to_cow(start..end).to_string(), buffer.clone()) + }); + self.common.internal_command.send(InternalCommand::Search { + pattern: Some(word), + }); + let next = self.common.find.next(buffer.text(), offset, false, true); + + if let Some((start, _end)) = next { + self.run_move_command( + &lapce_core::movement::Movement::Offset(start), + None, + mods, + ); + } + } + + fn search_forward(&self, mods: Modifiers) { + let offset = self.cursor().with_untracked(|c| c.offset()); + let text = self + .doc() + .buffer + .with_untracked(|buffer| buffer.text().clone()); + let next = self.common.find.next(&text, offset, false, true); + + if let Some((start, _end)) = next { + self.run_move_command( + &lapce_core::movement::Movement::Offset(start), + None, + mods, + ); + } + } + + fn search_backward(&self, mods: Modifiers) { + let offset = self.cursor().with_untracked(|c| c.offset()); + let text = self + .doc() + .buffer + .with_untracked(|buffer| buffer.text().clone()); + let next = self.common.find.next(&text, offset, true, true); + + if let Some((start, _end)) = next { + self.run_move_command( + &lapce_core::movement::Movement::Offset(start), + None, + mods, + ); + } + } + + fn replace_next(&self, text: &str) { + let offset = self.cursor().with_untracked(|c| c.offset()); + let buffer = self.doc().buffer.with_untracked(|buffer| buffer.clone()); + let next = self.common.find.next(buffer.text(), offset, false, true); + + if let Some((start, end)) = next { + let selection = Selection::region(start, end); + self.do_edit(&selection, &[(selection.clone(), text)]); + } + } + + fn replace_all(&self, text: &str) { + let offset = self.cursor().with_untracked(|c| c.offset()); + + self.doc().update_find(); + + let edits: Vec<(Selection, &str)> = self + .doc() + .find_result + .occurrences + .get_untracked() + .regions() + .iter() + .map(|region| (Selection::region(region.start, region.end), text)) + .collect(); + if !edits.is_empty() { + self.do_edit(&Selection::caret(offset), &edits); + } + } + + pub fn save_doc_position(&self) { + let doc = self.doc(); + let path = match if doc.loaded() { + doc.content.with_untracked(|c| c.path().cloned()) + } else { + None + } { + Some(path) => path, + None => return, + }; + + let cursor_offset = self.cursor().with_untracked(|c| c.offset()); + let scroll_offset = self.viewport().with_untracked(|v| v.origin().to_vec2()); + + let db: Arc = use_context().unwrap(); + db.save_doc_position( + &self.common.workspace, + path, + cursor_offset, + scroll_offset, + ); + } + + fn rename(&self) { + let doc = self.doc(); + let path = match if doc.loaded() { + doc.content.with_untracked(|c| c.path().cloned()) + } else { + None + } { + Some(path) => path, + None => return, + }; + + let offset = self.cursor().with_untracked(|c| c.offset()); + let (position, rev) = doc + .buffer + .with_untracked(|buffer| (buffer.offset_to_position(offset), doc.rev())); + + let cursor = self.cursor(); + let buffer = doc.buffer; + let internal_command = self.common.internal_command; + let local_path = path.clone(); + let send = create_ext_action(self.scope, move |result| { + if let Ok(ProxyResponse::PrepareRename { resp }) = result { + if buffer.with_untracked(|buffer| buffer.rev()) != rev { + return; + } + + if cursor.with_untracked(|c| c.offset()) != offset { + return; + } + + let (start, _end, position, placeholder) = + buffer.with_untracked(|buffer| match resp { + lsp_types::PrepareRenameResponse::Range(range) => ( + buffer.offset_of_position(&range.start), + buffer.offset_of_position(&range.end), + range.start, + None, + ), + lsp_types::PrepareRenameResponse::RangeWithPlaceholder { + range, + placeholder, + } => ( + buffer.offset_of_position(&range.start), + buffer.offset_of_position(&range.end), + range.start, + Some(placeholder), + ), + lsp_types::PrepareRenameResponse::DefaultBehavior { + .. + } => { + let start = buffer.prev_code_boundary(offset); + let position = buffer.offset_to_position(start); + ( + start, + buffer.next_code_boundary(offset), + position, + None, + ) + } + }); + let placeholder = placeholder.unwrap_or_else(|| { + buffer.with_untracked(|buffer| { + let (start, end) = buffer.select_word(offset); + buffer.slice_to_cow(start..end).to_string() + }) + }); + internal_command.send(InternalCommand::StartRename { + path: local_path.clone(), + placeholder, + start, + position, + }); + } + }); + self.common + .proxy + .prepare_rename(path, position, move |result| { + send(result); + }); + } + + #[instrument] + pub fn word_at_cursor(&self) -> String { + let doc = self.doc(); + let region = self.cursor().with_untracked(|c| match &c.mode { + lapce_core::cursor::CursorMode::Normal(offset) => { + lapce_core::selection::SelRegion::caret(*offset) + } + lapce_core::cursor::CursorMode::Visual { + start, + end, + mode: _, + } => lapce_core::selection::SelRegion::new( + *start.min(end), + doc.buffer.with_untracked(|buffer| { + buffer.next_grapheme_offset(*start.max(end), 1, buffer.len()) + }), + None, + ), + lapce_core::cursor::CursorMode::Insert(selection) => { + *selection.last_inserted().unwrap() + } + }); + + if region.is_caret() { + doc.buffer.with_untracked(|buffer| { + let (start, end) = buffer.select_word(region.start); + buffer.slice_to_cow(start..end).to_string() + }) + } else { + doc.buffer.with_untracked(|buffer| { + buffer.slice_to_cow(region.min()..region.max()).to_string() + }) + } + } + + #[instrument] + pub fn clear_search(&self) { + self.common.find.visual.set(false); + self.find_focus.set(false); + } + + #[instrument] + fn search(&self) { + let pattern = self.word_at_cursor(); + + let pattern = if pattern.contains('\n') || pattern.is_empty() { + None + } else { + Some(pattern) + }; + + self.common + .internal_command + .send(InternalCommand::Search { pattern }); + self.common.find.visual.set(true); + self.find_focus.set(true); + self.common.find.replace_focus.set(false); + } + + pub fn pointer_down(&self, pointer_event: &PointerInputEvent) { + self.cancel_completion(); + self.cancel_inline_completion(); + if let Some(editor_tab_id) = self.editor_tab_id.get_untracked() { + self.common + .internal_command + .send(InternalCommand::FocusEditorTab { editor_tab_id }); + } + if self + .doc() + .content + .with_untracked(|content| !content.is_local()) + { + self.common.focus.set(Focus::Workbench); + self.find_focus.set(false); + } + match pointer_event.button.mouse_button() { + MouseButton::Primary => { + self.active().set(true); + self.left_click(pointer_event); + + let y = + pointer_event.pos.y - self.editor.viewport.get_untracked().y0; + if self.sticky_header_height.get_untracked() > y { + let index = y as usize + / self.common.config.get_untracked().editor.line_height(); + if let (Some(path), Some(line)) = ( + self.doc().content.get_untracked().path(), + self.sticky_header_info + .get_untracked() + .sticky_lines + .get(index), + ) { + self.common.internal_command.send( + InternalCommand::JumpToLocation { + location: EditorLocation { + path: path.clone(), + position: Some(EditorPosition::Line(*line)), + scroll_offset: None, + ignore_unconfirmed: true, + same_editor_tab: false, + }, + }, + ); + return; + } + } + + if (cfg!(target_os = "macos") && pointer_event.modifiers.meta()) + || (cfg!(not(target_os = "macos")) + && pointer_event.modifiers.control()) + { + let rs = self.find_hint(pointer_event.pos); + match rs { + FindHintRs::NoMatchBreak + | FindHintRs::NoMatchContinue { .. } => { + self.common.lapce_command.send(LapceCommand { + kind: CommandKind::Focus( + FocusCommand::GotoDefinition, + ), + data: None, + }) + } + FindHintRs::MatchWithoutLocation => {} + FindHintRs::Match(location) => { + let Ok(path) = location.uri.to_file_path() else { + return; + }; + self.common.internal_command.send( + InternalCommand::JumpToLocation { + location: EditorLocation { + path, + position: Some(EditorPosition::Position( + location.range.start, + )), + scroll_offset: None, + ignore_unconfirmed: true, + same_editor_tab: false, + }, + }, + ); + } + } + } + } + MouseButton::Secondary => { + self.right_click(pointer_event); + } + _ => {} + } + } + + fn find_hint(&self, pos: Point) -> FindHintRs { + let rs = self.editor.line_col_of_point_with_phantom(pos); + let line = rs.0 as u32; + let index = rs.1 as u32; + self.doc().inlay_hints.with_untracked(|x| { + if let Some(hints) = x { + let mut pre_len = 0; + for hint in hints + .iter() + .filter_map(|(_, hint)| { + if hint.position.line == line { + Some(hint) + } else { + None + } + }) + .sorted_by(|pre, next| { + pre.position.character.cmp(&next.position.character) + }) + { + match find_hint(pre_len, index, hint) { + FindHintRs::NoMatchContinue { pre_hint_len } => { + pre_len = pre_hint_len; + } + rs => return rs, + } + } + FindHintRs::NoMatchBreak + } else { + FindHintRs::NoMatchBreak + } + }) + } + + #[instrument] + fn left_click(&self, pointer_event: &PointerInputEvent) { + match pointer_event.count { + 1 => { + self.single_click(pointer_event); + } + 2 => { + self.double_click(pointer_event); + } + 3 => { + self.triple_click(pointer_event); + } + _ => {} + } + } + + #[instrument] + fn single_click(&self, pointer_event: &PointerInputEvent) { + self.editor.single_click(pointer_event); + } + + #[instrument] + fn double_click(&self, pointer_event: &PointerInputEvent) { + self.editor.double_click(pointer_event); + } + + #[instrument] + fn triple_click(&self, pointer_event: &PointerInputEvent) { + self.editor.triple_click(pointer_event); + } + + #[instrument] + pub fn pointer_move(&self, pointer_event: &PointerMoveEvent) { + let mode = self.cursor().with_untracked(|c| c.get_mode()); + let (offset, is_inside) = + self.editor.offset_of_point(mode, pointer_event.pos); + if self.active().get_untracked() + && self.cursor().with_untracked(|c| c.offset()) != offset + { + self.cursor().update(|cursor| { + cursor.set_offset(offset, true, pointer_event.modifiers.alt()) + }); + } + if self.common.hover.active.get_untracked() { + let hover_editor_id = self.common.hover.editor_id.get_untracked(); + if hover_editor_id != self.id() { + self.common.hover.active.set(false); + } else { + let current_offset = self.common.hover.offset.get_untracked(); + let start_offset = self + .doc() + .buffer + .with_untracked(|buffer| buffer.prev_code_boundary(offset)); + if current_offset != start_offset { + self.common.hover.active.set(false); + } + } + } + let hover_delay = self.common.config.get_untracked().editor.hover_delay; + if hover_delay > 0 { + if is_inside { + let start_offset = self + .doc() + .buffer + .with_untracked(|buffer| buffer.prev_code_boundary(offset)); + + let editor = self.clone(); + let mouse_hover_timer = self.common.mouse_hover_timer; + let timer_token = + exec_after(Duration::from_millis(hover_delay), move |token| { + if mouse_hover_timer.try_get_untracked() == Some(token) + && editor.editor_tab_id.try_get_untracked().is_some() + { + editor.update_hover(start_offset); + } + }); + mouse_hover_timer.set(timer_token); + } else { + self.common.mouse_hover_timer.set(TimerToken::INVALID); + } + } + } + + #[instrument] + pub fn pointer_up(&self, pointer_event: &PointerInputEvent) { + self.editor.pointer_up(pointer_event); + } + + #[instrument] + pub fn pointer_leave(&self) { + self.common.mouse_hover_timer.set(TimerToken::INVALID); + } + + #[instrument] + fn right_click(&self, pointer_event: &PointerInputEvent) { + let mode = self.cursor().with_untracked(|c| c.get_mode()); + let (offset, _) = self.editor.offset_of_point(mode, pointer_event.pos); + let doc = self.doc(); + let pointer_inside_selection = doc.buffer.with_untracked(|buffer| { + self.cursor() + .with_untracked(|c| c.edit_selection(buffer).contains(offset)) + }); + if !pointer_inside_selection { + // move cursor to pointer position if outside current selection + self.single_click(pointer_event); + } + + let (path, is_file) = doc.content.with_untracked(|content| match content { + DocContent::File { path, .. } => { + (Some(path.to_path_buf()), path.is_file()) + } + DocContent::Local + | DocContent::History(_) + | DocContent::Scratch { .. } => (None, false), + }); + let mut menu = Menu::new(""); + let mut cmds = if is_file { + if path + .as_ref() + .and_then(|x| x.file_name().and_then(|x| x.to_str())) + .map(|x| x == "run.toml") + .unwrap_or_default() + { + vec![ + Some(CommandKind::Workbench( + LapceWorkbenchCommand::RevealInPanel, + )), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::RevealInFileExplorer, + )), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::SourceControlOpenActiveFileRemoteUrl, + )), + None, + Some(CommandKind::Edit(EditCommand::ClipboardCut)), + Some(CommandKind::Edit(EditCommand::ClipboardCopy)), + Some(CommandKind::Edit(EditCommand::ClipboardPaste)), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::AddRunDebugConfig, + )), + None, + Some(CommandKind::Workbench( + LapceWorkbenchCommand::PaletteCommand, + )), + ] + } else { + vec![ + Some(CommandKind::Focus(FocusCommand::GotoDefinition)), + Some(CommandKind::Focus(FocusCommand::GotoTypeDefinition)), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::ShowCallHierarchy, + )), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::FindReferences, + )), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::GoToImplementation, + )), + Some(CommandKind::Focus(FocusCommand::Rename)), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::RunInTerminal, + )), + None, + Some(CommandKind::Workbench( + LapceWorkbenchCommand::RevealInPanel, + )), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::RevealInFileExplorer, + )), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::SourceControlOpenActiveFileRemoteUrl, + )), + None, + Some(CommandKind::Edit(EditCommand::ClipboardCut)), + Some(CommandKind::Edit(EditCommand::ClipboardCopy)), + Some(CommandKind::Edit(EditCommand::ClipboardPaste)), + None, + Some(CommandKind::Workbench( + LapceWorkbenchCommand::PaletteCommand, + )), + ] + } + } else { + vec![ + Some(CommandKind::Edit(EditCommand::ClipboardCut)), + Some(CommandKind::Edit(EditCommand::ClipboardCopy)), + Some(CommandKind::Edit(EditCommand::ClipboardPaste)), + None, + Some(CommandKind::Workbench( + LapceWorkbenchCommand::PaletteCommand, + )), + ] + }; + if self.diff_editor_id.get_untracked().is_some() && is_file { + cmds.push(Some(CommandKind::Workbench( + LapceWorkbenchCommand::GoToLocation, + ))); + } + let lapce_command = self.common.lapce_command; + for cmd in cmds { + if let Some(cmd) = cmd { + menu = menu.entry( + MenuItem::new(cmd.desc().unwrap_or_else(|| cmd.str())).action( + move || { + lapce_command.send(LapceCommand { + kind: cmd.clone(), + data: None, + }) + }, + ), + ); + } else { + menu = menu.separator(); + } + } + show_context_menu(menu, None); + } + + #[instrument] + fn update_hover(&self, offset: usize) { + let doc = self.doc(); + let path = doc + .content + .with_untracked(|content| content.path().cloned()); + let position = doc + .buffer + .with_untracked(|buffer| buffer.offset_to_position(offset)); + let path = match path { + Some(path) => path, + None => return, + }; + let config = self.common.config; + let hover_data = self.common.hover.clone(); + let editor_id = self.id(); + let send = create_ext_action(self.scope, move |resp| { + if let Ok(ProxyResponse::HoverResponse { hover, .. }) = resp { + let content = parse_hover_resp(hover, &config.get_untracked()); + hover_data.content.set(content); + hover_data.offset.set(offset); + hover_data.editor_id.set(editor_id); + hover_data.active.set(true); + } + }); + self.common.proxy.get_hover(0, path, position, |resp| { + send(resp); + }); + } + + // reset the doc inside and move cursor back + pub fn reset(&self) { + let doc = self.doc(); + doc.reload(Rope::from(""), true); + self.cursor() + .update(|cursor| cursor.set_offset(0, false, false)); + } + + pub fn visual_line(&self, line: usize) -> usize { + self.kind.with_untracked(|kind| match kind { + EditorViewKind::Normal => line, + EditorViewKind::Diff(diff) => { + let is_right = diff.is_right; + let mut last_change: Option<&DiffLines> = None; + let mut visual_line = 0; + let mut changes = diff.changes.iter().peekable(); + while let Some(change) = changes.next() { + match (is_right, change) { + (true, DiffLines::Left(range)) => { + if let Some(DiffLines::Right(_)) = changes.peek() { + } else { + visual_line += range.len(); + } + } + (false, DiffLines::Right(range)) => { + let len = if let Some(DiffLines::Left(r)) = last_change { + range.len() - r.len().min(range.len()) + } else { + range.len() + }; + if len > 0 { + visual_line += len; + } + } + (true, DiffLines::Right(range)) + | (false, DiffLines::Left(range)) => { + if line < range.end { + return visual_line + line - range.start; + } + visual_line += range.len(); + if is_right { + if let Some(DiffLines::Left(r)) = last_change { + let len = r.len() - r.len().min(range.len()); + if len > 0 { + visual_line += len; + } + } + } + } + (_, DiffLines::Both(info)) => { + let end = if is_right { + info.right.end + } else { + info.left.end + }; + if line >= end { + visual_line += info.right.len() + - info + .skip + .as_ref() + .map(|skip| skip.len().saturating_sub(1)) + .unwrap_or(0); + last_change = Some(change); + continue; + } + + let start = if is_right { + info.right.start + } else { + info.left.start + }; + if let Some(skip) = info.skip.as_ref() { + if start + skip.start > line { + return visual_line + line - start; + } else if start + skip.end > line { + return visual_line + skip.start; + } else { + return visual_line + + (line - start - skip.len() + 1); + } + } else { + return visual_line + line - start; + } + } + } + last_change = Some(change); + } + visual_line + } + }) + } + + pub fn actual_line(&self, visual_line: usize, bottom_affinity: bool) -> usize { + self.kind.with_untracked(|kind| match kind { + EditorViewKind::Normal => visual_line, + EditorViewKind::Diff(diff) => { + let is_right = diff.is_right; + let mut actual_line: usize = 0; + let mut current_visual_line = 0; + let mut last_change: Option<&DiffLines> = None; + let mut changes = diff.changes.iter().peekable(); + while let Some(change) = changes.next() { + match (is_right, change) { + (true, DiffLines::Left(range)) => { + if let Some(DiffLines::Right(_)) = changes.peek() { + } else { + current_visual_line += range.len(); + if current_visual_line >= visual_line { + return if bottom_affinity { + actual_line + } else { + actual_line.saturating_sub(1) + }; + } + } + } + (false, DiffLines::Right(range)) => { + let len = if let Some(DiffLines::Left(r)) = last_change { + range.len() - r.len().min(range.len()) + } else { + range.len() + }; + if len > 0 { + current_visual_line += len; + if current_visual_line >= visual_line { + return actual_line; + } + } + } + (true, DiffLines::Right(range)) + | (false, DiffLines::Left(range)) => { + let len = range.len(); + if current_visual_line + len > visual_line { + return range.start + + (visual_line - current_visual_line); + } + current_visual_line += len; + actual_line += len; + if is_right { + if let Some(DiffLines::Left(r)) = last_change { + let len = r.len() - r.len().min(range.len()); + if len > 0 { + current_visual_line += len; + if current_visual_line > visual_line { + return if bottom_affinity { + actual_line + } else { + actual_line - range.len() + }; + } + } + } + } + } + (_, DiffLines::Both(info)) => { + let len = info.right.len(); + let start = if is_right { + info.right.start + } else { + info.left.start + }; + + if let Some(skip) = info.skip.as_ref() { + if current_visual_line + skip.start == visual_line { + return if bottom_affinity { + actual_line + skip.end + } else { + (actual_line + skip.start).saturating_sub(1) + }; + } else if current_visual_line + skip.start + 1 + > visual_line + { + return actual_line + visual_line + - current_visual_line; + } else if current_visual_line + len - skip.len() + 1 + >= visual_line + { + return actual_line + + skip.end + + (visual_line + - current_visual_line + - skip.start + - 1); + } + actual_line += len; + current_visual_line += len - skip.len() + 1; + } else { + if current_visual_line + len > visual_line { + return start + + (visual_line - current_visual_line); + } + current_visual_line += len; + actual_line += len; + } + } + } + last_change = Some(change); + } + actual_line + } + }) + } +} + +impl KeyPressFocus for EditorData { + fn get_mode(&self) -> Mode { + if self.common.find.visual.get_untracked() && self.find_focus.get_untracked() + { + Mode::Insert + } else { + self.cursor().with_untracked(|c| c.get_mode()) + } + } + + #[instrument] + fn check_condition(&self, condition: Condition) -> bool { + match condition { + Condition::InputFocus => { + self.common.find.visual.get_untracked() + && self.find_focus.get_untracked() + } + Condition::ListFocus => self.has_completions(), + Condition::CompletionFocus => self.has_completions(), + Condition::InlineCompletionVisible => self.has_inline_completions(), + Condition::OnScreenFindActive => { + self.on_screen_find.with_untracked(|f| f.active) + } + Condition::InSnippet => self.snippet.with_untracked(|s| s.is_some()), + Condition::EditorFocus => self + .doc() + .content + .with_untracked(|content| !content.is_local()), + Condition::SearchFocus => { + self.common.find.visual.get_untracked() + && self.find_focus.get_untracked() + && !self.common.find.replace_focus.get_untracked() + } + Condition::ReplaceFocus => { + self.common.find.visual.get_untracked() + && self.find_focus.get_untracked() + && self.common.find.replace_focus.get_untracked() + } + Condition::SearchActive => { + if self.common.config.get_untracked().core.modal + && self.cursor().with_untracked(|c| !c.is_normal()) + { + false + } else { + self.common.find.visual.get_untracked() + } + } + _ => false, + } + } + + #[instrument] + fn run_command( + &self, + command: &crate::command::LapceCommand, + count: Option, + mods: Modifiers, + ) -> CommandExecuted { + if self.common.find.visual.get_untracked() && self.find_focus.get_untracked() + { + match &command.kind { + CommandKind::Edit(_) + | CommandKind::Move(_) + | CommandKind::MultiSelection(_) => { + if self.common.find.replace_focus.get_untracked() { + self.common.internal_command.send( + InternalCommand::ReplaceEditorCommand { + command: command.clone(), + count, + mods, + }, + ); + } else { + self.common.internal_command.send( + InternalCommand::FindEditorCommand { + command: command.clone(), + count, + mods, + }, + ); + } + return CommandExecuted::Yes; + } + _ => {} + } + } + + match &command.kind { + crate::command::CommandKind::Workbench(_) => CommandExecuted::No, + crate::command::CommandKind::Edit(cmd) => self.run_edit_command(cmd), + crate::command::CommandKind::Move(cmd) => { + let movement = cmd.to_movement(count); + self.run_move_command(&movement, count, mods) + } + crate::command::CommandKind::Scroll(cmd) => { + if self + .doc() + .content + .with_untracked(|content| content.is_local()) + { + return CommandExecuted::No; + } + self.run_scroll_command(cmd, count, mods) + } + crate::command::CommandKind::Focus(cmd) => { + if self + .doc() + .content + .with_untracked(|content| content.is_local()) + { + return CommandExecuted::No; + } + self.run_focus_command(cmd, count, mods) + } + crate::command::CommandKind::MotionMode(cmd) => { + self.run_motion_mode_command(cmd, count) + } + crate::command::CommandKind::MultiSelection(cmd) => { + self.run_multi_selection_command(cmd) + } + } + } + + fn expect_char(&self) -> bool { + if self.common.find.visual.get_untracked() && self.find_focus.get_untracked() + { + false + } else { + self.inline_find.with_untracked(|f| f.is_some()) + || self.on_screen_find.with_untracked(|f| f.active) + } + } + + fn receive_char(&self, c: &str) { + if self.common.find.visual.get_untracked() && self.find_focus.get_untracked() + { + // find/relace editor receive char + if self.common.find.replace_focus.get_untracked() { + self.common.internal_command.send( + InternalCommand::ReplaceEditorReceiveChar { s: c.to_string() }, + ); + } else { + self.common.internal_command.send( + InternalCommand::FindEditorReceiveChar { s: c.to_string() }, + ); + } + } else { + // normal editor receive char + if self.get_mode() == Mode::Insert { + let mut cursor = self.cursor().get_untracked(); + let deltas = self.doc().do_insert( + &mut cursor, + c, + &self.common.config.get_untracked(), + ); + self.cursor().set(cursor); + + if !c + .chars() + .all(|c| c.is_whitespace() || c.is_ascii_whitespace()) + { + self.update_completion(false); + } else { + self.cancel_completion(); + } + + self.update_inline_completion( + InlineCompletionTriggerKind::Automatic, + ); + + self.apply_deltas(&deltas); + } else if let Some(direction) = self.inline_find.get_untracked() { + self.inline_find(direction.clone(), c); + self.last_inline_find.set(Some((direction, c.to_string()))); + self.inline_find.set(None); + } else if self.on_screen_find.with_untracked(|f| f.active) { + self.on_screen_find.update(|find| { + let pattern = format!("{}{c}", find.pattern); + find.regions = self.on_screen_find(&pattern); + find.pattern = pattern; + }); + } + } + } +} + +/// Custom signal wrapper for [`Doc`], because [`Editor`] only knows it as a +/// `Rc`, and there is currently no way to have an `RwSignal>` and +/// an `RwSignal>`. +/// +// FIXME: This could possibly be swapped with a generic impl? +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct DocSignal { + // TODO: replace with ReadSignal once that impls `track` + inner: RwSignal>, +} +impl DocSignal { + pub fn get(&self) -> Rc { + let doc = self.inner.get(); + (doc as Rc) + .downcast() + .expect("doc is not Rc") + } + + pub fn get_untracked(&self) -> Rc { + let doc = self.inner.get_untracked(); + (doc as Rc) + .downcast() + .expect("doc is not Rc") + } + + pub fn with(&self, f: impl FnOnce(&Rc) -> O) -> O { + self.inner.with(|doc| { + let doc = doc.clone(); + let doc: Rc = (doc as Rc) + .downcast() + .expect("doc is not Rc"); + f(&doc) + }) + } + + pub fn with_untracked(&self, f: impl FnOnce(&Rc) -> O) -> O { + self.inner.with_untracked(|doc| { + let doc = doc.clone(); + let doc: Rc = (doc as Rc) + .downcast() + .expect("doc is not Rc"); + f(&doc) + }) + } + + pub fn track(&self) { + self.inner.track(); + } +} + +/// Checks if completion should be triggered if the received command +/// is one that inserts whitespace or deletes whitespace +fn show_completion( + cmd: &EditCommand, + doc: &Rope, + deltas: &[(Rope, RopeDelta, InvalLines)], +) -> bool { + match cmd { + EditCommand::DeleteBackward + | EditCommand::DeleteForward + | EditCommand::DeleteWordBackward + | EditCommand::DeleteWordForward + | EditCommand::DeleteForwardAndInsert => { + let start = match deltas.first().and_then(|delta| delta.1.els.first()) { + Some(lapce_xi_rope::DeltaElement::Copy(_, start)) => *start, + _ => 0, + }; + + let end = match deltas.first().and_then(|delta| delta.1.els.get(1)) { + Some(lapce_xi_rope::DeltaElement::Copy(end, _)) => *end, + _ => 0, + }; + + if start > 0 && end > start { + !doc.slice_to_cow(start..end) + .chars() + .all(|c| c.is_whitespace() || c.is_ascii_whitespace()) + } else { + true + } + } + _ => false, + } +} + +fn show_inline_completion(cmd: &EditCommand) -> bool { + matches!( + cmd, + EditCommand::DeleteBackward + | EditCommand::DeleteForward + | EditCommand::DeleteWordBackward + | EditCommand::DeleteWordForward + | EditCommand::DeleteForwardAndInsert + | EditCommand::IndentLine + | EditCommand::InsertMode + ) +} + +// TODO(minor): Should we just put this on view, since it only requires those values? +pub(crate) fn compute_screen_lines( + config: ReadSignal>, + base: RwSignal, + view_kind: ReadSignal, + doc: &Doc, + lines: &Lines, + text_prov: impl TextLayoutProvider + Clone, + config_id: ConfigId, +) -> ScreenLines { + // TODO: this should probably be a get since we need to depend on line-height + let config = config.get(); + let line_height = config.editor.line_height(); + + let (y0, y1) = base + .with_untracked(|base| (base.active_viewport.y0, base.active_viewport.y1)); + // Get the start and end (visual) lines that are visible in the viewport + let min_vline = VLine((y0 / line_height as f64).floor() as usize); + let max_vline = VLine((y1 / line_height as f64).ceil() as usize); + + let cache_rev = doc.cache_rev.get(); + lines.check_cache_rev(cache_rev); + // TODO(minor): we don't really need to depend on various subdetails that aren't affecting how + // the screen lines are set up, like the title of a scratch document. + doc.content.track(); + doc.loaded.track(); + + let min_info = once_cell::sync::Lazy::new(|| { + lines + .iter_vlines(text_prov.clone(), false, min_vline) + .next() + }); + + match view_kind.get() { + EditorViewKind::Normal => { + let mut rvlines = Vec::new(); + let mut info = HashMap::new(); + + let Some(min_info) = *min_info else { + return ScreenLines { + lines: Rc::new(rvlines), + info: Rc::new(info), + diff_sections: None, + base, + }; + }; + + // TODO: the original was min_line..max_line + 1, are we iterating too little now? + // the iterator is from min_vline..max_vline + let count = max_vline.get() - min_vline.get(); + let iter = lines.iter_rvlines_init( + text_prov, + cache_rev, + config_id, + min_info.rvline, + false, + ); + + // let range = doc.folding_ranges.get().get_folded_range(); + // let mut init_index = 0; + + for (i, vline_info) in iter.enumerate() { + if rvlines.len() >= count { + break; + } + + // let (folded, next_index) = + // range.contain_line(init_index, vline_info.rvline.line as u32); + // init_index = next_index; + // if folded { + // continue; + // } + rvlines.push(vline_info.rvline); + + let y_idx = min_vline.get() + i; + let vline_y = y_idx * line_height; + let line_y = vline_y - vline_info.rvline.line_index * line_height; + + // Add the information to make it cheap to get in the future. + // This y positions are shifted by the baseline y0 + info.insert( + vline_info.rvline, + LineInfo { + y: line_y as f64 - y0, + vline_y: vline_y as f64 - y0, + vline_info, + }, + ); + } + + ScreenLines { + lines: Rc::new(rvlines), + info: Rc::new(info), + diff_sections: None, + base, + } + } + EditorViewKind::Diff(diff_info) => { + // TODO: let lines in diff view be wrapped, possibly screen_lines should be impl'd + // on DiffEditorData + + let mut y_idx = 0; + let mut rvlines = Vec::new(); + let mut info = HashMap::new(); + let mut diff_sections = Vec::new(); + let mut last_change: Option<&DiffLines> = None; + let mut changes = diff_info.changes.iter().peekable(); + let is_right = diff_info.is_right; + + let line_y = |info: VLineInfo<()>, vline_y: usize| -> usize { + vline_y.saturating_sub(info.rvline.line_index * line_height) + }; + + while let Some(change) = changes.next() { + match (is_right, change) { + (true, DiffLines::Left(range)) => { + if let Some(DiffLines::Right(_)) = changes.peek() { + } else { + let len = range.len(); + diff_sections.push(DiffSection { + y_idx, + height: len, + kind: DiffSectionKind::NoCode, + }); + y_idx += len; + } + } + (false, DiffLines::Right(range)) => { + let len = if let Some(DiffLines::Left(r)) = last_change { + range.len() - r.len().min(range.len()) + } else { + range.len() + }; + if len > 0 { + diff_sections.push(DiffSection { + y_idx, + height: len, + kind: DiffSectionKind::NoCode, + }); + y_idx += len; + } + } + (true, DiffLines::Right(range)) + | (false, DiffLines::Left(range)) => { + // TODO: count vline count in the range instead + let height = range.len(); + + diff_sections.push(DiffSection { + y_idx, + height, + kind: if is_right { + DiffSectionKind::Added + } else { + DiffSectionKind::Removed + }, + }); + + let initial_y_idx = y_idx; + // Mopve forward by the count given. + y_idx += height; + + if y_idx < min_vline.get() { + if is_right { + if let Some(DiffLines::Left(r)) = last_change { + // TODO: count vline count in the other editor since this is skipping an amount dependent on those vlines + let len = r.len() - r.len().min(range.len()); + if len > 0 { + diff_sections.push(DiffSection { + y_idx, + height: len, + kind: DiffSectionKind::NoCode, + }); + y_idx += len; + } + }; + } + last_change = Some(change); + continue; + } + + let start_rvline = + lines.rvline_of_line(&text_prov, range.start); + + // TODO: this wouldn't need to produce vlines if screen lines didn't + // require them. + let iter = lines + .iter_rvlines_init( + &text_prov, + cache_rev, + config_id, + start_rvline, + false, + ) + .take_while(|vline_info| { + vline_info.rvline.line < range.end + }) + .enumerate(); + for (i, rvline_info) in iter { + let rvline = rvline_info.rvline; + if initial_y_idx + i < min_vline.0 { + continue; + } + + rvlines.push(rvline); + let vline_y = (initial_y_idx + i) * line_height; + info.insert( + rvline, + LineInfo { + y: line_y(rvline_info, vline_y) as f64 - y0, + vline_y: vline_y as f64 - y0, + vline_info: rvline_info, + }, + ); + + if initial_y_idx + i > max_vline.0 { + break; + } + } + + if is_right { + if let Some(DiffLines::Left(r)) = last_change { + // TODO: count vline count in the other editor since this is skipping an amount dependent on those vlines + let len = r.len() - r.len().min(range.len()); + if len > 0 { + diff_sections.push(DiffSection { + y_idx, + height: len, + kind: DiffSectionKind::NoCode, + }); + y_idx += len; + } + }; + } + } + (_, DiffLines::Both(bothinfo)) => { + let start = if is_right { + bothinfo.right.start + } else { + bothinfo.left.start + }; + let len = bothinfo.right.len(); + let diff_height = len + - bothinfo + .skip + .as_ref() + .map(|skip| skip.len().saturating_sub(1)) + .unwrap_or(0); + if y_idx + diff_height < min_vline.get() { + y_idx += diff_height; + last_change = Some(change); + continue; + } + + let start_rvline = lines.rvline_of_line(&text_prov, start); + + let mut iter = lines + .iter_rvlines_init( + &text_prov, + cache_rev, + config_id, + start_rvline, + false, + ) + .peekable(); + while let Some(rvline_info) = iter.next() { + let line = rvline_info.rvline.line; + + if line >= start + len { + break; + } + + // Skip over the lines + if let Some(skip) = bothinfo.skip.as_ref() { + if Some(skip.start) == line.checked_sub(start) { + y_idx += 1; + + // restart iterator after the skip + let start_rvline = lines.rvline_of_line( + &text_prov, + start + skip.end, + ); + + iter = lines + .iter_rvlines_init( + &text_prov, + cache_rev, + config_id, + start_rvline, + false, + ) + .peekable(); + + continue; + } + } + + // Add the vline if it is within view + if y_idx >= min_vline.get() { + rvlines.push(rvline_info.rvline); + let vline_y = y_idx * line_height; + info.insert( + rvline_info.rvline, + LineInfo { + y: line_y(rvline_info, vline_y) as f64 - y0, + vline_y: vline_y as f64 - y0, + vline_info: rvline_info, + }, + ); + } + + y_idx += 1; + + if y_idx - 1 > max_vline.get() { + break; + } + } + } + } + last_change = Some(change); + } + ScreenLines { + lines: Rc::new(rvlines), + info: Rc::new(info), + diff_sections: Some(Rc::new(diff_sections)), + base, + } + } + } +} + +fn parse_hover_resp( + hover: lsp_types::Hover, + config: &LapceConfig, +) -> Vec { + match hover.contents { + HoverContents::Scalar(text) => match text { + MarkedString::String(text) => parse_markdown(&text, 1.8, config), + MarkedString::LanguageString(code) => parse_markdown( + &format!("```{}\n{}\n```", code.language, code.value), + 1.8, + config, + ), + }, + HoverContents::Array(array) => array + .into_iter() + .map(|t| from_marked_string(t, config)) + .rev() + .reduce(|mut contents, more| { + contents.push(MarkdownContent::Separator); + contents.extend(more); + contents + }) + .unwrap_or_default(), + HoverContents::Markup(content) => match content.kind { + MarkupKind::PlainText => from_plaintext(&content.value, 1.8, config), + MarkupKind::Markdown => parse_markdown(&content.value, 1.8, config), + }, + } +} + +#[derive(Debug)] +enum FindHintRs { + NoMatchBreak, + NoMatchContinue { pre_hint_len: u32 }, + MatchWithoutLocation, + Match(Location), +} + +fn find_hint(mut pre_hint_len: u32, index: u32, hint: &InlayHint) -> FindHintRs { + use FindHintRs::*; + match &hint.label { + InlayHintLabel::String(text) => { + let actual_col = pre_hint_len + hint.position.character; + let actual_col_end = actual_col + (text.len() as u32); + if actual_col > index { + NoMatchBreak + } else if actual_col <= index && index < actual_col_end { + MatchWithoutLocation + } else { + pre_hint_len += text.len() as u32; + NoMatchContinue { pre_hint_len } + } + } + InlayHintLabel::LabelParts(parts) => { + for part in parts { + let actual_col = pre_hint_len + hint.position.character; + let actual_col_end = actual_col + part.value.len() as u32; + if index < actual_col { + return NoMatchBreak; + } else if actual_col <= index && index < actual_col_end { + if let Some(location) = &part.location { + return Match(location.clone()); + } else { + return MatchWithoutLocation; + } + } else { + pre_hint_len += part.value.len() as u32; + } + } + NoMatchContinue { pre_hint_len } + } + } +} diff --git a/lapce-app/src/editor/diff.rs b/lapce-app/src/editor/diff.rs new file mode 100644 index 0000000..5cb82c8 --- /dev/null +++ b/lapce-app/src/editor/diff.rs @@ -0,0 +1,552 @@ +use std::{rc::Rc, sync::atomic}; + +use floem::{ + View, + event::{Event, EventListener}, + ext_event::create_ext_action, + reactive::{RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, + style::CursorStyle, + views::{ + Decorators, clip, dyn_stack, editor::id::EditorId, empty, label, stack, svg, + }, +}; +use lapce_core::buffer::{ + diff::{DiffExpand, DiffLines, expand_diff_lines, rope_diff}, + rope_text::RopeText, +}; +use lapce_rpc::{buffer::BufferId, proxy::ProxyResponse}; +use lapce_xi_rope::Rope; +use serde::{Deserialize, Serialize}; + +use super::{EditorData, EditorViewKind}; +use crate::{ + config::{color::LapceColor, icon::LapceIcons}, + doc::{Doc, DocContent}, + id::{DiffEditorId, EditorTabId}, + main_split::{Editors, MainSplitData}, + wave::wave_box, + window_tab::CommonData, +}; + +#[derive(Clone)] +pub struct DiffInfo { + pub is_right: bool, + pub changes: Vec, +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct DiffEditorInfo { + pub left_content: DocContent, + pub right_content: DocContent, +} + +impl DiffEditorInfo { + pub fn to_data( + &self, + data: MainSplitData, + editor_tab_id: EditorTabId, + ) -> DiffEditorData { + let cx = data.scope.create_child(); + + let diff_editor_id = DiffEditorId::next(); + + let new_doc = { + let data = data.clone(); + let common = data.common.clone(); + move |content: &DocContent| match content { + DocContent::File { path, .. } => { + let (doc, _) = data.get_doc(path.clone(), None); + doc + } + DocContent::Local => { + Rc::new(Doc::new_local(cx, data.editors, common.clone())) + } + DocContent::History(history) => { + let doc = Doc::new_history( + cx, + content.clone(), + data.editors, + common.clone(), + ); + let doc = Rc::new(doc); + + { + let doc = doc.clone(); + let send = create_ext_action(cx, move |result| { + if let Ok(ProxyResponse::BufferHeadResponse { + content, + .. + }) = result + { + doc.init_content(Rope::from(content)); + } + }); + common.proxy.get_buffer_head( + history.path.clone(), + move |result| { + send(result); + }, + ); + } + + doc + } + DocContent::Scratch { name, .. } => { + let doc_content = DocContent::Scratch { + id: BufferId::next(), + name: name.to_string(), + }; + let doc = Doc::new_content( + cx, + doc_content, + data.editors, + common.clone(), + ); + let doc = Rc::new(doc); + data.scratch_docs.update(|scratch_docs| { + scratch_docs.insert(name.to_string(), doc.clone()); + }); + doc + } + } + }; + + let left_doc = new_doc(&self.left_content); + let right_doc = new_doc(&self.right_content); + + let diff_editor_data = DiffEditorData::new( + cx, + diff_editor_id, + editor_tab_id, + left_doc, + right_doc, + data.editors, + data.common.clone(), + ); + + data.diff_editors.update(|diff_editors| { + diff_editors.insert(diff_editor_id, diff_editor_data.clone()); + }); + + diff_editor_data + } +} + +#[derive(Clone)] +pub struct DiffEditorData { + pub id: DiffEditorId, + pub editor_tab_id: RwSignal, + pub scope: Scope, + pub left: EditorData, + pub right: EditorData, + pub confirmed: RwSignal, + pub focus_right: RwSignal, +} + +impl DiffEditorData { + pub fn new( + cx: Scope, + id: DiffEditorId, + editor_tab_id: EditorTabId, + left_doc: Rc, + right_doc: Rc, + editors: Editors, + common: Rc, + ) -> Self { + let cx = cx.create_child(); + let confirmed = cx.create_rw_signal(false); + + // TODO: ensure that left/right are cleaned up + let [left, right] = [left_doc, right_doc].map(|doc| { + editors.make_from_doc( + cx, + doc, + None, + Some((editor_tab_id, id)), + Some(confirmed), + common.clone(), + ) + }); + + let data = Self { + id, + editor_tab_id: cx.create_rw_signal(editor_tab_id), + scope: cx, + left, + right, + confirmed, + focus_right: cx.create_rw_signal(true), + }; + + data.listen_diff_changes(); + + data + } + + pub fn diff_editor_info(&self) -> DiffEditorInfo { + DiffEditorInfo { + left_content: self.left.doc().content.get_untracked(), + right_content: self.right.doc().content.get_untracked(), + } + } + + pub fn copy( + &self, + cx: Scope, + editor_tab_id: EditorTabId, + diff_editor_id: EditorId, + editors: Editors, + ) -> Self { + let cx = cx.create_child(); + let confirmed = cx.create_rw_signal(true); + + let [left, right] = [&self.left, &self.right].map(|editor_data| { + editors + .make_copy( + editor_data.id(), + cx, + None, + Some((editor_tab_id, diff_editor_id)), + Some(confirmed), + ) + .unwrap() + }); + + let diff_editor = DiffEditorData { + scope: cx, + id: diff_editor_id, + editor_tab_id: cx.create_rw_signal(editor_tab_id), + focus_right: cx.create_rw_signal(true), + left, + right, + confirmed, + }; + + diff_editor.listen_diff_changes(); + diff_editor + } + + fn listen_diff_changes(&self) { + let cx = self.scope; + + let left = self.left.clone(); + let left_doc_rev = { + let left = left.clone(); + cx.create_memo(move |_| { + let doc = left.doc_signal().get(); + (doc.content.get(), doc.buffer.with(|b| b.rev())) + }) + }; + + let right = self.right.clone(); + let right_doc_rev = { + let right = right.clone(); + cx.create_memo(move |_| { + let doc = right.doc_signal().get(); + (doc.content.get(), doc.buffer.with(|b| b.rev())) + }) + }; + + cx.create_effect(move |_| { + let (_, left_rev) = left_doc_rev.get(); + let (left_editor_view, left_doc) = (left.kind, left.doc()); + let (left_atomic_rev, left_rope) = + left_doc.buffer.with_untracked(|buffer| { + (buffer.atomic_rev(), buffer.text().clone()) + }); + + let (_, right_rev) = right_doc_rev.get(); + let (right_editor_view, right_doc) = (right.kind, right.doc()); + let (right_atomic_rev, right_rope) = + right_doc.buffer.with_untracked(|buffer| { + (buffer.atomic_rev(), buffer.text().clone()) + }); + + let send = { + let right_atomic_rev = right_atomic_rev.clone(); + create_ext_action(cx, move |changes: Option>| { + let changes = if let Some(changes) = changes { + changes + } else { + return; + }; + + if left_atomic_rev.load(atomic::Ordering::Acquire) != left_rev { + return; + } + + if right_atomic_rev.load(atomic::Ordering::Acquire) != right_rev + { + return; + } + + left_editor_view.set(EditorViewKind::Diff(DiffInfo { + is_right: false, + changes: changes.clone(), + })); + right_editor_view.set(EditorViewKind::Diff(DiffInfo { + is_right: true, + changes, + })); + }) + }; + + rayon::spawn(move || { + let changes = rope_diff( + left_rope, + right_rope, + right_rev, + right_atomic_rev.clone(), + Some(3), + ); + send(changes); + }); + }); + } +} + +#[derive(Clone, PartialEq)] +struct DiffShowMoreSection { + left_actual_line: usize, + right_actual_line: usize, + skip_start: usize, + lines: usize, +} + +pub fn diff_show_more_section_view( + left_editor: &EditorData, + right_editor: &EditorData, +) -> impl View + use<> { + let left_editor_view = left_editor.kind; + let right_editor_view = right_editor.kind; + let right_screen_lines = right_editor.screen_lines(); + let right_scroll_delta = right_editor.editor.scroll_delta; + let viewport = right_editor.viewport(); + let config = right_editor.common.config; + + let each_fn = move || { + let editor_view = right_editor_view.get(); + + if let EditorViewKind::Diff(diff_info) = editor_view { + diff_info + .changes + .iter() + .filter_map(|change| { + let DiffLines::Both(info) = change else { + return None; + }; + + let skip = info.skip.as_ref()?; + + Some(DiffShowMoreSection { + left_actual_line: info.left.start, + right_actual_line: info.right.start, + skip_start: skip.start, + lines: skip.len(), + }) + }) + .collect() + } else { + Vec::new() + } + }; + + let key_fn = move |section: &DiffShowMoreSection| { + ( + section.right_actual_line + section.skip_start, + section.lines, + ) + }; + + let view_fn = move |section: DiffShowMoreSection| { + stack(( + wave_box().style(move |s| { + s.absolute() + .size_pct(100.0, 100.0) + .color(config.get().color(LapceColor::PANEL_BACKGROUND)) + }), + label(move || format!("{} Hidden Lines", section.lines)), + label(|| "|".to_string()).style(|s| s.margin_left(10.0)), + stack(( + svg(move || config.get().ui_svg(LapceIcons::FOLD)).style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.size(size, size) + .color(config.color(LapceColor::EDITOR_FOREGROUND)) + }), + label(|| "Expand All".to_string()).style(|s| s.margin_left(6.0)), + )) + .on_event_stop(EventListener::PointerDown, move |_| {}) + .on_click_stop(move |_event| { + left_editor_view.update(|editor_view| { + if let EditorViewKind::Diff(diff_info) = editor_view { + expand_diff_lines( + &mut diff_info.changes, + section.left_actual_line, + DiffExpand::All, + false, + ); + } + }); + right_editor_view.update(|editor_view| { + if let EditorViewKind::Diff(diff_info) = editor_view { + expand_diff_lines( + &mut diff_info.changes, + section.right_actual_line, + DiffExpand::All, + true, + ); + } + }); + }) + .style(|s| { + s.margin_left(10.0) + .height_pct(100.0) + .items_center() + .hover(|s| s.cursor(CursorStyle::Pointer)) + }), + label(|| "|".to_string()).style(|s| s.margin_left(10.0)), + stack(( + svg(move || config.get().ui_svg(LapceIcons::FOLD_UP)).style( + move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.size(size, size) + .color(config.color(LapceColor::EDITOR_FOREGROUND)) + }, + ), + label(|| "Expand Up".to_string()).style(|s| s.margin_left(6.0)), + )) + .on_event_stop(EventListener::PointerDown, move |_| {}) + .on_click_stop(move |_event| { + left_editor_view.update(|editor_view| { + if let EditorViewKind::Diff(diff_info) = editor_view { + expand_diff_lines( + &mut diff_info.changes, + section.left_actual_line, + DiffExpand::Up(10), + false, + ); + } + }); + right_editor_view.update(|editor_view| { + if let EditorViewKind::Diff(diff_info) = editor_view { + expand_diff_lines( + &mut diff_info.changes, + section.right_actual_line, + DiffExpand::Up(10), + true, + ); + } + }); + }) + .style(move |s| { + s.margin_left(10.0) + .height_pct(100.0) + .items_center() + .hover(|s| s.cursor(CursorStyle::Pointer)) + }), + label(|| "|".to_string()).style(|s| s.margin_left(10.0)), + stack(( + svg(move || config.get().ui_svg(LapceIcons::FOLD_DOWN)).style( + move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.size(size, size) + .color(config.color(LapceColor::EDITOR_FOREGROUND)) + }, + ), + label(|| "Expand Down".to_string()).style(|s| s.margin_left(6.0)), + )) + .on_event_stop(EventListener::PointerDown, move |_| {}) + .on_click_stop(move |_event| { + left_editor_view.update(|editor_view| { + if let EditorViewKind::Diff(diff_info) = editor_view { + expand_diff_lines( + &mut diff_info.changes, + section.left_actual_line, + DiffExpand::Down(10), + false, + ); + } + }); + right_editor_view.update(|editor_view| { + if let EditorViewKind::Diff(diff_info) = editor_view { + expand_diff_lines( + &mut diff_info.changes, + section.right_actual_line, + DiffExpand::Down(10), + true, + ); + } + }); + }) + .style(move |s| { + s.margin_left(10.0) + .height_pct(100.0) + .items_center() + .hover(|s| s.cursor(CursorStyle::Pointer)) + }), + )) + .on_event_cont(EventListener::PointerWheel, move |event| { + if let Event::PointerWheel(event) = event { + right_scroll_delta.set(event.delta); + } + }) + .style(move |s| { + let right_screen_lines = right_screen_lines.get(); + + let mut right_line = section.right_actual_line + section.skip_start; + let is_before_skip = if right_line > 0 { + right_line -= 1; + true + } else { + right_line += section.lines; + false + }; + + let Some(line_info) = right_screen_lines.info_for_line(right_line) + else { + return s.hide(); + }; + + let config = config.get(); + let line_height = config.editor.line_height(); + + let mut y = line_info.y - viewport.get().y0; + + if is_before_skip { + y += line_height as f64 + } else { + y -= line_height as f64 + } + + s.absolute() + .width_pct(100.0) + .height(line_height as f32) + .justify_center() + .items_center() + .margin_top(y) + .pointer_events_auto() + .hover(|s| s.cursor(CursorStyle::Default)) + }) + }; + + stack(( + empty().style(move |s| { + s.height(config.get().editor.line_height() as f32 + 1.0) + }), + clip( + dyn_stack(each_fn, key_fn, view_fn) + .style(|s| s.flex_col().size_pct(100.0, 100.0)), + ) + .style(|s| s.size_pct(100.0, 100.0)), + )) + .style(|s| { + s.absolute() + .flex_col() + .size_pct(100.0, 100.0) + .pointer_events_none() + }) + .debug_name("Diff Show More Section") +} diff --git a/lapce-app/src/editor/gutter.rs b/lapce-app/src/editor/gutter.rs new file mode 100644 index 0000000..20b0d7c --- /dev/null +++ b/lapce-app/src/editor/gutter.rs @@ -0,0 +1,402 @@ +use floem::{ + Renderer, View, ViewId, + context::PaintCx, + peniko::kurbo::{Point, Rect, Size}, + reactive::{Memo, SignalGet, SignalWith}, + text::{Attrs, AttrsList, FamilyOwned, TextLayout}, +}; +use im::HashMap; +use lapce_core::{buffer::rope_text::RopeText, mode::Mode}; +use serde::{Deserialize, Serialize}; + +use super::{EditorData, view::changes_colors_screen}; +use crate::config::{LapceConfig, color::LapceColor}; + +pub struct EditorGutterView { + id: ViewId, + editor: EditorData, + width: f64, + gutter_padding_right: Memo, +} + +pub fn editor_gutter_view( + editor: EditorData, + gutter_padding_right: Memo, +) -> EditorGutterView { + let id = ViewId::new(); + + EditorGutterView { + id, + editor, + width: 0.0, + gutter_padding_right, + } +} + +impl EditorGutterView { + fn paint_head_changes( + &self, + cx: &mut PaintCx, + e_data: &EditorData, + viewport: Rect, + is_normal: bool, + config: &LapceConfig, + ) { + if !is_normal { + return; + } + + let changes = e_data.doc().head_changes().get_untracked(); + let line_height = config.editor.line_height() as f64; + let gutter_padding_right = self.gutter_padding_right.get_untracked() as f64; + + let changes = changes_colors_screen(config, &e_data.editor, changes); + for (y, height, removed, color) in changes { + let height = if removed { + 10.0 + } else { + height as f64 * line_height + }; + let mut y = y - viewport.y0; + if removed { + y -= 5.0; + } + cx.fill( + &Size::new(3.0, height).to_rect().with_origin(Point::new( + self.width + 5.0 - gutter_padding_right, + y, + )), + color, + 0.0, + ) + } + } + + fn paint_sticky_headers( + &self, + cx: &mut PaintCx, + is_normal: bool, + config: &LapceConfig, + ) { + if !is_normal { + return; + } + + if !config.editor.sticky_header { + return; + } + let sticky_header_height = self.editor.sticky_header_height.get_untracked(); + if sticky_header_height == 0.0 { + return; + } + + let sticky_area_rect = + Size::new(self.width + 25.0 + 30.0, sticky_header_height) + .to_rect() + .with_origin(Point::new(-25.0, 0.0)) + .inflate(25.0, 0.0); + cx.fill( + &sticky_area_rect, + config.color(LapceColor::LAPCE_DROPDOWN_SHADOW), + 3.0, + ); + cx.fill( + &sticky_area_rect, + config.color(LapceColor::EDITOR_STICKY_HEADER_BACKGROUND), + 0.0, + ); + } +} + +impl View for EditorGutterView { + fn id(&self) -> ViewId { + self.id + } + + fn compute_layout( + &mut self, + _cx: &mut floem::context::ComputeLayoutCx, + ) -> Option { + if let Some(width) = self.id.get_layout().map(|l| l.size.width as f64) { + self.width = width; + } + None + } + + fn paint(&mut self, cx: &mut floem::context::PaintCx) { + let viewport = self.editor.viewport().get_untracked(); + let cursor = self.editor.cursor(); + let screen_lines = self.editor.screen_lines(); + let config = self.editor.common.config; + + let kind_is_normal = + self.editor.kind.with_untracked(|kind| kind.is_normal()); + let (offset, mode) = cursor.with_untracked(|c| (c.offset(), c.get_mode())); + let config = config.get_untracked(); + let line_height = config.editor.line_height() as f64; + let last_line = self.editor.editor.last_line(); + let current_line = self + .editor + .doc() + .buffer + .with_untracked(|buffer| buffer.line_of_offset(offset)); + + let family: Vec = + FamilyOwned::parse_list(&config.editor.font_family).collect(); + let attrs = Attrs::new() + .family(&family) + .color(config.color(LapceColor::EDITOR_DIM)) + .font_size(config.editor.font_size() as f32); + let attrs_list = AttrsList::new(attrs.clone()); + let current_line_attrs_list = AttrsList::new( + attrs + .clone() + .color(config.color(LapceColor::EDITOR_FOREGROUND)), + ); + let show_relative = config.core.modal + && config.editor.modal_mode_relative_line_numbers + && mode != Mode::Insert + && kind_is_normal; + + screen_lines.with_untracked(|screen_lines| { + for (line, y) in screen_lines.iter_lines_y() { + // If it ends up outside the bounds of the file, stop trying to display line numbers + if line > last_line { + break; + } + + let text = if show_relative { + if line == current_line { + line + 1 + } else { + line.abs_diff(current_line) + } + } else { + line + 1 + } + .to_string(); + + let mut text_layout = TextLayout::new(); + if line == current_line { + text_layout.set_text( + &text, + current_line_attrs_list.clone(), + None, + ); + } else { + text_layout.set_text(&text, attrs_list.clone(), None); + } + let size = text_layout.size(); + let height = size.height; + + cx.draw_text( + &text_layout, + Point::new( + (self.width + - size.width + - self.gutter_padding_right.get_untracked() as f64) + .max(0.0), + y + (line_height - height) / 2.0 - viewport.y0, + ), + ); + } + }); + + self.paint_head_changes(cx, &self.editor, viewport, kind_is_normal, &config); + self.paint_sticky_headers(cx, kind_is_normal, &config); + } + + fn debug_name(&self) -> std::borrow::Cow<'static, str> { + "Editor Gutter".into() + } +} + +#[derive(Default, Clone)] +pub struct FoldingRanges(pub Vec); + +#[derive(Default, Clone)] +pub struct FoldedRanges(pub Vec); + +impl FoldingRanges { + pub fn get_folded_range(&self) -> FoldedRanges { + let mut range = Vec::new(); + let mut limit_line = 0; + for item in &self.0 { + if item.start.line < limit_line && limit_line > 0 { + continue; + } + if item.status.is_folded() { + range.push(crate::editor::gutter::FoldedRange { + start: item.start, + end: item.end, + }); + limit_line = item.end.line; + } + } + + FoldedRanges(range) + } + pub fn to_display_items(&self) -> Vec { + let mut folded = HashMap::new(); + let mut unfold_start: HashMap = HashMap::new(); + let mut unfold_end = HashMap::new(); + let mut limit_line = 0; + for item in &self.0 { + if item.start.line < limit_line && limit_line > 0 { + continue; + } + match item.status { + FoldingRangeStatus::Fold => { + folded.insert( + item.start.line, + FoldingDisplayItem::Folded(item.start), + ); + limit_line = item.end.line; + } + FoldingRangeStatus::Unfold => { + unfold_start.insert( + item.start.line, + FoldingDisplayItem::UnfoldStart(item.start), + ); + unfold_end.insert( + item.end.line, + FoldingDisplayItem::UnfoldEnd(item.end), + ); + limit_line = 0; + } + }; + } + for (key, val) in unfold_end { + unfold_start.insert(key, val); + } + for (key, val) in folded { + unfold_start.insert(key, val); + } + + unfold_start.into_iter().map(|x| x.1).collect() + } +} + +impl FoldedRanges { + pub fn contain_line(&self, start_index: usize, line: u32) -> (bool, usize) { + if start_index >= self.0.len() { + return (false, start_index); + } + let mut last_index = start_index; + for range in self.0[start_index..].iter() { + if range.start.line >= line { + return (false, last_index); + } else if range.start.line < line && range.end.line > line { + return (true, last_index); + } else if range.end.line < line { + last_index += 1; + } + } + (false, last_index) + } +} + +#[derive(Debug, Clone)] +pub struct FoldedRange { + pub start: FoldingPosition, + pub end: FoldingPosition, +} + +#[derive(Debug, Clone)] +pub struct FoldingRange { + pub start: FoldingPosition, + pub end: FoldingPosition, + pub status: FoldingRangeStatus, + pub collapsed_text: Option, +} + +impl FoldingRange { + pub fn from_lsp(value: lsp_types::FoldingRange) -> Self { + let lsp_types::FoldingRange { + start_line, + start_character, + end_line, + end_character, + collapsed_text, + .. + } = value; + let status = FoldingRangeStatus::Unfold; + Self { + start: FoldingPosition { + line: start_line, + character: start_character, + // kind: kind.clone().map(|x| FoldingRangeKind::from(x)), + }, + end: FoldingPosition { + line: end_line, + character: end_character, + // kind: kind.map(|x| FoldingRangeKind::from(x)), + }, + status, + collapsed_text, + } + } +} + +#[derive(Debug, Clone, Eq, PartialEq, Hash, Copy)] +pub struct FoldingPosition { + pub line: u32, + pub character: Option, + // pub kind: Option, +} + +#[derive(Debug, Clone, Default, Eq, PartialEq)] +pub enum FoldingRangeStatus { + Fold, + #[default] + Unfold, +} + +impl FoldingRangeStatus { + pub fn click(&mut self) { + // match self { + // FoldingRangeStatus::Fold => { + // *self = FoldingRangeStatus::Unfold; + // } + // FoldingRangeStatus::Unfold => { + // *self = FoldingRangeStatus::Fold; + // } + // } + } + pub fn is_folded(&self) -> bool { + *self == Self::Fold + } +} +#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] +pub enum FoldingDisplayItem { + UnfoldStart(FoldingPosition), + Folded(FoldingPosition), + UnfoldEnd(FoldingPosition), +} + +impl FoldingDisplayItem { + pub fn position(&self) -> FoldingPosition { + match self { + FoldingDisplayItem::UnfoldStart(x) => *x, + FoldingDisplayItem::Folded(x) => *x, + FoldingDisplayItem::UnfoldEnd(x) => *x, + } + } +} + +#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Clone, Hash, Copy)] +pub enum FoldingRangeKind { + Comment, + Imports, + Region, +} + +impl From for FoldingRangeKind { + fn from(value: lsp_types::FoldingRangeKind) -> Self { + match value { + lsp_types::FoldingRangeKind::Comment => FoldingRangeKind::Comment, + lsp_types::FoldingRangeKind::Imports => FoldingRangeKind::Imports, + lsp_types::FoldingRangeKind::Region => FoldingRangeKind::Region, + } + } +} diff --git a/lapce-app/src/editor/location.rs b/lapce-app/src/editor/location.rs new file mode 100644 index 0000000..35e79f5 --- /dev/null +++ b/lapce-app/src/editor/location.rs @@ -0,0 +1,34 @@ +use std::path::PathBuf; + +use floem::peniko::kurbo::Vec2; +use lapce_core::{buffer::rope_text::RopeText, rope_text_pos::RopeTextPosition}; +use lsp_types::Position; + +#[derive(Clone, Debug, PartialEq)] +pub struct EditorLocation { + pub path: PathBuf, + pub position: Option, + pub scroll_offset: Option, + // This will ignore unconfirmed editors, and always create new editors + // if there's no match path on the active editor tab + pub ignore_unconfirmed: bool, + // This will stop finding matching path on different editor tabs + pub same_editor_tab: bool, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum EditorPosition { + Line(usize), + Position(Position), + Offset(usize), +} + +impl EditorPosition { + pub fn to_offset(&self, text: &impl RopeText) -> usize { + match self { + EditorPosition::Line(n) => text.first_non_blank_character_on_line(*n), + EditorPosition::Position(position) => text.offset_of_position(position), + EditorPosition::Offset(offset) => *offset, + } + } +} diff --git a/lapce-app/src/editor/view.rs b/lapce-app/src/editor/view.rs new file mode 100644 index 0000000..309d301 --- /dev/null +++ b/lapce-app/src/editor/view.rs @@ -0,0 +1,2667 @@ +use std::{ + cmp, collections::BTreeMap, ops::DerefMut, path::PathBuf, rc::Rc, sync::Arc, +}; + +use floem::{ + Renderer, View, ViewId, + action::{set_ime_allowed, set_ime_cursor_area}, + context::{PaintCx, StyleCx}, + event::{Event, EventListener, EventPropagation}, + keyboard::Modifiers, + kurbo::Stroke, + peniko::{ + Color, + kurbo::{Line, Point, Rect, Size}, + }, + prelude::SignalTrack, + reactive::{ + Memo, ReadSignal, RwSignal, SignalGet, SignalUpdate, SignalWith, + create_effect, create_memo, create_rw_signal, + }, + style::{CursorColor, CursorStyle, Style, TextColor}, + taffy::prelude::NodeId, + views::{ + Decorators, clip, container, dyn_stack, + editor::{ + CurrentLineColor, CursorSurroundingLines, Editor, EditorStyle, + IndentGuideColor, IndentStyleProp, Modal, ModalRelativeLine, + PhantomColor, PlaceholderColor, PreeditUnderlineColor, + RenderWhitespaceProp, ScrollBeyondLastLine, SelectionColor, + ShowIndentGuide, SmartTab, VisibleWhitespaceColor, WrapProp, + text::WrapMethod, + view::{ + DiffSectionKind, EditorView as FloemEditorView, EditorViewClass, + LineRegion, ScreenLines, cursor_caret, + }, + visual_line::{RVLine, VLine}, + }, + empty, label, + scroll::{PropagatePointerWheel, scroll}, + stack, svg, + }, +}; +use itertools::Itertools; +use lapce_core::{ + buffer::{Buffer, diff::DiffLines, rope_text::RopeText}, + cursor::{CursorAffinity, CursorMode}, + selection::SelRegion, +}; +use lapce_rpc::{ + dap_types::{DapId, SourceBreakpoint}, + plugin::PluginId, +}; +use lapce_xi_rope::find::CaseMatching; +use lsp_types::CodeLens; + +use super::{DocSignal, EditorData, gutter::editor_gutter_view}; +use crate::{ + app::clickable_icon, + command::InternalCommand, + config::{LapceConfig, color::LapceColor, editor::WrapStyle, icon::LapceIcons}, + debug::{DapData, LapceBreakpoint}, + doc::DocContent, + editor::gutter::FoldingDisplayItem, + text_input::TextInputBuilder, + window_tab::{CommonData, Focus, WindowTabData}, + workspace::LapceWorkspace, +}; + +#[derive(Clone, Debug, Default)] +pub struct StickyHeaderInfo { + pub sticky_lines: Vec, + pub last_sticky_should_scroll: bool, + pub y_diff: f64, +} + +fn editor_wrap(config: &LapceConfig) -> WrapMethod { + /// Minimum width that we'll allow the view to be wrapped at. + const MIN_WRAPPED_WIDTH: f32 = 100.0; + + match config.editor.wrap_style { + WrapStyle::None => WrapMethod::None, + WrapStyle::EditorWidth => WrapMethod::EditorWidth, + WrapStyle::WrapWidth => WrapMethod::WrapWidth { + width: (config.editor.wrap_width as f32).max(MIN_WRAPPED_WIDTH), + }, + } +} + +pub fn editor_style( + config: ReadSignal>, + doc: DocSignal, + s: Style, +) -> Style { + let config = config.get(); + let doc = doc.get(); + + s.set( + IndentStyleProp, + doc.buffer.with_untracked(Buffer::indent_style), + ) + .set(CursorColor, config.color(LapceColor::EDITOR_CARET)) + .set(SelectionColor, config.color(LapceColor::EDITOR_SELECTION)) + .set( + CurrentLineColor, + config.color(LapceColor::EDITOR_CURRENT_LINE), + ) + .set( + VisibleWhitespaceColor, + config.color(LapceColor::EDITOR_VISIBLE_WHITESPACE), + ) + .set( + IndentGuideColor, + config.color(LapceColor::EDITOR_INDENT_GUIDE), + ) + .set(ScrollBeyondLastLine, config.editor.scroll_beyond_last_line) + .color(config.color(LapceColor::EDITOR_FOREGROUND)) + .set(TextColor, config.color(LapceColor::EDITOR_FOREGROUND)) + .set(PhantomColor, config.color(LapceColor::EDITOR_DIM)) + .set(PlaceholderColor, config.color(LapceColor::EDITOR_DIM)) + .set( + PreeditUnderlineColor, + config.color(LapceColor::EDITOR_FOREGROUND), + ) + .set(ShowIndentGuide, config.editor.show_indent_guide) + .set(Modal, config.core.modal) + .set( + ModalRelativeLine, + config.editor.modal_mode_relative_line_numbers, + ) + .set(SmartTab, config.editor.smart_tab) + .set(WrapProp, editor_wrap(&config)) + .set( + CursorSurroundingLines, + config.editor.cursor_surrounding_lines, + ) + .set(RenderWhitespaceProp, config.editor.render_whitespace) +} + +pub struct EditorView { + id: ViewId, + editor: EditorData, + is_active: Memo, + inner_node: Option, + viewport: RwSignal, + debug_breakline: Memo>, +} + +pub fn editor_view( + e_data: EditorData, + debug_breakline: Memo>, + is_active: impl Fn(bool) -> bool + 'static + Copy, +) -> EditorView { + let id = ViewId::new(); + let is_active = create_memo(move |_| is_active(true)); + + let viewport = e_data.viewport(); + + let doc = e_data.doc_signal(); + let view_kind = e_data.kind; + let screen_lines = e_data.screen_lines(); + create_effect(move |_| { + doc.track(); + view_kind.track(); + id.request_layout(); + }); + + let hide_cursor = e_data.common.window_common.hide_cursor; + create_effect(move |_| { + hide_cursor.track(); + let occurrences = doc.with(|doc| doc.find_result.occurrences); + occurrences.track(); + id.request_paint(); + }); + + create_effect(move |last_rev| { + let buffer = doc.with(|doc| doc.buffer); + let rev = buffer.with(|buffer| buffer.rev()); + if last_rev == Some(rev) { + return rev; + } + id.request_layout(); + rev + }); + + let config = e_data.common.config; + let sticky_header_height_signal = e_data.sticky_header_height; + let editor2 = e_data.clone(); + create_effect(move |last_rev| { + let config = config.get(); + if !config.editor.sticky_header { + return (DocContent::Local, 0, 0, Rect::ZERO, 0, None); + } + + let doc = doc.get(); + let rect = viewport.get(); + let (screen_lines_len, screen_lines_first) = screen_lines + .with(|lines| (lines.lines.len(), lines.lines.first().copied())); + let rev = ( + doc.content.get(), + doc.buffer.with(|b| b.rev()), + doc.cache_rev.get(), + rect, + screen_lines_len, + screen_lines_first, + ); + if last_rev.as_ref() == Some(&rev) { + return rev; + } + + let sticky_header_info = get_sticky_header_info( + &editor2, + viewport, + sticky_header_height_signal, + &config, + ); + + id.update_state(sticky_header_info); + + rev + }); + + let ed1 = e_data.editor.clone(); + let ed2 = ed1.clone(); + let ed3 = ed1.clone(); + + let editor_window_origin = e_data.window_origin(); + let cursor = e_data.cursor(); + let find_focus = e_data.find_focus; + let ime_allowed = e_data.common.window_common.ime_allowed; + let editor_viewport = e_data.viewport(); + let editor_cursor = e_data.cursor(); + create_effect(move |_| { + let active = is_active.get(); + if active && !find_focus.get() { + if !cursor.with(|c| c.is_insert()) { + if ime_allowed.get_untracked() { + ime_allowed.set(false); + set_ime_allowed(false); + } + } else { + if !ime_allowed.get_untracked() { + ime_allowed.set(true); + set_ime_allowed(true); + } + let (offset, affinity) = cursor.with(|c| (c.offset(), c.affinity)); + let (_, point_below) = ed1.points_of_offset(offset, affinity); + let window_origin = editor_window_origin.get(); + let viewport = editor_viewport.get(); + let pos = window_origin + + (point_below.x - viewport.x0, point_below.y - viewport.y0); + set_ime_cursor_area(pos, Size::new(800.0, 600.0)); + } + } + }); + + let doc = e_data.doc_signal(); + EditorView { + id, + editor: e_data, + is_active, + inner_node: None, + viewport, + debug_breakline, + } + .on_event(EventListener::ImePreedit, move |event| { + if !is_active.get_untracked() { + return EventPropagation::Continue; + } + + if let Event::ImePreedit { text, cursor } = event { + if text.is_empty() { + ed2.clear_preedit(); + } else { + let offset = editor_cursor.with_untracked(|c| c.offset()); + ed2.set_preedit(text.clone(), *cursor, offset); + } + } + EventPropagation::Stop + }) + .on_event(EventListener::ImeCommit, move |event| { + if !is_active.get_untracked() { + return EventPropagation::Continue; + } + + if let Event::ImeCommit(text) = event { + ed3.clear_preedit(); + ed3.receive_char(text); + } + EventPropagation::Stop + }) + .class(EditorViewClass) + .style(move |s| editor_style(config, doc, s)) +} + +impl EditorView { + fn paint_diff_sections( + &self, + cx: &mut PaintCx, + viewport: Rect, + screen_lines: &ScreenLines, + config: &LapceConfig, + ) { + let Some(diff_sections) = &screen_lines.diff_sections else { + return; + }; + for section in diff_sections.iter() { + match section.kind { + DiffSectionKind::NoCode => self.paint_diff_no_code( + cx, + viewport, + section.y_idx, + section.height, + config, + ), + DiffSectionKind::Added => { + cx.fill( + &Rect::ZERO + .with_size(Size::new( + viewport.width(), + (config.editor.line_height() * section.height) + as f64, + )) + .with_origin(Point::new( + viewport.x0, + (section.y_idx * config.editor.line_height()) as f64, + )), + config + .color(LapceColor::SOURCE_CONTROL_ADDED) + .multiply_alpha(0.2), + 0.0, + ); + } + DiffSectionKind::Removed => { + cx.fill( + &Rect::ZERO + .with_size(Size::new( + viewport.width(), + (config.editor.line_height() * section.height) + as f64, + )) + .with_origin(Point::new( + viewport.x0, + (section.y_idx * config.editor.line_height()) as f64, + )), + config + .color(LapceColor::SOURCE_CONTROL_REMOVED) + .multiply_alpha(0.2), + 0.0, + ); + } + } + } + } + + fn paint_diff_no_code( + &self, + cx: &mut PaintCx, + viewport: Rect, + start_line: usize, + height: usize, + config: &LapceConfig, + ) { + let line_height = config.editor.line_height(); + let height = (height * line_height) as f64; + let y = (start_line * line_height) as f64; + let y_end = y + height; + + if y_end < viewport.y0 || y > viewport.y1 { + return; + } + + let y = y.max(viewport.y0 - 10.0); + let y_end = y_end.min(viewport.y1 + 10.0); + let height = y_end - y; + + let start_x = viewport.x0.floor() as usize; + let start_x = start_x - start_x % 8; + + for x in (start_x..viewport.x1.ceil() as usize + 1 + height.ceil() as usize) + .step_by(8) + { + let p0 = if x as f64 > viewport.x1.ceil() { + Point::new(viewport.x1.ceil(), y + (x as f64 - viewport.x1.ceil())) + } else { + Point::new(x as f64, y) + }; + + let height = if x as f64 - height < viewport.x0.floor() { + x as f64 - viewport.x0.floor() + } else { + height + }; + if height > 0.0 { + let p1 = Point::new(x as f64 - height, y + height); + cx.stroke( + &Line::new(p0, p1), + config.color(LapceColor::EDITOR_DIM), + &Stroke::new(1.0), + ); + } + } + } + + fn paint_current_line( + &self, + cx: &mut PaintCx, + is_local: bool, + screen_lines: &ScreenLines, + ) { + let e_data = self.editor.clone(); + let ed = e_data.editor.clone(); + let cursor = self.editor.cursor(); + let config = self.editor.common.config; + + let config = config.get_untracked(); + let line_height = config.editor.line_height() as f64; + let viewport = self.viewport.get_untracked(); + + let current_line_color = ed.es.with_untracked(EditorStyle::current_line); + + let breakline = self.debug_breakline.get_untracked().and_then( + |(breakline, breakline_path)| { + if e_data + .doc() + .content + .with_untracked(|c| c.path() == Some(&breakline_path)) + { + Some(breakline) + } else { + None + } + }, + ); + + // TODO: check if this is correct + if let Some(breakline) = breakline { + if let Some(info) = screen_lines.info_for_line(breakline) { + let rect = Rect::from_origin_size( + (viewport.x0, info.vline_y), + (viewport.width(), line_height), + ); + + cx.fill( + &rect, + config.color(LapceColor::EDITOR_DEBUG_BREAK_LINE), + 0.0, + ); + } + } + + cursor.with_untracked(|cursor| { + let highlight_current_line = match cursor.mode { + CursorMode::Normal(_) | CursorMode::Insert(_) => true, + CursorMode::Visual { .. } => false, + }; + + if let Some(current_line_color) = current_line_color { + // Highlight the current line + if !is_local && highlight_current_line { + for (_, end) in cursor.regions_iter() { + // TODO: unsure if this is correct for wrapping lines + let rvline = ed.rvline_of_offset(end, cursor.affinity); + + if let Some(info) = screen_lines + .info(rvline) + .filter(|_| Some(rvline.line) != breakline) + { + let rect = Rect::from_origin_size( + (viewport.x0, info.vline_y), + (viewport.width(), line_height), + ); + + cx.fill(&rect, current_line_color, 0.0); + } + } + } + } + }); + } + + fn paint_find(&self, cx: &mut PaintCx, screen_lines: &ScreenLines) { + let find_visual = self.editor.common.find.visual.get_untracked(); + if !find_visual && self.editor.on_screen_find.with_untracked(|f| !f.active) { + return; + } + if screen_lines.lines.is_empty() { + return; + } + + let min_vline = *screen_lines.lines.first().unwrap(); + let max_vline = *screen_lines.lines.last().unwrap(); + let min_line = screen_lines.info(min_vline).unwrap().vline_info.rvline.line; + let max_line = screen_lines.info(max_vline).unwrap().vline_info.rvline.line; + + let e_data = &self.editor; + let ed = &e_data.editor; + let doc = e_data.doc(); + + let config = self.editor.common.config; + let occurrences = doc.find_result.occurrences; + + let config = config.get_untracked(); + let line_height = config.editor.line_height() as f64; + let color = config.color(LapceColor::EDITOR_FOREGROUND); + + let start = ed.offset_of_line(min_line); + let end = ed.offset_of_line(max_line + 1); + + // TODO: The selection rect creation logic for find is quite similar to the version + // within insert cursor. It would be good to deduplicate it. + if find_visual { + doc.update_find(); + for region in occurrences.with_untracked(|selection| { + selection.regions_in_range(start, end).to_vec() + }) { + self.paint_find_region( + cx, + ed, + ®ion, + color, + screen_lines, + line_height, + ); + } + } + + self.editor.on_screen_find.with_untracked(|find| { + if find.active { + for region in &find.regions { + self.paint_find_region( + cx, + ed, + region, + color, + screen_lines, + line_height, + ); + } + } + }); + } + + fn paint_find_region( + &self, + cx: &mut PaintCx, + ed: &Editor, + region: &SelRegion, + color: Color, + screen_lines: &ScreenLines, + line_height: f64, + ) { + let start = region.min(); + let end = region.max(); + + // TODO(minor): the proper affinity here should probably be tracked by selregion + let (start_rvline, start_col) = + ed.rvline_col_of_offset(start, CursorAffinity::Forward); + let (end_rvline, end_col) = + ed.rvline_col_of_offset(end, CursorAffinity::Backward); + + for line_info in screen_lines.iter_line_info() { + let rvline_info = line_info.vline_info; + let rvline = rvline_info.rvline; + let line = rvline.line; + + if rvline < start_rvline { + continue; + } + + if rvline > end_rvline { + break; + } + + let left_col = if rvline == start_rvline { start_col } else { 0 }; + let (right_col, _vline_end) = if rvline == end_rvline { + let max_col = ed.last_col(rvline_info, true); + (end_col.min(max_col), false) + } else { + (ed.last_col(rvline_info, true), true) + }; + + // TODO(minor): sel region should have the affinity of the start/end + let x0 = ed + .line_point_of_line_col( + line, + left_col, + CursorAffinity::Forward, + true, + ) + .x; + let x1 = ed + .line_point_of_line_col( + line, + right_col, + CursorAffinity::Backward, + true, + ) + .x; + + if !rvline_info.is_empty() && start != end && left_col != right_col { + let rect = Size::new(x1 - x0, line_height) + .to_rect() + .with_origin(Point::new(x0, line_info.vline_y)); + cx.stroke(&rect, color, &Stroke::new(1.0)); + } + } + } + + fn paint_sticky_headers( + &self, + cx: &mut PaintCx, + viewport: Rect, + screen_lines: &ScreenLines, + ) { + let config = self.editor.common.config.get_untracked(); + if !config.editor.sticky_header { + return; + } + if !self.editor.kind.get_untracked().is_normal() { + return; + } + + let line_height = config.editor.line_height(); + let Some(start_vline) = screen_lines.lines.first() else { + return; + }; + let start_info = screen_lines.vline_info(*start_vline).unwrap(); + let start_line = start_info.rvline.line; + + let sticky_header_info = self.editor.sticky_header_info.get_untracked(); + let total_sticky_lines = sticky_header_info.sticky_lines.len(); + + let paint_last_line = total_sticky_lines > 0 + && (sticky_header_info.last_sticky_should_scroll + || sticky_header_info.y_diff != 0.0 + || start_line + total_sticky_lines - 1 + != *sticky_header_info.sticky_lines.last().unwrap()); + + let total_sticky_lines = if paint_last_line { + total_sticky_lines + } else { + total_sticky_lines.saturating_sub(1) + }; + + if total_sticky_lines == 0 { + return; + } + + let scroll_offset = if sticky_header_info.last_sticky_should_scroll { + sticky_header_info.y_diff + } else { + 0.0 + }; + + // Clear background + + let area_height = sticky_header_info + .sticky_lines + .iter() + .copied() + .map(|line| { + let layout = self.editor.editor.text_layout(line); + layout.line_count() * line_height + }) + .sum::() as f64 + - scroll_offset; + + let sticky_area_rect = Size::new(viewport.x1, area_height) + .to_rect() + .with_origin(Point::new(0.0, viewport.y0)) + .inflate(10.0, 0.0); + + cx.fill( + &sticky_area_rect, + config.color(LapceColor::LAPCE_DROPDOWN_SHADOW), + 3.0, + ); + cx.fill( + &sticky_area_rect, + config.color(LapceColor::EDITOR_STICKY_HEADER_BACKGROUND), + 0.0, + ); + self.editor.sticky_header_info.get_untracked(); + // Paint lines + let mut y_accum = 0.0; + for (i, line) in sticky_header_info.sticky_lines.iter().copied().enumerate() + { + let y_diff = if i == total_sticky_lines - 1 { + scroll_offset + } else { + 0.0 + }; + + let text_layout = self.editor.editor.text_layout(line); + + let text_height = (text_layout.line_count() * line_height) as f64; + let height = text_height - y_diff; + + cx.save(); + + let line_area_rect = Size::new(viewport.width(), height) + .to_rect() + .with_origin(Point::new(viewport.x0, viewport.y0 + y_accum)); + + cx.clip(&line_area_rect); + + let y = viewport.y0 - y_diff + y_accum; + cx.draw_text(&text_layout.text, Point::new(viewport.x0, y)); + + y_accum += text_height; + + cx.restore(); + } + } + + fn paint_scroll_bar( + &self, + cx: &mut PaintCx, + viewport: Rect, + is_local: bool, + config: Arc, + ) { + const BAR_WIDTH: f64 = 10.0; + + if is_local { + return; + } + + cx.fill( + &Rect::ZERO + .with_size(Size::new(1.0, viewport.height())) + .with_origin(Point::new( + viewport.x0 + viewport.width() - BAR_WIDTH, + viewport.y0, + )) + .inflate(0.0, 10.0), + config.color(LapceColor::LAPCE_SCROLL_BAR), + 0.0, + ); + + if !self.editor.kind.get_untracked().is_normal() { + return; + } + + let doc = self.editor.doc(); + let total_len = doc.buffer.with_untracked(|buffer| buffer.last_line()); + let changes = doc.head_changes().get_untracked(); + let total_height = viewport.height(); + let total_width = viewport.width(); + let line_height = config.editor.line_height(); + let content_height = if config.editor.scroll_beyond_last_line { + (total_len * line_height) as f64 + total_height - line_height as f64 + } else { + (total_len * line_height) as f64 + }; + + let colors = changes_colors_all(&config, &self.editor.editor, changes); + for (y, height, _, color) in colors { + let y = y / content_height * total_height; + let height = ((height * line_height) as f64 / content_height + * total_height) + .max(3.0); + let rect = Rect::ZERO.with_size(Size::new(3.0, height)).with_origin( + Point::new( + viewport.x0 + total_width - BAR_WIDTH + 1.0, + y + viewport.y0, + ), + ); + cx.fill(&rect, color, 0.0); + } + } + + /// Paint a highlight around the characters at the given positions. + fn paint_char_highlights( + &self, + cx: &mut PaintCx, + screen_lines: &ScreenLines, + highlight_line_cols: impl Iterator, + ) { + let editor = &self.editor.editor; + let config = self.editor.common.config.get_untracked(); + let line_height = config.editor.line_height() as f64; + + for (rvline, col) in highlight_line_cols { + // Is the given line on screen? + if let Some(line_info) = screen_lines.info(rvline) { + let x0 = editor + .line_point_of_line_col( + rvline.line, + col, + CursorAffinity::Forward, + true, + ) + .x; + let x1 = editor + .line_point_of_line_col( + rvline.line, + col + 1, + CursorAffinity::Backward, + true, + ) + .x; + + let y0 = line_info.vline_y; + let y1 = y0 + line_height; + + let rect = Rect::new(x0, y0, x1, y1); + + cx.stroke( + &rect, + config.color(LapceColor::EDITOR_FOREGROUND), + &Stroke::new(1.0), + ); + } + } + } + + /// Paint scope lines between `(start_rvline, start_line, start_col)` and + /// `(end_rvline, end_line end_col)`. + fn paint_scope_lines( + &self, + cx: &mut PaintCx, + viewport: Rect, + screen_lines: &ScreenLines, + (start, start_col): (RVLine, usize), + (end, end_col): (RVLine, usize), + ) { + let editor = &self.editor.editor; + let doc = self.editor.doc(); + let config = self.editor.common.config.get_untracked(); + let line_height = config.editor.line_height() as f64; + let brush = config.color(LapceColor::EDITOR_FOREGROUND); + + if start == end { + if let Some(line_info) = screen_lines.info(start) { + // TODO: Due to line wrapping the y positions of these two spots could be different, do we need to change it? + let x0 = editor + .line_point_of_line_col( + start.line, + start_col + 1, + CursorAffinity::Forward, + true, + ) + .x; + let x1 = editor + .line_point_of_line_col( + end.line, + end_col, + CursorAffinity::Backward, + true, + ) + .x; + + if x0 < x1 { + let y = line_info.vline_y + line_height; + + let p0 = Point::new(x0, y); + let p1 = Point::new(x1, y); + let line = Line::new(p0, p1); + + cx.stroke(&line, brush, &Stroke::new(1.0)); + } + } + } else { + // Are start_line and end_line on screen? + let start_line_y = screen_lines + .info(start) + .map(|line_info| line_info.vline_y + line_height); + let end_line_y = screen_lines + .info(end) + .map(|line_info| line_info.vline_y + line_height); + + // We only need to draw anything if start_line is on or before the visible section and + // end_line is on or after the visible section. + let y0 = start_line_y.or_else(|| { + screen_lines + .lines + .first() + .is_some_and(|&first_vline| first_vline > start) + .then(|| viewport.min_y()) + }); + let y1 = end_line_y.or_else(|| { + screen_lines + .lines + .last() + .is_some_and(|&last_line| last_line < end) + .then(|| viewport.max_y()) + }); + + if let [Some(y0), Some(y1)] = [y0, y1] { + let start_x = editor + .line_point_of_line_col( + start.line, + start_col + 1, + CursorAffinity::Forward, + true, + ) + .x; + let end_x = editor + .line_point_of_line_col( + end.line, + end_col, + CursorAffinity::Backward, + true, + ) + .x; + + // TODO(minor): is this correct with line wrapping? + // The vertical line should be drawn to the left of any non-whitespace characters + // in the enclosed section. + let min_text_x = doc.buffer.with_untracked(|buffer| { + ((start.line + 1)..=end.line) + .filter(|&line| !buffer.is_line_whitespace(line)) + .map(|line| { + let non_blank_offset = + buffer.first_non_blank_character_on_line(line); + let (_, col) = + editor.offset_to_line_col(non_blank_offset); + + editor + .line_point_of_line_col( + line, + col, + CursorAffinity::Backward, + true, + ) + .x + }) + .min_by(f64::total_cmp) + }); + + let min_x = min_text_x.map_or(start_x, |min_text_x| { + cmp::min_by(min_text_x, start_x, f64::total_cmp) + }); + + // Is start_line on screen, and is the vertical line to the left of the opening + // bracket? + if let Some(y) = start_line_y.filter(|_| start_x > min_x) { + let p0 = Point::new(min_x, y); + let p1 = Point::new(start_x, y); + let line = Line::new(p0, p1); + + cx.stroke(&line, brush, &Stroke::new(1.0)); + } + + // Is end_line on screen, and is the vertical line to the left of the closing + // bracket? + if let Some(y) = end_line_y.filter(|_| end_x > min_x) { + let p0 = Point::new(min_x, y); + let p1 = Point::new(end_x, y); + let line = Line::new(p0, p1); + + cx.stroke(&line, brush, &Stroke::new(1.0)); + } + + let p0 = Point::new(min_x, y0); + let p1 = Point::new(min_x, y1); + let line = Line::new(p0, p1); + + cx.stroke(&line, brush, &Stroke::new(1.0)); + } + } + } + + /// Paint enclosing bracket highlights and scope lines if the corresponding settings are + /// enabled. + fn paint_bracket_highlights_scope_lines( + &self, + cx: &mut PaintCx, + viewport: Rect, + screen_lines: &ScreenLines, + ) { + let config = self.editor.common.config.get_untracked(); + + if config.editor.highlight_matching_brackets + || config.editor.highlight_scope_lines + { + let e_data = &self.editor; + let ed = &e_data.editor; + let offset = ed.cursor.with_untracked(|cursor| cursor.mode.offset()); + + let bracket_offsets = e_data + .doc_signal() + .with_untracked(|doc| doc.find_enclosing_brackets(offset)) + .map(|(start, end)| [start, end]); + + let bracket_line_cols = bracket_offsets.map(|bracket_offsets| { + bracket_offsets.map(|offset| { + let (rvline, col) = + ed.rvline_col_of_offset(offset, CursorAffinity::Forward); + (rvline, col) + }) + }); + + if config.editor.highlight_matching_brackets { + self.paint_char_highlights( + cx, + screen_lines, + bracket_line_cols.into_iter().flatten(), + ); + } + + if config.editor.highlight_scope_lines { + if let Some([start_line_col, end_line_col]) = bracket_line_cols { + self.paint_scope_lines( + cx, + viewport, + screen_lines, + start_line_col, + end_line_col, + ); + } + } + } + } +} + +impl View for EditorView { + fn id(&self) -> ViewId { + self.id + } + + fn style_pass(&mut self, cx: &mut StyleCx<'_>) { + let editor = &self.editor.editor; + if editor.es.try_update(|s| s.read(cx)).unwrap() { + editor.floem_style_id.update(|val| *val += 1); + cx.app_state_mut().request_paint(self.id()); + } + } + + fn debug_name(&self) -> std::borrow::Cow<'static, str> { + "Editor View".into() + } + + fn update( + &mut self, + _cx: &mut floem::context::UpdateCx, + state: Box, + ) { + if let Ok(state) = state.downcast() { + self.editor.sticky_header_info.set(*state); + self.id.request_layout(); + } + } + + fn layout( + &mut self, + cx: &mut floem::context::LayoutCx, + ) -> floem::taffy::prelude::NodeId { + cx.layout_node(self.id, true, |_cx| { + if self.inner_node.is_none() { + self.inner_node = Some(self.id.new_taffy_node()); + } + + let e_data = &self.editor; + let editor = &e_data.editor; + + let viewport_size = self.viewport.get_untracked().size(); + + let screen_lines = e_data.screen_lines().get_untracked(); + for (line, _) in screen_lines.iter_lines_y() { + // fill in text layout cache so that max width is correct. + editor.text_layout(line); + } + + let inner_node = self.inner_node.unwrap(); + + let config = self.editor.common.config.get_untracked(); + let line_height = config.editor.line_height() as f64; + + let is_local = e_data.doc().content.with_untracked(|c| c.is_local()); + + let width = editor.max_line_width() + 10.0; + let width = if !is_local { + width.max(viewport_size.width) + } else { + width + }; + let last_vline = editor.last_vline().get(); + let last_vline = e_data.visual_line(last_vline); + let last_line_height = line_height * (last_vline + 1) as f64; + let height = last_line_height.max(line_height); + let height = if !is_local { + height.max(viewport_size.height) + } else { + height + }; + + let margin_bottom = if !is_local + && editor + .es + .with_untracked(EditorStyle::scroll_beyond_last_line) + { + viewport_size.height.min(last_line_height) - line_height + } else { + 0.0 + }; + + let style = Style::new() + .width(width) + .height(height) + .margin_bottom(margin_bottom) + .to_taffy_style(); + self.id.set_taffy_style(inner_node, style); + + vec![inner_node] + }) + } + + fn compute_layout( + &mut self, + cx: &mut floem::context::ComputeLayoutCx, + ) -> Option { + let viewport = cx.current_viewport(); + if self.viewport.with_untracked(|v| v != &viewport) { + self.viewport.set(viewport); + } + None + } + + fn paint(&mut self, cx: &mut PaintCx) { + let viewport = self.viewport.get_untracked(); + let e_data = &self.editor; + let ed = &e_data.editor; + let config = e_data.common.config.get_untracked(); + let doc = e_data.doc(); + let is_local = doc.content.with_untracked(|content| content.is_local()); + let find_focus = self.editor.find_focus; + let is_active = + self.is_active.get_untracked() && !find_focus.get_untracked(); + + // We repeatedly get the screen lines because we don't currently carefully manage the + // paint functions to avoid potentially needing to recompute them, which could *maybe* + // make them invalid. + // TODO: One way to get around the above issue would be to more careful, since we + // technically don't need to stop it from *recomputing* just stop any possible changes, but + // avoiding recomputation seems easiest/clearest. + // I expect that most/all of the paint functions could restrict themselves to only what is + // within the active screen lines without issue. + let screen_lines = ed.screen_lines.get_untracked(); + self.paint_current_line(cx, is_local, &screen_lines); + FloemEditorView::paint_selection(cx, ed, &screen_lines); + let screen_lines = ed.screen_lines.get_untracked(); + self.paint_diff_sections(cx, viewport, &screen_lines, &config); + let screen_lines = ed.screen_lines.get_untracked(); + self.paint_find(cx, &screen_lines); + let screen_lines = ed.screen_lines.get_untracked(); + self.paint_bracket_highlights_scope_lines(cx, viewport, &screen_lines); + let screen_lines = ed.screen_lines.get_untracked(); + FloemEditorView::paint_text( + cx, + None, + ed, + viewport, + is_active, + &screen_lines, + ); + let screen_lines = ed.screen_lines.get_untracked(); + self.paint_sticky_headers(cx, viewport, &screen_lines); + self.paint_scroll_bar(cx, viewport, is_local, config); + } +} + +fn get_sticky_header_info( + editor_data: &EditorData, + viewport: RwSignal, + sticky_header_height_signal: RwSignal, + config: &LapceConfig, +) -> StickyHeaderInfo { + let editor = &editor_data.editor; + let doc = editor_data.doc(); + + let viewport = viewport.get(); + // TODO(minor): should this be a `get` + let screen_lines = editor.screen_lines.get(); + let line_height = config.editor.line_height() as f64; + // let start_line = (viewport.y0 / line_height).floor() as usize; + let Some(start) = screen_lines.lines.first() else { + return StickyHeaderInfo { + sticky_lines: Vec::new(), + last_sticky_should_scroll: false, + y_diff: 0.0, + }; + }; + let start_info = screen_lines.info(*start).unwrap(); + let start_line = start_info.vline_info.rvline.line; + + let y_diff = viewport.y0 - start_info.vline_y; + + let mut last_sticky_should_scroll = false; + let mut sticky_lines = Vec::new(); + if let Some(lines) = doc.sticky_headers(start_line) { + let total_lines = lines.len(); + if total_lines > 0 { + let line = start_line + total_lines; + if let Some(new_lines) = doc.sticky_headers(line) { + if new_lines.len() > total_lines { + sticky_lines = new_lines; + } else { + sticky_lines = lines; + last_sticky_should_scroll = new_lines.len() < total_lines; + if new_lines.len() < total_lines { + if let Some(new_new_lines) = + doc.sticky_headers(start_line + total_lines - 1) + { + if new_new_lines.len() < total_lines { + sticky_lines.pop(); + last_sticky_should_scroll = false; + } + } else { + sticky_lines.pop(); + last_sticky_should_scroll = false; + } + } + } + } else { + sticky_lines = lines; + last_sticky_should_scroll = true; + } + } + } + + let total_sticky_lines = sticky_lines.len(); + + let paint_last_line = total_sticky_lines > 0 + && (last_sticky_should_scroll + || y_diff != 0.0 + || start_line + total_sticky_lines - 1 != *sticky_lines.last().unwrap()); + + // Fix up the line count in case we don't need to paint the last one. + let total_sticky_lines = if paint_last_line { + total_sticky_lines + } else { + total_sticky_lines.saturating_sub(1) + }; + + if total_sticky_lines == 0 { + sticky_header_height_signal.set(0.0); + return StickyHeaderInfo { + sticky_lines: Vec::new(), + last_sticky_should_scroll: false, + y_diff: 0.0, + }; + } + + let scroll_offset = if last_sticky_should_scroll { + y_diff + } else { + 0.0 + }; + + let sticky_header_height = sticky_lines + .iter() + .enumerate() + .map(|(i, line)| { + // TODO(question): won't y_diff always be scroll_offset here? so we should just sub on + // the outside + let y_diff = if i == total_sticky_lines - 1 { + scroll_offset + } else { + 0.0 + }; + + let layout = editor.text_layout(*line); + layout.line_count() as f64 * line_height - y_diff + }) + .sum(); + + sticky_header_height_signal.set(sticky_header_height); + StickyHeaderInfo { + sticky_lines, + last_sticky_should_scroll, + y_diff, + } +} + +pub fn editor_container_view( + window_tab_data: Rc, + workspace: Arc, + is_active: impl Fn(bool) -> bool + 'static + Copy, + editor: RwSignal, +) -> impl View { + let (editor_id, find_focus, sticky_header_height, editor_view, config, doc, ed) = + editor.with_untracked(|editor| { + ( + editor.id(), + editor.find_focus, + editor.sticky_header_height, + editor.kind, + editor.common.config, + editor.doc_signal(), + editor.editor.clone(), + ) + }); + + let main_split = window_tab_data.main_split.clone(); + let editors = main_split.editors; + let scratch_docs = main_split.scratch_docs; + let find_editor = main_split.find_editor; + let replace_editor = main_split.replace_editor; + let replace_active = main_split.common.find.replace_active; + let replace_focus = main_split.common.find.replace_focus; + let debug_breakline = window_tab_data.terminal.breakline; + + let viewport = ed.viewport; + let screen_lines = ed.screen_lines; + + stack(( + editor_breadcrumbs(workspace, editor.get_untracked(), config), + stack(( + editor_gutter(window_tab_data.clone(), editor), + editor_gutter_folding_range( + window_tab_data.clone(), + doc, + screen_lines, + viewport, + ), + editor_content(editor, debug_breakline, is_active), + empty().style(move |s| { + let config = config.get(); + s.absolute() + .width_pct(100.0) + .height(sticky_header_height.get() as f32) + // .box_shadow_blur(5.0) + // .border_bottom(1.0) + // .border_color( + // config.get_color(LapceColor::LAPCE_BORDER), + // ) + .apply_if( + !config.editor.sticky_header + || sticky_header_height.get() == 0.0 + || !editor_view.get().is_normal(), + |s| s.hide(), + ) + }), + find_view( + editor, + find_editor, + find_focus, + replace_editor, + replace_active, + replace_focus, + is_active, + ) + .debug_name("find view"), + )) + .style(|s| s.width_full().flex_basis(0).flex_grow(1.0)), + )) + .on_cleanup(move || { + let editor = editor.get_untracked(); + editor.cancel_completion(); + editor.cancel_inline_completion(); + if editors.contains_untracked(editor_id) { + // editor still exist, so it might be moved to a different editor tab + return; + } + let doc = editor.doc(); + editor.scope.dispose(); + + let scratch_doc_name = + if let DocContent::Scratch { name, .. } = doc.content.get_untracked() { + Some(name.to_string()) + } else { + None + }; + if let Some(name) = scratch_doc_name { + if !scratch_docs + .with_untracked(|scratch_docs| scratch_docs.contains_key(&name)) + { + doc.scope.dispose(); + } + } + }) + .style(|s| s.flex_col().absolute().size_pct(100.0, 100.0)) + .debug_name("Editor Container") +} + +fn editor_gutter_breakpoint_view( + i: usize, + doc: DocSignal, + daps: RwSignal>, + breakpoints: RwSignal>>, + screen_lines: RwSignal, + common: Rc, + icon_padding: f32, +) -> impl View { + let hovered = create_rw_signal(false); + let config = common.config; + container( + svg(move || config.get().ui_svg(LapceIcons::DEBUG_BREAKPOINT)).style( + move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32 + 2.0; + s.size(size, size) + .color(config.color(LapceColor::DEBUG_BREAKPOINT_HOVER)) + .apply_if(!hovered.get(), |s| s.hide()) + }, + ), + ) + .on_click_stop(move |_| { + let screen_lines = screen_lines.get_untracked(); + let line = screen_lines.lines.get(i).map(|r| r.line).unwrap_or(0); + // let line = (viewport.get_untracked().y0 + // / config.get_untracked().editor.line_height() as f64) + // .floor() as usize + // + i; + let doc = doc.get_untracked(); + let offset = doc.buffer.with_untracked(|b| b.offset_of_line(line)); + if let Some(path) = doc.content.get_untracked().path() { + let path_breakpoints = breakpoints + .try_update(|breakpoints| { + let breakpoints = breakpoints.entry(path.clone()).or_default(); + if let std::collections::btree_map::Entry::Vacant(e) = + breakpoints.entry(line) + { + e.insert(LapceBreakpoint { + id: None, + verified: false, + message: None, + line, + offset, + dap_line: None, + active: true, + }); + } else { + let mut toggle_active = false; + if let Some(breakpoint) = breakpoints.get_mut(&line) { + if !breakpoint.active { + breakpoint.active = true; + toggle_active = true; + } + } + if !toggle_active { + breakpoints.remove(&line); + } + } + breakpoints.clone() + }) + .unwrap(); + let source_breakpoints: Vec = path_breakpoints + .iter() + .filter_map(|(_, b)| { + if b.active { + Some(SourceBreakpoint { + line: b.line + 1, + column: None, + condition: None, + hit_condition: None, + log_message: None, + }) + } else { + None + } + }) + .collect(); + let daps: Vec = + daps.with_untracked(|daps| daps.keys().cloned().collect()); + for dap_id in daps { + common.proxy.dap_set_breakpoints( + dap_id, + path.to_path_buf(), + source_breakpoints.clone(), + ); + } + } + }) + .on_event_stop(EventListener::PointerEnter, move |_| { + hovered.set(true); + }) + .on_event_stop(EventListener::PointerLeave, move |_| { + hovered.set(false); + }) + .style(move |s| { + let config = config.get(); + s.width(config.ui.icon_size() as f32 + icon_padding * 2.0) + .height(config.editor.line_height() as f32) + .justify_center() + .items_center() + .cursor(CursorStyle::Pointer) + }) +} + +fn editor_gutter_breakpoints( + window_tab_data: Rc, + e_data: RwSignal, + icon_padding: f32, +) -> impl View { + let breakpoints = window_tab_data.terminal.debug.breakpoints; + let daps = window_tab_data.terminal.debug.daps; + let common = window_tab_data.common.clone(); + + let (ed, doc, config) = e_data + .with_untracked(|e| (e.editor.clone(), e.doc_signal(), e.common.config)); + let viewport = ed.viewport; + let screen_lines = ed.screen_lines; + + let num_display_lines = create_memo(move |_| { + let screen_lines = screen_lines.get(); + screen_lines.lines.len() + // let viewport = viewport.get(); + // let line_height = config.get().editor.line_height() as f64; + // (viewport.height() / line_height).ceil() as usize + 1 + }); + + clip( + stack(( + dyn_stack( + move || { + let num = num_display_lines.get(); + 0..num + }, + move |i| *i, + move |i| { + editor_gutter_breakpoint_view( + i, + doc, + daps, + breakpoints, + screen_lines, + common.clone(), + icon_padding, + ) + }, + ) + .style(move |s| { + s.absolute().flex_col().margin_top( + -(viewport.get().y0 % config.get().editor.line_height() as f64) + as f32, + ) + }) + .debug_name("Breakpoint Stack"), + dyn_stack( + move || { + let e_data = e_data.get(); + let doc = e_data.doc_signal().get(); + let content = doc.content.get(); + let breakpoints = if let Some(path) = content.path() { + breakpoints + .with(|b| b.get(path).cloned()) + .unwrap_or_default() + } else { + Default::default() + }; + breakpoints.into_iter() + }, + move |(line, b)| (*line, b.active), + move |(line, breakpoint)| { + let active = breakpoint.active; + container( + svg(move || { + config.get().ui_svg(LapceIcons::DEBUG_BREAKPOINT) + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32 + 2.0; + let color = if active { + LapceColor::DEBUG_BREAKPOINT + } else { + LapceColor::EDITOR_DIM + }; + let color = config.color(color); + s.size(size, size).color(color) + }), + ) + .style(move |s| { + let config = config.get(); + let line_y = screen_lines + .with(|s| s.info_for_line(line)) + .map(|l| l.y) + .unwrap_or_default(); + s.absolute() + .width(config.ui.icon_size() as f32 + icon_padding * 2.0) + .height(config.editor.line_height() as f32) + .justify_center() + .items_center() + .margin_top(line_y as f32 - viewport.get().y0 as f32) + }) + }, + ) + .style(|s| s.absolute().size_pct(100.0, 100.0)), + )) + .style(|s| s.size_pct(100.0, 100.0)), + ) + .style(move |s| { + s.absolute() + .size_pct(100.0, 100.0) + .background(config.get().color(LapceColor::EDITOR_BACKGROUND)) + }) +} + +fn editor_gutter_code_lens_view( + window_tab_data: Rc, + line: usize, + lens: (PluginId, usize, im::Vector), + screen_lines: RwSignal, + viewport: RwSignal, + icon_padding: f32, +) -> impl View { + let config = window_tab_data.common.config; + let view = container(svg(move || config.get().ui_svg(LapceIcons::START)).style( + move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.size(size, size) + .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + }, + )) + .style(move |s| { + let config = config.get(); + s.padding(4.0) + .border_radius(6.0) + .hover(|s| { + s.cursor(CursorStyle::Pointer) + .background(config.color(LapceColor::PANEL_HOVERED_BACKGROUND)) + }) + .active(|s| { + s.background( + config.color(LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND), + ) + }) + }) + .on_click_stop({ + move |_| { + let (plugin_id, offset, lens) = lens.clone(); + window_tab_data.show_code_lens(true, plugin_id, offset, lens); + } + }); + container(view).style(move |s| { + let line_info = screen_lines.with(|s| s.info_for_line(line)); + let line_y = line_info.clone().map(|l| l.y).unwrap_or(-100.0); + let rect = viewport.get(); + let config = config.get(); + let icon_size = config.ui.icon_size(); + let width = icon_size as f32 + icon_padding * 2.0; + s.absolute() + .width(width) + .height(config.editor.line_height() as f32) + .justify_center() + .items_center() + .margin_top(line_y as f32 - rect.y0 as f32) + }) +} + +fn editor_gutter_folding_view( + window_tab_data: Rc, + screen_lines: RwSignal, + viewport: RwSignal, + folding_display_item: FoldingDisplayItem, +) -> impl View { + let config = window_tab_data.common.config; + let view = container( + svg(move || { + let icon_str = match folding_display_item { + FoldingDisplayItem::UnfoldStart(_) => LapceIcons::FOLD_DOWN, + FoldingDisplayItem::Folded(_) => LapceIcons::FOLD, + FoldingDisplayItem::UnfoldEnd(_) => LapceIcons::FOLD_UP, + }; + config.get().ui_svg(icon_str) + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.size(size, size) + .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + }), + ) + .style(move |s| { + let config = config.get(); + s.padding(4.0) + .border_radius(6.0) + .hover(|s| { + s.cursor(CursorStyle::Pointer) + .background(config.color(LapceColor::PANEL_HOVERED_BACKGROUND)) + }) + .active(|s| { + s.background( + config.color(LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND), + ) + }) + }); + container(view).style(move |s| { + let line = folding_display_item.position().line; + let line_info = screen_lines.with(|s| s.info_for_line(line as usize)); + let line_y = line_info.clone().map(|l| l.y).unwrap_or(-100.0); + let rect = viewport.get(); + let config = config.get(); + let icon_size = config.ui.icon_size(); + let width = icon_size as f32 + 4.0; + s.absolute() + .width(width / 2.0) + .height(config.editor.line_height() as f32) + .justify_center() + .items_center() + .margin_top(line_y as f32 - rect.y0 as f32) + }) +} + +fn editor_gutter_code_lens( + window_tab_data: Rc, + doc: DocSignal, + screen_lines: RwSignal, + viewport: RwSignal, + icon_padding: f32, +) -> impl View { + let config = window_tab_data.common.config; + + dyn_stack( + move || { + let doc = doc.get(); + doc.code_lens.get() + }, + move |(line, _)| (*line, doc.with_untracked(|doc| doc.rev())), + move |(line, lens)| { + editor_gutter_code_lens_view( + window_tab_data.clone(), + line, + lens, + screen_lines, + viewport, + icon_padding, + ) + }, + ) + .style(move |s| { + let config = config.get(); + let width = config.ui.icon_size() as f32 + icon_padding * 2.0; + s.absolute() + .width(width) + .height_full() + .margin_left(width - 8.0) + }) + .debug_name("CodeLens Stack") +} + +fn editor_gutter_folding_range( + window_tab_data: Rc, + doc: DocSignal, + screen_lines: RwSignal, + viewport: RwSignal, +) -> impl View { + let config = window_tab_data.common.config; + dyn_stack( + move || doc.get().folding_ranges.get().to_display_items(), + move |item| *item, + move |item| { + editor_gutter_folding_view( + window_tab_data.clone(), + screen_lines, + viewport, + item, + ) + .on_click_stop({ + move |_| { + doc.get_untracked().folding_ranges.update(|x| match item { + FoldingDisplayItem::UnfoldStart(pos) + | FoldingDisplayItem::Folded(pos) => { + x.0.iter_mut().find_map(|mut range| { + let range = range.deref_mut(); + if range.start == pos { + range.status.click(); + Some(()) + } else { + None + } + }); + } + FoldingDisplayItem::UnfoldEnd(pos) => { + x.0.iter_mut().find_map(|mut range| { + let range = range.deref_mut(); + if range.end == pos { + range.status.click(); + Some(()) + } else { + None + } + }); + } + }) + } + }) + }, + ) + .style(move |s| { + let config = config.get(); + let width = config.ui.icon_size() as f32; + // hide for now + s.width(width) + .height_full() + .margin_left(-width / 2.0) + .hide() + }) + .debug_name("Folding Range Stack") +} + +fn editor_gutter_code_actions( + e_data: RwSignal, + gutter_width: Memo, + icon_padding: f32, +) -> impl View { + let (ed, doc, config) = e_data + .with_untracked(|e| (e.editor.clone(), e.doc_signal(), e.common.config)); + let viewport = ed.viewport; + let cursor = ed.cursor; + + let code_action_vline = create_memo(move |_| { + let doc = doc.get(); + let (offset, affinity) = + cursor.with(|cursor| (cursor.offset(), cursor.affinity)); + let has_code_actions = doc + .code_actions() + .with(|c| c.get(&offset).map(|c| !c.1.is_empty()).unwrap_or(false)); + if has_code_actions { + let vline = ed.vline_of_offset(offset, affinity); + Some(vline) + } else { + None + } + }); + + container( + container( + svg(move || config.get().ui_svg(LapceIcons::LIGHTBULB)).style( + move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.size(size, size) + .color(config.color(LapceColor::LAPCE_WARN)) + }, + ), + ) + .on_click_stop(move |_| { + e_data.get_untracked().show_code_actions(true); + }) + .style(move |s| { + let config = config.get(); + s.padding(4.0) + .border_radius(6.0) + .hover(|s| { + s.cursor(CursorStyle::Pointer).background( + config.color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + }) + .active(|s| { + s.background( + config.color(LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND), + ) + }) + }), + ) + .style(move |s| { + let config = config.get(); + let viewport = viewport.get(); + let gutter_width = gutter_width.get(); + let code_action_vline = code_action_vline.get(); + let size = config.ui.icon_size() as f32; + let line_height = config.editor.line_height(); + let margin_top = if let Some(vline) = code_action_vline { + (vline.get() * line_height) as f32 - viewport.y0 as f32 + } else { + 0.0 + }; + let width = size + icon_padding * 2.0; + s.absolute() + .items_center() + .justify_center() + .margin_left(gutter_width as f32 - width + 1.0) + .margin_top(margin_top) + .width(width) + .height(line_height as f32) + .apply_if(code_action_vline.is_none(), |s| s.hide()) + }) + .debug_name("Code Action LightBulb") +} + +fn editor_gutter( + window_tab_data: Rc, + e_data: RwSignal, +) -> impl View { + let icon_padding = 6.0; + + let (ed, doc, config) = e_data + .with_untracked(|e| (e.editor.clone(), e.doc_signal(), e.common.config)); + let viewport = ed.viewport; + let scroll_delta = ed.scroll_delta; + let screen_lines = ed.screen_lines; + + let gutter_rect = create_rw_signal(Rect::ZERO); + let gutter_width = create_memo(move |_| gutter_rect.get().width()); + + let icon_total_width = move || { + let icon_size = config.get().ui.icon_size() as f32; + icon_size + icon_padding * 2.0 + }; + + let gutter_padding_right = create_memo(move |_| icon_total_width() + 6.0); + + stack(( + stack(( + empty().style(move |s| s.width(icon_total_width() * 2.0 - 8.0)), + label(move || { + let doc = doc.get(); + doc.buffer.with(|b| b.last_line() + 1).to_string() + }), + empty().style(move |s| s.width(gutter_padding_right.get())), + )) + .debug_name("Centered Last Line Count") + .style(|s| s.height_pct(100.0)), + editor_gutter_breakpoints(window_tab_data.clone(), e_data, icon_padding), + clip( + stack(( + editor_gutter_code_lens( + window_tab_data.clone(), + doc, + screen_lines, + viewport, + icon_padding, + ), + editor_gutter_view(e_data.get_untracked(), gutter_padding_right) + .on_resize(move |rect| { + gutter_rect.set(rect); + }) + .on_event_stop(EventListener::PointerWheel, move |event| { + if let Event::PointerWheel(pointer_event) = event { + scroll_delta.set(pointer_event.delta); + } + }) + .style(|s| s.size_pct(100.0, 100.0)), + editor_gutter_code_actions(e_data, gutter_width, icon_padding), + )) + .style(|s| s.size_pct(100.0, 100.0)), + ) + .style(move |s| s.absolute().size_pct(100.0, 100.0)), + )) + .style(|s| s.height_pct(100.0)) + .debug_name("Editor Gutter") +} + +fn editor_breadcrumbs( + workspace: Arc, + e_data: EditorData, + config: ReadSignal>, +) -> impl View { + let doc = e_data.doc_signal(); + let doc_path = create_memo(move |_| { + let doc = doc.get(); + let content = doc.content.get(); + if let DocContent::History(history) = &content { + Some(history.path.clone()) + } else { + content.path().cloned() + } + }); + container( + scroll( + stack(( + { + let workspace = workspace.clone(); + dyn_stack( + move || { + let full_path = doc_path.get().unwrap_or_default(); + let mut path = full_path; + if let Some(workspace_path) = + workspace.clone().path.as_ref() + { + path = path + .strip_prefix(workspace_path) + .unwrap_or(&path) + .to_path_buf(); + } + path.ancestors() + .filter_map(|path| { + Some( + path.file_name()? + .to_string_lossy() + .into_owned(), + ) + }) + .collect::>() + .into_iter() + .rev() + .enumerate() + }, + |(i, section)| (*i, section.to_string()), + move |(i, section)| { + stack(( + svg(move || { + config + .get() + .ui_svg(LapceIcons::BREADCRUMB_SEPARATOR) + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.apply_if(i == 0, |s| s.hide()) + .size(size, size) + .color( + config.color( + LapceColor::LAPCE_ICON_ACTIVE, + ), + ) + }), + label(move || section.clone()) + .style(move |s| s.selectable(false)), + )) + .style(|s| s.items_center()) + }, + ) + .style(|s| s.padding_horiz(10.0)) + }, + label(move || { + let doc = doc.get(); + if let DocContent::History(history) = doc.content.get() { + format!("({})", history.version) + } else { + "".to_string() + } + }) + .style(move |s| { + let doc = doc.get(); + let is_history = doc.content.with_untracked(|content| { + matches!(content, DocContent::History(_)) + }); + + s.padding_right(10.0).apply_if(!is_history, |s| s.hide()) + }), + )) + .style(|s| s.items_center()), + ) + .scroll_to(move || { + doc.track(); + Some(Point::new(3000.0, 0.0)) + }) + .scroll_style(|s| s.hide_bars(true)) + .style(move |s| { + s.absolute() + .size_pct(100.0, 100.0) + .border_bottom(1.0) + .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + .items_center() + }), + ) + .style(move |s| { + let config = config.get_untracked(); + let line_height = config.editor.line_height(); + s.items_center() + .width_pct(100.0) + .height(line_height as f32) + .apply_if(doc_path.get().is_none(), |s| s.hide()) + .apply_if(!config.editor.show_bread_crumbs, |s| s.hide()) + }) + .debug_name("Editor BreadCrumbs") +} + +fn editor_content( + e_data: RwSignal, + debug_breakline: Memo>, + is_active: impl Fn(bool) -> bool + 'static + Copy, +) -> impl View { + let ( + cursor, + scroll_delta, + scroll_to, + window_origin, + viewport, + sticky_header_height, + config, + editor, + ) = e_data.with_untracked(|editor| { + ( + editor.cursor().read_only(), + editor.scroll_delta().read_only(), + editor.scroll_to(), + editor.window_origin(), + editor.viewport(), + editor.sticky_header_height, + editor.common.config, + editor.editor.clone(), + ) + }); + + { + create_effect(move |_| { + is_active(true); + let e_data = e_data.get_untracked(); + e_data.cancel_completion(); + e_data.cancel_inline_completion(); + }); + } + + let current_scroll = create_rw_signal(Rect::ZERO); + + scroll({ + let editor_content_view = + editor_view(e_data.get_untracked(), debug_breakline, is_active).style( + move |s| { + s.absolute() + .margin_left(1.0) + .min_size_full() + .cursor(CursorStyle::Text) + }, + ); + + let id = editor_content_view.id(); + editor.editor_view_id.set(Some(id)); + + let editor2 = editor.clone(); + editor_content_view + .on_event_cont(EventListener::FocusGained, move |_| { + editor.editor_view_focused.notify(); + }) + .on_event_cont(EventListener::FocusLost, move |_| { + editor2.editor_view_focus_lost.notify(); + }) + .on_event_cont(EventListener::PointerDown, move |event| { + if let Event::PointerDown(pointer_event) = event { + id.request_active(); + e_data.get_untracked().pointer_down(pointer_event); + } + }) + .on_event_stop(EventListener::PointerMove, move |event| { + if let Event::PointerMove(pointer_event) = event { + e_data.get_untracked().pointer_move(pointer_event); + } + }) + .on_event_stop(EventListener::PointerUp, move |event| { + if let Event::PointerUp(pointer_event) = event { + e_data.get_untracked().pointer_up(pointer_event); + } + }) + .on_event_stop(EventListener::PointerLeave, move |event| { + if let Event::PointerLeave = event { + e_data.get_untracked().pointer_leave(); + } + }) + }) + .on_move(move |point| { + window_origin.set(point); + }) + .on_scroll(move |rect| { + if rect.y0 != current_scroll.get_untracked().y0 { + // only cancel completion if scrolled vertically + let e_data = e_data.get_untracked(); + e_data.cancel_completion(); + e_data.cancel_inline_completion(); + } + current_scroll.set(rect); + }) + .scroll_to(move || scroll_to.get().map(|s| s.to_point())) + .scroll_delta(move || scroll_delta.get()) + .ensure_visible(move || { + let e_data = e_data.get_untracked(); + let cursor = cursor.get(); + let offset = cursor.offset(); + e_data.doc_signal().track(); + e_data.kind.track(); + + let LineRegion { x, width, rvline } = cursor_caret( + &e_data.editor, + offset, + !cursor.is_insert(), + cursor.affinity, + ); + let config = config.get_untracked(); + let line_height = config.editor.line_height(); + // TODO: is there a good way to avoid the calculation of the vline here? + let vline = e_data.editor.vline_of_rvline(rvline); + let vline = e_data.visual_line(vline.get()); + let rect = Rect::from_origin_size( + (x, (vline * line_height) as f64), + (width, line_height as f64), + ) + .inflate(10.0, 0.0); + + let viewport = viewport.get_untracked(); + let smallest_distance = (viewport.y0 - rect.y0) + .abs() + .min((viewport.y1 - rect.y0).abs()) + .min((viewport.y0 - rect.y1).abs()) + .min((viewport.y1 - rect.y1).abs()); + let biggest_distance = (viewport.y0 - rect.y0) + .abs() + .max((viewport.y1 - rect.y0).abs()) + .max((viewport.y0 - rect.y1).abs()) + .max((viewport.y1 - rect.y1).abs()); + let jump_to_middle = biggest_distance > viewport.height() + && smallest_distance > viewport.height() / 2.0; + + if jump_to_middle { + rect.inflate(0.0, viewport.height() / 2.0) + } else { + let cursor_surrounding_lines = + e_data.editor.es.with(|s| s.cursor_surrounding_lines()); + let mut rect = rect; + rect.y0 -= (cursor_surrounding_lines * line_height) as f64 + + sticky_header_height.get_untracked(); + rect.y1 += (cursor_surrounding_lines * line_height) as f64; + rect + } + }) + .style(|s| s.size_full().set(PropagatePointerWheel, false)) + .debug_name("Editor Content") +} + +fn search_editor_view( + find_editor: EditorData, + find_focus: RwSignal, + is_active: impl Fn(bool) -> bool + 'static + Copy, + replace_focus: RwSignal, +) -> impl View { + let config = find_editor.common.config; + + let case_matching = find_editor.common.find.case_matching; + let whole_word = find_editor.common.find.whole_words; + let is_regex = find_editor.common.find.is_regex; + let visual = find_editor.common.find.visual; + + stack(( + TextInputBuilder::new() + .is_focused(move || { + is_active(true) + && visual.get() + && find_focus.get() + && !replace_focus.get() + }) + .build_editor(find_editor) + .on_event_cont(EventListener::PointerDown, move |_| { + find_focus.set(true); + replace_focus.set(false); + }) + .style(|s| s.width_pct(100.0)), + clickable_icon( + || LapceIcons::SEARCH_CASE_SENSITIVE, + move || { + let new = match case_matching.get_untracked() { + CaseMatching::Exact => CaseMatching::CaseInsensitive, + CaseMatching::CaseInsensitive => CaseMatching::Exact, + }; + case_matching.set(new); + }, + move || case_matching.get() == CaseMatching::Exact, + || false, + || "Case Sensitive", + config, + ) + .style(|s| s.padding_vert(4.0)), + clickable_icon( + || LapceIcons::SEARCH_WHOLE_WORD, + move || { + whole_word.update(|whole_word| { + *whole_word = !*whole_word; + }); + }, + move || whole_word.get(), + || false, + || "Whole Word", + config, + ) + .style(|s| s.padding_left(6.0)), + clickable_icon( + || LapceIcons::SEARCH_REGEX, + move || { + is_regex.update(|is_regex| { + *is_regex = !*is_regex; + }); + }, + move || is_regex.get(), + || false, + || "Use Regex", + config, + ) + .style(|s| s.padding_horiz(6.0)), + )) + .style(move |s| { + let config = config.get(); + s.width(200.0) + .items_center() + .border(1.0) + .border_radius(6.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .background(config.color(LapceColor::EDITOR_BACKGROUND)) + }) +} + +fn replace_editor_view( + replace_editor: EditorData, + replace_active: RwSignal, + replace_focus: RwSignal, + is_active: impl Fn(bool) -> bool + 'static + Copy, + find_focus: RwSignal, +) -> impl View { + let config = replace_editor.common.config; + let visual = replace_editor.common.find.visual; + + stack(( + TextInputBuilder::new() + .is_focused(move || { + is_active(true) + && visual.get() + && find_focus.get() + && replace_active.get() + && replace_focus.get() + }) + .build_editor(replace_editor) + .on_event_cont(EventListener::PointerDown, move |_| { + find_focus.set(true); + replace_focus.set(true); + }) + .style(|s| s.width_pct(100.0)), + empty().style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32 + 10.0; + s.size(0.0, size).padding_vert(4.0) + }), + )) + .style(move |s| { + let config = config.get(); + s.width(200.0) + .items_center() + .border(1.0) + .border_radius(6.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .background(config.color(LapceColor::EDITOR_BACKGROUND)) + }) +} + +fn find_view( + editor: RwSignal, + find_editor: EditorData, + find_focus: RwSignal, + replace_editor: EditorData, + replace_active: RwSignal, + replace_focus: RwSignal, + is_active: impl Fn(bool) -> bool + 'static + Copy, +) -> impl View { + let common = find_editor.common.clone(); + let config = common.config; + let find_visual = common.find.visual; + let replace_doc = replace_editor.doc_signal(); + let focus = common.focus; + + let find_pos = create_memo(move |_| { + let visual = find_visual.get(); + if !visual { + return (0, 0); + } + let editor = editor.get_untracked(); + let cursor = editor.cursor(); + let offset = cursor.with(|cursor| cursor.offset()); + let occurrences = editor.doc_signal().get().find_result.occurrences; + occurrences.with(|occurrences| { + for (i, region) in occurrences.regions().iter().enumerate() { + if offset <= region.max() { + return (i + 1, occurrences.regions().len()); + } + } + (occurrences.regions().len(), occurrences.regions().len()) + }) + }); + + container( + stack(( + stack(( + clickable_icon( + move || { + if replace_active.get() { + LapceIcons::ITEM_OPENED + } else { + LapceIcons::ITEM_CLOSED + } + }, + move || { + replace_active.update(|active| *active = !*active); + }, + move || false, + || false, + || "Toggle Replace", + config, + ) + .style(|s| s.padding_horiz(6.0)), + search_editor_view( + find_editor, + find_focus, + is_active, + replace_focus, + ), + label(move || { + let (current, all) = find_pos.get(); + if all == 0 { + "No Results".to_string() + } else { + format!("{current} of {all}") + } + }) + .style(|s| s.margin_left(6.0).min_width(70.0)), + clickable_icon( + || LapceIcons::SEARCH_BACKWARD, + move || { + editor.get_untracked().search_backward(Modifiers::empty()); + }, + move || false, + || false, + || "Previous Match", + config, + ) + .style(|s| s.padding_left(6.0)), + clickable_icon( + || LapceIcons::SEARCH_FORWARD, + move || { + editor.get_untracked().search_forward(Modifiers::empty()); + }, + move || false, + || false, + || "Next Match", + config, + ) + .style(|s| s.padding_left(6.0)), + clickable_icon( + || LapceIcons::CLOSE, + move || { + editor.get_untracked().clear_search(); + }, + move || false, + || false, + || "Close", + config, + ) + .style(|s| s.padding_horiz(6.0)), + )) + .style(|s| s.items_center()), + stack(( + empty().style(move |s| { + let config = config.get(); + let width = config.ui.icon_size() as f32 + 10.0 + 6.0 * 2.0; + s.width(width) + }), + replace_editor_view( + replace_editor, + replace_active, + replace_focus, + is_active, + find_focus, + ), + clickable_icon( + || LapceIcons::SEARCH_REPLACE, + move || { + let text = replace_doc + .get_untracked() + .buffer + .with_untracked(|b| b.to_string()); + editor.get_untracked().replace_next(&text); + }, + move || false, + || false, + || "Replace Next", + config, + ) + .style(|s| s.padding_left(6.0)), + clickable_icon( + || LapceIcons::SEARCH_REPLACE_ALL, + move || { + let text = replace_doc + .get_untracked() + .buffer + .with_untracked(|b| b.to_string()); + editor.get_untracked().replace_all(&text); + }, + move || false, + || false, + || "Replace All", + config, + ) + .style(|s| s.padding_left(6.0)), + )) + .style(move |s| { + s.items_center() + .margin_top(4.0) + .apply_if(!replace_active.get(), |s| s.hide()) + }), + )) + .style(move |s| { + let config = config.get(); + s.margin_right(50.0) + .background(config.color(LapceColor::PANEL_BACKGROUND)) + .border_radius(6.0) + .border(1.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .padding_vert(4.0) + .cursor(CursorStyle::Default) + .flex_col() + }) + .on_event_stop(EventListener::PointerDown, move |_| { + // Shift the editor tab focus to the editor the find search is attached to + // So that if you have two tabs open side-by-side (and thus two find views), + // clicking on one will shift the focus to the editor it's attached to + let editor = editor.get_untracked(); + if let Some(editor_tab_id) = editor.editor_tab_id.get_untracked() { + editor + .common + .internal_command + .send(InternalCommand::FocusEditorTab { editor_tab_id }); + } + focus.set(Focus::Workbench); + // Request focus on the app view, as our current method of dispatching pointer events + // is from the app_view to the actual editor. That's also why this stops the pointer + // event is stopped here, as otherwise our default handling would make it go through to + // the editor. + common + .window_common + .app_view_id + .get_untracked() + .request_focus(); + }), + ) + .style(move |s| { + s.absolute() + .margin_top(-1.0) + .width_pct(100.0) + .justify_end() + .apply_if(!find_visual.get(), |s| s.hide()) + }) +} + +/// Iterator over (len, color, modified) for each change in the diff +fn changes_color_iter<'a>( + changes: &'a im::Vector, + config: &'a LapceConfig, +) -> impl Iterator, bool)> + 'a { + let mut last_change = None; + changes.iter().map(move |change| { + let len = match change { + DiffLines::Left(_range) => 0, + DiffLines::Both(info) => info.right.len(), + DiffLines::Right(range) => range.len(), + }; + let mut modified = false; + let color = match change { + DiffLines::Left(_range) => { + Some(config.color(LapceColor::SOURCE_CONTROL_REMOVED)) + } + DiffLines::Right(_range) => { + if let Some(DiffLines::Left(_)) = last_change.as_ref() { + modified = true; + } + if modified { + Some(config.color(LapceColor::SOURCE_CONTROL_MODIFIED)) + } else { + Some(config.color(LapceColor::SOURCE_CONTROL_ADDED)) + } + } + _ => None, + }; + + last_change = Some(change.clone()); + + (len, color, modified) + }) +} + +// TODO: both of the changes color functions could easily return iterators + +/// Get the position and coloring information for over the entire current [`ScreenLines`] +/// Returns `(y, height_idx, removed, color)` +pub fn changes_colors_screen( + config: &LapceConfig, + editor: &Editor, + changes: im::Vector, +) -> Vec<(f64, usize, bool, Color)> { + let screen_lines = editor.screen_lines.get_untracked(); + + let Some((min, max)) = screen_lines.rvline_range() else { + return Vec::new(); + }; + + let line_height = config.editor.line_height(); + let mut line = 0; + let mut colors = Vec::new(); + + for (len, color, modified) in changes_color_iter(&changes, config) { + let pre_line = line; + + line += len; + if line < min.line { + continue; + } + + if let Some(color) = color { + if modified { + colors.pop(); + } + + let rvline = editor.rvline_of_line(pre_line); + let vline = editor.vline_of_line(pre_line); + let y = (vline.0 * line_height) as f64; + let height = { + // Accumulate the number of line indices each potentially wrapped line spans + let end_line = rvline.line + len; + + editor.iter_rvlines_over(false, rvline, end_line).count() + }; + let removed = len == 0; + + colors.push((y, height, removed, color)); + } + + if line > max.line { + break; + } + } + + colors +} + +// TODO: limit the visual line that changes are considered past to some reasonable number +// TODO(minor): This could be a `changes_colors_range` with some minor changes, but it isn't needed +/// Get the position and coloring information for over the entire current [`ScreenLines`] +/// Returns `(y, height_idx, removed, color)` +pub fn changes_colors_all( + config: &LapceConfig, + ed: &Editor, + changes: im::Vector, +) -> Vec<(f64, usize, bool, Color)> { + let line_height = config.editor.line_height(); + + let mut line = 0; + let mut colors = Vec::new(); + + let mut vline_iter = ed.iter_vlines(false, VLine(0)).peekable(); + + for (len, color, modified) in changes_color_iter(&changes, config) { + let pre_line = line; + + line += len; + + // Skip over all vlines that are before the current line + vline_iter + .by_ref() + .peeking_take_while(|info| info.rvline.line < pre_line) + .count(); + + if let Some(color) = color { + if modified { + colors.pop(); + } + + // Find the info with a line == pre_line + let Some(info) = vline_iter.peek() else { + continue; + }; + + let y = info.vline.get() * line_height; + let end_line = info.rvline.line + len; + let height = vline_iter + .by_ref() + .peeking_take_while(|info| info.rvline.line < end_line) + .count(); + let removed = len == 0; + + colors.push((y as f64, height, removed, color)); + } + + if vline_iter.peek().is_none() { + break; + } + } + + colors +} diff --git a/lapce-app/src/editor_tab.rs b/lapce-app/src/editor_tab.rs new file mode 100644 index 0000000..1845bf9 --- /dev/null +++ b/lapce-app/src/editor_tab.rs @@ -0,0 +1,484 @@ +use std::{ + path::{Path, PathBuf}, + rc::Rc, + sync::Arc, +}; + +use floem::{ + peniko::{ + Color, + kurbo::{Point, Rect}, + }, + reactive::{ + Memo, ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith, + create_memo, create_rw_signal, + }, + views::editor::id::EditorId, +}; +use lapce_rpc::plugin::VoltID; +use serde::{Deserialize, Serialize}; + +use crate::{ + config::{LapceConfig, color::LapceColor, icon::LapceIcons}, + doc::{Doc, DocContent}, + editor::{ + EditorData, EditorInfo, + diff::{DiffEditorData, DiffEditorInfo}, + location::EditorLocation, + }, + id::{ + DiffEditorId, EditorTabId, KeymapId, SettingsId, SplitId, + ThemeColorSettingsId, VoltViewId, + }, + main_split::{Editors, MainSplitData}, + plugin::PluginData, + window_tab::WindowTabData, +}; + +#[derive(Clone, Serialize, Deserialize)] +pub enum EditorTabChildInfo { + Editor(EditorInfo), + DiffEditor(DiffEditorInfo), + Settings, + ThemeColorSettings, + Keymap, + Volt(VoltID), +} + +impl EditorTabChildInfo { + pub fn to_data( + &self, + data: MainSplitData, + editor_tab_id: EditorTabId, + ) -> EditorTabChild { + match &self { + EditorTabChildInfo::Editor(editor_info) => { + let editor_id = editor_info.to_data(data, editor_tab_id); + EditorTabChild::Editor(editor_id) + } + EditorTabChildInfo::DiffEditor(diff_editor_info) => { + let diff_editor_data = diff_editor_info.to_data(data, editor_tab_id); + EditorTabChild::DiffEditor(diff_editor_data.id) + } + EditorTabChildInfo::Settings => { + EditorTabChild::Settings(SettingsId::next()) + } + EditorTabChildInfo::ThemeColorSettings => { + EditorTabChild::ThemeColorSettings(ThemeColorSettingsId::next()) + } + EditorTabChildInfo::Keymap => EditorTabChild::Keymap(KeymapId::next()), + EditorTabChildInfo::Volt(id) => { + EditorTabChild::Volt(VoltViewId::next(), id.to_owned()) + } + } + } +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct EditorTabInfo { + pub active: usize, + pub is_focus: bool, + pub children: Vec, +} + +impl EditorTabInfo { + pub fn to_data( + &self, + data: MainSplitData, + split: SplitId, + ) -> RwSignal { + let editor_tab_id = EditorTabId::next(); + let editor_tab_data = { + let cx = data.scope.create_child(); + let editor_tab_data = EditorTabData { + scope: cx, + editor_tab_id, + split, + active: self.active, + children: self + .children + .iter() + .map(|child| { + ( + cx.create_rw_signal(0), + cx.create_rw_signal(Rect::ZERO), + child.to_data(data.clone(), editor_tab_id), + ) + }) + .collect(), + layout_rect: Rect::ZERO, + window_origin: Point::ZERO, + locations: cx.create_rw_signal(im::Vector::new()), + current_location: cx.create_rw_signal(0), + }; + cx.create_rw_signal(editor_tab_data) + }; + if self.is_focus { + data.active_editor_tab.set(Some(editor_tab_id)); + } + data.editor_tabs.update(|editor_tabs| { + editor_tabs.insert(editor_tab_id, editor_tab_data); + }); + editor_tab_data + } +} + +pub enum EditorTabChildSource { + Editor { path: PathBuf, doc: Rc }, + DiffEditor { left: Rc, right: Rc }, + NewFileEditor, + Settings, + ThemeColorSettings, + Keymap, + Volt(VoltID), +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum EditorTabChild { + Editor(EditorId), + DiffEditor(DiffEditorId), + Settings(SettingsId), + ThemeColorSettings(ThemeColorSettingsId), + Keymap(KeymapId), + Volt(VoltViewId, VoltID), +} + +#[derive(PartialEq)] +pub struct EditorTabChildViewInfo { + pub icon: String, + pub color: Option, + pub name: String, + pub path: Option, + pub confirmed: Option>, + pub is_pristine: bool, +} + +impl EditorTabChild { + pub fn id(&self) -> u64 { + match self { + EditorTabChild::Editor(id) => id.to_raw(), + EditorTabChild::DiffEditor(id) => id.to_raw(), + EditorTabChild::Settings(id) => id.to_raw(), + EditorTabChild::ThemeColorSettings(id) => id.to_raw(), + EditorTabChild::Keymap(id) => id.to_raw(), + EditorTabChild::Volt(id, _) => id.to_raw(), + } + } + + pub fn is_settings(&self) -> bool { + matches!(self, EditorTabChild::Settings(_)) + } + + pub fn child_info(&self, data: &WindowTabData) -> EditorTabChildInfo { + match &self { + EditorTabChild::Editor(editor_id) => { + let editor_data = data + .main_split + .editors + .editor_untracked(*editor_id) + .unwrap(); + EditorTabChildInfo::Editor(editor_data.editor_info(data)) + } + EditorTabChild::DiffEditor(diff_editor_id) => { + let diff_editor_data = data + .main_split + .diff_editors + .get_untracked() + .get(diff_editor_id) + .cloned() + .unwrap(); + EditorTabChildInfo::DiffEditor(diff_editor_data.diff_editor_info()) + } + EditorTabChild::Settings(_) => EditorTabChildInfo::Settings, + EditorTabChild::ThemeColorSettings(_) => { + EditorTabChildInfo::ThemeColorSettings + } + EditorTabChild::Keymap(_) => EditorTabChildInfo::Keymap, + EditorTabChild::Volt(_, id) => EditorTabChildInfo::Volt(id.to_owned()), + } + } + + pub fn view_info( + &self, + editors: Editors, + diff_editors: RwSignal>, + plugin: PluginData, + config: ReadSignal>, + ) -> Memo { + match self.clone() { + EditorTabChild::Editor(editor_id) => create_memo(move |_| { + let config = config.get(); + let editor_data = editors.editor(editor_id); + let path = if let Some(editor_data) = editor_data { + let doc = editor_data.doc_signal().get(); + let (content, is_pristine, confirmed) = ( + doc.content.get(), + doc.buffer.with(|b| b.is_pristine()), + editor_data.confirmed, + ); + match content { + DocContent::File { path, .. } => { + Some((path, confirmed, is_pristine)) + } + DocContent::Local => None, + DocContent::History(_) => None, + DocContent::Scratch { name, .. } => { + Some((PathBuf::from(name), confirmed, is_pristine)) + } + } + } else { + None + }; + let (icon, color, name, confirmed, is_pristine) = match path { + Some((ref path, confirmed, is_pritine)) => { + let (svg, color) = config.file_svg(path); + ( + svg, + color, + path.file_name() + .unwrap_or_default() + .to_string_lossy() + .into_owned(), + confirmed, + is_pritine, + ) + } + None => ( + config.ui_svg(LapceIcons::FILE), + Some(config.color(LapceColor::LAPCE_ICON_ACTIVE)), + "local".to_string(), + create_rw_signal(true), + true, + ), + }; + EditorTabChildViewInfo { + icon, + color, + name, + path: path.map(|opt| opt.0), + confirmed: Some(confirmed), + is_pristine, + } + }), + EditorTabChild::DiffEditor(diff_editor_id) => create_memo(move |_| { + let config = config.get(); + let diff_editor_data = diff_editors + .with(|diff_editors| diff_editors.get(&diff_editor_id).cloned()); + let confirmed = diff_editor_data.as_ref().map(|d| d.confirmed); + + let info = diff_editor_data + .map(|diff_editor_data| { + [diff_editor_data.left, diff_editor_data.right].map(|data| { + let (content, is_pristine) = + data.doc_signal().with(|doc| { + ( + doc.content.get(), + doc.buffer.with(|b| b.is_pristine()), + ) + }); + match content { + DocContent::File { path, .. } => { + Some((path, is_pristine)) + } + DocContent::Local => None, + DocContent::History(_) => None, + DocContent::Scratch { name, .. } => { + Some((PathBuf::from(name), is_pristine)) + } + } + }) + }) + .unwrap_or([None, None]); + + let (icon, color, path, is_pristine) = match info { + [Some((path, is_pristine)), None] + | [None, Some((path, is_pristine))] => { + let (svg, color) = config.file_svg(&path); + ( + svg, + color, + format!( + "{} (Diff)", + path.file_name() + .unwrap_or_default() + .to_string_lossy() + ), + is_pristine, + ) + } + [ + Some((left_path, left_is_pristine)), + Some((right_path, right_is_pristine)), + ] => { + let (svg, color) = + config.files_svg(&[&left_path, &right_path]); + let [left_file_name, right_file_name] = + [&left_path, &right_path].map(|path| { + path.file_name() + .unwrap_or_default() + .to_string_lossy() + }); + ( + svg, + color, + format!("{left_file_name} - {right_file_name} (Diff)"), + left_is_pristine && right_is_pristine, + ) + } + [None, None] => ( + config.ui_svg(LapceIcons::FILE), + Some(config.color(LapceColor::LAPCE_ICON_ACTIVE)), + "local".to_string(), + true, + ), + }; + EditorTabChildViewInfo { + icon, + color, + name: path, + path: None, + confirmed, + is_pristine, + } + }), + EditorTabChild::Settings(_) => create_memo(move |_| { + let config = config.get(); + EditorTabChildViewInfo { + icon: config.ui_svg(LapceIcons::SETTINGS), + color: Some(config.color(LapceColor::LAPCE_ICON_ACTIVE)), + name: "Settings".to_string(), + path: None, + confirmed: None, + is_pristine: true, + } + }), + EditorTabChild::ThemeColorSettings(_) => create_memo(move |_| { + let config = config.get(); + EditorTabChildViewInfo { + icon: config.ui_svg(LapceIcons::SYMBOL_COLOR), + color: Some(config.color(LapceColor::LAPCE_ICON_ACTIVE)), + name: "Theme Colors".to_string(), + path: None, + confirmed: None, + is_pristine: true, + } + }), + EditorTabChild::Keymap(_) => create_memo(move |_| { + let config = config.get(); + EditorTabChildViewInfo { + icon: config.ui_svg(LapceIcons::KEYBOARD), + color: Some(config.color(LapceColor::LAPCE_ICON_ACTIVE)), + name: "Keyboard Shortcuts".to_string(), + path: None, + confirmed: None, + is_pristine: true, + } + }), + EditorTabChild::Volt(_, id) => create_memo(move |_| { + let config = config.get(); + let display_name = plugin + .installed + .with(|volts| volts.get(&id).cloned()) + .map(|volt| volt.meta.with(|m| m.display_name.clone())) + .or_else(|| { + plugin.available.volts.with(|volts| { + let volt = volts.get(&id); + volt.map(|volt| { + volt.info.with(|m| m.display_name.clone()) + }) + }) + }) + .unwrap_or_else(|| id.name.clone()); + EditorTabChildViewInfo { + icon: config.ui_svg(LapceIcons::EXTENSIONS), + color: Some(config.color(LapceColor::LAPCE_ICON_ACTIVE)), + name: display_name, + path: None, + confirmed: None, + is_pristine: true, + } + }), + } + } +} + +#[derive(Clone)] +pub struct EditorTabData { + pub scope: Scope, + pub split: SplitId, + pub editor_tab_id: EditorTabId, + pub active: usize, + pub children: Vec<(RwSignal, RwSignal, EditorTabChild)>, + pub window_origin: Point, + pub layout_rect: Rect, + pub locations: RwSignal>, + pub current_location: RwSignal, +} + +impl EditorTabData { + pub fn get_editor( + &self, + editors: Editors, + path: &Path, + ) -> Option<(usize, EditorData)> { + for (i, child) in self.children.iter().enumerate() { + if let (_, _, EditorTabChild::Editor(editor_id)) = child { + if let Some(editor) = editors.editor_untracked(*editor_id) { + let is_path = editor.doc().content.with_untracked(|content| { + if let DocContent::File { path: p, .. } = content { + p == path + } else { + false + } + }); + if is_path { + return Some((i, editor)); + } + } + } + } + None + } + + pub fn get_unconfirmed_editor_tab_child( + &self, + editors: Editors, + diff_editors: &im::HashMap, + ) -> Option<(usize, EditorTabChild)> { + for (i, (_, _, child)) in self.children.iter().enumerate() { + match child { + EditorTabChild::Editor(editor_id) => { + if let Some(editor) = editors.editor_untracked(*editor_id) { + let confirmed = editor.confirmed.get_untracked(); + if !confirmed { + return Some((i, child.clone())); + } + } + } + EditorTabChild::DiffEditor(diff_editor_id) => { + if let Some(diff_editor) = diff_editors.get(diff_editor_id) { + let confirmed = diff_editor.confirmed.get_untracked(); + if !confirmed { + return Some((i, child.clone())); + } + } + } + _ => (), + } + } + None + } + + pub fn tab_info(&self, data: &WindowTabData) -> EditorTabInfo { + EditorTabInfo { + active: self.active, + is_focus: data.main_split.active_editor_tab.get_untracked() + == Some(self.editor_tab_id), + children: self + .children + .iter() + .map(|(_, _, child)| child.child_info(data)) + .collect(), + } + } +} diff --git a/lapce-app/src/file_explorer/data.rs b/lapce-app/src/file_explorer/data.rs new file mode 100644 index 0000000..a4f3ac5 --- /dev/null +++ b/lapce-app/src/file_explorer/data.rs @@ -0,0 +1,681 @@ +use std::{ + borrow::Cow, + collections::HashMap, + ffi::OsStr, + path::{Path, PathBuf}, + rc::Rc, + sync::Arc, +}; + +use floem::{ + action::show_context_menu, + event::EventPropagation, + ext_event::create_ext_action, + keyboard::Modifiers, + menu::{Menu, MenuItem}, + reactive::{ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, + views::editor::text::SystemClipboard, +}; +use globset::Glob; +use lapce_core::{ + command::{EditCommand, FocusCommand}, + mode::Mode, + register::Clipboard, +}; +use lapce_rpc::{ + file::{ + Duplicating, FileNodeItem, FileNodeViewKind, Naming, NamingState, NewNode, + Renaming, + }, + proxy::ProxyResponse, +}; + +use crate::{ + command::{CommandExecuted, CommandKind, InternalCommand, LapceCommand}, + config::LapceConfig, + editor::EditorData, + keypress::{KeyPressFocus, condition::Condition}, + main_split::Editors, + window_tab::CommonData, +}; + +enum RenamedPath { + NotRenaming, + NameUnchanged, + Renamed { + current_path: PathBuf, + new_path: PathBuf, + }, +} + +#[derive(Clone, Debug)] +pub struct FileExplorerData { + pub root: RwSignal, + pub naming: RwSignal, + pub naming_editor_data: EditorData, + pub common: Rc, + pub scroll_to_line: RwSignal>, + left_diff_path: RwSignal>, + pub select: RwSignal>, +} + +impl KeyPressFocus for FileExplorerData { + fn get_mode(&self) -> Mode { + Mode::Insert + } + + fn check_condition(&self, condition: Condition) -> bool { + self.naming.with_untracked(Naming::is_accepting_input) + && condition == Condition::ModalFocus + } + + fn run_command( + &self, + command: &LapceCommand, + count: Option, + mods: Modifiers, + ) -> CommandExecuted { + if self.naming.with_untracked(Naming::is_accepting_input) { + match command.kind { + CommandKind::Focus(FocusCommand::ModalClose) => { + self.cancel_naming(); + CommandExecuted::Yes + } + CommandKind::Edit(EditCommand::InsertNewLine) => { + self.finish_naming(); + CommandExecuted::Yes + } + CommandKind::Edit(_) => { + let command_executed = + self.naming_editor_data.run_command(command, count, mods); + + if let Some(new_path) = self.naming_path() { + self.common + .internal_command + .send(InternalCommand::TestPathCreation { new_path }); + } + + command_executed + } + _ => self.naming_editor_data.run_command(command, count, mods), + } + } else { + CommandExecuted::No + } + } + + fn receive_char(&self, c: &str) { + if self.naming.with_untracked(Naming::is_accepting_input) { + self.naming_editor_data.receive_char(c); + + if let Some(new_path) = self.naming_path() { + self.common + .internal_command + .send(InternalCommand::TestPathCreation { new_path }); + } + } + } +} + +impl FileExplorerData { + pub fn new(cx: Scope, editors: Editors, common: Rc) -> Self { + let path = common.workspace.path.clone().unwrap_or_default(); + let root = cx.create_rw_signal(FileNodeItem { + path: path.clone(), + is_dir: true, + read: false, + open: false, + children: HashMap::new(), + children_open_count: 0, + }); + let naming = cx.create_rw_signal(Naming::None); + let naming_editor_data = editors.make_local(cx, common.clone()); + let data = Self { + root, + naming, + naming_editor_data, + common, + scroll_to_line: cx.create_rw_signal(None), + left_diff_path: cx.create_rw_signal(None), + select: cx.create_rw_signal(None), + }; + if data.common.workspace.path.is_some() { + // only fill in the child files if there is open folder + data.toggle_expand(&path); + } + data + } + + /// Reload the file explorer data via reading the root directory. + /// Note that this will not update immediately. + pub fn reload(&self) { + let path = self.root.with_untracked(|root| root.path.clone()); + self.read_dir(&path); + } + + /// Toggle whether the directory is expanded or not. + /// Does nothing if the path does not exist or is not a directory. + pub fn toggle_expand(&self, path: &Path) { + let Some(Some(read)) = self.root.try_update(|root| { + let read = if let Some(node) = root.get_file_node_mut(path) { + if !node.is_dir { + return None; + } + node.open = !node.open; + Some(node.read) + } else { + None + }; + + if Some(true) == read { + root.update_node_count_recursive(path); + } + read + }) else { + return; + }; + + // Read the directory's files if they haven't been read yet + if !read { + self.read_dir(path); + } + } + + pub fn read_dir(&self, path: &Path) { + self.read_dir_cb(path, |_| {}); + } + + /// Read the directory's information and update the file explorer tree. + /// `done : FnOnce(was_read: bool)` is called when the operation is completed, whether success, + /// failure, or ignored. + pub fn read_dir_cb(&self, path: &Path, done: impl FnOnce(bool) + 'static) { + let root = self.root; + let data = self.clone(); + let config = self.common.config; + let send = { + let path = path.to_path_buf(); + create_ext_action(self.common.scope, move |result| { + let Ok(ProxyResponse::ReadDirResponse { mut items }) = result else { + done(false); + return; + }; + + root.update(|root| { + // Get the node for this path, which should already exist if we're calling + // read_dir on it. + if let Some(node) = root.get_file_node_mut(&path) { + // TODO: do not recreate glob every time we read a directory + // Retain only items that are not excluded from view by the configuration + match Glob::new(&config.get().editor.files_exclude) { + Ok(glob) => { + let matcher = glob.compile_matcher(); + items.retain(|i| !matcher.is_match(&i.path)); + } + Err(e) => tracing::error!( + target:"files_exclude", + "Failed to compile glob: {}", + e + ), + } + + node.read = true; + + // Remove paths that no longer exist + let removed_paths: Vec = node + .children + .keys() + .filter(|p| !items.iter().any(|i| &&i.path == p)) + .map(PathBuf::from) + .collect(); + for path in removed_paths { + node.children.remove(&path); + } + + // Reread dirs that were already read and add new paths + for item in items { + if let Some(existing) = node.children.get(&item.path) { + if existing.read { + data.read_dir(&existing.path); + } + } else { + node.children.insert(item.path.clone(), item); + } + } + } + root.update_node_count_recursive(&path); + }); + + done(true); + }) + }; + + // Ask the proxy for the directory information + self.common.proxy.read_dir(path.to_path_buf(), send); + } + + /// Returns `true` if `path` exists in the file explorer tree and is a directory, `false` + /// otherwise. + fn is_dir(&self, path: &Path) -> bool { + self.root.with_untracked(|root| { + root.get_file_node(path).is_some_and(|node| node.is_dir) + }) + } + + /// The current path that we're renaming to / creating or duplicating a node at. + /// Note: returns `None` when renaming if the file name has not changed. + fn naming_path(&self) -> Option { + self.naming.with_untracked(|naming| match naming { + Naming::None => None, + Naming::Renaming(_) => { + if let RenamedPath::Renamed { new_path, .. } = self.renamed_path() { + Some(new_path) + } else { + None + } + } + Naming::NewNode(n) => { + let relative_path = self.naming_editor_data.text(); + let relative_path: Cow = match relative_path.slice_to_cow(..) + { + Cow::Borrowed(path) => Cow::Borrowed(path.as_ref()), + Cow::Owned(path) => Cow::Owned(path.into()), + }; + + Some(n.base_path.join(relative_path)) + } + Naming::Duplicating(d) => { + let relative_path = self.naming_editor_data.text(); + let relative_path: Cow = match relative_path.slice_to_cow(..) + { + Cow::Borrowed(path) => Cow::Borrowed(path.as_ref()), + Cow::Owned(path) => Cow::Owned(path.into()), + }; + + let new_path = + d.path.parent().unwrap_or("".as_ref()).join(relative_path); + + Some(new_path) + } + }) + } + + /// If there is an in progress rename and the user has entered a path that differs from the + /// current path, gets the current and new paths of the renamed node. + fn renamed_path(&self) -> RenamedPath { + self.naming.with_untracked(|naming| { + if let Some(current_path) = naming.as_renaming().map(|x| &x.path) { + let current_file_name = current_path.file_name().unwrap_or_default(); + // `new_relative_path` is the new path relative to the parent directory, unless the + // user has entered an absolute path. + let new_relative_path = self.naming_editor_data.text(); + + let new_relative_path: Cow = + match new_relative_path.slice_to_cow(..) { + Cow::Borrowed(path) => Cow::Borrowed(path.as_ref()), + Cow::Owned(path) => Cow::Owned(path.into()), + }; + + if new_relative_path == current_file_name { + RenamedPath::NameUnchanged + } else { + let new_path = current_path + .parent() + .unwrap_or("".as_ref()) + .join(new_relative_path); + + RenamedPath::Renamed { + current_path: current_path.to_owned(), + new_path, + } + } + } else { + RenamedPath::NotRenaming + } + }) + } + + /// If a naming is in progress and the user has entered a valid path, send the request to + /// actually perform the change. + pub fn finish_naming(&self) { + match self.naming.get_untracked() { + Naming::None => {} + Naming::Renaming(_) => { + let renamed_path = self.renamed_path(); + match renamed_path { + // Should not occur + RenamedPath::NotRenaming => {} + RenamedPath::NameUnchanged => { + self.cancel_naming(); + } + RenamedPath::Renamed { + current_path, + new_path, + } => { + self.common.internal_command.send( + InternalCommand::FinishRenamePath { + current_path, + new_path, + }, + ); + } + } + } + Naming::NewNode(n) => { + let Some(path) = self.naming_path() else { + return; + }; + + self.common + .internal_command + .send(InternalCommand::FinishNewNode { + is_dir: n.is_dir, + path, + }); + } + Naming::Duplicating(d) => { + let Some(path) = self.naming_path() else { + return; + }; + + self.common.internal_command.send( + InternalCommand::FinishDuplicate { + source: d.path.to_owned(), + path, + }, + ); + } + } + } + + /// Closes the naming text box without applying the effect. + pub fn cancel_naming(&self) { + self.naming.set(Naming::None); + } + + pub fn click(&self, path: &Path, config: ReadSignal>) { + if self.is_dir(path) { + self.toggle_expand(path); + } else if !config.get_untracked().core.file_explorer_double_click { + self.common + .internal_command + .send(InternalCommand::OpenFile { + path: path.to_path_buf(), + }) + } + } + + pub fn reveal_in_file_tree(&self, path: PathBuf) { + let done = self + .root + .try_update(|root| { + // the directories in which the file are located are all read and opened + if root.get_file_node(&path).is_some() { + for current_path in path.ancestors() { + if let Some(file) = root.get_file_node_mut(current_path) { + if file.is_dir { + file.open = true; + } + } + } + root.update_node_count_recursive(&path); + true + } else { + // read and open the directories in which the file are located + let mut read_dir = None; + // Whether the file is in the workspace + let mut exist = false; + for current_path in path.ancestors() { + if let Some(file) = root.get_file_node_mut(current_path) { + exist = true; + if file.is_dir { + file.open = true; + if !file.read { + read_dir = Some(current_path.to_path_buf()) + } + } + break; + } + } + if let (true, Some(dir)) = (exist, read_dir) { + let explorer = self.clone(); + let select_path = path.clone(); + self.read_dir_cb(&dir, move |_| { + explorer.reveal_in_file_tree(select_path); + }) + } + false + } + }) + .unwrap_or(false); + if done { + let (found, line) = + self.root.with_untracked(|x| x.find_file_at_line(&path)); + if found { + self.scroll_to_line.set(Some(line)); + self.select.set(Some(FileNodeViewKind::Path(path))); + } + } + } + + pub fn double_click( + &self, + path: &Path, + config: ReadSignal>, + ) -> EventPropagation { + if self.is_dir(path) { + EventPropagation::Continue + } else if config.get_untracked().core.file_explorer_double_click { + self.common.internal_command.send( + InternalCommand::OpenAndConfirmedFile { + path: path.to_path_buf(), + }, + ); + EventPropagation::Stop + } else { + self.common + .internal_command + .send(InternalCommand::MakeConfirmed); + EventPropagation::Stop + } + } + + pub fn secondary_click(&self, path: &Path) { + let common = self.common.clone(); + let path_a = path.to_owned(); + let left_diff_path = self.left_diff_path; + // TODO: should we just pass is_dir into secondary click? + let is_dir = self.is_dir(path); + + let Some(workspace_path) = self.common.workspace.path.as_ref() else { + // There is no context menu if we are not in a workspace + return; + }; + + let is_workspace = path == workspace_path; + + let base_path_a = if is_dir { + Some(path_a.clone()) + } else { + path_a.parent().map(ToOwned::to_owned) + }; + let base_path_a = base_path_a.as_ref().unwrap_or(workspace_path); + + let mut menu = Menu::new(""); + + let base_path = base_path_a.clone(); + let data = self.clone(); + let naming = self.naming; + menu = menu.entry(MenuItem::new("New File").action(move || { + let base_path_b = &base_path; + let base_path = base_path.clone(); + data.read_dir_cb(base_path_b, move |was_read| { + if !was_read { + tracing::warn!( + "Failed to read directory, avoiding creating node in: {:?}", + base_path + ); + return; + } + + naming.set(Naming::NewNode(NewNode { + state: NamingState::Naming, + base_path: base_path.clone(), + is_dir: false, + editor_needs_reset: true, + })); + }); + })); + + let base_path = base_path_a.clone(); + let data = self.clone(); + let naming = self.naming; + menu = menu.entry(MenuItem::new("New Directory").action(move || { + let base_path_b = &base_path; + let base_path = base_path.clone(); + data.read_dir_cb(base_path_b, move |was_read| { + if !was_read { + tracing::warn!( + "Failed to read directory, avoiding creating node in: {:?}", + base_path + ); + return; + } + + naming.set(Naming::NewNode(NewNode { + state: NamingState::Naming, + base_path: base_path.clone(), + is_dir: true, + editor_needs_reset: true, + })); + }) + })); + + menu = menu.separator(); + + // TODO: there are situations where we can open the file explorer to remote files + if !common.workspace.kind.is_remote() { + let path = path_a.clone(); + #[cfg(not(target_os = "macos"))] + let title = "Reveal in system file explorer"; + #[cfg(target_os = "macos")] + let title = "Reveal in Finder"; + menu = menu.entry(MenuItem::new(title).action(move || { + let path = path.parent().unwrap_or(&path); + if !path.exists() { + return; + } + + if let Err(err) = open::that(path) { + tracing::error!( + "Failed to reveal file in system file explorer: {}", + err + ); + } + })); + } + + if !is_workspace { + let path = path_a.clone(); + menu = menu.entry(MenuItem::new("Rename").action(move || { + naming.set(Naming::Renaming(Renaming { + state: NamingState::Naming, + path: path.clone(), + editor_needs_reset: true, + })); + })); + + let path = path_a.clone(); + menu = menu.entry(MenuItem::new("Duplicate").action(move || { + naming.set(Naming::Duplicating(Duplicating { + state: NamingState::Naming, + path: path.clone(), + editor_needs_reset: true, + })); + })); + + // TODO: it is common for shift+right click to make 'Move file to trash' an actual + // Delete, which can be useful for large files. + let path = path_a.clone(); + let proxy = common.proxy.clone(); + let trash_text = if is_dir { + "Move Directory to Trash" + } else { + "Move File to Trash" + }; + menu = menu.entry(MenuItem::new(trash_text).action(move || { + proxy.trash_path(path.clone(), |res| { + if let Err(err) = res { + tracing::warn!("Failed to trash path: {:?}", err); + } + }) + })); + } + + menu = menu.separator(); + + let path = path_a.clone(); + menu = menu.entry(MenuItem::new("Copy Path").action(move || { + let mut clipboard = SystemClipboard::new(); + clipboard.put_string(path.to_string_lossy()); + })); + + let path = path_a.clone(); + let workspace = common.workspace.clone(); + menu = menu.entry(MenuItem::new("Copy Relative Path").action(move || { + let relative_path = if let Some(workspace_path) = &workspace.path { + path.strip_prefix(workspace_path).unwrap_or(&path) + } else { + path.as_ref() + }; + + let mut clipboard = SystemClipboard::new(); + clipboard.put_string(relative_path.to_string_lossy()); + })); + + menu = menu.separator(); + + let path = path_a.clone(); + menu = menu.entry( + MenuItem::new("Select for Compare") + .action(move || left_diff_path.set(Some(path.clone()))), + ); + + if let Some(left_path) = self.left_diff_path.get_untracked() { + let common = self.common.clone(); + let right_path = path_a.to_owned(); + + menu = menu.entry(MenuItem::new("Compare with Selected").action( + move || { + common + .internal_command + .send(InternalCommand::OpenDiffFiles { + left_path: left_path.clone(), + right_path: right_path.clone(), + }) + }, + )) + } + + menu = menu.separator(); + + let internal_command = common.internal_command; + menu = menu.entry(MenuItem::new("Refresh").action(move || { + internal_command.send(InternalCommand::ReloadFileExplorer); + })); + + show_context_menu(menu, None); + } + + pub fn middle_click(&self, path: &Path) -> EventPropagation { + if self.is_dir(path) { + EventPropagation::Continue + } else { + self.common + .internal_command + .send(InternalCommand::OpenFileInNewTab { + path: path.to_path_buf(), + }); + EventPropagation::Stop + } + } +} diff --git a/lapce-app/src/file_explorer/mod.rs b/lapce-app/src/file_explorer/mod.rs new file mode 100644 index 0000000..14b4d9b --- /dev/null +++ b/lapce-app/src/file_explorer/mod.rs @@ -0,0 +1,3 @@ +pub mod data; +pub mod node; +pub mod view; diff --git a/lapce-app/src/file_explorer/node.rs b/lapce-app/src/file_explorer/node.rs new file mode 100644 index 0000000..68b2386 --- /dev/null +++ b/lapce-app/src/file_explorer/node.rs @@ -0,0 +1,38 @@ +use floem::views::VirtualVector; +use lapce_rpc::file::{FileNodeItem, FileNodeViewData, Naming}; + +pub struct FileNodeVirtualList { + file_node_item: FileNodeItem, + naming: Naming, +} + +impl FileNodeVirtualList { + pub fn new(file_node_item: FileNodeItem, naming: Naming) -> Self { + Self { + file_node_item, + naming, + } + } +} + +impl VirtualVector for FileNodeVirtualList { + fn total_len(&self) -> usize { + self.file_node_item.children_open_count + 1 + } + + fn slice( + &mut self, + range: std::ops::Range, + ) -> impl Iterator { + let naming = &self.naming; + let root = &self.file_node_item; + + let min = range.start; + let max = range.end; + let mut view_items = Vec::new(); + + root.append_view_slice(&mut view_items, naming, min, max, 0, 1); + + view_items.into_iter() + } +} diff --git a/lapce-app/src/file_explorer/view.rs b/lapce-app/src/file_explorer/view.rs new file mode 100644 index 0000000..1960e46 --- /dev/null +++ b/lapce-app/src/file_explorer/view.rs @@ -0,0 +1,620 @@ +use std::{path::Path, rc::Rc, sync::Arc}; + +use floem::{ + View, + event::{Event, EventListener}, + kurbo::Rect, + peniko::Color, + reactive::{ + ReadSignal, RwSignal, SignalGet, SignalUpdate, SignalWith, create_rw_signal, + }, + style::{AlignItems, CursorStyle, Position, Style}, + text::Style as FontStyle, + views::{ + Container, Decorators, container, dyn_stack, label, scroll, stack, svg, + virtual_stack, + }, +}; +use lapce_core::selection::Selection; +use lapce_rpc::{ + file::{FileNodeViewData, FileNodeViewKind, Naming}, + source_control::FileDiffKind, +}; +use lapce_xi_rope::Rope; + +use super::{data::FileExplorerData, node::FileNodeVirtualList}; +use crate::{ + app::clickable_icon, + command::InternalCommand, + config::{LapceConfig, color::LapceColor, icon::LapceIcons}, + editor_tab::{EditorTabChild, EditorTabData}, + panel::{ + data::PanelSection, kind::PanelKind, position::PanelPosition, + view::PanelBuilder, + }, + plugin::PluginData, + source_control::SourceControlData, + text_input::TextInputBuilder, + window_tab::{Focus, WindowTabData}, +}; + +/// Blends `foreground` with `background`. +/// +/// Uses the alpha channel from `foreground` - if `foreground` is opaque, `foreground` will be +/// returned unchanged. +/// +/// The result is always opaque regardless of the transparency of the inputs. +fn blend_colors(background: Color, foreground: Color) -> Color { + let background = background.to_rgba8(); + let foreground = foreground.to_rgba8(); + let a: u16 = foreground.a.into(); + let [r, g, b] = [ + [background.r, foreground.r], + [background.g, foreground.g], + [background.b, foreground.b], + ] + .map(|x| x.map(u16::from)) + .map(|[b, f]| (a * f + (255 - a) * b) / 255) + .map(|x| x as u8); + + Color::from_rgba8(r, g, b, 255) +} + +pub fn file_explorer_panel( + window_tab_data: Rc, + position: PanelPosition, +) -> impl View { + let config = window_tab_data.common.config; + let data = window_tab_data.file_explorer.clone(); + let source_control = window_tab_data.source_control.clone(); + PanelBuilder::new(config, position) + .add_height_style( + "Open Editors", + 150.0, + container(open_editors_view(window_tab_data.clone())) + .style(|s| s.size_full()), + window_tab_data.panel.section_open(PanelSection::OpenEditor), + move |s| s.apply_if(!config.get().ui.open_editors_visible, |s| s.hide()), + ) + .add( + "File Explorer", + container(file_explorer_view(data, source_control)) + .style(|s| s.size_full()), + window_tab_data + .panel + .section_open(PanelSection::FileExplorer), + ) + .build() + .debug_name("File Explorer Panel") +} + +/// Initialize the file explorer's naming (renaming, creating, etc.) editor with the given path. +fn initialize_naming_editor_with_path(data: &FileExplorerData, path: &Path) { + let file_name = path.file_name().unwrap_or_default().to_string_lossy(); + // Start with the part of the file or directory name before the extension + // selected. + let selection_end = { + let without_leading_dot = file_name.strip_prefix('.').unwrap_or(&file_name); + let idx = without_leading_dot + .find('.') + .unwrap_or(without_leading_dot.len()); + + idx + file_name.len() - without_leading_dot.len() + }; + + initialize_naming_editor(data, &file_name, Some(selection_end)); +} + +fn initialize_naming_editor( + data: &FileExplorerData, + text: &str, + selection_end: Option, +) { + let text = Rope::from(text); + let selection_end = selection_end.unwrap_or(text.len()); + + let doc = data.naming_editor_data.doc(); + doc.reload(text, true); + data.naming_editor_data + .cursor() + .update(|cursor| cursor.set_insert(Selection::region(0, selection_end))); + + data.naming + .update(|naming| naming.set_editor_needs_reset(false)); +} + +fn file_node_text_color( + config: ReadSignal>, + node: FileNodeViewData, + source_control: SourceControlData, +) -> Color { + let diff = source_control.file_diffs.with(|file_diffs| { + let FileNodeViewKind::Path(path) = &node.kind else { + return None; + }; + + if node.is_dir { + file_diffs + .keys() + .find(|p| p.as_path().starts_with(path)) + .map(|_| FileDiffKind::Modified) + } else { + file_diffs.get(path).map(|(diff, _)| diff.kind()) + } + }); + + let color = match diff { + Some(FileDiffKind::Modified | FileDiffKind::Renamed) => { + LapceColor::SOURCE_CONTROL_MODIFIED + } + Some(FileDiffKind::Added) => LapceColor::SOURCE_CONTROL_ADDED, + Some(FileDiffKind::Deleted) => LapceColor::SOURCE_CONTROL_REMOVED, + None => LapceColor::PANEL_FOREGROUND, + }; + + config.get().color(color) +} + +fn file_node_text_view( + data: FileExplorerData, + node: FileNodeViewData, + source_control: SourceControlData, +) -> impl View { + let config = data.common.config; + let ui_line_height = data.common.ui_line_height; + + match node.kind.clone() { + FileNodeViewKind::Path(path) => { + if node.is_root { + let file = path.clone(); + container(( + label(move || { + file.file_name() + .map(|f| f.to_string_lossy().to_string()) + .unwrap_or_default() + }) + .style(move |s| { + s.height(ui_line_height.get()) + .color(file_node_text_color( + config, + node.clone(), + source_control.clone(), + )) + .padding_right(5.0) + .selectable(false) + }), + label(move || path.to_string_lossy().to_string()).style( + move |s| { + s.height(ui_line_height.get()) + .color( + config + .get() + .color(LapceColor::PANEL_FOREGROUND_DIM), + ) + .selectable(false) + }, + ), + )) + } else { + container( + label(move || { + path.file_name() + .map(|f| f.to_string_lossy().to_string()) + .unwrap_or_default() + }) + .style(move |s| { + s.height(ui_line_height.get()) + .color(file_node_text_color( + config, + node.clone(), + source_control.clone(), + )) + .selectable(false) + }), + ) + } + } + FileNodeViewKind::Renaming { path, err } => { + if data.naming.with_untracked(Naming::editor_needs_reset) { + initialize_naming_editor_with_path(&data, &path); + } + + file_node_input_view(data, err.clone()) + } + FileNodeViewKind::Naming { err } => { + if data.naming.with_untracked(Naming::editor_needs_reset) { + initialize_naming_editor(&data, "", None); + } + + file_node_input_view(data, err.clone()) + } + FileNodeViewKind::Duplicating { source, err } => { + if data.naming.with_untracked(Naming::editor_needs_reset) { + initialize_naming_editor_with_path(&data, &source); + } + + file_node_input_view(data, err.clone()) + } + } +} + +/// Input used for naming a file/directory +fn file_node_input_view(data: FileExplorerData, err: Option) -> Container { + let ui_line_height = data.common.ui_line_height; + + let naming_editor_data = data.naming_editor_data.clone(); + let text_input_file_explorer_data = data.clone(); + let focus = data.common.focus; + let config = data.common.config; + + let is_focused = move || { + focus.with_untracked(|focus| focus == &Focus::Panel(PanelKind::FileExplorer)) + }; + let text_input_view = TextInputBuilder::new() + .is_focused(is_focused) + .key_focus(text_input_file_explorer_data) + .build_editor(naming_editor_data.clone()) + .on_event_stop(EventListener::FocusLost, move |_| { + data.finish_naming(); + data.naming.set(Naming::None); + }) + .style(move |s| { + s.width_full() + .height(ui_line_height.get()) + .padding(0.0) + .margin(0.0) + .border_radius(6.0) + .border(1.0) + .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + }); + + let text_input_id = text_input_view.id(); + text_input_id.request_focus(); + + if let Some(err) = err { + container( + stack(( + text_input_view, + label(move || err.clone()).style(move |s| { + let config = config.get(); + + let editor_background_color = + config.color(LapceColor::PANEL_CURRENT_BACKGROUND); + let error_background_color = + config.color(LapceColor::ERROR_LENS_ERROR_BACKGROUND); + + let background_color = blend_colors( + editor_background_color, + error_background_color, + ); + + s.position(Position::Absolute) + .inset_top(ui_line_height.get()) + .width_full() + .color(config.color(LapceColor::ERROR_LENS_ERROR_FOREGROUND)) + .background(background_color) + .z_index(100) + }), + )) + .style(|s| s.flex_grow(1.0)), + ) + } else { + container(text_input_view) + } + .style(move |s| s.width_full()) +} + +fn file_explorer_view( + data: FileExplorerData, + source_control: SourceControlData, +) -> impl View { + let root = data.root; + let ui_line_height = data.common.ui_line_height; + let config = data.common.config; + let naming = data.naming; + let scroll_to_line = data.scroll_to_line; + let select = data.select; + let secondary_click_data = data.clone(); + let scroll_rect = create_rw_signal(Rect::ZERO); + + scroll( + virtual_stack( + move || FileNodeVirtualList::new(root.get(), data.naming.get()), + move |node| (node.kind.clone(), node.is_dir, node.open, node.level), + move |node| { + let level = node.level; + let data = data.clone(); + let click_data = data.clone(); + let double_click_data = data.clone(); + let secondary_click_data = data.clone(); + let aux_click_data = data.clone(); + let kind = node.kind.clone(); + let open = node.open; + let is_dir = node.is_dir; + + let view = stack(( + svg(move || { + let config = config.get(); + let svg_str = match open { + true => LapceIcons::ITEM_OPENED, + false => LapceIcons::ITEM_CLOSED, + }; + config.ui_svg(svg_str) + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + + let color = if is_dir { + config.color(LapceColor::LAPCE_ICON_ACTIVE) + } else { + Color::TRANSPARENT + }; + s.size(size, size) + .flex_shrink(0.0) + .margin_left(10.0) + .color(color) + }), + { + let kind = kind.clone(); + let kind_for_style = kind.clone(); + // TODO: use the current naming input as the path for the file svg + svg(move || { + let config = config.get(); + if is_dir { + let svg_str = match open { + true => LapceIcons::DIRECTORY_OPENED, + false => LapceIcons::DIRECTORY_CLOSED, + }; + config.ui_svg(svg_str) + } else if let Some(path) = kind.path() { + config.file_svg(path).0 + } else { + config.ui_svg(LapceIcons::FILE) + } + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + + s.size(size, size) + .flex_shrink(0.0) + .margin_horiz(6.0) + .apply_if(is_dir, |s| { + s.color( + config.color(LapceColor::LAPCE_ICON_ACTIVE), + ) + }) + .apply_if(!is_dir, |s| { + s.apply_opt( + kind_for_style + .path() + .and_then(|p| config.file_svg(p).1), + Style::color, + ) + }) + }) + }, + file_node_text_view(data, node, source_control.clone()), + )) + .style({ + let kind = kind.clone(); + move |s| { + s.padding_right(15.0) + .min_width_full() + .padding_left((level * 10) as f32) + .align_items(AlignItems::Center) + .hover(|s| { + s.background( + config + .get() + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + .cursor(CursorStyle::Pointer) + }) + .apply_if( + select.get().map(|x| x == kind).unwrap_or_default(), + |x| { + x.background( + config.get().color( + LapceColor::PANEL_CURRENT_BACKGROUND, + ), + ) + }, + ) + } + }) + .debug_name("file item"); + + // Only handle click events if we are not naming the file node + if let FileNodeViewKind::Path(path) = &kind { + let click_path = path.clone(); + let double_click_path = path.clone(); + let secondary_click_path = path.clone(); + let aux_click_path = path.clone(); + view.on_click_stop({ + let kind = kind.clone(); + move |_| { + click_data.click(&click_path, config); + select.update(|x| *x = Some(kind.clone())); + } + }) + .on_double_click({ + move |_| { + double_click_data + .double_click(&double_click_path, config) + } + }) + .on_secondary_click_stop(move |_| { + secondary_click_data.secondary_click(&secondary_click_path); + }) + .on_event_stop( + EventListener::PointerDown, + move |event| { + if let Event::PointerDown(pointer_event) = event { + if pointer_event.button.is_auxiliary() { + aux_click_data.middle_click(&aux_click_path); + } + } + }, + ) + } else { + view + } + }, + ) + .item_size_fixed(move || ui_line_height.get()) + .style(|s| s.absolute().flex_col().min_width_full()), + ) + .style(|s| s.absolute().size_full().line_height(1.8)) + .on_secondary_click_stop(move |_| { + if let Naming::None = naming.get_untracked() { + if let Some(path) = &secondary_click_data.common.workspace.path { + secondary_click_data.secondary_click(path); + } + } + }) + .on_resize(move |rect| { + scroll_rect.set(rect); + }) + .scroll_to(move || { + if let Some(line) = scroll_to_line.get() { + let line_height = ui_line_height.get_untracked(); + Some( + ( + 0.0, + line * line_height - scroll_rect.get_untracked().height() / 2.0, + ) + .into(), + ) + } else { + None + } + }) +} + +fn open_editors_view(window_tab_data: Rc) -> impl View { + let diff_editors = window_tab_data.main_split.diff_editors; + let editors = window_tab_data.main_split.editors; + let editor_tabs = window_tab_data.main_split.editor_tabs; + let config = window_tab_data.common.config; + let internal_command = window_tab_data.common.internal_command; + let active_editor_tab = window_tab_data.main_split.active_editor_tab; + let plugin = window_tab_data.plugin.clone(); + + let child_view = move |plugin: PluginData, + editor_tab: RwSignal, + child_index: RwSignal, + child: EditorTabChild| { + let editor_tab_id = + editor_tab.with_untracked(|editor_tab| editor_tab.editor_tab_id); + let child_for_close = child.clone(); + let info = child.view_info(editors, diff_editors, plugin, config); + let hovered = create_rw_signal(false); + + stack(( + clickable_icon( + move || { + if hovered.get() || info.with(|info| info.is_pristine) { + LapceIcons::CLOSE + } else { + LapceIcons::UNSAVED + } + }, + move || { + let editor_tab_id = + editor_tab.with_untracked(|t| t.editor_tab_id); + internal_command.send(InternalCommand::EditorTabChildClose { + editor_tab_id, + child: child_for_close.clone(), + }); + }, + || false, + || false, + || "Close", + config, + ) + .on_event_stop(EventListener::PointerEnter, move |_| { + hovered.set(true); + }) + .on_event_stop(EventListener::PointerLeave, move |_| { + hovered.set(false); + }) + .on_event_stop(EventListener::PointerDown, |_| {}) + .style(|s| s.margin_left(10.0)), + container(svg(move || info.with(|info| info.icon.clone())).style( + move |s| { + let size = config.get().ui.icon_size() as f32; + s.size(size, size) + .apply_opt(info.with(|info| info.color), |s, c| s.color(c)) + }, + )) + .style(|s| s.padding_horiz(6.0)), + label(move || info.with(|info| info.name.clone())).style(move |s| { + s.apply_if( + !info + .with(|info| info.confirmed) + .map(|confirmed| confirmed.get()) + .unwrap_or(true), + |s| s.font_style(FontStyle::Italic), + ) + }), + )) + .style(move |s| { + let config = config.get(); + s.items_center() + .width_pct(100.0) + .cursor(CursorStyle::Pointer) + .apply_if( + active_editor_tab.get() == Some(editor_tab_id) + && editor_tab.with(|editor_tab| editor_tab.active) + == child_index.get(), + |s| { + s.background( + config.color(LapceColor::PANEL_CURRENT_BACKGROUND), + ) + }, + ) + .hover(|s| { + s.background(config.color(LapceColor::PANEL_HOVERED_BACKGROUND)) + }) + }) + .on_event_cont(EventListener::PointerDown, move |_| { + editor_tab.update(|editor_tab| { + editor_tab.active = child_index.get_untracked(); + }); + active_editor_tab.set(Some(editor_tab_id)); + }) + }; + + scroll( + dyn_stack( + move || editor_tabs.get().into_iter().enumerate(), + move |(index, (editor_tab_id, _))| (*index, *editor_tab_id), + move |(index, (_, editor_tab))| { + let plugin = plugin.clone(); + stack(( + label(move || format!("Group {}", index + 1)) + .style(|s| s.margin_left(10.0)), + dyn_stack( + move || editor_tab.get().children, + move |(_, _, child)| child.id(), + move |(child_index, _, child)| { + child_view( + plugin.clone(), + editor_tab, + child_index, + child, + ) + }, + ) + .style(|s| s.flex_col().width_pct(100.0)), + )) + .style(|s| s.flex_col()) + }, + ) + .style(|s| s.flex_col().width_pct(100.0)), + ) + .style(|s| s.absolute().size_full().line_height(1.8)) + .debug_name("Open Editors") +} diff --git a/lapce-app/src/find.rs b/lapce-app/src/find.rs new file mode 100644 index 0000000..293ee21 --- /dev/null +++ b/lapce-app/src/find.rs @@ -0,0 +1,545 @@ +use std::cmp::{max, min}; + +use floem::{ + prelude::SignalTrack, + reactive::{RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, +}; +use lapce_core::{ + selection::{SelRegion, Selection}, + word::WordCursor, +}; +use lapce_xi_rope::{ + Cursor, Interval, Rope, + find::{CaseMatching, find, is_multiline_regex}, +}; +use regex::{Regex, RegexBuilder}; +use serde::{Deserialize, Serialize}; + +const REGEX_SIZE_LIMIT: usize = 1000000; + +/// Indicates what changed in the find state. +#[derive(PartialEq, Debug, Clone)] +pub enum FindProgress { + /// Incremental find is done/not running. + Ready, + + /// The find process just started. + Started, + + /// Incremental find is in progress. Keeps tracked of already searched range. + InProgress(Selection), +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct FindStatus { + /// Identifier for the current search query. + id: usize, + + /// The current search query. + chars: Option, + + /// Whether the active search is case matching. + case_sensitive: Option, + + /// Whether the search query is considered as regular expression. + is_regex: Option, + + /// Query only matches whole words. + whole_words: Option, + + /// Total number of matches. + matches: usize, + + /// Line numbers which have find results. + lines: Vec, +} + +#[derive(Clone)] +pub struct FindSearchString { + pub content: String, + pub regex: Option, +} + +#[derive(Clone)] +pub struct Find { + pub rev: RwSignal, + /// If the find is shown + pub visual: RwSignal, + /// The currently active search string. + pub search_string: RwSignal>, + /// The case matching setting for the currently active search. + pub case_matching: RwSignal, + /// Query matches only whole words. + pub whole_words: RwSignal, + /// The search query should be considered as regular expression. + pub is_regex: RwSignal, + /// replace editor is shown + pub replace_active: RwSignal, + /// replace editor is focused + pub replace_focus: RwSignal, + /// Triggered by changes in the search string + pub triggered_by_changes: RwSignal, +} + +impl Find { + pub fn new(cx: Scope) -> Self { + let find = Self { + rev: cx.create_rw_signal(0), + visual: cx.create_rw_signal(false), + search_string: cx.create_rw_signal(None), + case_matching: cx.create_rw_signal(CaseMatching::CaseInsensitive), + whole_words: cx.create_rw_signal(false), + is_regex: cx.create_rw_signal(false), + replace_active: cx.create_rw_signal(false), + replace_focus: cx.create_rw_signal(false), + triggered_by_changes: cx.create_rw_signal(false), + }; + + { + let find = find.clone(); + cx.create_effect(move |_| { + find.is_regex.with(|_| ()); + let s = find.search_string.with_untracked(|s| { + if let Some(s) = s.as_ref() { + s.content.clone() + } else { + "".to_string() + } + }); + if !s.is_empty() { + find.set_find(&s); + } + }); + } + + { + let find = find.clone(); + cx.create_effect(move |_| { + find.search_string.track(); + find.case_matching.track(); + find.whole_words.track(); + find.rev.update(|rev| { + *rev += 1; + }); + }); + } + + find + } + + /// Returns `true` if case sensitive, otherwise `false` + pub fn case_sensitive(&self, tracked: bool) -> bool { + match if tracked { + self.case_matching.get() + } else { + self.case_matching.get_untracked() + } { + CaseMatching::Exact => true, + CaseMatching::CaseInsensitive => false, + } + } + + /// Sets find case sensitivity. + pub fn set_case_sensitive(&self, case_sensitive: bool) { + if self.case_sensitive(false) == case_sensitive { + return; + } + + let case_matching = if case_sensitive { + CaseMatching::Exact + } else { + CaseMatching::CaseInsensitive + }; + self.case_matching.set(case_matching); + } + + pub fn set_find(&self, search_string: &str) { + if search_string.is_empty() { + self.search_string.set(None); + return; + } + + if !self.visual.get_untracked() { + self.visual.set(true); + } + + let is_regex = self.is_regex.get_untracked(); + + let search_string_unchanged = self.search_string.with_untracked(|search| { + if let Some(s) = search { + s.content == search_string && s.regex.is_some() == is_regex + } else { + false + } + }); + + if search_string_unchanged { + return; + } + + // create regex from untrusted input + let regex = match is_regex { + false => None, + true => RegexBuilder::new(search_string) + .size_limit(REGEX_SIZE_LIMIT) + .case_insensitive(!self.case_sensitive(false)) + .build() + .ok(), + }; + self.triggered_by_changes.set(true); + self.search_string.set(Some(FindSearchString { + content: search_string.to_string(), + regex, + })); + } + + pub fn next( + &self, + text: &Rope, + offset: usize, + reverse: bool, + wrap: bool, + ) -> Option<(usize, usize)> { + if !self.visual.get_untracked() { + self.visual.set(true); + } + let case_matching = self.case_matching.get_untracked(); + let whole_words = self.whole_words.get_untracked(); + self.search_string.with_untracked( + |search_string| -> Option<(usize, usize)> { + let search_string = search_string.as_ref()?; + if !reverse { + let mut raw_lines = text.lines_raw(offset..text.len()); + let mut find_cursor = Cursor::new(text, offset); + while let Some(start) = find( + &mut find_cursor, + &mut raw_lines, + case_matching, + &search_string.content, + search_string.regex.as_ref(), + ) { + let end = find_cursor.pos(); + + if whole_words + && !Self::is_matching_whole_words(text, start, end) + { + raw_lines = + text.lines_raw(find_cursor.pos()..text.len()); + continue; + } + raw_lines = text.lines_raw(find_cursor.pos()..text.len()); + + if start > offset { + return Some((start, end)); + } + } + if wrap { + let mut raw_lines = text.lines_raw(0..offset); + let mut find_cursor = Cursor::new(text, 0); + while let Some(start) = find( + &mut find_cursor, + &mut raw_lines, + case_matching, + &search_string.content, + search_string.regex.as_ref(), + ) { + let end = find_cursor.pos(); + + if whole_words + && !Self::is_matching_whole_words(text, start, end) + { + raw_lines = + text.lines_raw(find_cursor.pos()..offset); + continue; + } + return Some((start, end)); + } + } + } else { + let mut raw_lines = text.lines_raw(0..offset); + let mut find_cursor = Cursor::new(text, 0); + let mut regions = Vec::new(); + while let Some(start) = find( + &mut find_cursor, + &mut raw_lines, + case_matching, + &search_string.content, + search_string.regex.as_ref(), + ) { + let end = find_cursor.pos(); + raw_lines = text.lines_raw(find_cursor.pos()..offset); + if whole_words + && !Self::is_matching_whole_words(text, start, end) + { + continue; + } + if start < offset { + regions.push((start, end)); + } + } + if !regions.is_empty() { + return Some(regions[regions.len() - 1]); + } + if wrap { + let mut raw_lines = text.lines_raw(offset..text.len()); + let mut find_cursor = Cursor::new(text, offset); + let mut regions = Vec::new(); + while let Some(start) = find( + &mut find_cursor, + &mut raw_lines, + case_matching, + &search_string.content, + search_string.regex.as_ref(), + ) { + let end = find_cursor.pos(); + + if whole_words + && !Self::is_matching_whole_words(text, start, end) + { + raw_lines = + text.lines_raw(find_cursor.pos()..text.len()); + continue; + } + raw_lines = + text.lines_raw(find_cursor.pos()..text.len()); + + if start > offset { + regions.push((start, end)); + } + } + if !regions.is_empty() { + return Some(regions[regions.len() - 1]); + } + } + } + None + }, + ) + } + + /// Checks if the start and end of a match is matching whole words. + fn is_matching_whole_words(text: &Rope, start: usize, end: usize) -> bool { + let mut word_end_cursor = WordCursor::new(text, end - 1); + let mut word_start_cursor = WordCursor::new(text, start + 1); + + if word_start_cursor.prev_code_boundary() != start { + return false; + } + + if word_end_cursor.next_code_boundary() != end { + return false; + } + + true + } + + /// Returns `true` if the search query is a multi-line regex. + pub fn is_multiline_regex(&self) -> bool { + self.search_string.with_untracked(|search| { + if let Some(search) = search.as_ref() { + search.regex.is_some() && is_multiline_regex(&search.content) + } else { + false + } + }) + } + + #[allow(clippy::too_many_arguments)] + pub fn find( + text: &Rope, + search: &FindSearchString, + start: usize, + end: usize, + case_matching: CaseMatching, + whole_words: bool, + include_slop: bool, + occurrences: &mut Selection, + ) { + let search_string = &search.content; + + let slop = if include_slop { + search.content.len() * 2 + } else { + 0 + }; + + // expand region to be able to find occurrences around the region's edges + let expanded_start = max(start, slop) - slop; + let expanded_end = min(end + slop, text.len()); + let from = text + .at_or_prev_codepoint_boundary(expanded_start) + .unwrap_or(0); + let to = text + .at_or_next_codepoint_boundary(expanded_end) + .unwrap_or_else(|| text.len()); + let mut to_cursor = Cursor::new(text, to); + let _ = to_cursor.next_leaf(); + + let sub_text = text.subseq(Interval::new(0, to_cursor.pos())); + let mut find_cursor = Cursor::new(&sub_text, from); + + let mut raw_lines = text.lines_raw(from..to); + + while let Some(start) = find( + &mut find_cursor, + &mut raw_lines, + case_matching, + search_string, + search.regex.as_ref(), + ) { + let end = find_cursor.pos(); + + if whole_words && !Self::is_matching_whole_words(text, start, end) { + raw_lines = text.lines_raw(find_cursor.pos()..to); + continue; + } + + let region = SelRegion::new(start, end, None); + let (_, e) = occurrences.add_range_distinct(region); + // in case of ambiguous search results (e.g. search "aba" in "ababa"), + // the search result closer to the beginning of the file wins + if e != end { + // Skip the search result and keep the occurrence that is closer to + // the beginning of the file. Re-align the cursor to the kept + // occurrence + find_cursor.set(e); + raw_lines = text.lines_raw(find_cursor.pos()..to); + continue; + } + + // in case current cursor matches search result (for example query a* matches) + // all cursor positions, then cursor needs to be increased so that search + // continues at next position. Otherwise, search will result in overflow since + // search will always repeat at current cursor position. + if start == end { + // determine whether end of text is reached and stop search or increase + // cursor manually + if end + 1 >= text.len() { + break; + } else { + find_cursor.set(end + 1); + } + } + + // update line iterator so that line starts at current cursor position + raw_lines = text.lines_raw(find_cursor.pos()..to); + } + } + + /// Execute the search on the provided text in the range provided by `start` and `end`. + pub fn update_find( + &self, + text: &Rope, + start: usize, + end: usize, + include_slop: bool, + occurrences: &mut Selection, + ) { + if self.search_string.with_untracked(|search| search.is_none()) { + return; + } + + let search = self.search_string.get_untracked().unwrap(); + let search_string = &search.content; + // extend the search by twice the string length (twice, because case matching may increase + // the length of an occurrence) + let slop = if include_slop { + search.content.len() * 2 + } else { + 0 + }; + + // expand region to be able to find occurrences around the region's edges + let expanded_start = max(start, slop) - slop; + let expanded_end = min(end + slop, text.len()); + let from = text + .at_or_prev_codepoint_boundary(expanded_start) + .unwrap_or(0); + let to = text + .at_or_next_codepoint_boundary(expanded_end) + .unwrap_or_else(|| text.len()); + let mut to_cursor = Cursor::new(text, to); + let _ = to_cursor.next_leaf(); + + let sub_text = text.subseq(Interval::new(0, to_cursor.pos())); + let mut find_cursor = Cursor::new(&sub_text, from); + + let mut raw_lines = text.lines_raw(from..to); + + let case_matching = self.case_matching.get_untracked(); + let whole_words = self.whole_words.get_untracked(); + while let Some(start) = find( + &mut find_cursor, + &mut raw_lines, + case_matching, + search_string, + search.regex.as_ref(), + ) { + let end = find_cursor.pos(); + + if whole_words && !Self::is_matching_whole_words(text, start, end) { + raw_lines = text.lines_raw(find_cursor.pos()..to); + continue; + } + + let region = SelRegion::new(start, end, None); + let (_, e) = occurrences.add_range_distinct(region); + // in case of ambiguous search results (e.g. search "aba" in "ababa"), + // the search result closer to the beginning of the file wins + if e != end { + // Skip the search result and keep the occurrence that is closer to + // the beginning of the file. Re-align the cursor to the kept + // occurrence + find_cursor.set(e); + raw_lines = text.lines_raw(find_cursor.pos()..to); + continue; + } + + // in case current cursor matches search result (for example query a* matches) + // all cursor positions, then cursor needs to be increased so that search + // continues at next position. Otherwise, search will result in overflow since + // search will always repeat at current cursor position. + if start == end { + // determine whether end of text is reached and stop search or increase + // cursor manually + if end + 1 >= text.len() { + break; + } else { + find_cursor.set(end + 1); + } + } + + // update line iterator so that line starts at current cursor position + raw_lines = text.lines_raw(find_cursor.pos()..to); + } + } +} + +#[derive(Clone)] +pub struct FindResult { + pub find_rev: RwSignal, + pub progress: RwSignal, + pub occurrences: RwSignal, + pub search_string: RwSignal>, + pub case_matching: RwSignal, + pub whole_words: RwSignal, + pub is_regex: RwSignal, +} + +impl FindResult { + pub fn new(cx: Scope) -> Self { + Self { + find_rev: cx.create_rw_signal(0), + progress: cx.create_rw_signal(FindProgress::Started), + occurrences: cx.create_rw_signal(Selection::new()), + search_string: cx.create_rw_signal(None), + case_matching: cx.create_rw_signal(CaseMatching::Exact), + whole_words: cx.create_rw_signal(false), + is_regex: cx.create_rw_signal(false), + } + } + + pub fn reset(&self) { + self.progress.set(FindProgress::Started); + } +} diff --git a/lapce-app/src/focus_text.rs b/lapce-app/src/focus_text.rs new file mode 100644 index 0000000..597bc50 --- /dev/null +++ b/lapce-app/src/focus_text.rs @@ -0,0 +1,287 @@ +use floem::{ + Renderer, View, ViewId, + peniko::{ + Color, + kurbo::{Point, Rect}, + }, + prop_extractor, + reactive::create_effect, + style::{FontFamily, FontSize, LineHeight, Style, TextColor}, + taffy::prelude::NodeId, + text::{Attrs, AttrsList, FamilyOwned, TextLayout, Weight}, +}; + +prop_extractor! { + Extractor { + color: TextColor, + font_size: FontSize, + font_family: FontFamily, + line_height: LineHeight, + } +} + +enum FocusTextState { + Text(String), + FocusColor(Color), + FocusIndices(Vec), +} + +pub fn focus_text( + text: impl Fn() -> String + 'static, + focus_indices: impl Fn() -> Vec + 'static, + focus_color: impl Fn() -> Color + 'static, +) -> FocusText { + let id = ViewId::new(); + + create_effect(move |_| { + let new_text = text(); + id.update_state(FocusTextState::Text(new_text)); + }); + + create_effect(move |_| { + let focus_color = focus_color(); + id.update_state(FocusTextState::FocusColor(focus_color)); + }); + + create_effect(move |_| { + let focus_indices = focus_indices(); + id.update_state(FocusTextState::FocusIndices(focus_indices)); + }); + + FocusText { + id, + text: "".to_string(), + text_layout: None, + focus_color: Color::BLACK, + focus_indices: Vec::new(), + text_node: None, + available_text: None, + available_width: None, + available_text_layout: None, + style: Default::default(), + } +} + +pub struct FocusText { + id: ViewId, + text: String, + text_layout: Option, + focus_color: Color, + focus_indices: Vec, + text_node: Option, + available_text: Option, + available_width: Option, + available_text_layout: Option, + style: Extractor, +} + +impl FocusText { + fn set_text_layout(&mut self) { + let mut attrs = + Attrs::new().color(self.style.color().unwrap_or(Color::BLACK)); + if let Some(font_size) = self.style.font_size() { + attrs = attrs.font_size(font_size); + } + let font_family = self.style.font_family().as_ref().map(|font_family| { + let family: Vec = + FamilyOwned::parse_list(font_family).collect(); + family + }); + if let Some(font_family) = font_family.as_ref() { + attrs = attrs.family(font_family); + } + if let Some(line_height) = self.style.line_height() { + attrs = attrs.line_height(line_height); + } + + let mut attrs_list = AttrsList::new(attrs.clone()); + + for &i_start in &self.focus_indices { + let i_end = self + .text + .char_indices() + .find(|(i, _)| *i == i_start) + .map(|(_, c)| c.len_utf8() + i_start); + let i_end = if let Some(i_end) = i_end { + i_end + } else { + continue; + }; + attrs_list.add_span( + i_start..i_end, + attrs.clone().color(self.focus_color).weight(Weight::BOLD), + ); + } + let mut text_layout = TextLayout::new(); + text_layout.set_text(&self.text, attrs_list, None); + self.text_layout = Some(text_layout); + + if let Some(new_text) = self.available_text.as_ref() { + let new_text_len = new_text.len(); + + let mut attrs = + Attrs::new().color(self.style.color().unwrap_or(Color::BLACK)); + if let Some(font_size) = self.style.font_size() { + attrs = attrs.font_size(font_size); + } + let font_family = self.style.font_family().as_ref().map(|font_family| { + let family: Vec = + FamilyOwned::parse_list(font_family).collect(); + family + }); + if let Some(font_family) = font_family.as_ref() { + attrs = attrs.family(font_family); + } + + let mut attrs_list = AttrsList::new(attrs.clone()); + + for &i_start in &self.focus_indices { + if i_start + 3 > new_text_len { + break; + } + let i_end = self + .text + .char_indices() + .find(|(i, _)| *i == i_start) + .map(|(_, c)| c.len_utf8() + i_start); + let i_end = if let Some(i_end) = i_end { + i_end + } else { + continue; + }; + attrs_list.add_span( + i_start..i_end, + attrs.clone().color(self.focus_color).weight(Weight::BOLD), + ); + } + let mut text_layout = TextLayout::new(); + text_layout.set_text(new_text, attrs_list, None); + self.available_text_layout = Some(text_layout); + } + } +} + +impl View for FocusText { + fn id(&self) -> ViewId { + self.id + } + + fn update( + &mut self, + _cx: &mut floem::context::UpdateCx, + state: Box, + ) { + if let Ok(state) = state.downcast() { + match *state { + FocusTextState::Text(text) => { + self.text = text; + } + FocusTextState::FocusColor(color) => { + self.focus_color = color; + } + FocusTextState::FocusIndices(indices) => { + self.focus_indices = indices; + } + } + self.set_text_layout(); + self.id.request_layout(); + } + } + + fn style_pass(&mut self, cx: &mut floem::context::StyleCx<'_>) { + if self.style.read(cx) { + self.set_text_layout(); + self.id.request_layout(); + } + } + + fn layout( + &mut self, + cx: &mut floem::context::LayoutCx, + ) -> floem::taffy::prelude::NodeId { + cx.layout_node(self.id, true, |_cx| { + if self.text_layout.is_none() { + self.set_text_layout(); + } + + let text_layout = self.text_layout.as_ref().unwrap(); + let size = text_layout.size(); + let width = size.width.ceil() as f32; + let height = size.height as f32; + + if self.text_node.is_none() { + self.text_node = Some(self.id.new_taffy_node()); + } + let text_node = self.text_node.unwrap(); + + let style = Style::new().width(width).height(height).to_taffy_style(); + self.id.set_taffy_style(text_node, style); + vec![text_node] + }) + } + + fn compute_layout( + &mut self, + _cx: &mut floem::context::ComputeLayoutCx, + ) -> Option { + let text_node = self.text_node.unwrap(); + let layout = self.id.taffy_layout(text_node).unwrap_or_default(); + let text_layout = self.text_layout.as_ref().unwrap(); + let width = text_layout.size().width as f32; + if width > layout.size.width { + if self.available_width != Some(layout.size.width) { + let mut dots_text = TextLayout::new(); + let mut attrs = Attrs::new().color( + self.style + .color() + .unwrap_or_else(|| Color::from_rgb8(0xf0, 0xf0, 0xea)), + ); + if let Some(font_size) = self.style.font_size() { + attrs = attrs.font_size(font_size); + } + let font_family = + self.style.font_family().as_ref().map(|font_family| { + let family: Vec = + FamilyOwned::parse_list(font_family).collect(); + family + }); + if let Some(font_family) = font_family.as_ref() { + attrs = attrs.family(font_family); + } + dots_text.set_text("...", AttrsList::new(attrs), None); + + let dots_width = dots_text.size().width as f32; + let width_left = layout.size.width - dots_width; + let hit_point = + text_layout.hit_point(Point::new(width_left as f64, 0.0)); + let index = hit_point.index; + + let new_text = if index > 0 { + format!("{}...", &self.text[..index]) + } else { + "".to_string() + }; + self.available_text = Some(new_text); + self.available_width = Some(layout.size.width); + self.set_text_layout(); + } + } else { + self.available_text = None; + self.available_width = None; + self.available_text_layout = None; + } + + None + } + + fn paint(&mut self, cx: &mut floem::context::PaintCx) { + let text_node = self.text_node.unwrap(); + let location = self.id.taffy_layout(text_node).unwrap_or_default().location; + let point = Point::new(location.x as f64, location.y as f64); + if let Some(text_layout) = self.available_text_layout.as_ref() { + cx.draw_text(text_layout, point); + } else { + cx.draw_text(self.text_layout.as_ref().unwrap(), point); + } + } +} diff --git a/lapce-app/src/global_search.rs b/lapce-app/src/global_search.rs new file mode 100644 index 0000000..557bf28 --- /dev/null +++ b/lapce-app/src/global_search.rs @@ -0,0 +1,200 @@ +use std::{ops::Range, path::PathBuf, rc::Rc}; + +use floem::{ + ext_event::create_ext_action, + keyboard::Modifiers, + reactive::{Memo, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, + views::VirtualVector, +}; +use indexmap::IndexMap; +use lapce_core::{mode::Mode, selection::Selection}; +use lapce_rpc::proxy::{ProxyResponse, SearchMatch}; +use lapce_xi_rope::Rope; + +use crate::{ + command::{CommandExecuted, CommandKind}, + editor::EditorData, + keypress::{KeyPressFocus, condition::Condition}, + main_split::MainSplitData, + window_tab::CommonData, +}; + +#[derive(Clone)] +pub struct SearchMatchData { + pub expanded: RwSignal, + pub matches: RwSignal>, + pub line_height: Memo, +} + +impl SearchMatchData { + pub fn height(&self) -> f64 { + let line_height = self.line_height.get(); + let count = if self.expanded.get() { + self.matches.with(|m| m.len()) + 1 + } else { + 1 + }; + line_height * count as f64 + } +} + +#[derive(Clone, Debug)] +pub struct GlobalSearchData { + pub editor: EditorData, + pub search_result: RwSignal>, + pub main_split: MainSplitData, + pub common: Rc, +} + +impl KeyPressFocus for GlobalSearchData { + fn get_mode(&self) -> Mode { + Mode::Insert + } + + fn check_condition(&self, condition: Condition) -> bool { + matches!(condition, Condition::PanelFocus) + } + + fn run_command( + &self, + command: &crate::command::LapceCommand, + count: Option, + mods: Modifiers, + ) -> CommandExecuted { + match &command.kind { + CommandKind::Workbench(_) => {} + CommandKind::Scroll(_) => {} + CommandKind::Focus(_) => {} + CommandKind::Edit(_) + | CommandKind::Move(_) + | CommandKind::MultiSelection(_) => { + return self.editor.run_command(command, count, mods); + } + CommandKind::MotionMode(_) => {} + } + CommandExecuted::No + } + + fn receive_char(&self, c: &str) { + self.editor.receive_char(c); + } +} + +impl VirtualVector<(PathBuf, SearchMatchData)> for GlobalSearchData { + fn total_len(&self) -> usize { + self.search_result.with(|result| { + result + .iter() + .map(|(_, data)| { + if data.expanded.get() { + data.matches.with(|m| m.len()) + 1 + } else { + 1 + } + }) + .sum() + }) + } + + fn slice( + &mut self, + _range: Range, + ) -> impl Iterator { + self.search_result.get().into_iter() + } +} + +impl GlobalSearchData { + pub fn new(cx: Scope, main_split: MainSplitData) -> Self { + let common = main_split.common.clone(); + let editor = main_split.editors.make_local(cx, common.clone()); + let search_result = cx.create_rw_signal(IndexMap::new()); + + let global_search = Self { + editor, + search_result, + main_split, + common, + }; + + { + let global_search = global_search.clone(); + let buffer = global_search.editor.doc().buffer; + cx.create_effect(move |_| { + let pattern = buffer.with(|buffer| buffer.to_string()); + if pattern.is_empty() { + global_search.search_result.update(|r| r.clear()); + return; + } + let case_sensitive = global_search.common.find.case_sensitive(true); + let whole_word = global_search.common.find.whole_words.get(); + let is_regex = global_search.common.find.is_regex.get(); + let send = { + let global_search = global_search.clone(); + create_ext_action(cx, move |result| { + if let Ok(ProxyResponse::GlobalSearchResponse { matches }) = + result + { + global_search.update_matches(matches); + } + }) + }; + global_search.common.proxy.global_search( + pattern, + case_sensitive, + whole_word, + is_regex, + move |result| { + send(result); + }, + ); + }); + } + + { + let buffer = global_search.editor.doc().buffer; + let main_split = global_search.main_split.clone(); + cx.create_effect(move |_| { + let content = buffer.with(|buffer| buffer.to_string()); + main_split.set_find_pattern(Some(content)); + }); + } + + global_search + } + + fn update_matches(&self, matches: IndexMap>) { + let current = self.search_result.get_untracked(); + + self.search_result.set( + matches + .into_iter() + .map(|(path, matches)| { + let match_data = + current.get(&path).cloned().unwrap_or_else(|| { + SearchMatchData { + expanded: self.common.scope.create_rw_signal(true), + matches: self + .common + .scope + .create_rw_signal(im::Vector::new()), + line_height: self.common.ui_line_height, + } + }); + + match_data.matches.set(matches.into()); + + (path, match_data) + }) + .collect(), + ); + } + + pub fn set_pattern(&self, pattern: String) { + let pattern_len = pattern.len(); + self.editor.doc().reload(Rope::from(pattern), true); + self.editor + .cursor() + .update(|cursor| cursor.set_insert(Selection::region(0, pattern_len))); + } +} diff --git a/lapce-app/src/history.rs b/lapce-app/src/history.rs new file mode 100644 index 0000000..36125f5 --- /dev/null +++ b/lapce-app/src/history.rs @@ -0,0 +1,26 @@ +use std::path::PathBuf; + +use lapce_core::buffer::Buffer; + +#[derive(Clone)] +pub struct DocumentHistory { + pub buffer: Buffer, + // path: PathBuf, + // version: String, + // styles: Arc>, + // line_styles: Rc>, + // text_layouts: Rc>, +} + +impl DocumentHistory { + pub fn new(_path: PathBuf, _version: String, content: &str) -> Self { + Self { + buffer: Buffer::new(content), + // path, + // version, + // styles: Arc::new(Spans::default()), + // line_styles: Rc::new(RefCell::new(LineStyles::new())), + // text_layouts: Rc::new(RefCell::new(TextLayoutCache::new())), + } + } +} diff --git a/lapce-app/src/hover.rs b/lapce-app/src/hover.rs new file mode 100644 index 0000000..67a2641 --- /dev/null +++ b/lapce-app/src/hover.rs @@ -0,0 +1,28 @@ +use floem::{ + peniko::kurbo::Rect, + reactive::{RwSignal, Scope}, + views::editor::id::EditorId, +}; + +use crate::markdown::MarkdownContent; + +#[derive(Clone)] +pub struct HoverData { + pub active: RwSignal, + pub offset: RwSignal, + pub editor_id: RwSignal, + pub content: RwSignal>, + pub layout_rect: RwSignal, +} + +impl HoverData { + pub fn new(cx: Scope) -> Self { + Self { + active: cx.create_rw_signal(false), + offset: cx.create_rw_signal(0), + content: cx.create_rw_signal(Vec::new()), + editor_id: cx.create_rw_signal(EditorId::next()), + layout_rect: cx.create_rw_signal(Rect::ZERO), + } + } +} diff --git a/lapce-app/src/id.rs b/lapce-app/src/id.rs new file mode 100644 index 0000000..87011d4 --- /dev/null +++ b/lapce-app/src/id.rs @@ -0,0 +1,11 @@ +use floem::views::editor::id::Id; + +pub type SplitId = Id; +pub type WindowTabId = Id; +pub type EditorTabId = Id; +pub type SettingsId = Id; +pub type KeymapId = Id; +pub type ThemeColorSettingsId = Id; +pub type VoltViewId = Id; +pub type DiffEditorId = Id; +pub type TerminalTabId = Id; diff --git a/lapce-app/src/inline_completion.rs b/lapce-app/src/inline_completion.rs new file mode 100644 index 0000000..9482771 --- /dev/null +++ b/lapce-app/src/inline_completion.rs @@ -0,0 +1,288 @@ +use std::{borrow::Cow, ops::Range, path::PathBuf, str::FromStr}; + +use floem::reactive::{RwSignal, Scope, SignalGet, SignalUpdate, SignalWith, batch}; +use lapce_core::{ + buffer::{ + Buffer, + rope_text::{RopeText, RopeTextRef}, + }, + rope_text_pos::RopeTextPosition, + selection::Selection, +}; +use lsp_types::InsertTextFormat; + +use crate::{config::LapceConfig, doc::Doc, editor::EditorData, snippet::Snippet}; + +// TODO: we could integrate completion lens with this, so it is considered at the same time + +/// Redefinition of lsp types inline completion item with offset range +#[derive(Debug, Clone)] +pub struct InlineCompletionItem { + /// The text to replace the range with. + pub insert_text: String, + /// Text used to decide if this inline completion should be shown. + pub filter_text: Option, + /// The range (of offsets) to replace + pub range: Option>, + pub command: Option, + pub insert_text_format: Option, +} +impl InlineCompletionItem { + pub fn from_lsp(buffer: &Buffer, item: lsp_types::InlineCompletionItem) -> Self { + let range = item.range.map(|r| { + let start = buffer.offset_of_position(&r.start); + let end = buffer.offset_of_position(&r.end); + start..end + }); + Self { + insert_text: item.insert_text, + filter_text: item.filter_text, + range, + command: item.command, + insert_text_format: item.insert_text_format, + } + } + + pub fn apply( + &self, + editor: &EditorData, + start_offset: usize, + ) -> anyhow::Result<()> { + let text_format = self + .insert_text_format + .unwrap_or(InsertTextFormat::PLAIN_TEXT); + + let selection = if let Some(range) = &self.range { + Selection::region(range.start, range.end) + } else { + Selection::caret(start_offset) + }; + + match text_format { + InsertTextFormat::PLAIN_TEXT => editor.do_edit( + &selection, + &[(selection.clone(), self.insert_text.as_str())], + ), + InsertTextFormat::SNIPPET => { + editor.completion_apply_snippet( + &self.insert_text, + &selection, + Vec::new(), + start_offset, + )?; + } + _ => { + // We don't know how to support this text format + } + } + + Ok(()) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum InlineCompletionStatus { + /// The inline completion is not active. + Inactive, + /// The inline completion is active and is waiting for the server to respond. + Started, + /// The inline completion is active and has received a response from the server. + Active, +} + +#[derive(Clone)] +pub struct InlineCompletionData { + pub status: InlineCompletionStatus, + /// The active inline completion index in the list of completions. + pub active: RwSignal, + pub items: im::Vector, + pub start_offset: usize, + pub path: PathBuf, +} +impl InlineCompletionData { + pub fn new(cx: Scope) -> Self { + Self { + status: InlineCompletionStatus::Inactive, + active: cx.create_rw_signal(0), + items: im::vector![], + start_offset: 0, + path: PathBuf::new(), + } + } + + pub fn current_item(&self) -> Option<&InlineCompletionItem> { + let active = self.active.get_untracked(); + self.items.get(active) + } + + pub fn next(&mut self) { + if !self.items.is_empty() { + let next_index = (self.active.get_untracked() + 1) % self.items.len(); + self.active.set(next_index); + } + } + + pub fn previous(&mut self) { + if !self.items.is_empty() { + let prev_index = if self.active.get_untracked() == 0 { + self.items.len() - 1 + } else { + self.active.get_untracked() - 1 + }; + self.active.set(prev_index); + } + } + + pub fn cancel(&mut self) { + if self.status == InlineCompletionStatus::Inactive { + return; + } + + self.items.clear(); + self.status = InlineCompletionStatus::Inactive; + } + + /// Set the items for the inline completion. + /// Sets `active` to `0` and `status` to `InlineCompletionStatus::Active`. + pub fn set_items( + &mut self, + items: im::Vector, + start_offset: usize, + path: PathBuf, + ) { + batch(|| { + self.items = items; + self.active.set(0); + self.status = InlineCompletionStatus::Active; + self.start_offset = start_offset; + self.path = path; + }); + } + + pub fn update_doc(&self, doc: &Doc, offset: usize) { + if self.status != InlineCompletionStatus::Active { + doc.clear_inline_completion(); + return; + } + + if self.items.is_empty() { + doc.clear_inline_completion(); + return; + } + + let active = self.active.get_untracked(); + let active = if active >= self.items.len() { + self.active.set(0); + 0 + } else { + active + }; + + let item = &self.items[active]; + let text = item.insert_text.clone(); + + // TODO: is range really meant to be used for this? + let offset = item.range.as_ref().map(|r| r.start).unwrap_or(offset); + let (line, col) = doc + .buffer + .with_untracked(|buffer| buffer.offset_to_line_col(offset)); + doc.set_inline_completion(text, line, col); + } + + pub fn update_inline_completion( + &self, + config: &LapceConfig, + doc: &Doc, + cursor_offset: usize, + ) { + if !config.editor.enable_inline_completion { + doc.clear_inline_completion(); + return; + } + + let text = doc.buffer.with_untracked(|buffer| buffer.text().clone()); + let text = RopeTextRef::new(&text); + let Some(item) = self.current_item() else { + // TODO(minor): should we cancel completion + return; + }; + + let completion = doc.inline_completion.with_untracked(|cur| { + let cur = cur.as_deref(); + inline_completion_text(text, self.start_offset, cursor_offset, item, cur) + }); + + match completion { + ICompletionRes::Hide => { + doc.clear_inline_completion(); + } + ICompletionRes::Unchanged => {} + ICompletionRes::Set(new, shift) => { + let offset = self.start_offset + shift; + let (line, col) = text.offset_to_line_col(offset); + doc.set_inline_completion(new, line, col); + } + } + } +} + +enum ICompletionRes { + Hide, + Unchanged, + Set(String, usize), +} + +/// Get the text of the inline completion item +fn inline_completion_text( + rope_text: impl RopeText, + start_offset: usize, + cursor_offset: usize, + item: &InlineCompletionItem, + current_completion: Option<&str>, +) -> ICompletionRes { + let text_format = item + .insert_text_format + .unwrap_or(InsertTextFormat::PLAIN_TEXT); + + // TODO: is this check correct? I mostly copied it from completion lens + let cursor_prev_offset = rope_text.prev_code_boundary(cursor_offset); + if let Some(range) = &item.range { + let edit_start = range.start; + + // If the start of the edit isn't where the cursor currently is, and is not at the start of + // the inline completion, then we ignore it. + if cursor_prev_offset != edit_start && start_offset != edit_start { + return ICompletionRes::Hide; + } + } + + let text = match text_format { + InsertTextFormat::PLAIN_TEXT => Cow::Borrowed(&item.insert_text), + InsertTextFormat::SNIPPET => { + let Ok(snippet) = Snippet::from_str(&item.insert_text) else { + return ICompletionRes::Hide; + }; + let text = snippet.text(); + + Cow::Owned(text) + } + _ => { + // We don't know how to support this text format + return ICompletionRes::Hide; + } + }; + + let range = start_offset..rope_text.offset_line_end(start_offset, true); + let prefix = rope_text.slice_to_cow(range); + // We strip the prefix of the current input from the label. + // So that, for example `p` with a completion of `println` will show `rintln`. + let Some(text) = text.strip_prefix(prefix.as_ref()) else { + return ICompletionRes::Hide; + }; + + if Some(text) == current_completion { + ICompletionRes::Unchanged + } else { + ICompletionRes::Set(text.to_string(), prefix.len()) + } +} diff --git a/lapce-app/src/keymap.rs b/lapce-app/src/keymap.rs new file mode 100644 index 0000000..f89639b --- /dev/null +++ b/lapce-app/src/keymap.rs @@ -0,0 +1,562 @@ +use std::{rc::Rc, sync::Arc}; + +use floem::{ + View, + event::{Event, EventListener}, + reactive::{ + Memo, ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith, + create_effect, create_memo, create_rw_signal, + }, + style::CursorStyle, + views::{ + Decorators, container, dyn_stack, label, scroll, stack, text, virtual_stack, + }, +}; +use lapce_core::mode::Modes; + +use crate::{ + command::LapceCommand, + config::{LapceConfig, color::LapceColor}, + keypress::{ + KeyPressData, + keymap::{KeyMap, KeyMapPress}, + }, + main_split::Editors, + text_input::TextInputBuilder, + window_tab::CommonData, +}; + +#[derive(Clone)] +pub struct KeymapPicker { + cmd: RwSignal>, + keymap: RwSignal>, + keys: RwSignal>, +} + +pub fn keymap_view(editors: Editors, common: Rc) -> impl View { + let config = common.config; + let keypress = common.keypress; + let ui_line_height_memo = common.ui_line_height; + let ui_line_height = move || ui_line_height_memo.get() * 1.2; + let modal = create_memo(move |_| config.get().core.modal); + let picker = KeymapPicker { + cmd: create_rw_signal(None), + keymap: create_rw_signal(None), + keys: create_rw_signal(Vec::new()), + }; + + let cx = Scope::current(); + let text_input_view = TextInputBuilder::new().build(cx, editors, common.clone()); + let doc = text_input_view.doc_signal(); + + let items = move || { + let doc = doc.get(); + let pattern = doc.buffer.with(|b| b.to_string().to_lowercase()); + let keypress = keypress.get(); + let mut items = keypress + .commands_with_keymap + .iter() + .filter_map(|keymap| { + let cmd = keypress.commands.get(&keymap.command).cloned()?; + + let cmd_name_contains_pattern = + cmd.kind.str().replace('_', " ").contains(&pattern); + let cmd_desc_contains_pattern = cmd + .kind + .desc() + .map(|desc| desc.to_lowercase().contains(&pattern)) + .unwrap_or(false); + let shortcut_contains_pattern = keymap + .key + .iter() + .any(|k| k.label().trim().to_lowercase().contains(&pattern)); + let when_contains_pattern = keymap + .when + .as_ref() + .map(|when| when.to_lowercase().contains(&pattern)) + .unwrap_or(false); + + if cmd_name_contains_pattern + || cmd_desc_contains_pattern + || shortcut_contains_pattern + || when_contains_pattern + { + Some((cmd, Some(keymap.clone()))) + } else { + None + } + }) + .collect::)>>(); + items.extend(keypress.commands_without_keymap.iter().filter_map(|cmd| { + let match_pattern = cmd.kind.str().replace('_', " ").contains(&pattern) + || cmd + .kind + .desc() + .map(|desc| desc.to_lowercase().contains(&pattern)) + .unwrap_or(false); + if !match_pattern { + return None; + } + Some((cmd.clone(), None)) + })); + items + .into_iter() + .enumerate() + .collect::))>>() + }; + + let view_fn = + move |(i, (cmd, keymap)): (usize, (LapceCommand, Option))| { + let local_keymap = keymap.clone(); + let local_cmd = cmd.clone(); + stack(( + container( + text( + cmd.kind + .desc() + .map(|desc| desc.to_string()) + .unwrap_or_else(|| cmd.kind.str().replace('_', " ")), + ) + .style(|s| { + s.text_ellipsis() + .absolute() + .items_center() + .min_width(0.0) + .padding_horiz(10.0) + .size_pct(100.0, 100.0) + }), + ) + .style(move |s| { + s.height_pct(100.0) + .min_width(0.0) + .flex_basis(0.0) + .flex_grow(1.0) + .border_right(1.0) + .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + }), + { + let keymap = keymap.clone(); + dyn_stack( + move || { + keymap + .as_ref() + .map(|keymap| { + keymap + .key + .iter() + .map(|key| key.label()) + .filter(|l| !l.is_empty()) + .collect::>() + }) + .unwrap_or_default() + }, + |k| k.clone(), + move |key| { + text(key.clone()).style(move |s| { + s.padding_horiz(5.0) + .padding_vert(1.0) + .margin_right(5.0) + .border(1.0) + .border_radius(3.0) + .border_color( + config.get().color(LapceColor::LAPCE_BORDER), + ) + }) + }, + ) + .style(move |s| { + s.items_center() + .padding_horiz(10.0) + .min_width(200.0) + .height_pct(100.0) + .border_right(1.0) + .border_color( + config.get().color(LapceColor::LAPCE_BORDER), + ) + }) + }, + { + let keymap = keymap.clone(); + let bits = [ + (Modes::INSERT, "Insert"), + (Modes::NORMAL, "Normal"), + (Modes::VISUAL, "Visual"), + (Modes::TERMINAL, "Terminal"), + ]; + let modes = keymap + .as_ref() + .map(|keymap| { + bits.iter() + .filter_map(|(bit, mode)| { + if keymap.modes.contains(*bit) { + Some(mode.to_string()) + } else { + None + } + }) + .collect::>() + }) + .unwrap_or_default(); + dyn_stack( + move || modes.clone(), + |m| m.clone(), + move |mode| { + text(mode.clone()).style(move |s| { + s.padding_horiz(5.0) + .padding_vert(1.0) + .margin_right(5.0) + .border(1.0) + .border_radius(3.0) + .border_color( + config.get().color(LapceColor::LAPCE_BORDER), + ) + }) + }, + ) + .style(move |s| { + s.items_center() + .padding_horiz(10.0) + .min_width(200.0) + .height_pct(100.0) + .border_right(1.0) + .border_color( + config.get().color(LapceColor::LAPCE_BORDER), + ) + .apply_if(!modal.get(), |s| s.hide()) + }) + }, + container( + text( + keymap + .as_ref() + .and_then(|keymap| keymap.when.clone()) + .unwrap_or_default(), + ) + .style(|s| { + s.text_ellipsis() + .absolute() + .items_center() + .min_width(0.0) + .padding_horiz(10.0) + .size_pct(100.0, 100.0) + }), + ) + .style(move |s| { + s.height_pct(100.0) + .min_width(0.0) + .flex_basis(0.0) + .flex_grow(1.0) + }), + )) + .on_click_stop(move |_| { + let keymap = if let Some(keymap) = local_keymap.clone() { + keymap + } else { + KeyMap { + command: local_cmd.kind.str().to_string(), + key: Vec::new(), + modes: Modes::empty(), + when: None, + } + }; + picker.keymap.set(Some(keymap)); + picker.cmd.set(Some(local_cmd.clone())); + picker.keys.update(|keys| { + keys.clear(); + }); + }) + .style(move |s| { + let config = config.get(); + s.items_center() + .height(ui_line_height() as f32) + .width_pct(100.0) + .apply_if(i % 2 > 0, |s| { + s.background(config.color(LapceColor::EDITOR_CURRENT_LINE)) + }) + .border_bottom(1.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + }) + }; + + stack(( + container( + text_input_view + .placeholder(|| "Search Key Bindings".to_string()) + .keyboard_navigable() + .request_focus(|| {}) + .style(move |s| { + s.width_pct(100.0) + .border_radius(6.0) + .border(1.0) + .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + }), + ) + .style(|s| s.padding_bottom(10.0).width_pct(100.0)), + stack(( + container(text("Command").style(move |s| { + s.text_ellipsis().padding_horiz(10.0).min_width(0.0) + })) + .style(move |s| { + s.items_center() + .height_pct(100.0) + .min_width(0.0) + .flex_basis(0.0) + .flex_grow(1.0) + .border_right(1.0) + .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + }), + text("Key Binding").style(move |s| { + s.width(200.0) + .items_center() + .padding_horiz(10.0) + .height_pct(100.0) + .border_right(1.0) + .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + }), + text("Modes").style(move |s| { + s.width(200.0) + .items_center() + .padding_horiz(10.0) + .height_pct(100.0) + .border_right(1.0) + .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + .apply_if(!modal.get(), |s| s.hide()) + }), + container(text("When").style(move |s| { + s.text_ellipsis().padding_horiz(10.0).min_width(0.0) + })) + .style(move |s| { + s.items_center() + .height_pct(100.0) + .min_width(0.0) + .flex_basis(0.0) + .flex_grow(1.0) + }), + )) + .style(move |s| { + let config = config.get(); + s.font_bold() + .height(ui_line_height() as f32) + .width_pct(100.0) + .border_top(1.0) + .border_bottom(1.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .background(config.color(LapceColor::EDITOR_CURRENT_LINE)) + }), + container( + scroll( + virtual_stack( + items, + |(i, (cmd, keymap)): &( + usize, + (LapceCommand, Option), + )| { (*i, cmd.kind.str(), keymap.clone()) }, + view_fn, + ) + .item_size_fixed(ui_line_height) + .style(|s| s.flex_col().width_pct(100.0)), + ) + .style(|s| s.absolute().size_pct(100.0, 100.0)), + ) + .style(|s| s.width_pct(100.0).flex_basis(0.0).flex_grow(1.0)), + keyboard_picker_view(picker, common.ui_line_height, config), + )) + .style(|s| { + s.absolute() + .size_pct(100.0, 100.0) + .flex_col() + .padding_top(20.0) + .padding_left(20.0) + .padding_right(20.0) + }) +} + +fn keyboard_picker_view( + picker: KeymapPicker, + ui_line_height: Memo, + config: ReadSignal>, +) -> impl View { + let picker_cmd = picker.cmd; + let view = container( + stack(( + label(move || { + picker_cmd.with(|cmd| { + cmd.as_ref() + .map(|cmd| { + cmd.kind + .desc() + .map(|desc| desc.to_string()) + .unwrap_or_else(|| cmd.kind.str().replace('_', " ")) + }) + .unwrap_or_default() + }) + }), + dyn_stack( + move || { + picker + .keys + .get() + .iter() + .map(|(key, _)| key.label()) + .filter(|l| !l.is_empty()) + .enumerate() + .collect::>() + }, + |(i, k)| (*i, k.clone()), + move |(_, key)| { + text(key.clone()).style(move |s| { + s.padding_horiz(5.0) + .padding_vert(1.0) + .margin_right(5.0) + .height(ui_line_height.get() as f32) + .border(1.0) + .border_radius(6.0) + .border_color( + config.get().color(LapceColor::LAPCE_BORDER), + ) + }) + }, + ) + .style(move |s| { + let config = config.get(); + s.items_center() + .justify_center() + .width_pct(100.0) + .margin_top(20.0) + .height((ui_line_height.get() as f32) * 1.2) + .border(1.0) + .border_radius(6.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .background(config.color(LapceColor::EDITOR_BACKGROUND)) + }), + stack(( + text("Save") + .style(move |s| { + let config = config.get(); + s.width(100.0) + .justify_center() + .padding_vert(8.0) + .border(1.0) + .border_radius(6.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .hover(|s| { + s.cursor(CursorStyle::Pointer).background( + config + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + }) + .active(|s| { + s.background(config.color( + LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND, + )) + }) + }) + .on_click_stop(move |_| { + let keymap = picker.keymap.get_untracked(); + if let Some(keymap) = keymap { + let keys = picker.keys.get_untracked(); + picker.keymap.set(None); + KeyPressData::update_file( + &keymap, + &keys + .iter() + .map(|(key, _)| key.clone()) + .collect::>(), + ); + } + }), + text("Cancel") + .style(move |s| { + let config = config.get(); + s.margin_left(20.0) + .width(100.0) + .justify_center() + .padding_vert(8.0) + .border(1.0) + .border_radius(6.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .hover(|s| { + s.cursor(CursorStyle::Pointer).background( + config + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + }) + .active(|s| { + s.background(config.color( + LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND, + )) + }) + }) + .on_click_stop(move |_| { + picker.keymap.set(None); + }), + )) + .style(move |s| { + let config = config.get(); + s.items_center() + .justify_center() + .width_pct(100.0) + .margin_top(20.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + }), + )) + .on_event_stop(EventListener::PointerDown, |_| {}) + .style(move |s| { + let config = config.get(); + s.items_center() + .flex_col() + .padding(20.0) + .width(400.0) + .border(1.0) + .border_radius(6.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .background(config.color(LapceColor::PANEL_BACKGROUND)) + }), + ) + .keyboard_navigable() + .on_event_stop(EventListener::KeyDown, move |event| { + if let Event::KeyDown(key_event) = event { + if let Some(keypress) = KeyPressData::keypress(key_event) { + if let Some(keypress) = keypress.keymap_press() { + picker.keys.update(|keys| { + if let Some((last_key, last_key_confirmed)) = keys.last() { + if !*last_key_confirmed && last_key.is_modifiers() { + keys.pop(); + } + } + if keys.len() == 2 { + keys.clear(); + } + keys.push((keypress, false)); + }) + } + } + } + }) + .on_event_stop(EventListener::KeyUp, move |event| { + if let Event::KeyUp(_key_event) = event { + picker.keys.update(|keys| { + if let Some((_last_key, last_key_confirmed)) = keys.last_mut() { + *last_key_confirmed = true; + } + }) + } + }) + .style(move |s| { + s.absolute() + .size_pct(100.0, 100.0) + .items_center() + .justify_center() + .apply_if(picker.keymap.with(|keymap| keymap.is_none()), |s| s.hide()) + }) + .debug_name("keyboard picker"); + + let id = view.id(); + create_effect(move |_| { + if picker.keymap.with(|k| k.is_some()) { + id.request_focus(); + } + }); + + view +} diff --git a/lapce-app/src/keypress.rs b/lapce-app/src/keypress.rs new file mode 100644 index 0000000..7dc0b09 --- /dev/null +++ b/lapce-app/src/keypress.rs @@ -0,0 +1,701 @@ +pub mod condition; +mod key; +pub mod keymap; +mod loader; +mod press; + +use std::{path::PathBuf, rc::Rc, str::FromStr, time::SystemTime}; + +use anyhow::Result; +use floem::{ + keyboard::{Key, KeyEvent, KeyEventExtModifierSupplement, Modifiers, NamedKey}, + pointer::{MouseButton, PointerButton, PointerInputEvent}, + reactive::{RwSignal, Scope, SignalUpdate, SignalWith}, +}; +use indexmap::IndexMap; +use itertools::Itertools; +use lapce_core::mode::{Mode, Modes}; + +pub use self::press::KeyPress; +use self::{ + key::KeyInput, + keymap::{KeyMap, KeyMapPress}, + loader::KeyMapLoader, +}; +use crate::{ + command::{CommandExecuted, CommandKind, LapceCommand, lapce_internal_commands}, + config::LapceConfig, + keypress::{ + condition::{CheckCondition, Condition}, + keymap::KeymapMatch, + }, + tracing::*, +}; + +const DEFAULT_KEYMAPS_COMMON: &str = + include_str!("../../defaults/keymaps-common.toml"); +const DEFAULT_KEYMAPS_MACOS: &str = + include_str!("../../defaults/keymaps-macos.toml"); +const DEFAULT_KEYMAPS_NONMACOS: &str = + include_str!("../../defaults/keymaps-nonmacos.toml"); + +pub trait KeyPressFocus: std::fmt::Debug { + fn get_mode(&self) -> Mode; + + fn check_condition(&self, condition: Condition) -> bool; + + fn run_command( + &self, + command: &LapceCommand, + count: Option, + mods: Modifiers, + ) -> CommandExecuted; + + fn expect_char(&self) -> bool { + false + } + + fn focus_only(&self) -> bool { + false + } + + fn receive_char(&self, c: &str); +} +impl KeyPressFocus for () { + fn get_mode(&self) -> Mode { + Mode::Normal + } + + fn check_condition(&self, _condition: Condition) -> bool { + false + } + + fn run_command( + &self, + _command: &LapceCommand, + _count: Option, + _mods: Modifiers, + ) -> CommandExecuted { + CommandExecuted::No + } + + fn expect_char(&self) -> bool { + false + } + + fn focus_only(&self) -> bool { + false + } + + fn receive_char(&self, _c: &str) {} +} +impl KeyPressFocus for Box { + fn get_mode(&self) -> Mode { + (**self).get_mode() + } + + fn check_condition(&self, condition: Condition) -> bool { + (**self).check_condition(condition) + } + + fn run_command( + &self, + command: &LapceCommand, + count: Option, + mods: Modifiers, + ) -> CommandExecuted { + (**self).run_command(command, count, mods) + } + + fn expect_char(&self) -> bool { + (**self).expect_char() + } + + fn focus_only(&self) -> bool { + (**self).focus_only() + } + + fn receive_char(&self, c: &str) { + (**self).receive_char(c) + } +} + +#[derive(Clone, Copy, Debug)] +pub enum EventRef<'a> { + Keyboard(&'a floem::keyboard::KeyEvent), + Pointer(&'a floem::pointer::PointerInputEvent), +} + +impl<'a> From<&'a KeyEvent> for EventRef<'a> { + fn from(ev: &'a KeyEvent) -> Self { + Self::Keyboard(ev) + } +} + +impl<'a> From<&'a PointerInputEvent> for EventRef<'a> { + fn from(ev: &'a PointerInputEvent) -> Self { + Self::Pointer(ev) + } +} + +pub struct KeyPressHandle { + pub handled: bool, + pub keypress: KeyPress, + pub keymatch: KeymapMatch, +} + +#[derive(Clone, Debug)] +pub struct KeyPressData { + count: RwSignal>, + pending_keypress: RwSignal<(Vec, Option)>, + pub commands: Rc>, + pub keymaps: Rc, Vec>>, + pub command_keymaps: Rc>>, + pub commands_with_keymap: Rc>, + pub commands_without_keymap: Rc>, +} + +impl KeyPressData { + pub fn new(cx: Scope, config: &LapceConfig) -> Self { + let (keymaps, command_keymaps) = + Self::get_keymaps(config).unwrap_or((IndexMap::new(), IndexMap::new())); + let mut keypress = Self { + count: cx.create_rw_signal(None), + pending_keypress: cx.create_rw_signal((Vec::new(), None)), + keymaps: Rc::new(keymaps), + command_keymaps: Rc::new(command_keymaps), + commands: Rc::new(lapce_internal_commands()), + commands_with_keymap: Rc::new(Vec::new()), + commands_without_keymap: Rc::new(Vec::new()), + }; + keypress.load_commands(); + keypress + } + + pub fn update_keymaps(&mut self, config: &LapceConfig) { + if let Ok((new_keymaps, new_command_keymaps)) = Self::get_keymaps(config) { + self.keymaps = Rc::new(new_keymaps); + self.command_keymaps = Rc::new(new_command_keymaps); + self.load_commands(); + } + } + + fn load_commands(&mut self) { + let mut commands_with_keymap = Vec::new(); + let mut commands_without_keymap = Vec::new(); + for (_, keymaps) in self.command_keymaps.iter() { + for keymap in keymaps.iter() { + if self.commands.get(&keymap.command).is_some() { + commands_with_keymap.push(keymap.clone()); + } + } + } + + for (_, cmd) in self.commands.iter() { + if self + .command_keymaps + .get(cmd.kind.str()) + .map(|x| x.is_empty()) + .unwrap_or(true) + { + commands_without_keymap.push(cmd.clone()); + } + } + + self.commands_with_keymap = Rc::new(commands_with_keymap); + self.commands_without_keymap = Rc::new(commands_without_keymap); + } + + fn handle_count( + &self, + focus: &T, + keypress: &KeyPress, + ) -> bool { + if focus.expect_char() { + return false; + } + let mode = focus.get_mode(); + if mode == Mode::Insert || mode == Mode::Terminal { + return false; + } + + if !keypress.mods.is_empty() { + return false; + } + + if let KeyInput::Keyboard { + logical: Key::Character(c), + .. + } = &keypress.key + { + if let Ok(n) = c.parse::() { + if self.count.with_untracked(|count| count.is_some()) || n > 0 { + self.count + .update(|count| *count = Some(count.unwrap_or(0) * 10 + n)); + return true; + } + } + } + + false + } + + fn run_command( + &self, + command: &str, + count: Option, + mods: Modifiers, + focus: &T, + ) -> CommandExecuted { + if let Some(cmd) = self.commands.get(command) { + focus.run_command(cmd, count, mods) + } else { + CommandExecuted::No + } + } + + pub fn keypress<'a>(event: impl Into>) -> Option { + let event = event.into(); + + let keypress = match event { + EventRef::Keyboard(ev) => KeyPress { + key: KeyInput::Keyboard { + logical: ev.key.logical_key.to_owned(), + physical: ev.key.physical_key, + key_without_modifiers: ev.key.key_without_modifiers(), + location: ev.key.location, + repeat: ev.key.repeat, + }, + mods: Self::get_key_modifiers(ev), + }, + EventRef::Pointer(ev) => KeyPress { + key: KeyInput::Pointer(ev.button), + mods: ev.modifiers, + }, + }; + Some(keypress) + } + + pub fn key_down<'a, T: KeyPressFocus + ?Sized>( + &self, + event: impl Into>, + focus: &T, + ) -> KeyPressHandle { + let keypress = match Self::keypress(event) { + Some(keypress) => keypress, + None => { + return KeyPressHandle { + handled: false, + keymatch: KeymapMatch::None, + keypress: KeyPress { + key: KeyInput::Pointer(PointerButton::Mouse( + MouseButton::Primary, + )), + mods: Modifiers::empty(), + }, + }; + } + }; + + if self.handle_count(focus, &keypress) { + return KeyPressHandle { + handled: true, + keymatch: KeymapMatch::None, + keypress, + }; + } + + self.pending_keypress + .update(|(pending_keypress, last_time)| { + let last_time = last_time.replace(SystemTime::now()); + if let Some(last_time_val) = last_time { + if last_time_val + .elapsed() + .map(|x| x.as_millis() > 1000) + .unwrap_or_default() + { + pending_keypress.clear(); + } + } + pending_keypress.push(keypress.clone()); + }); + + let keymatch = + self.pending_keypress + .with_untracked(|(pending_keypress, _)| { + self.match_keymap(pending_keypress, focus) + }); + self.handle_keymatch(focus, keymatch, keypress) + } + + pub fn handle_keymatch( + &self, + focus: &T, + keymatch: KeymapMatch, + keypress: KeyPress, + ) -> KeyPressHandle { + let mods = keypress.mods; + match &keymatch { + KeymapMatch::Full(command) => { + self.pending_keypress + .update(|(pending_keypress, last_time)| { + last_time.take(); + pending_keypress.clear(); + }); + let count = self.count.try_update(|count| count.take()).unwrap(); + let handled = self.run_command(command, count, mods, focus) + == CommandExecuted::Yes; + return KeyPressHandle { + handled, + keymatch, + keypress, + }; + } + KeymapMatch::Multiple(commands) => { + self.pending_keypress + .update(|(pending_keypress, last_time)| { + last_time.take(); + pending_keypress.clear(); + }); + let count = self.count.try_update(|count| count.take()).unwrap(); + for command in commands { + let handled = self.run_command(command, count, mods, focus) + == CommandExecuted::Yes; + if handled { + return KeyPressHandle { + handled, + keymatch, + keypress, + }; + } + } + + return KeyPressHandle { + handled: false, + keymatch, + keypress, + }; + } + KeymapMatch::Prefix => { + // Here pending_keypress contains only a prefix of some keymap, so let's keep + // collecting key presses. + return KeyPressHandle { + handled: true, + keymatch, + keypress, + }; + } + KeymapMatch::None => { + self.pending_keypress + .update(|(pending_keypress, last_time)| { + pending_keypress.clear(); + last_time.take(); + }); + if focus.get_mode() == Mode::Insert { + let old_keypress = keypress.clone(); + let mut keypress = keypress.clone(); + keypress.mods.set(Modifiers::SHIFT, false); + if let KeymapMatch::Full(command) = + self.match_keymap(&[keypress], focus) + { + if let Some(cmd) = self.commands.get(&command) { + if let CommandKind::Move(_) = cmd.kind { + let handled = focus.run_command(cmd, None, mods) + == CommandExecuted::Yes; + return KeyPressHandle { + handled, + keymatch, + keypress: old_keypress, + }; + } + } + } + } + } + } + + let mut mods = keypress.mods; + + #[cfg(target_os = "macos")] + { + mods.set(Modifiers::SHIFT, false); + mods.set(Modifiers::ALT, false); + } + #[cfg(not(target_os = "macos"))] + { + mods.set(Modifiers::SHIFT, false); + mods.set(Modifiers::ALTGR, false); + } + if mods.is_empty() { + if let KeyInput::Keyboard { logical, .. } = &keypress.key { + if let Key::Character(c) = logical { + focus.receive_char(c); + self.count.set(None); + return KeyPressHandle { + handled: true, + keymatch, + keypress, + }; + } else if let Key::Named(NamedKey::Space) = logical { + focus.receive_char(" "); + self.count.set(None); + return KeyPressHandle { + handled: true, + keymatch, + keypress, + }; + } + } + } + + KeyPressHandle { + handled: false, + keymatch, + keypress, + } + } + + fn get_key_modifiers(key_event: &KeyEvent) -> Modifiers { + let mut mods = key_event.modifiers; + + match &key_event.key.logical_key { + Key::Named(NamedKey::Shift) => mods.set(Modifiers::SHIFT, false), + Key::Named(NamedKey::Alt) => mods.set(Modifiers::ALT, false), + Key::Named(NamedKey::Meta) => mods.set(Modifiers::META, false), + Key::Named(NamedKey::Control) => mods.set(Modifiers::CONTROL, false), + Key::Named(NamedKey::AltGraph) => mods.set(Modifiers::ALTGR, false), + _ => (), + } + + mods + } + + fn match_keymap( + &self, + keypresses: &[KeyPress], + check: &T, + ) -> KeymapMatch { + let keypresses: Vec = + keypresses.iter().filter_map(|k| k.keymap_press()).collect(); + let matches: Vec<_> = self + .keymaps + .get(&keypresses) + .map(|keymaps| { + keymaps + .iter() + .filter(|keymap| { + if check.expect_char() + && keypresses.len() == 1 + && keypresses[0].is_char() + { + return false; + } + if !keymap.modes.is_empty() + && !keymap.modes.contains(check.get_mode().into()) + { + return false; + } + if let Some(condition) = &keymap.when { + if !Self::check_condition(condition, check) { + return false; + } + } + true + }) + .collect() + }) + .unwrap_or_default(); + + if matches.is_empty() { + KeymapMatch::None + } else if matches.len() == 1 && matches[0].key == keypresses { + KeymapMatch::Full(matches[0].command.clone()) + } else if matches.len() > 1 + && matches.iter().filter(|m| m.key != keypresses).count() == 0 + { + KeymapMatch::Multiple( + matches.iter().rev().map(|m| m.command.clone()).collect(), + ) + } else { + KeymapMatch::Prefix + } + } + + fn check_condition( + condition: &str, + check: &T, + ) -> bool { + fn check_one_condition( + condition: &str, + check: &T, + ) -> bool { + let trimmed = condition.trim(); + if let Some(stripped) = trimmed.strip_prefix('!') { + if let Ok(condition) = Condition::from_str(stripped) { + !check.check_condition(condition) + } else { + true + } + } else if let Ok(condition) = Condition::from_str(trimmed) { + check.check_condition(condition) + } else { + false + } + } + + match CheckCondition::parse_first(condition) { + CheckCondition::Single(condition) => { + check_one_condition(condition, check) + } + CheckCondition::Or(left, right) => { + let left = check_one_condition(left, check); + let right = Self::check_condition(right, check); + + left || right + } + CheckCondition::And(left, right) => { + let left = check_one_condition(left, check); + let right = Self::check_condition(right, check); + + left && right + } + } + } + + #[allow(clippy::type_complexity)] + fn get_keymaps( + config: &LapceConfig, + ) -> Result<( + IndexMap, Vec>, + IndexMap>, + )> { + let is_modal = config.core.modal; + + let mut loader = KeyMapLoader::new(); + + if let Err(err) = loader.load_from_str(DEFAULT_KEYMAPS_COMMON, is_modal) { + trace!(TraceLevel::ERROR, "Failed to load common defaults: {err}"); + } + + let os_keymaps = if std::env::consts::OS == "macos" { + DEFAULT_KEYMAPS_MACOS + } else { + DEFAULT_KEYMAPS_NONMACOS + }; + + if let Err(err) = loader.load_from_str(os_keymaps, is_modal) { + trace!(TraceLevel::ERROR, "Failed to load OS defaults: {err}"); + } + + if let Some(path) = Self::file() { + if let Ok(content) = std::fs::read_to_string(&path) { + if let Err(err) = loader.load_from_str(&content, is_modal) { + trace!(TraceLevel::WARN, "Failed to load from {path:?}: {err}"); + } + } + } + + Ok(loader.finalize()) + } + + pub fn file() -> Option { + LapceConfig::keymaps_file() + } + + fn get_file_array() -> Option { + let path = Self::file()?; + let content = std::fs::read_to_string(path).ok()?; + let document: toml_edit::Document = content.parse().ok()?; + document + .as_table() + .get("keymaps")? + .as_array_of_tables() + .cloned() + } + + pub fn update_file(keymap: &KeyMap, keys: &[KeyMapPress]) -> Option<()> { + let mut array = Self::get_file_array().unwrap_or_default(); + let index = array.iter().position(|value| { + Some(keymap.command.as_str()) + == value.get("command").and_then(|c| c.as_str()) + && keymap.when.as_deref() + == value.get("when").and_then(|w| w.as_str()) + && keymap.modes == get_modes(value) + && Some(keymap.key.clone()) + == value + .get("key") + .and_then(|v| v.as_str()) + .map(KeyMapPress::parse) + }); + + if let Some(index) = index { + if !keys.is_empty() { + array.get_mut(index)?.insert( + "key", + toml_edit::value(toml_edit::Value::from(keys.iter().join(" "))), + ); + } else { + array.remove(index); + }; + } else { + let mut table = toml_edit::Table::new(); + table.insert( + "command", + toml_edit::value(toml_edit::Value::from(keymap.command.clone())), + ); + if !keymap.modes.is_empty() { + table.insert( + "mode", + toml_edit::value(toml_edit::Value::from( + keymap.modes.to_string(), + )), + ); + } + if let Some(when) = keymap.when.as_ref() { + table.insert( + "when", + toml_edit::value(toml_edit::Value::from(when.to_string())), + ); + } + + if !keys.is_empty() { + table.insert( + "key", + toml_edit::value(toml_edit::Value::from(keys.iter().join(" "))), + ); + array.push(table.clone()); + } + + if !keymap.key.is_empty() { + table.insert( + "key", + toml_edit::value(toml_edit::Value::from( + keymap.key.iter().join(" "), + )), + ); + table.insert( + "command", + toml_edit::value(toml_edit::Value::from(format!( + "-{}", + keymap.command + ))), + ); + array.push(table.clone()); + } + } + + let mut table = toml_edit::Document::new(); + table.insert("keymaps", toml_edit::Item::ArrayOfTables(array)); + let path = Self::file()?; + std::fs::write(path, table.to_string().as_bytes()).ok()?; + None + } +} + +fn get_modes(toml_keymap: &toml_edit::Table) -> Modes { + toml_keymap + .get("mode") + .and_then(|v| v.as_str()) + .map(Modes::parse) + .unwrap_or_else(Modes::empty) +} diff --git a/lapce-app/src/keypress/condition.rs b/lapce-app/src/keypress/condition.rs new file mode 100644 index 0000000..c1f8d18 --- /dev/null +++ b/lapce-app/src/keypress/condition.rs @@ -0,0 +1,162 @@ +use strum_macros::EnumString; + +#[derive(Debug, PartialEq, Eq)] +pub(super) enum CheckCondition<'a> { + Single(&'a str), + Or(&'a str, &'a str), + And(&'a str, &'a str), +} + +impl<'a> CheckCondition<'a> { + pub(super) fn parse_first(condition: &'a str) -> Self { + let or = condition.match_indices("||").next(); + let and = condition.match_indices("&&").next(); + + match (or, and) { + (None, None) => CheckCondition::Single(condition), + (Some((pos, _)), None) => { + CheckCondition::Or(&condition[..pos], &condition[pos + 2..]) + } + (None, Some((pos, _))) => { + CheckCondition::And(&condition[..pos], &condition[pos + 2..]) + } + (Some((or_pos, _)), Some((and_pos, _))) => { + if or_pos < and_pos { + CheckCondition::Or( + &condition[..or_pos], + &condition[or_pos + 2..], + ) + } else { + CheckCondition::And( + &condition[..and_pos], + &condition[and_pos + 2..], + ) + } + } + } + } +} + +#[derive(Clone, Copy, Debug, EnumString, PartialEq, Eq)] +pub enum Condition { + #[strum(serialize = "editor_focus")] + EditorFocus, + #[strum(serialize = "input_focus")] + InputFocus, + #[strum(serialize = "list_focus")] + ListFocus, + #[strum(serialize = "palette_focus")] + PaletteFocus, + #[strum(serialize = "completion_focus")] + CompletionFocus, + #[strum(serialize = "inline_completion_visible")] + InlineCompletionVisible, + #[strum(serialize = "modal_focus")] + ModalFocus, + #[strum(serialize = "in_snippet")] + InSnippet, + #[strum(serialize = "terminal_focus")] + TerminalFocus, + #[strum(serialize = "source_control_focus")] + SourceControlFocus, + #[strum(serialize = "panel_focus")] + PanelFocus, + #[strum(serialize = "rename_focus")] + RenameFocus, + #[strum(serialize = "search_active")] + SearchActive, + #[strum(serialize = "on_screen_find_active")] + OnScreenFindActive, + #[strum(serialize = "search_focus")] + SearchFocus, + #[strum(serialize = "replace_focus")] + ReplaceFocus, +} + +#[cfg(test)] +mod test { + use floem::keyboard::Modifiers; + use lapce_core::mode::Mode; + + use super::Condition; + use crate::keypress::{KeyPressData, KeyPressFocus, condition::CheckCondition}; + + #[derive(Clone, Copy, Debug)] + struct MockFocus { + accepted_conditions: &'static [Condition], + } + + impl KeyPressFocus for MockFocus { + fn check_condition(&self, condition: Condition) -> bool { + self.accepted_conditions.contains(&condition) + } + + fn get_mode(&self) -> Mode { + unimplemented!() + } + + fn run_command( + &self, + _command: &crate::command::LapceCommand, + _count: Option, + _mods: Modifiers, + ) -> crate::command::CommandExecuted { + unimplemented!() + } + + fn receive_char(&self, _c: &str) { + unimplemented!() + } + } + + #[test] + fn test_parse() { + assert_eq!( + CheckCondition::Or("foo", "bar"), + CheckCondition::parse_first("foo||bar") + ); + assert_eq!( + CheckCondition::And("foo", "bar"), + CheckCondition::parse_first("foo&&bar") + ); + assert_eq!( + CheckCondition::And("foo", "bar||baz"), + CheckCondition::parse_first("foo&&bar||baz") + ); + assert_eq!( + CheckCondition::And("foo ", " bar || baz"), + CheckCondition::parse_first("foo && bar || baz") + ); + } + + #[test] + fn test_check_condition() { + let focus = MockFocus { + accepted_conditions: &[Condition::EditorFocus, Condition::ListFocus], + }; + + let test_cases = [ + ("editor_focus", true), + ("list_focus", true), + ("!editor_focus", false), + ("!list_focus", false), + ("editor_focus || list_focus", true), + ("editor_focus || !list_focus", true), + ("!editor_focus || list_focus", true), + ("editor_focus && list_focus", true), + ("editor_focus && !list_focus", false), + ("!editor_focus && list_focus", false), + ("editor_focus && list_focus || baz", true), + ("editor_focus && list_focus && baz", false), + ("editor_focus && list_focus && !baz", true), + ]; + + for (condition, should_accept) in test_cases.into_iter() { + assert_eq!( + should_accept, + KeyPressData::check_condition(condition, &focus), + "Condition check failed. Condition: {condition}. Expected result: {should_accept}", + ); + } + } +} diff --git a/lapce-app/src/keypress/key.rs b/lapce-app/src/keypress/key.rs new file mode 100644 index 0000000..a78a413 --- /dev/null +++ b/lapce-app/src/keypress/key.rs @@ -0,0 +1,74 @@ +use floem::keyboard::{Key, KeyLocation, NamedKey, PhysicalKey}; + +use super::keymap::KeyMapKey; + +#[derive(Clone, Debug)] +pub(crate) enum KeyInput { + Keyboard { + physical: PhysicalKey, + logical: Key, + location: KeyLocation, + key_without_modifiers: Key, + repeat: bool, + }, + Pointer(floem::pointer::PointerButton), +} + +impl KeyInput { + pub fn keymap_key(&self) -> Option { + if let KeyInput::Keyboard { + repeat, logical, .. + } = self + { + if *repeat + && (matches!( + logical, + Key::Named(NamedKey::Meta) + | Key::Named(NamedKey::Shift) + | Key::Named(NamedKey::Alt) + | Key::Named(NamedKey::Control), + )) + { + return None; + } + } + + Some(match self { + KeyInput::Pointer(b) => KeyMapKey::Pointer(*b), + KeyInput::Keyboard { + physical, + key_without_modifiers, + logical, + location, + .. + } => { + #[allow(clippy::single_match)] + match location { + KeyLocation::Numpad => { + return Some(KeyMapKey::Logical(logical.to_owned())); + } + _ => {} + } + + match key_without_modifiers { + Key::Named(_) => { + KeyMapKey::Logical(key_without_modifiers.to_owned()) + } + Key::Character(c) => { + if c == " " { + KeyMapKey::Logical(Key::Named(NamedKey::Space)) + } else if c.len() == 1 && c.is_ascii() { + KeyMapKey::Logical(Key::Character( + c.to_lowercase().into(), + )) + } else { + KeyMapKey::Physical(*physical) + } + } + Key::Unidentified(_) => KeyMapKey::Physical(*physical), + Key::Dead(_) => KeyMapKey::Physical(*physical), + } + } + }) + } +} diff --git a/lapce-app/src/keypress/keymap.rs b/lapce-app/src/keypress/keymap.rs new file mode 100644 index 0000000..da3401d --- /dev/null +++ b/lapce-app/src/keypress/keymap.rs @@ -0,0 +1,707 @@ +use std::{fmt::Display, str::FromStr}; + +use floem::{ + keyboard::{Key, KeyCode, Modifiers, NamedKey, PhysicalKey}, + pointer::{MouseButton, PointerButton}, +}; +use lapce_core::mode::Modes; + +#[derive(PartialEq, Debug, Clone)] +pub enum KeymapMatch { + Full(String), + Multiple(Vec), + Prefix, + None, +} + +#[derive(PartialEq, Eq, Hash, Clone, Debug)] +pub struct KeyMap { + pub key: Vec, + pub modes: Modes, + pub when: Option, + pub command: String, +} + +#[derive(PartialEq, Eq, Clone, Debug)] +pub enum KeyMapKey { + Pointer(PointerButton), + Logical(Key), + Physical(PhysicalKey), +} + +impl std::hash::Hash for KeyMapKey { + fn hash(&self, state: &mut H) { + match self { + Self::Pointer(btn) => (btn.mouse_button() as u8).hash(state), + Self::Logical(key) => key.hash(state), + Self::Physical(physical) => physical.hash(state), + } + } +} + +#[derive(PartialEq, Eq, Hash, Clone, Debug)] +pub struct KeyMapPress { + pub key: KeyMapKey, + pub mods: Modifiers, +} + +impl KeyMapPress { + pub fn is_char(&self) -> bool { + let mut mods = self.mods; + mods.set(Modifiers::SHIFT, false); + if mods.is_empty() { + if let KeyMapKey::Logical(Key::Character(_)) = &self.key { + return true; + } + } + false + } + + pub fn is_modifiers(&self) -> bool { + if let KeyMapKey::Physical(physical) = &self.key { + matches!( + physical, + PhysicalKey::Code(KeyCode::Meta) + | PhysicalKey::Code(KeyCode::SuperLeft) + | PhysicalKey::Code(KeyCode::SuperRight) + | PhysicalKey::Code(KeyCode::ShiftLeft) + | PhysicalKey::Code(KeyCode::ShiftRight) + | PhysicalKey::Code(KeyCode::ControlLeft) + | PhysicalKey::Code(KeyCode::ControlRight) + | PhysicalKey::Code(KeyCode::AltLeft) + | PhysicalKey::Code(KeyCode::AltRight) + ) + } else if let KeyMapKey::Logical(Key::Named(key)) = &self.key { + matches!( + key, + NamedKey::Meta + | NamedKey::Super + | NamedKey::Shift + | NamedKey::Control + | NamedKey::Alt + | NamedKey::AltGraph + ) + } else { + false + } + } + + pub fn label(&self) -> String { + let mut keys = String::from(""); + if self.mods.control() { + keys.push_str("Ctrl+"); + } + if self.mods.alt() { + keys.push_str("Alt+"); + } + if self.mods.altgr() { + keys.push_str("AltGr+"); + } + if self.mods.meta() { + let keyname = match std::env::consts::OS { + "macos" => "Cmd+", + "windows" => "Win+", + _ => "Meta+", + }; + keys.push_str(keyname); + } + if self.mods.shift() { + keys.push_str("Shift+"); + } + keys.push_str(&self.key.to_string()); + keys + } + + pub fn parse(key: &str) -> Vec { + key.split(' ') + .filter_map(|k| { + let (modifiers, key) = if k == "+" { + ("", "+") + } else if let Some(remaining) = k.strip_suffix("++") { + (remaining, "+") + } else { + match k.rsplit_once('+') { + Some(pair) => pair, + None => ("", k), + } + }; + + let key = match key.parse().ok() { + Some(key) => key, + None => { + // Skip past unrecognized key definitions + tracing::warn!("Unrecognized key: {key}"); + return None; + } + }; + + let mut mods = Modifiers::empty(); + for part in modifiers.to_lowercase().split('+') { + match part { + "ctrl" => mods.set(Modifiers::CONTROL, true), + "meta" => mods.set(Modifiers::META, true), + "shift" => mods.set(Modifiers::SHIFT, true), + "alt" => mods.set(Modifiers::ALT, true), + "altgr" => mods.set(Modifiers::ALTGR, true), + "" => (), + other => tracing::warn!("Invalid key modifier: {}", other), + } + } + + Some(KeyMapPress { key, mods }) + }) + .collect() + } +} + +impl FromStr for KeyMapKey { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + let key = if s.starts_with('[') && s.ends_with(']') { + let code = match s[1..s.len() - 2].to_lowercase().as_str() { + "esc" => KeyCode::Escape, + "space" => KeyCode::Space, + "bs" => KeyCode::Backspace, + "up" => KeyCode::ArrowUp, + "down" => KeyCode::ArrowDown, + "left" => KeyCode::ArrowLeft, + "right" => KeyCode::ArrowRight, + "del" => KeyCode::Delete, + "alt" => KeyCode::AltLeft, + "altgraph" => KeyCode::AltRight, + "capslock" => KeyCode::CapsLock, + "control" => KeyCode::ControlLeft, + "fn" => KeyCode::Fn, + "fnlock" => KeyCode::FnLock, + "meta" => KeyCode::Meta, + "numlock" => KeyCode::NumLock, + "scrolllock" => KeyCode::ScrollLock, + "shift" => KeyCode::ShiftLeft, + "hyper" => KeyCode::Hyper, + "super" => KeyCode::Meta, + "enter" => KeyCode::Enter, + "tab" => KeyCode::Tab, + "arrowdown" => KeyCode::ArrowDown, + "arrowleft" => KeyCode::ArrowLeft, + "arrowright" => KeyCode::ArrowRight, + "arrowup" => KeyCode::ArrowUp, + "end" => KeyCode::End, + "home" => KeyCode::Home, + "pagedown" => KeyCode::PageDown, + "pageup" => KeyCode::PageUp, + "backspace" => KeyCode::Backspace, + "copy" => KeyCode::Copy, + "cut" => KeyCode::Cut, + "delete" => KeyCode::Delete, + "insert" => KeyCode::Insert, + "paste" => KeyCode::Paste, + "undo" => KeyCode::Undo, + "again" => KeyCode::Again, + "contextmenu" => KeyCode::ContextMenu, + "escape" => KeyCode::Escape, + "find" => KeyCode::Find, + "help" => KeyCode::Help, + "pause" => KeyCode::Pause, + "play" => KeyCode::MediaPlayPause, + "props" => KeyCode::Props, + "select" => KeyCode::Select, + "eject" => KeyCode::Eject, + "power" => KeyCode::Power, + "printscreen" => KeyCode::PrintScreen, + "wakeup" => KeyCode::WakeUp, + "convert" => KeyCode::Convert, + "nonconvert" => KeyCode::NonConvert, + "hiragana" => KeyCode::Hiragana, + "katakana" => KeyCode::Katakana, + "f1" => KeyCode::F1, + "f2" => KeyCode::F2, + "f3" => KeyCode::F3, + "f4" => KeyCode::F4, + "f5" => KeyCode::F5, + "f6" => KeyCode::F6, + "f7" => KeyCode::F7, + "f8" => KeyCode::F8, + "f9" => KeyCode::F9, + "f10" => KeyCode::F10, + "f11" => KeyCode::F11, + "f12" => KeyCode::F12, + "mediastop" => KeyCode::MediaStop, + "open" => KeyCode::Open, + _ => { + return Err(anyhow::anyhow!( + "unrecognized physical key code {}", + &s[1..s.len() - 2] + )); + } + }; + KeyMapKey::Physical(PhysicalKey::Code(code)) + } else { + let key = match s.to_lowercase().as_str() { + "esc" => Key::Named(NamedKey::Escape), + "space" => Key::Named(NamedKey::Space), + "bs" => Key::Named(NamedKey::Backspace), + "up" => Key::Named(NamedKey::ArrowUp), + "down" => Key::Named(NamedKey::ArrowDown), + "left" => Key::Named(NamedKey::ArrowLeft), + "right" => Key::Named(NamedKey::ArrowRight), + "del" => Key::Named(NamedKey::Delete), + "alt" => Key::Named(NamedKey::Alt), + "altgraph" => Key::Named(NamedKey::AltGraph), + "capslock" => Key::Named(NamedKey::CapsLock), + "control" => Key::Named(NamedKey::Control), + "fn" => Key::Named(NamedKey::Fn), + "fnlock" => Key::Named(NamedKey::FnLock), + "meta" => Key::Named(NamedKey::Meta), + "numlock" => Key::Named(NamedKey::NumLock), + "scrolllock" => Key::Named(NamedKey::ScrollLock), + "shift" => Key::Named(NamedKey::Shift), + "hyper" => Key::Named(NamedKey::Hyper), + "super" => Key::Named(NamedKey::Meta), + "enter" => Key::Named(NamedKey::Enter), + "tab" => Key::Named(NamedKey::Tab), + "arrowdown" => Key::Named(NamedKey::ArrowDown), + "arrowleft" => Key::Named(NamedKey::ArrowLeft), + "arrowright" => Key::Named(NamedKey::ArrowRight), + "arrowup" => Key::Named(NamedKey::ArrowUp), + "end" => Key::Named(NamedKey::End), + "home" => Key::Named(NamedKey::Home), + "pagedown" => Key::Named(NamedKey::PageDown), + "pageup" => Key::Named(NamedKey::PageUp), + "backspace" => Key::Named(NamedKey::Backspace), + "copy" => Key::Named(NamedKey::Copy), + "cut" => Key::Named(NamedKey::Cut), + "delete" => Key::Named(NamedKey::Delete), + "insert" => Key::Named(NamedKey::Insert), + "paste" => Key::Named(NamedKey::Paste), + "undo" => Key::Named(NamedKey::Undo), + "again" => Key::Named(NamedKey::Again), + "contextmenu" => Key::Named(NamedKey::ContextMenu), + "escape" => Key::Named(NamedKey::Escape), + "find" => Key::Named(NamedKey::Find), + "help" => Key::Named(NamedKey::Help), + "pause" => Key::Named(NamedKey::Pause), + "play" => Key::Named(NamedKey::MediaPlayPause), + "props" => Key::Named(NamedKey::Props), + "select" => Key::Named(NamedKey::Select), + "eject" => Key::Named(NamedKey::Eject), + "power" => Key::Named(NamedKey::Power), + "printscreen" => Key::Named(NamedKey::PrintScreen), + "wakeup" => Key::Named(NamedKey::WakeUp), + "convert" => Key::Named(NamedKey::Convert), + "nonconvert" => Key::Named(NamedKey::NonConvert), + "hiragana" => Key::Named(NamedKey::Hiragana), + "katakana" => Key::Named(NamedKey::Katakana), + "f1" => Key::Named(NamedKey::F1), + "f2" => Key::Named(NamedKey::F2), + "f3" => Key::Named(NamedKey::F3), + "f4" => Key::Named(NamedKey::F4), + "f5" => Key::Named(NamedKey::F5), + "f6" => Key::Named(NamedKey::F6), + "f7" => Key::Named(NamedKey::F7), + "f8" => Key::Named(NamedKey::F8), + "f9" => Key::Named(NamedKey::F9), + "f10" => Key::Named(NamedKey::F10), + "f11" => Key::Named(NamedKey::F11), + "f12" => Key::Named(NamedKey::F12), + "mediastop" => Key::Named(NamedKey::MediaStop), + "open" => Key::Named(NamedKey::Open), + _ => Key::Character(s.to_lowercase().into()), + }; + KeyMapKey::Logical(key) + }; + Ok(key) + } +} + +impl Display for KeyMapPress { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if self.mods.contains(Modifiers::CONTROL) { + if let Err(err) = f.write_str("Ctrl+") { + tracing::error!("{:?}", err); + } + } + if self.mods.contains(Modifiers::ALT) { + if let Err(err) = f.write_str("Alt+") { + tracing::error!("{:?}", err); + } + } + if self.mods.contains(Modifiers::ALTGR) { + if let Err(err) = f.write_str("AltGr+") { + tracing::error!("{:?}", err); + } + } + if self.mods.contains(Modifiers::META) { + if let Err(err) = f.write_str("Meta+") { + tracing::error!("{:?}", err); + } + } + if self.mods.contains(Modifiers::SHIFT) { + if let Err(err) = f.write_str("Shift+") { + tracing::error!("{:?}", err); + } + } + f.write_str(&self.key.to_string()) + } +} + +impl Display for KeyMapKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + use floem::pointer::PointerButton as B; + + match self { + Self::Physical(physical) => { + f.write_str("[")?; + match physical { + PhysicalKey::Unidentified(_) => f.write_str("Unidentified"), + PhysicalKey::Code(KeyCode::Backquote) => { + f.write_str("Backquote") + } + PhysicalKey::Code(KeyCode::Backslash) => { + f.write_str("Backslash") + } + PhysicalKey::Code(KeyCode::BracketLeft) => { + f.write_str("BracketLeft") + } + PhysicalKey::Code(KeyCode::BracketRight) => { + f.write_str("BracketRight") + } + PhysicalKey::Code(KeyCode::Comma) => f.write_str("Comma"), + PhysicalKey::Code(KeyCode::Digit0) => f.write_str("0"), + PhysicalKey::Code(KeyCode::Digit1) => f.write_str("1"), + PhysicalKey::Code(KeyCode::Digit2) => f.write_str("2"), + PhysicalKey::Code(KeyCode::Digit3) => f.write_str("3"), + PhysicalKey::Code(KeyCode::Digit4) => f.write_str("4"), + PhysicalKey::Code(KeyCode::Digit5) => f.write_str("5"), + PhysicalKey::Code(KeyCode::Digit6) => f.write_str("6"), + PhysicalKey::Code(KeyCode::Digit7) => f.write_str("7"), + PhysicalKey::Code(KeyCode::Digit8) => f.write_str("8"), + PhysicalKey::Code(KeyCode::Digit9) => f.write_str("9"), + PhysicalKey::Code(KeyCode::Equal) => f.write_str("Equal"), + PhysicalKey::Code(KeyCode::IntlBackslash) => { + f.write_str("IntlBackslash") + } + PhysicalKey::Code(KeyCode::IntlRo) => f.write_str("IntlRo"), + PhysicalKey::Code(KeyCode::IntlYen) => f.write_str("IntlYen"), + PhysicalKey::Code(KeyCode::KeyA) => f.write_str("A"), + PhysicalKey::Code(KeyCode::KeyB) => f.write_str("B"), + PhysicalKey::Code(KeyCode::KeyC) => f.write_str("C"), + PhysicalKey::Code(KeyCode::KeyD) => f.write_str("D"), + PhysicalKey::Code(KeyCode::KeyE) => f.write_str("E"), + PhysicalKey::Code(KeyCode::KeyF) => f.write_str("F"), + PhysicalKey::Code(KeyCode::KeyG) => f.write_str("G"), + PhysicalKey::Code(KeyCode::KeyH) => f.write_str("H"), + PhysicalKey::Code(KeyCode::KeyI) => f.write_str("I"), + PhysicalKey::Code(KeyCode::KeyJ) => f.write_str("J"), + PhysicalKey::Code(KeyCode::KeyK) => f.write_str("K"), + PhysicalKey::Code(KeyCode::KeyL) => f.write_str("L"), + PhysicalKey::Code(KeyCode::KeyM) => f.write_str("M"), + PhysicalKey::Code(KeyCode::KeyN) => f.write_str("N"), + PhysicalKey::Code(KeyCode::KeyO) => f.write_str("O"), + PhysicalKey::Code(KeyCode::KeyP) => f.write_str("P"), + PhysicalKey::Code(KeyCode::KeyQ) => f.write_str("Q"), + PhysicalKey::Code(KeyCode::KeyR) => f.write_str("R"), + PhysicalKey::Code(KeyCode::KeyS) => f.write_str("S"), + PhysicalKey::Code(KeyCode::KeyT) => f.write_str("T"), + PhysicalKey::Code(KeyCode::KeyU) => f.write_str("U"), + PhysicalKey::Code(KeyCode::KeyV) => f.write_str("V"), + PhysicalKey::Code(KeyCode::KeyW) => f.write_str("W"), + PhysicalKey::Code(KeyCode::KeyX) => f.write_str("X"), + PhysicalKey::Code(KeyCode::KeyY) => f.write_str("Y"), + PhysicalKey::Code(KeyCode::KeyZ) => f.write_str("Z"), + PhysicalKey::Code(KeyCode::Minus) => f.write_str("Minus"), + PhysicalKey::Code(KeyCode::Period) => f.write_str("Period"), + PhysicalKey::Code(KeyCode::Quote) => f.write_str("Quote"), + PhysicalKey::Code(KeyCode::Semicolon) => { + f.write_str("Semicolon") + } + PhysicalKey::Code(KeyCode::Slash) => f.write_str("Slash"), + PhysicalKey::Code(KeyCode::AltLeft) => f.write_str("Alt"), + PhysicalKey::Code(KeyCode::AltRight) => f.write_str("Alt"), + PhysicalKey::Code(KeyCode::Backspace) => { + f.write_str("Backspace") + } + PhysicalKey::Code(KeyCode::CapsLock) => f.write_str("CapsLock"), + PhysicalKey::Code(KeyCode::ContextMenu) => { + f.write_str("ContextMenu") + } + PhysicalKey::Code(KeyCode::ControlLeft) => f.write_str("Ctrl"), + PhysicalKey::Code(KeyCode::ControlRight) => f.write_str("Ctrl"), + PhysicalKey::Code(KeyCode::Enter) => f.write_str("Enter"), + PhysicalKey::Code(KeyCode::SuperLeft) => f.write_str("Meta"), + PhysicalKey::Code(KeyCode::SuperRight) => f.write_str("Meta"), + PhysicalKey::Code(KeyCode::ShiftLeft) => f.write_str("Shift"), + PhysicalKey::Code(KeyCode::ShiftRight) => f.write_str("Shift"), + PhysicalKey::Code(KeyCode::Space) => f.write_str("Space"), + PhysicalKey::Code(KeyCode::Tab) => f.write_str("Tab"), + PhysicalKey::Code(KeyCode::Convert) => f.write_str("Convert"), + PhysicalKey::Code(KeyCode::KanaMode) => f.write_str("KanaMode"), + PhysicalKey::Code(KeyCode::Lang1) => f.write_str("Lang1"), + PhysicalKey::Code(KeyCode::Lang2) => f.write_str("Lang2"), + PhysicalKey::Code(KeyCode::Lang3) => f.write_str("Lang3"), + PhysicalKey::Code(KeyCode::Lang4) => f.write_str("Lang4"), + PhysicalKey::Code(KeyCode::Lang5) => f.write_str("Lang5"), + PhysicalKey::Code(KeyCode::NonConvert) => { + f.write_str("NonConvert") + } + PhysicalKey::Code(KeyCode::Delete) => f.write_str("Delete"), + PhysicalKey::Code(KeyCode::End) => f.write_str("End"), + PhysicalKey::Code(KeyCode::Help) => f.write_str("Help"), + PhysicalKey::Code(KeyCode::Home) => f.write_str("Home"), + PhysicalKey::Code(KeyCode::Insert) => f.write_str("Insert"), + PhysicalKey::Code(KeyCode::PageDown) => f.write_str("PageDown"), + PhysicalKey::Code(KeyCode::PageUp) => f.write_str("PageUp"), + PhysicalKey::Code(KeyCode::ArrowDown) => f.write_str("Down"), + PhysicalKey::Code(KeyCode::ArrowLeft) => f.write_str("Left"), + PhysicalKey::Code(KeyCode::ArrowRight) => f.write_str("Right"), + PhysicalKey::Code(KeyCode::ArrowUp) => f.write_str("Up"), + PhysicalKey::Code(KeyCode::NumLock) => f.write_str("NumLock"), + PhysicalKey::Code(KeyCode::Numpad0) => f.write_str("Numpad0"), + PhysicalKey::Code(KeyCode::Numpad1) => f.write_str("Numpad1"), + PhysicalKey::Code(KeyCode::Numpad2) => f.write_str("Numpad2"), + PhysicalKey::Code(KeyCode::Numpad3) => f.write_str("Numpad3"), + PhysicalKey::Code(KeyCode::Numpad4) => f.write_str("Numpad4"), + PhysicalKey::Code(KeyCode::Numpad5) => f.write_str("Numpad5"), + PhysicalKey::Code(KeyCode::Numpad6) => f.write_str("Numpad6"), + PhysicalKey::Code(KeyCode::Numpad7) => f.write_str("Numpad7"), + PhysicalKey::Code(KeyCode::Numpad8) => f.write_str("Numpad8"), + PhysicalKey::Code(KeyCode::Numpad9) => f.write_str("Numpad9"), + PhysicalKey::Code(KeyCode::NumpadAdd) => { + f.write_str("NumpadAdd") + } + PhysicalKey::Code(KeyCode::NumpadBackspace) => { + f.write_str("NumpadBackspace") + } + PhysicalKey::Code(KeyCode::NumpadClear) => { + f.write_str("NumpadClear") + } + PhysicalKey::Code(KeyCode::NumpadClearEntry) => { + f.write_str("NumpadClearEntry") + } + PhysicalKey::Code(KeyCode::NumpadComma) => { + f.write_str("NumpadComma") + } + PhysicalKey::Code(KeyCode::NumpadDecimal) => { + f.write_str("NumpadDecimal") + } + PhysicalKey::Code(KeyCode::NumpadDivide) => { + f.write_str("NumpadDivide") + } + PhysicalKey::Code(KeyCode::NumpadEnter) => { + f.write_str("NumpadEnter") + } + PhysicalKey::Code(KeyCode::NumpadEqual) => { + f.write_str("NumpadEqual") + } + PhysicalKey::Code(KeyCode::NumpadHash) => { + f.write_str("NumpadHash") + } + PhysicalKey::Code(KeyCode::NumpadMemoryAdd) => { + f.write_str("NumpadMemoryAdd") + } + PhysicalKey::Code(KeyCode::NumpadMemoryClear) => { + f.write_str("NumpadMemoryClear") + } + PhysicalKey::Code(KeyCode::NumpadMemoryRecall) => { + f.write_str("NumpadMemoryRecall") + } + PhysicalKey::Code(KeyCode::NumpadMemoryStore) => { + f.write_str("NumpadMemoryStore") + } + PhysicalKey::Code(KeyCode::NumpadMemorySubtract) => { + f.write_str("NumpadMemorySubtract") + } + PhysicalKey::Code(KeyCode::NumpadMultiply) => { + f.write_str("NumpadMultiply") + } + PhysicalKey::Code(KeyCode::NumpadParenLeft) => { + f.write_str("NumpadParenLeft") + } + PhysicalKey::Code(KeyCode::NumpadParenRight) => { + f.write_str("NumpadParenRight") + } + PhysicalKey::Code(KeyCode::NumpadStar) => { + f.write_str("NumpadStar") + } + PhysicalKey::Code(KeyCode::NumpadSubtract) => { + f.write_str("NumpadSubtract") + } + PhysicalKey::Code(KeyCode::Escape) => f.write_str("Escape"), + PhysicalKey::Code(KeyCode::Fn) => f.write_str("Fn"), + PhysicalKey::Code(KeyCode::FnLock) => f.write_str("FnLock"), + PhysicalKey::Code(KeyCode::PrintScreen) => { + f.write_str("PrintScreen") + } + PhysicalKey::Code(KeyCode::ScrollLock) => { + f.write_str("ScrollLock") + } + PhysicalKey::Code(KeyCode::Pause) => f.write_str("Pause"), + PhysicalKey::Code(KeyCode::BrowserBack) => { + f.write_str("BrowserBack") + } + PhysicalKey::Code(KeyCode::BrowserFavorites) => { + f.write_str("BrowserFavorites") + } + PhysicalKey::Code(KeyCode::BrowserForward) => { + f.write_str("BrowserForward") + } + PhysicalKey::Code(KeyCode::BrowserHome) => { + f.write_str("BrowserHome") + } + PhysicalKey::Code(KeyCode::BrowserRefresh) => { + f.write_str("BrowserRefresh") + } + PhysicalKey::Code(KeyCode::BrowserSearch) => { + f.write_str("BrowserSearch") + } + PhysicalKey::Code(KeyCode::BrowserStop) => { + f.write_str("BrowserStop") + } + PhysicalKey::Code(KeyCode::Eject) => f.write_str("Eject"), + PhysicalKey::Code(KeyCode::LaunchApp1) => { + f.write_str("LaunchApp1") + } + PhysicalKey::Code(KeyCode::LaunchApp2) => { + f.write_str("LaunchApp2") + } + PhysicalKey::Code(KeyCode::LaunchMail) => { + f.write_str("LaunchMail") + } + PhysicalKey::Code(KeyCode::MediaPlayPause) => { + f.write_str("MediaPlayPause") + } + PhysicalKey::Code(KeyCode::MediaSelect) => { + f.write_str("MediaSelect") + } + PhysicalKey::Code(KeyCode::MediaStop) => { + f.write_str("MediaStop") + } + PhysicalKey::Code(KeyCode::MediaTrackNext) => { + f.write_str("MediaTrackNext") + } + PhysicalKey::Code(KeyCode::MediaTrackPrevious) => { + f.write_str("MediaTrackPrevious") + } + PhysicalKey::Code(KeyCode::Power) => f.write_str("Power"), + PhysicalKey::Code(KeyCode::Sleep) => f.write_str("Sleep"), + PhysicalKey::Code(KeyCode::AudioVolumeDown) => { + f.write_str("AudioVolumeDown") + } + PhysicalKey::Code(KeyCode::AudioVolumeMute) => { + f.write_str("AudioVolumeMute") + } + PhysicalKey::Code(KeyCode::AudioVolumeUp) => { + f.write_str("AudioVolumeUp") + } + PhysicalKey::Code(KeyCode::WakeUp) => f.write_str("WakeUp"), + PhysicalKey::Code(KeyCode::Meta) => match std::env::consts::OS { + "macos" => f.write_str("Cmd"), + "windows" => f.write_str("Win"), + _ => f.write_str("Meta"), + }, + PhysicalKey::Code(KeyCode::Hyper) => f.write_str("Hyper"), + PhysicalKey::Code(KeyCode::Turbo) => f.write_str("Turbo"), + PhysicalKey::Code(KeyCode::Abort) => f.write_str("Abort"), + PhysicalKey::Code(KeyCode::Resume) => f.write_str("Resume"), + PhysicalKey::Code(KeyCode::Suspend) => f.write_str("Suspend"), + PhysicalKey::Code(KeyCode::Again) => f.write_str("Again"), + PhysicalKey::Code(KeyCode::Copy) => f.write_str("Copy"), + PhysicalKey::Code(KeyCode::Cut) => f.write_str("Cut"), + PhysicalKey::Code(KeyCode::Find) => f.write_str("Find"), + PhysicalKey::Code(KeyCode::Open) => f.write_str("Open"), + PhysicalKey::Code(KeyCode::Paste) => f.write_str("Paste"), + PhysicalKey::Code(KeyCode::Props) => f.write_str("Props"), + PhysicalKey::Code(KeyCode::Select) => f.write_str("Select"), + PhysicalKey::Code(KeyCode::Undo) => f.write_str("Undo"), + PhysicalKey::Code(KeyCode::Hiragana) => f.write_str("Hiragana"), + PhysicalKey::Code(KeyCode::Katakana) => f.write_str("Katakana"), + PhysicalKey::Code(KeyCode::F1) => f.write_str("F1"), + PhysicalKey::Code(KeyCode::F2) => f.write_str("F2"), + PhysicalKey::Code(KeyCode::F3) => f.write_str("F3"), + PhysicalKey::Code(KeyCode::F4) => f.write_str("F4"), + PhysicalKey::Code(KeyCode::F5) => f.write_str("F5"), + PhysicalKey::Code(KeyCode::F6) => f.write_str("F6"), + PhysicalKey::Code(KeyCode::F7) => f.write_str("F7"), + PhysicalKey::Code(KeyCode::F8) => f.write_str("F8"), + PhysicalKey::Code(KeyCode::F9) => f.write_str("F9"), + PhysicalKey::Code(KeyCode::F10) => f.write_str("F10"), + PhysicalKey::Code(KeyCode::F11) => f.write_str("F11"), + PhysicalKey::Code(KeyCode::F12) => f.write_str("F12"), + PhysicalKey::Code(KeyCode::F13) => f.write_str("F13"), + PhysicalKey::Code(KeyCode::F14) => f.write_str("F14"), + PhysicalKey::Code(KeyCode::F15) => f.write_str("F15"), + PhysicalKey::Code(KeyCode::F16) => f.write_str("F16"), + PhysicalKey::Code(KeyCode::F17) => f.write_str("F17"), + PhysicalKey::Code(KeyCode::F18) => f.write_str("F18"), + PhysicalKey::Code(KeyCode::F19) => f.write_str("F19"), + PhysicalKey::Code(KeyCode::F20) => f.write_str("F20"), + PhysicalKey::Code(KeyCode::F21) => f.write_str("F21"), + PhysicalKey::Code(KeyCode::F22) => f.write_str("F22"), + PhysicalKey::Code(KeyCode::F23) => f.write_str("F23"), + PhysicalKey::Code(KeyCode::F24) => f.write_str("F24"), + PhysicalKey::Code(KeyCode::F25) => f.write_str("F25"), + PhysicalKey::Code(KeyCode::F26) => f.write_str("F26"), + PhysicalKey::Code(KeyCode::F27) => f.write_str("F27"), + PhysicalKey::Code(KeyCode::F28) => f.write_str("F28"), + PhysicalKey::Code(KeyCode::F29) => f.write_str("F29"), + PhysicalKey::Code(KeyCode::F30) => f.write_str("F30"), + PhysicalKey::Code(KeyCode::F31) => f.write_str("F31"), + PhysicalKey::Code(KeyCode::F32) => f.write_str("F32"), + PhysicalKey::Code(KeyCode::F33) => f.write_str("F33"), + PhysicalKey::Code(KeyCode::F34) => f.write_str("F34"), + PhysicalKey::Code(KeyCode::F35) => f.write_str("F35"), + _ => f.write_str("Unidentified"), + }?; + f.write_str("]") + } + Self::Logical(key) => match key { + Key::Named(key) => match key { + NamedKey::Backspace => f.write_str("Backspace"), + NamedKey::CapsLock => f.write_str("CapsLock"), + NamedKey::Enter => f.write_str("Enter"), + NamedKey::Delete => f.write_str("Delete"), + NamedKey::End => f.write_str("End"), + NamedKey::Home => f.write_str("Home"), + NamedKey::PageDown => f.write_str("PageDown"), + NamedKey::PageUp => f.write_str("PageUp"), + NamedKey::ArrowDown => f.write_str("ArrowDown"), + NamedKey::ArrowUp => f.write_str("ArrowUp"), + NamedKey::ArrowLeft => f.write_str("ArrowLeft"), + NamedKey::ArrowRight => f.write_str("ArrowRight"), + NamedKey::Escape => f.write_str("Escape"), + NamedKey::Fn => f.write_str("Fn"), + NamedKey::Space => f.write_str("Space"), + NamedKey::Shift => f.write_str("Shift"), + NamedKey::Meta => f.write_str("Meta"), + NamedKey::Super => f.write_str("Meta"), + NamedKey::Control => f.write_str("Ctrl"), + NamedKey::Alt => f.write_str("Alt"), + NamedKey::AltGraph => f.write_str("AltGraph"), + NamedKey::Tab => f.write_str("Tab"), + NamedKey::F1 => f.write_str("F1"), + NamedKey::F2 => f.write_str("F2"), + NamedKey::F3 => f.write_str("F3"), + NamedKey::F4 => f.write_str("F4"), + NamedKey::F5 => f.write_str("F5"), + NamedKey::F6 => f.write_str("F6"), + NamedKey::F7 => f.write_str("F7"), + NamedKey::F8 => f.write_str("F8"), + NamedKey::F9 => f.write_str("F9"), + NamedKey::F10 => f.write_str("F10"), + NamedKey::F11 => f.write_str("F11"), + NamedKey::F12 => f.write_str("F12"), + _ => f.write_str("Unidentified"), + }, + Key::Character(s) => f.write_str(s), + Key::Unidentified(_) => f.write_str("Unidentified"), + Key::Dead(_) => f.write_str("dead"), + }, + Self::Pointer(B::Mouse(MouseButton::Auxiliary)) => { + f.write_str("MouseMiddle") + } + Self::Pointer(B::Mouse(MouseButton::X2)) => f.write_str("MouseForward"), + Self::Pointer(B::Mouse(MouseButton::X1)) => f.write_str("MouseBackward"), + Self::Pointer(_) => f.write_str("MouseUnimplemented"), + } + } +} diff --git a/lapce-app/src/keypress/loader.rs b/lapce-app/src/keypress/loader.rs new file mode 100644 index 0000000..3b9ba94 --- /dev/null +++ b/lapce-app/src/keypress/loader.rs @@ -0,0 +1,253 @@ +use anyhow::{Result, anyhow}; +use indexmap::IndexMap; +use lapce_core::mode::Modes; +use tracing::{debug, error}; + +use super::keymap::{KeyMap, KeyMapPress}; + +pub struct KeyMapLoader { + keymaps: IndexMap, Vec>, + command_keymaps: IndexMap>, +} + +impl KeyMapLoader { + pub fn new() -> Self { + Self { + keymaps: Default::default(), + command_keymaps: Default::default(), + } + } + + pub fn load_from_str<'a>( + &'a mut self, + s: &str, + modal: bool, + ) -> Result<&'a mut Self> { + let toml_keymaps: toml_edit::Document = s.parse()?; + let toml_keymaps = toml_keymaps + .get("keymaps") + .and_then(|v| v.as_array_of_tables()) + .ok_or_else(|| anyhow!("no keymaps"))?; + + for toml_keymap in toml_keymaps { + let keymap = match Self::get_keymap(toml_keymap, modal) { + Ok(Some(keymap)) => keymap, + Ok(None) => { + // Keymap ignored + continue; + } + Err(err) => { + error!("Could not parse keymap: {err}"); + continue; + } + }; + + let (command, bind) = match keymap.command.strip_prefix('-') { + Some(cmd) => (cmd.to_string(), false), + None => (keymap.command.clone(), true), + }; + + let current_keymaps = self.command_keymaps.entry(command).or_default(); + if bind { + current_keymaps.push(keymap.clone()); + for i in 1..keymap.key.len() + 1 { + let key = keymap.key[..i].to_vec(); + self.keymaps.entry(key).or_default().push(keymap.clone()); + } + } else { + let is_keymap = |k: &KeyMap| -> bool { + k.when == keymap.when + && k.modes == keymap.modes + && k.key == keymap.key + }; + if let Some(index) = current_keymaps.iter().position(is_keymap) { + current_keymaps.remove(index); + } + for i in 1..keymap.key.len() + 1 { + if let Some(keymaps) = self.keymaps.get_mut(&keymap.key[..i]) { + if let Some(index) = keymaps.iter().position(is_keymap) { + keymaps.remove(index); + } + } + } + } + } + + Ok(self) + } + + #[allow(clippy::type_complexity)] + pub fn finalize( + self, + ) -> ( + IndexMap, Vec>, + IndexMap>, + ) { + let Self { + keymaps: map, + command_keymaps: command_map, + } = self; + + (map, command_map) + } + + fn get_keymap( + toml_keymap: &toml_edit::Table, + modal: bool, + ) -> Result> { + let key = toml_keymap + .get("key") + .and_then(|v| v.as_str()) + .ok_or_else(|| anyhow!("no key in keymap"))?; + + let modes = get_modes(toml_keymap); + // If not using modal editing, remove keymaps that only make sense in modal. + if !modal + && !modes.is_empty() + && !modes.contains(Modes::INSERT) + && !modes.contains(Modes::TERMINAL) + { + debug!("Keymap ignored: {}", key); + return Ok(None); + } + + Ok(Some(KeyMap { + key: KeyMapPress::parse(key), + modes, + when: toml_keymap + .get("when") + .and_then(|w| w.as_str()) + .map(|w| w.to_string()), + command: toml_keymap + .get("command") + .and_then(|c| c.as_str()) + .map(|w| w.trim().to_string()) + .unwrap_or_default(), + })) + } +} + +fn get_modes(toml_keymap: &toml_edit::Table) -> Modes { + toml_keymap + .get("mode") + .and_then(|v| v.as_str()) + .map(Modes::parse) + .unwrap_or_else(Modes::empty) +} + +#[cfg(test)] +mod tests { + use floem::keyboard::Key; + + use super::*; + use crate::keypress::keymap::KeyMapKey; + + #[test] + fn test_keymap() { + let keymaps = r#" +[[keymaps]] +key = "ctrl+w l l" +command = "right" +when = "n" + +[[keymaps]] +key = "ctrl+w l" +command = "right" +when = "n" + +[[keymaps]] +key = "ctrl+w h" +command = "left" +when = "n" + +[[keymaps]] +key = "ctrl+w" +command = "left" +when = "n" + +[[keymaps]] +key = "End" +command = "line_end" +when = "n" + +[[keymaps]] +key = "shift+i" +command = "insert_first_non_blank" +when = "n" + +[[keymaps]] +key = "MouseForward" +command = "jump_location_forward" + +[[keymaps]] +key = "MouseBackward" +command = "jump_location_backward" + +[[keymaps]] +key = "Ctrl+MouseMiddle" +command = "goto_definition" + "#; + let mut loader = KeyMapLoader::new(); + loader.load_from_str(keymaps, true).unwrap(); + + let (keymaps, _) = loader.finalize(); + + // Lower case modifiers + let keypress = KeyMapPress::parse("ctrl+w"); + assert_eq!(keymaps.get(&keypress).unwrap().len(), 4); + + let keypress = KeyMapPress::parse("ctrl+w l"); + assert_eq!(keymaps.get(&keypress).unwrap().len(), 2); + + let keypress = KeyMapPress::parse("ctrl+w h"); + assert_eq!(keymaps.get(&keypress).unwrap().len(), 1); + + let keypress = KeyMapPress::parse("ctrl+w l l"); + assert_eq!(keymaps.get(&keypress).unwrap().len(), 1); + + let keypress = KeyMapPress::parse("end"); + assert_eq!(keymaps.get(&keypress).unwrap().len(), 1); + + // Upper case modifiers + let keypress = KeyMapPress::parse("Ctrl+w"); + assert_eq!(keymaps.get(&keypress).unwrap().len(), 4); + + let keypress = KeyMapPress::parse("Ctrl+w l"); + assert_eq!(keymaps.get(&keypress).unwrap().len(), 2); + + let keypress = KeyMapPress::parse("Ctrl+w h"); + assert_eq!(keymaps.get(&keypress).unwrap().len(), 1); + + let keypress = KeyMapPress::parse("Ctrl+w l l"); + assert_eq!(keymaps.get(&keypress).unwrap().len(), 1); + + let keypress = KeyMapPress::parse("End"); + assert_eq!(keymaps.get(&keypress).unwrap().len(), 1); + + // No modifier + let keypress = KeyMapPress::parse("shift+i"); + assert_eq!(keymaps.get(&keypress).unwrap().len(), 1); + + // Mouse keys + let keypress = KeyMapPress::parse("MouseForward"); + assert_eq!(keymaps.get(&keypress).unwrap().len(), 1); + + let keypress = KeyMapPress::parse("mousebackward"); + assert_eq!(keymaps.get(&keypress).unwrap().len(), 1); + + let keypress = KeyMapPress::parse("Ctrl+MouseMiddle"); + assert_eq!(keymaps.get(&keypress).unwrap().len(), 1); + + let keypress = KeyMapPress::parse("Ctrl++"); + assert_eq!( + keypress[0].key, + KeyMapKey::Logical(Key::Character("+".into())) + ); + + let keypress = KeyMapPress::parse("+"); + assert_eq!( + keypress[0].key, + KeyMapKey::Logical(Key::Character("+".into())) + ); + } +} diff --git a/lapce-app/src/keypress/press.rs b/lapce-app/src/keypress/press.rs new file mode 100644 index 0000000..af262ac --- /dev/null +++ b/lapce-app/src/keypress/press.rs @@ -0,0 +1,18 @@ +use floem::keyboard::Modifiers; + +use super::{key::KeyInput, keymap::KeyMapPress}; + +#[derive(Clone, Debug)] +pub struct KeyPress { + pub(super) key: KeyInput, + pub(super) mods: Modifiers, +} + +impl KeyPress { + pub fn keymap_press(&self) -> Option { + self.key.keymap_key().map(|key| KeyMapPress { + key, + mods: self.mods, + }) + } +} diff --git a/lapce-app/src/lib.rs b/lapce-app/src/lib.rs new file mode 100644 index 0000000..43a55ce --- /dev/null +++ b/lapce-app/src/lib.rs @@ -0,0 +1,50 @@ +pub mod about; +pub mod alert; +pub mod app; +pub mod code_action; +pub mod code_lens; +pub mod command; +pub mod completion; +pub mod config; +pub mod db; +pub mod debug; +pub mod doc; +pub mod editor; +pub mod editor_tab; +pub mod file_explorer; +pub mod find; +pub mod focus_text; +pub mod global_search; +pub mod history; +pub mod hover; +pub mod id; +pub mod inline_completion; +pub mod keymap; +pub mod keypress; +pub mod listener; +pub mod lsp; +pub mod main_split; +pub mod markdown; +pub mod palette; +pub mod panel; +pub mod plugin; +pub mod proxy; +pub mod rename; +pub mod settings; +pub mod snippet; +pub mod source_control; +pub mod status; +pub mod terminal; +pub mod text_area; +pub mod text_input; +pub mod title; +pub mod tracing; +pub mod update; +pub mod wave; +pub mod web_link; +pub mod window; +pub mod window_tab; +pub mod workspace; + +#[cfg(windows)] +extern crate windows_sys as windows; diff --git a/lapce-app/src/listener.rs b/lapce-app/src/listener.rs new file mode 100644 index 0000000..55e4fa7 --- /dev/null +++ b/lapce-app/src/listener.rs @@ -0,0 +1,65 @@ +use floem::reactive::{RwSignal, Scope, SignalGet, SignalUpdate}; + +/// A signal listener that receives 'events' from the outside and runs the callback. +/// This is implemented using effects and normal rw signals. This should be used when it doesn't +/// make sense to think of it as 'storing' a value, like an `RwSignal` would typically be used for. +/// +/// Copied/Cloned listeners refer to the same listener. +#[derive(Debug)] +pub struct Listener { + cx: Scope, + val: RwSignal>, +} + +impl Listener { + pub fn new(cx: Scope, on_val: impl Fn(T) + 'static) -> Listener { + let val = cx.create_rw_signal(None); + + let listener = Listener { val, cx }; + listener.listen(on_val); + + listener + } + + /// Construct a listener when you can't yet give it a callback. + /// Call `listen` to set a callback. + pub fn new_empty(cx: Scope) -> Listener { + let val = cx.create_rw_signal(None); + Listener { val, cx } + } + + pub fn scope(&self) -> Scope { + self.cx + } + + /// Listen for values sent to this listener. + pub fn listen(self, on_val: impl Fn(T) + 'static) { + self.listen_with(self.cx, on_val) + } + + /// Listen for values sent to this listener. + /// Allows creating the effect with a custom scope, letting it be disposed of. + pub fn listen_with(self, cx: Scope, on_val: impl Fn(T) + 'static) { + let val = self.val; + + cx.create_effect(move |_| { + // TODO(minor): Signals could have a `take` method to avoid cloning. + if let Some(cmd) = val.get() { + on_val(cmd); + } + }); + } + + /// Send a value to the listener. + pub fn send(&self, v: T) { + self.val.set(Some(v)); + } +} + +impl Copy for Listener {} + +impl Clone for Listener { + fn clone(&self) -> Self { + *self + } +} diff --git a/lapce-app/src/lsp.rs b/lapce-app/src/lsp.rs new file mode 100644 index 0000000..9562f5b --- /dev/null +++ b/lapce-app/src/lsp.rs @@ -0,0 +1,92 @@ +use std::path::PathBuf; + +use tracing::{Level, event}; +use url::Url; + +// Rust-analyzer returns paths in the form of "file:///:/...", which gets parsed into URL +// as "/://" which is then interpreted by PathBuf::new() as a UNIX-like path from root. +// This function strips the additional / from the beginning, if the first segment is a drive letter. +#[cfg(windows)] +pub fn path_from_url(url: &Url) -> PathBuf { + use percent_encoding::percent_decode_str; + + event!(Level::DEBUG, "Converting `{:?}` to path", url); + + if let Ok(path) = url.to_file_path() { + return path; + } + + let path = url.path(); + + let path = if path.contains('%') { + percent_decode_str(path) + .decode_utf8() + .unwrap_or(std::borrow::Cow::from(path)) + } else { + std::borrow::Cow::from(path) + }; + + if let Some(path) = path.strip_prefix('/') { + event!(Level::DEBUG, "Found `/` prefix"); + if let Some((maybe_drive_letter, path_second_part)) = + path.split_once(['/', '\\']) + { + event!(Level::DEBUG, maybe_drive_letter); + event!(Level::DEBUG, path_second_part); + + let b = maybe_drive_letter.as_bytes(); + + if !b.is_empty() && !b[0].is_ascii_alphabetic() { + event!(Level::ERROR, "First byte is not ascii alphabetic: {b:?}"); + } + + match maybe_drive_letter.len() { + 2 => match maybe_drive_letter.chars().nth(1) { + Some(':') => { + event!(Level::DEBUG, "Returning path `{:?}`", path); + return PathBuf::from(path); + } + v => { + event!( + Level::ERROR, + "Unhandled 'maybe_drive_letter' chars: {v:?}" + ); + } + }, + 4 => { + if maybe_drive_letter.contains("%3A") { + let path = path.replace("%3A", ":"); + event!(Level::DEBUG, "Returning path `{:?}`", path); + return PathBuf::from(path); + } else { + event!( + Level::ERROR, + "Unhandled 'maybe_drive_letter' pattern: {maybe_drive_letter:?}" + ); + } + } + v => { + event!( + Level::ERROR, + "Unhandled 'maybe_drive_letter' length: {v}" + ); + } + } + } + } + + event!(Level::DEBUG, "Returning unmodified path `{:?}`", path); + PathBuf::from(path.into_owned()) +} + +#[cfg(not(windows))] +pub fn path_from_url(url: &Url) -> PathBuf { + event!(Level::DEBUG, "Converting `{:?}` to path", url); + url.to_file_path().unwrap_or_else(|_| { + let path = url.path(); + if let Ok(path) = percent_encoding::percent_decode_str(path).decode_utf8() { + return PathBuf::from(path.into_owned()); + } + PathBuf::from(path) + }) +} diff --git a/lapce-app/src/main_split.rs b/lapce-app/src/main_split.rs new file mode 100644 index 0000000..6dabd13 --- /dev/null +++ b/lapce-app/src/main_split.rs @@ -0,0 +1,3105 @@ +use std::{ + collections::HashMap, + path::{Path, PathBuf}, + rc::Rc, +}; + +use floem::{ + action::save_as, + ext_event::create_ext_action, + file::{FileDialogOptions, FileInfo}, + keyboard::Modifiers, + peniko::kurbo::{Point, Rect, Vec2}, + reactive::{Memo, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, + views::editor::id::EditorId, +}; +use itertools::Itertools; +use lapce_core::{ + buffer::rope_text::RopeText, command::FocusCommand, cursor::Cursor, + rope_text_pos::RopeTextPosition, selection::Selection, syntax::Syntax, +}; +use lapce_rpc::{ + buffer::BufferId, + core::FileChanged, + plugin::{PluginId, VoltID}, + proxy::ProxyResponse, +}; +use lapce_xi_rope::{Rope, spans::SpansBuilder}; +use lsp_types::{ + CodeAction, CodeActionOrCommand, DiagnosticSeverity, DocumentChangeOperation, + DocumentChanges, OneOf, Position, TextEdit, Url, WorkspaceEdit, +}; +use serde::{Deserialize, Serialize}; +use serde_json::Value; +use tracing::{Level, event}; + +use crate::{ + alert::AlertButton, + code_lens::CodeLensData, + command::InternalCommand, + doc::{DiagnosticData, Doc, DocContent, DocHistory, EditorDiagnostic}, + editor::{ + EditorData, + diff::DiffEditorData, + location::{EditorLocation, EditorPosition}, + }, + editor_tab::{ + EditorTabChild, EditorTabChildSource, EditorTabData, EditorTabInfo, + }, + id::{ + DiffEditorId, EditorTabId, KeymapId, SettingsId, SplitId, + ThemeColorSettingsId, VoltViewId, + }, + keypress::{EventRef, KeyPressData, KeyPressHandle}, + panel::implementation_view::ReferencesRoot, + window_tab::{CommonData, Focus, WindowTabData}, +}; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub enum SplitDirection { + Vertical, + Horizontal, +} + +#[derive(Clone, Copy, Debug)] +pub enum SplitMoveDirection { + Up, + Down, + Right, + Left, +} + +impl SplitMoveDirection { + pub fn direction(&self) -> SplitDirection { + match self { + SplitMoveDirection::Up | SplitMoveDirection::Down => { + SplitDirection::Horizontal + } + SplitMoveDirection::Left | SplitMoveDirection::Right => { + SplitDirection::Vertical + } + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum SplitContent { + EditorTab(EditorTabId), + Split(SplitId), +} + +impl SplitContent { + pub fn id(&self) -> u64 { + match self { + SplitContent::EditorTab(id) => id.to_raw(), + SplitContent::Split(id) => id.to_raw(), + } + } + + pub fn content_info(&self, data: &WindowTabData) -> SplitContentInfo { + match &self { + SplitContent::EditorTab(editor_tab_id) => { + let editor_tab_data = data + .main_split + .editor_tabs + .get_untracked() + .get(editor_tab_id) + .cloned() + .unwrap(); + SplitContentInfo::EditorTab( + editor_tab_data.get_untracked().tab_info(data), + ) + } + SplitContent::Split(split_id) => { + let split_data = data + .main_split + .splits + .get_untracked() + .get(split_id) + .cloned() + .unwrap(); + SplitContentInfo::Split(split_data.get_untracked().split_info(data)) + } + } + } +} + +#[derive(Clone)] +pub struct SplitData { + pub scope: Scope, + pub parent_split: Option, + pub split_id: SplitId, + pub children: Vec<(RwSignal, SplitContent)>, + pub direction: SplitDirection, + pub window_origin: Point, + pub layout_rect: Rect, +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct SplitInfo { + pub children: Vec, + pub direction: SplitDirection, +} + +impl SplitInfo { + pub fn to_data( + &self, + data: MainSplitData, + parent_split: Option, + split_id: SplitId, + ) -> RwSignal { + let split_data = { + let cx = data.scope.create_child(); + let split_data = SplitData { + scope: cx, + split_id, + direction: self.direction, + parent_split, + children: self + .children + .iter() + .map(|child| { + ( + cx.create_rw_signal(1.0), + child.to_data(data.clone(), split_id), + ) + }) + .collect(), + window_origin: Point::ZERO, + layout_rect: Rect::ZERO, + }; + cx.create_rw_signal(split_data) + }; + data.splits.update(|splits| { + splits.insert(split_id, split_data); + }); + split_data + } +} + +#[derive(Clone, Serialize, Deserialize)] +pub enum SplitContentInfo { + EditorTab(EditorTabInfo), + Split(SplitInfo), +} + +impl SplitContentInfo { + pub fn to_data( + &self, + data: MainSplitData, + parent_split: SplitId, + ) -> SplitContent { + match &self { + SplitContentInfo::EditorTab(tab_info) => { + let tab_data = tab_info.to_data(data, parent_split); + SplitContent::EditorTab( + tab_data.with_untracked(|tab_data| tab_data.editor_tab_id), + ) + } + SplitContentInfo::Split(split_info) => { + let split_id = SplitId::next(); + split_info.to_data(data, Some(parent_split), split_id); + SplitContent::Split(split_id) + } + } + } +} + +impl SplitData { + pub fn split_info(&self, data: &WindowTabData) -> SplitInfo { + SplitInfo { + direction: self.direction, + children: self + .children + .iter() + .map(|(_, child)| child.content_info(data)) + .collect(), + } + } + + pub fn editor_tab_index(&self, editor_tab_id: EditorTabId) -> Option { + self.children + .iter() + .position(|(_, c)| c == &SplitContent::EditorTab(editor_tab_id)) + } + + pub fn content_index(&self, content: &SplitContent) -> Option { + self.children.iter().position(|(_, c)| c == content) + } +} + +/// All the editors in a main split +#[derive(Clone, Copy)] +pub struct Editors(pub RwSignal>); +impl Editors { + fn new(cx: Scope) -> Self { + Self(cx.create_rw_signal(im::HashMap::new())) + } + + /// Add an editor to the editors. + /// Returns the id of the editor. + pub fn insert(&self, editor: EditorData) -> EditorId { + let id = editor.id(); + self.0.update(|editors| { + if editors.insert(id, editor).is_some() { + event!(Level::WARN, "Inserted EditorId that already exists"); + } + }); + + id + } + + pub fn insert_with_id(&self, id: EditorId, editor: EditorData) { + self.0.update(|editors| { + editors.insert(id, editor); + }); + } + + pub fn new_local(&self, cx: Scope, common: Rc) -> EditorId { + let editor = EditorData::new_local(cx, *self, common); + + self.insert(editor) + } + + /// Equivalent to [`Self::new_local`], but immediately gets the created editor. + pub fn make_local(&self, cx: Scope, common: Rc) -> EditorData { + let id = self.new_local(cx, common); + self.editor_untracked(id).unwrap() + } + + pub fn new_from_doc( + &self, + cx: Scope, + doc: Rc, + editor_tab_id: Option, + diff_editor_id: Option<(EditorTabId, DiffEditorId)>, + confirmed: Option>, + common: Rc, + ) -> EditorId { + let editor = EditorData::new_doc( + cx, + doc, + editor_tab_id, + diff_editor_id, + confirmed, + common, + ); + + self.insert(editor) + } + + /// Equivalent to [`Self::new_editor_doc`], but immediately gets the created editor. + pub fn make_from_doc( + &self, + cx: Scope, + doc: Rc, + editor_tab_id: Option, + diff_editor_id: Option<(EditorTabId, DiffEditorId)>, + confirmed: Option>, + common: Rc, + ) -> EditorData { + let id = self.new_from_doc( + cx, + doc, + editor_tab_id, + diff_editor_id, + confirmed, + common, + ); + self.editor_untracked(id).unwrap() + } + + /// Copy an existing editor which is inserted into [`Editors`] + pub fn copy( + &self, + editor_id: EditorId, + cx: Scope, + editor_tab_id: Option, + diff_editor_id: Option<(EditorTabId, DiffEditorId)>, + confirmed: Option>, + ) -> Option { + let editor = self.editor_untracked(editor_id)?; + let new_editor = editor.copy(cx, editor_tab_id, diff_editor_id, confirmed); + + Some(self.insert(new_editor)) + } + + pub fn make_copy( + &self, + editor_id: EditorId, + cx: Scope, + editor_tab_id: Option, + diff_editor_id: Option<(EditorTabId, DiffEditorId)>, + confirmed: Option>, + ) -> Option { + let editor_id = + self.copy(editor_id, cx, editor_tab_id, diff_editor_id, confirmed)?; + self.editor_untracked(editor_id) + } + + pub fn remove(&self, id: EditorId) -> Option { + self.0.try_update(|editors| editors.remove(&id)).unwrap() + } + + pub fn get_editor_id_by_path(&self, path: &Path) -> Option { + self.0.with_untracked(|x| { + for (id, data) in x { + if data.doc().content.with_untracked(|x| { + if let Some(doc_path) = x.path() { + doc_path == path + } else { + false + } + }) { + return Some(*id); + } + } + None + }) + } + + pub fn contains_untracked(&self, id: EditorId) -> bool { + self.0.with_untracked(|editors| editors.contains_key(&id)) + } + + /// Get the editor (tracking the signal) + pub fn editor(&self, id: EditorId) -> Option { + self.0.with(|editors| editors.get(&id).cloned()) + } + + /// Get the editor (not tracking the signal) + pub fn editor_untracked(&self, id: EditorId) -> Option { + self.0.with_untracked(|editors| editors.get(&id).cloned()) + } + + pub fn with_editors( + &self, + f: impl FnOnce(&im::HashMap) -> O, + ) -> O { + self.0.with(f) + } + + pub fn with_editors_untracked( + &self, + f: impl FnOnce(&im::HashMap) -> O, + ) -> O { + self.0.with_untracked(f) + } +} + +#[derive(Clone)] +pub struct MainSplitData { + pub scope: Scope, + pub root_split: SplitId, + pub active_editor_tab: RwSignal>, + pub splits: RwSignal>>, + pub editor_tabs: RwSignal>>, + pub editors: Editors, + pub diff_editors: RwSignal>, + pub docs: RwSignal>>, + pub scratch_docs: RwSignal>>, + pub diagnostics: RwSignal>, + pub references: RwSignal, + pub implementations: RwSignal, + pub active_editor: Memo>, + pub find_editor: EditorData, + pub replace_editor: EditorData, + pub locations: RwSignal>, + pub current_location: RwSignal, + pub width: RwSignal, + pub code_lens: RwSignal, + pub common: Rc, +} + +impl std::fmt::Debug for MainSplitData { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("MainSplitData") + .field("root_split", &self.root_split) + .finish() + } +} + +impl MainSplitData { + pub fn new(cx: Scope, common: Rc) -> Self { + let splits = cx.create_rw_signal(im::HashMap::new()); + let active_editor_tab = cx.create_rw_signal(None); + let editor_tabs: RwSignal< + im::HashMap>, + > = cx.create_rw_signal(im::HashMap::new()); + let editors = Editors::new(cx); + let diff_editors: RwSignal> = + cx.create_rw_signal(im::HashMap::new()); + let docs: RwSignal>> = + cx.create_rw_signal(im::HashMap::new()); + let scratch_docs = cx.create_rw_signal(im::HashMap::new()); + let locations = cx.create_rw_signal(im::Vector::new()); + let references = cx.create_rw_signal(ReferencesRoot::default()); + let implementations = cx.create_rw_signal( + crate::panel::implementation_view::ReferencesRoot::default(), + ); + let current_location = cx.create_rw_signal(0); + let diagnostics = cx.create_rw_signal(im::HashMap::new()); + let find_editor = editors.make_local(cx, common.clone()); + let replace_editor = editors.make_local(cx, common.clone()); + + let active_editor = cx.create_memo(move |_| -> Option { + let active_editor_tab = active_editor_tab.get()?; + let editor_tab = editor_tabs + .with(|editor_tabs| editor_tabs.get(&active_editor_tab).copied())?; + let (_, _, child) = editor_tab.with(|editor_tab| { + editor_tab.children.get(editor_tab.active).cloned() + })?; + + let editor = match child { + EditorTabChild::Editor(editor_id) => editors.editor(editor_id)?, + EditorTabChild::DiffEditor(diff_editor_id) => { + let diff_editor = diff_editors.with(|diff_editors| { + diff_editors.get(&diff_editor_id).cloned() + })?; + if diff_editor.focus_right.get() { + diff_editor.right + } else { + diff_editor.left + } + } + _ => return None, + }; + + Some(editor) + }); + + { + let buffer = find_editor.doc().buffer; + let find = common.find.clone(); + cx.create_effect(move |_| { + let content = buffer.with(|buffer| buffer.to_string()); + find.set_find(&content); + }); + } + + Self { + scope: cx, + root_split: SplitId::next(), + splits, + active_editor_tab, + editor_tabs, + editors, + diff_editors, + docs, + scratch_docs, + active_editor, + find_editor, + replace_editor, + diagnostics, + locations, + current_location, + width: cx.create_rw_signal(0.0), + code_lens: cx.create_rw_signal(CodeLensData::new(common.clone())), + common, + references, + implementations, + } + } + + pub fn key_down<'a>( + &self, + event: impl Into>, + keypress: &KeyPressData, + ) -> Option { + let active_editor_tab = self.active_editor_tab.get_untracked()?; + let editor_tab = self.editor_tabs.with_untracked(|editor_tabs| { + editor_tabs.get(&active_editor_tab).copied() + })?; + let (_, _, child) = editor_tab.with_untracked(|editor_tab| { + editor_tab.children.get(editor_tab.active).cloned() + })?; + match child { + EditorTabChild::Editor(editor_id) => { + let editor = self.editors.editor_untracked(editor_id)?; + let handle = keypress.key_down(event, &editor); + editor.get_code_actions(); + Some(handle) + } + EditorTabChild::DiffEditor(diff_editor_id) => { + let diff_editor = + self.diff_editors.with_untracked(|diff_editors| { + diff_editors.get(&diff_editor_id).cloned() + })?; + let editor = if diff_editor.focus_right.get_untracked() { + &diff_editor.right + } else { + &diff_editor.left + }; + let handle = keypress.key_down(event, editor); + editor.get_code_actions(); + Some(handle) + } + EditorTabChild::Settings(_) => None, + EditorTabChild::ThemeColorSettings(_) => None, + EditorTabChild::Keymap(_) => None, + EditorTabChild::Volt(_, _) => None, + } + } + + fn save_current_jump_location(&self) -> bool { + if let Some(editor) = self.active_editor.get_untracked() { + let (cursor, viewport) = (editor.cursor(), editor.viewport()); + let path = editor + .doc() + .content + .with_untracked(|content| content.path().cloned()); + if let Some(path) = path { + let offset = cursor.with_untracked(|c| c.offset()); + let scroll_offset = viewport.get_untracked().origin().to_vec2(); + return self.save_jump_location(path, offset, scroll_offset); + } + } + false + } + + pub fn save_jump_location( + &self, + path: PathBuf, + offset: usize, + scroll_offset: Vec2, + ) -> bool { + let mut locations = self.locations.get_untracked(); + if let Some(last_location) = locations.last() { + if last_location.path == path + && last_location.position == Some(EditorPosition::Offset(offset)) + && last_location.scroll_offset == Some(scroll_offset) + { + return false; + } + } + let location = EditorLocation { + path, + position: Some(EditorPosition::Offset(offset)), + scroll_offset: Some(scroll_offset), + ignore_unconfirmed: false, + same_editor_tab: false, + }; + locations.push_back(location.clone()); + let current_location = locations.len(); + self.locations.set(locations); + self.current_location.set(current_location); + + let active_editor_tab_id = self.active_editor_tab.get_untracked(); + let editor_tabs = self.editor_tabs.get_untracked(); + if let Some((locations, current_location)) = active_editor_tab_id + .and_then(|id| editor_tabs.get(&id)) + .map(|editor_tab| { + editor_tab.with_untracked(|editor_tab| { + (editor_tab.locations, editor_tab.current_location) + }) + }) + { + let mut l = locations.get_untracked(); + l.push_back(location); + let new_current_location = l.len(); + locations.set(l); + current_location.set(new_current_location); + } + + true + } + + pub fn jump_to_location( + &self, + location: EditorLocation, + edits: Option>, + ) { + self.save_current_jump_location(); + self.go_to_location(location, edits); + } + + pub fn get_doc( + &self, + path: PathBuf, + unsaved: Option, + ) -> (Rc, bool) { + let cx = self.scope; + let doc = self.docs.with_untracked(|docs| docs.get(&path).cloned()); + if let Some(doc) = doc { + (doc, false) + } else { + let diagnostic_data = self.get_diagnostic_data(&path); + + let doc = Doc::new( + cx, + path.clone(), + diagnostic_data, + self.editors, + self.common.clone(), + ); + let doc = Rc::new(doc); + self.docs.update(|docs| { + docs.insert(path.clone(), doc.clone()); + }); + + { + let doc = doc.clone(); + let local_doc = doc.clone(); + let send = create_ext_action(cx, move |result| { + if let Ok(ProxyResponse::NewBufferResponse { + content, + read_only, + }) = result + { + local_doc.init_content(Rope::from(content)); + if read_only { + local_doc.content.update(|content| { + if let DocContent::File { read_only, .. } = content { + *read_only = true; + } + }); + } else if let Some(unsaved) = unsaved { + local_doc.reload(Rope::from(unsaved), false); + } + } + }); + + self.common + .proxy + .new_buffer(doc.buffer_id, path, move |result| { + send(result); + }); + } + doc.get_code_lens(); + doc.get_folding_range(); + doc.get_document_symbol(); + (doc, true) + } + } + + pub fn go_to_location( + &self, + location: EditorLocation, + edits: Option>, + ) { + if self.common.focus.get_untracked() != Focus::Workbench { + self.common.focus.set(Focus::Workbench); + } + let path = location.path.clone(); + let (doc, new_doc) = self.get_doc(path.clone(), None); + + let child = self.get_editor_tab_child( + EditorTabChildSource::Editor { path, doc }, + location.ignore_unconfirmed, + location.same_editor_tab, + ); + if let EditorTabChild::Editor(editor_id) = child { + if let Some(editor) = self.editors.editor_untracked(editor_id) { + editor.go_to_location(location, new_doc, edits); + } + } + } + + pub fn open_file_changes(&self, path: PathBuf) { + let (right, _) = self.get_doc(path.clone(), None); + let left = Doc::new_history( + self.scope, + DocContent::History(DocHistory { + path: path.clone(), + version: "head".to_string(), + }), + self.editors, + self.common.clone(), + ); + let left = Rc::new(left); + + let send = { + let left = left.clone(); + create_ext_action(self.scope, move |result| { + if let Ok(ProxyResponse::BufferHeadResponse { content, .. }) = result + { + left.init_content(Rope::from(content)); + } + }) + }; + self.common.proxy.get_buffer_head(path, move |result| { + send(result); + }); + + self.get_editor_tab_child( + EditorTabChildSource::DiffEditor { left, right }, + false, + false, + ); + } + + pub fn open_diff_files(&self, left_path: PathBuf, right_path: PathBuf) { + let [left, right] = + [left_path, right_path].map(|path| self.get_doc(path, None).0); + + self.get_editor_tab_child( + EditorTabChildSource::DiffEditor { left, right }, + false, + false, + ); + } + + fn new_editor_tab( + &self, + editor_tab_id: EditorTabId, + split_id: SplitId, + ) -> RwSignal { + let editor_tab = { + let cx = self.scope.create_child(); + let editor_tab = EditorTabData { + scope: cx, + split: split_id, + active: 0, + editor_tab_id, + children: vec![], + window_origin: Point::ZERO, + layout_rect: Rect::ZERO, + locations: cx.create_rw_signal(im::Vector::new()), + current_location: cx.create_rw_signal(0), + }; + cx.create_rw_signal(editor_tab) + }; + self.editor_tabs.update(|editor_tabs| { + editor_tabs.insert(editor_tab_id, editor_tab); + }); + editor_tab + } + + fn get_editor_tab_child( + &self, + source: EditorTabChildSource, + ignore_unconfirmed: bool, + same_editor_tab: bool, + ) -> EditorTabChild { + let config = self.common.config.get_untracked(); + + let active_editor_tab_id = self.active_editor_tab.get_untracked(); + let editor_tabs = self.editor_tabs.get_untracked(); + let active_editor_tab = active_editor_tab_id + .and_then(|id| editor_tabs.get(&id)) + .cloned(); + + let editors = self.editors; + let diff_editors = self.diff_editors.get_untracked(); + + let active_editor_tab = if let Some(editor_tab) = active_editor_tab { + editor_tab + } else if editor_tabs.is_empty() { + let editor_tab_id = EditorTabId::next(); + let editor_tab = self.new_editor_tab(editor_tab_id, self.root_split); + let root_split = self.splits.with_untracked(|splits| { + splits.get(&self.root_split).cloned().unwrap() + }); + root_split.update(|root_split| { + root_split.children = vec![( + root_split.scope.create_rw_signal(1.0), + SplitContent::EditorTab(editor_tab_id), + )]; + }); + self.active_editor_tab.set(Some(editor_tab_id)); + editor_tab + } else { + let (editor_tab_id, editor_tab) = editor_tabs.iter().next().unwrap(); + self.active_editor_tab.set(Some(*editor_tab_id)); + *editor_tab + }; + + let is_same_diff_editor = + |diff_editor_id: &DiffEditorId, left: &Rc, right: &Rc| { + diff_editors + .get(diff_editor_id) + .map(|diff_editor| { + left.content.get_untracked() + == diff_editor.left.doc().content.get_untracked() + && right.content.get_untracked() + == diff_editor.right.doc().content.get_untracked() + }) + .unwrap_or(false) + }; + + let selected = if !config.editor.show_tab { + active_editor_tab.with_untracked(|editor_tab| { + for (i, (_, _, child)) in editor_tab.children.iter().enumerate() { + let can_be_selected = match child { + EditorTabChild::Editor(editor_id) => { + if let Some(editor) = + editors.editor_untracked(*editor_id) + { + let doc = editor.doc(); + let same_path = + if let EditorTabChildSource::Editor { + path, + .. + } = &source + { + doc.content.with_untracked(|content| { + content + .path() + .map(|p| p == path) + .unwrap_or(false) + }) + } else { + false + }; + + same_path + || doc.buffer.with_untracked(|b| b.is_pristine()) + } else { + false + } + } + EditorTabChild::DiffEditor(diff_editor_id) => { + if let EditorTabChildSource::DiffEditor { left, right } = + &source + { + is_same_diff_editor(diff_editor_id, left, right) + || diff_editors + .get(diff_editor_id) + .map(|diff_editor| { + diff_editor.left.doc().is_pristine() + && diff_editor + .right + .doc() + .is_pristine() + }) + .unwrap_or(false) + } else { + false + } + } + EditorTabChild::Settings(_) => true, + EditorTabChild::ThemeColorSettings(_) => true, + EditorTabChild::Keymap(_) => true, + EditorTabChild::Volt(_, _) => true, + }; + + if can_be_selected { + return Some(i); + } + } + None + }) + } else { + match &source { + EditorTabChildSource::Editor { path, .. } => active_editor_tab + .with_untracked(|editor_tab| { + editor_tab + .get_editor(editors, path) + .map(|(i, _)| i) + .or_else(|| { + if ignore_unconfirmed { + None + } else { + editor_tab + .get_unconfirmed_editor_tab_child( + editors, + &diff_editors, + ) + .map(|(i, _)| i) + } + }) + }), + EditorTabChildSource::DiffEditor { left, right } => { + if let Some(index) = + active_editor_tab.with_untracked(|editor_tab| { + editor_tab.children.iter().position(|(_, _, child)| { + if let EditorTabChild::DiffEditor(diff_editor_id) = + child + { + is_same_diff_editor(diff_editor_id, left, right) + } else { + false + } + }) + }) + { + Some(index) + } else if ignore_unconfirmed { + None + } else { + active_editor_tab.with_untracked(|editor_tab| { + editor_tab + .get_unconfirmed_editor_tab_child( + editors, + &diff_editors, + ) + .map(|(i, _)| i) + }) + } + } + EditorTabChildSource::NewFileEditor => { + if ignore_unconfirmed { + None + } else { + active_editor_tab.with_untracked(|editor_tab| { + editor_tab + .get_unconfirmed_editor_tab_child( + editors, + &diff_editors, + ) + .map(|(i, _)| i) + }) + } + } + EditorTabChildSource::Settings => { + if let Some(index) = + active_editor_tab.with_untracked(|editor_tab| { + editor_tab.children.iter().position(|(_, _, child)| { + matches!(child, EditorTabChild::Settings(_)) + }) + }) + { + Some(index) + } else if ignore_unconfirmed { + None + } else { + active_editor_tab.with_untracked(|editor_tab| { + editor_tab + .get_unconfirmed_editor_tab_child( + editors, + &diff_editors, + ) + .map(|(i, _)| i) + }) + } + } + EditorTabChildSource::ThemeColorSettings => { + if let Some(index) = + active_editor_tab.with_untracked(|editor_tab| { + editor_tab.children.iter().position(|(_, _, child)| { + matches!( + child, + EditorTabChild::ThemeColorSettings(_) + ) + }) + }) + { + Some(index) + } else if ignore_unconfirmed { + None + } else { + active_editor_tab.with_untracked(|editor_tab| { + editor_tab + .get_unconfirmed_editor_tab_child( + editors, + &diff_editors, + ) + .map(|(i, _)| i) + }) + } + } + EditorTabChildSource::Keymap => { + if let Some(index) = + active_editor_tab.with_untracked(|editor_tab| { + editor_tab.children.iter().position(|(_, _, child)| { + matches!(child, EditorTabChild::Keymap(_)) + }) + }) + { + Some(index) + } else if ignore_unconfirmed { + None + } else { + active_editor_tab.with_untracked(|editor_tab| { + editor_tab + .get_unconfirmed_editor_tab_child( + editors, + &diff_editors, + ) + .map(|(i, _)| i) + }) + } + } + EditorTabChildSource::Volt(id) => { + if let Some(index) = + active_editor_tab.with_untracked(|editor_tab| { + editor_tab.children.iter().position(|(_, _, child)| { + if let EditorTabChild::Volt(_, current_id) = child { + current_id == id + } else { + false + } + }) + }) + { + Some(index) + } else if ignore_unconfirmed { + None + } else { + active_editor_tab.with_untracked(|editor_tab| { + editor_tab + .get_unconfirmed_editor_tab_child( + editors, + &diff_editors, + ) + .map(|(i, _)| i) + }) + } + } + } + }; + + let new_child_from_source = + |editor_tab_id: EditorTabId, source: &EditorTabChildSource| match source + { + EditorTabChildSource::Editor { doc, .. } => { + let editor_id = editors.new_from_doc( + self.scope, + doc.clone(), + Some(editor_tab_id), + None, + None, + self.common.clone(), + ); + + EditorTabChild::Editor(editor_id) + } + EditorTabChildSource::NewFileEditor => { + let name = self.get_name_for_new_file(); + let doc_content = DocContent::Scratch { + id: BufferId::next(), + name: name.clone(), + }; + let doc = Doc::new_content( + self.scope, + doc_content, + self.editors, + self.common.clone(), + ); + let doc = Rc::new(doc); + self.scratch_docs.update(|scratch_docs| { + scratch_docs.insert(name, doc.clone()); + }); + let editor_id = editors.new_from_doc( + self.scope, + doc, + Some(editor_tab_id), + None, + None, + self.common.clone(), + ); + + EditorTabChild::Editor(editor_id) + } + EditorTabChildSource::Settings => { + EditorTabChild::Settings(SettingsId::next()) + } + EditorTabChildSource::ThemeColorSettings => { + EditorTabChild::ThemeColorSettings(SettingsId::next()) + } + EditorTabChildSource::Keymap => { + EditorTabChild::Keymap(KeymapId::next()) + } + EditorTabChildSource::Volt(id) => { + EditorTabChild::Volt(VoltViewId::next(), id.to_owned()) + } + EditorTabChildSource::DiffEditor { left, right } => { + let diff_editor_id = DiffEditorId::next(); + let diff_editor = DiffEditorData::new( + self.scope, + diff_editor_id, + editor_tab_id, + left.clone(), + right.clone(), + editors, + self.common.clone(), + ); + self.diff_editors.update(|diff_editors| { + diff_editors.insert(diff_editor_id, diff_editor); + }); + EditorTabChild::DiffEditor(diff_editor_id) + } + }; + + if let Some(selected) = selected { + let (editor_tab_id, current_child) = + active_editor_tab.with_untracked(|editor_tab| { + let editor_tab_id = editor_tab.editor_tab_id; + let (_, _, current_child) = &editor_tab.children[selected]; + match current_child { + EditorTabChild::Editor(editor_id) => { + if let Some(editor) = + editors.editor_untracked(*editor_id) + { + editor.save_doc_position(); + } + } + EditorTabChild::DiffEditor(_) => {} + EditorTabChild::Settings(_) => {} + EditorTabChild::ThemeColorSettings(_) => {} + EditorTabChild::Keymap(_) => {} + EditorTabChild::Volt(_, _) => {} + } + (editor_tab_id, current_child.clone()) + }); + + // firstly, if they are the same type of child, load the new doc to the old editor + let is_same = match (¤t_child, &source) { + ( + EditorTabChild::Editor(editor_id), + EditorTabChildSource::Editor { path, doc }, + ) => { + if let Some(editor) = editors.editor_untracked(*editor_id) { + let same_path = editor + .doc() + .content + .with_untracked(|content| content.path() == Some(path)); + if !same_path { + editor.update_doc(doc.clone()); + editor.cursor().set(Cursor::origin( + self.common.config.with_untracked(|c| c.core.modal), + )); + } + } + + true + } + ( + EditorTabChild::DiffEditor(diff_editor_id), + EditorTabChildSource::DiffEditor { left, right }, + ) => { + if !is_same_diff_editor(diff_editor_id, left, right) { + if let Some(diff_editor) = diff_editors.get(diff_editor_id) { + diff_editor.left.update_doc(left.clone()); + diff_editor.right.update_doc(right.clone()); + } + } + true + } + (EditorTabChild::Settings(_), EditorTabChildSource::Settings) => { + true + } + _ => false, + }; + if is_same { + let (_, _, child) = active_editor_tab.with_untracked(|editor_tab| { + editor_tab.children[selected].clone() + }); + active_editor_tab.update(|editor_tab| { + editor_tab.active = selected; + }); + return child; + } + + // We're loading a different kind of child, clean up the old resources + match ¤t_child { + EditorTabChild::Editor(editor_id) => { + self.remove_editor(*editor_id); + } + EditorTabChild::DiffEditor(diff_editor_id) => { + self.diff_editors.update(|diff_editors| { + diff_editors.remove(diff_editor_id); + }); + } + EditorTabChild::Settings(_) => {} + EditorTabChild::ThemeColorSettings(_) => {} + EditorTabChild::Keymap(_) => {} + EditorTabChild::Volt(_, _) => {} + } + + // Now loading the new child + let child = new_child_from_source(editor_tab_id, &source); + active_editor_tab.update(|editor_tab| { + editor_tab.children[selected] = ( + editor_tab.scope.create_rw_signal(0), + editor_tab.scope.create_rw_signal(Rect::ZERO), + child.clone(), + ); + editor_tab.active = selected; + }); + return child; + } + + // check file exists in non active editor tabs + if config.editor.show_tab && !ignore_unconfirmed && !same_editor_tab { + for (editor_tab_id, editor_tab) in &editor_tabs { + if Some(*editor_tab_id) != active_editor_tab_id { + if let Some(index) = + editor_tab.with_untracked(|editor_tab| match &source { + EditorTabChildSource::Editor { path, .. } => editor_tab + .get_editor(editors, path) + .map(|(index, _)| index), + EditorTabChildSource::DiffEditor { left, right } => { + editor_tab.children.iter().position( + |(_, _, child)| { + if let EditorTabChild::DiffEditor( + diff_editor_id, + ) = child + { + is_same_diff_editor( + diff_editor_id, + left, + right, + ) + } else { + false + } + }, + ) + } + EditorTabChildSource::Settings => editor_tab + .children + .iter() + .position(|(_, _, child)| { + matches!(child, EditorTabChild::Settings(_)) + }), + EditorTabChildSource::ThemeColorSettings => editor_tab + .children + .iter() + .position(|(_, _, child)| { + matches!( + child, + EditorTabChild::ThemeColorSettings(_) + ) + }), + EditorTabChildSource::Keymap => editor_tab + .children + .iter() + .position(|(_, _, child)| { + matches!(child, EditorTabChild::Keymap(_)) + }), + EditorTabChildSource::Volt(id) => editor_tab + .children + .iter() + .position(|(_, _, child)| { + if let EditorTabChild::Volt(_, current_id) = + child + { + current_id == id + } else { + false + } + }), + EditorTabChildSource::NewFileEditor => None, + }) + { + self.active_editor_tab.set(Some(*editor_tab_id)); + editor_tab.update(|editor_tab| { + editor_tab.active = index; + }); + let (_, _, child) = + editor_tab.with_untracked(|editor_tab| { + editor_tab.children[index].clone() + }); + return child; + } + } + } + } + + let editor_tab_id = + active_editor_tab.with_untracked(|editor_tab| editor_tab.editor_tab_id); + let child = new_child_from_source(editor_tab_id, &source); + + active_editor_tab.update(|editor_tab| { + let active = editor_tab + .active + .min(editor_tab.children.len().saturating_sub(1)); + let new_active = if editor_tab.children.is_empty() { + 0 + } else { + active + 1 + }; + editor_tab.children.insert( + new_active, + ( + self.scope.create_rw_signal(0), + self.scope.create_rw_signal(Rect::ZERO), + child.clone(), + ), + ); + editor_tab.active = new_active; + }); + + child + } + + pub fn remove_editor(&self, editor_id: EditorId) { + if let Some(editor) = self.editors.remove(editor_id) { + editor.save_doc_position(); + + let doc = editor.doc(); + let (content, _) = (doc.content.get_untracked(), doc.is_pristine()); + if let DocContent::Scratch { name, .. } = content { + let doc_exists = self.editors.with_editors_untracked(|editors| { + editors.iter().any(|(_, editor_data)| { + let doc = editor_data.doc(); + + if let DocContent::Scratch { + name: current_name, .. + } = &doc.content.get_untracked() + { + current_name == &name + } else { + false + } + }) + }); + if !doc_exists { + self.scratch_docs.update(|scratch_docs| { + scratch_docs.remove(&name); + }); + } + } + } + } + + pub fn jump_location_backward(&self, local: bool) { + let (locations, current_location) = if local { + let active_editor_tab_id = self.active_editor_tab.get_untracked(); + let editor_tabs = self.editor_tabs.get_untracked(); + if let Some((locations, current_location)) = active_editor_tab_id + .and_then(|id| editor_tabs.get(&id)) + .map(|editor_tab| { + editor_tab.with_untracked(|editor_tab| { + (editor_tab.locations, editor_tab.current_location) + }) + }) + { + (locations, current_location) + } else { + return; + } + } else { + (self.locations, self.current_location) + }; + + let locations_value = locations.get_untracked(); + let current_location_value = current_location.get_untracked(); + if current_location_value < 1 { + return; + } + + if current_location_value >= locations_value.len() { + // if we are at the head of the locations, save the current location + // before jump back + if self.save_current_jump_location() { + current_location.update(|l| { + *l -= 1; + }); + } + } + + current_location.update(|l| { + *l -= 1; + }); + let current_location_value = current_location.get_untracked(); + current_location.set(current_location_value); + let mut location = locations_value[current_location_value].clone(); + // for local jumps, we keep on the same editor tab + // because we only jump on the same split + location.same_editor_tab = local; + + self.go_to_location(location, None); + } + + pub fn jump_location_forward(&self, local: bool) { + let (locations, current_location) = if local { + let active_editor_tab_id = self.active_editor_tab.get_untracked(); + let editor_tabs = self.editor_tabs.get_untracked(); + if let Some((locations, current_location)) = active_editor_tab_id + .and_then(|id| editor_tabs.get(&id)) + .map(|editor_tab| { + editor_tab.with_untracked(|editor_tab| { + (editor_tab.locations, editor_tab.current_location) + }) + }) + { + (locations, current_location) + } else { + return; + } + } else { + (self.locations, self.current_location) + }; + + let locations_value = locations.get_untracked(); + let current_location_value = current_location.get_untracked(); + if locations_value.is_empty() { + return; + } + if current_location_value >= locations_value.len() - 1 { + return; + } + current_location.set(current_location_value + 1); + let mut location = locations_value[current_location_value + 1].clone(); + // for local jumps, we keep on the same editor tab + // because we only jump on the same split + location.same_editor_tab = local; + self.go_to_location(location, None); + } + + pub fn split( + &self, + direction: SplitDirection, + editor_tab_id: EditorTabId, + ) -> Option<()> { + let editor_tabs = self.editor_tabs.get_untracked(); + let editor_tab = editor_tabs.get(&editor_tab_id).copied()?; + + let split_id = editor_tab.with_untracked(|editor_tab| editor_tab.split); + let splits = self.splits.get_untracked(); + let split = splits.get(&split_id).copied()?; + let split_direction = split.with_untracked(|split| split.direction); + + let (index, children_len) = split.with_untracked(|split| { + split + .children + .iter() + .position(|(_, c)| c == &SplitContent::EditorTab(editor_tab_id)) + .map(|index| (index, split.children.len())) + })?; + + if split_direction == direction { + let new_editor_tab = editor_tab.with_untracked(|editor_tab| { + self.split_editor_tab(self.scope, split_id, editor_tab) + })?; + let new_editor_tab_id = + new_editor_tab.with_untracked(|editor_tab| editor_tab.editor_tab_id); + split.update(|split| { + for (size, _) in &split.children { + size.set(1.0); + } + split.children.insert( + index + 1, + ( + split.scope.create_rw_signal(1.0), + SplitContent::EditorTab(new_editor_tab_id), + ), + ); + }); + } else if children_len == 1 { + let new_editor_tab = editor_tab.with_untracked(|editor_tab| { + self.split_editor_tab(self.scope, split_id, editor_tab) + })?; + let new_editor_tab_id = + new_editor_tab.with_untracked(|editor_tab| editor_tab.editor_tab_id); + split.update(|split| { + split.direction = direction; + for (size, _) in &split.children { + size.set(1.0); + } + split.children.push(( + split.scope.create_rw_signal(1.0), + SplitContent::EditorTab(new_editor_tab_id), + )); + }); + } else { + let new_split_id = SplitId::next(); + + editor_tab.update(|editor_tab| { + editor_tab.split = new_split_id; + }); + let new_editor_tab = editor_tab.with_untracked(|editor_tab| { + self.split_editor_tab(self.scope, new_split_id, editor_tab) + })?; + let new_editor_tab_id = + new_editor_tab.with_untracked(|editor_tab| editor_tab.editor_tab_id); + + let new_split = { + let cx = self.scope.create_child(); + let new_split = SplitData { + scope: cx, + parent_split: Some(split_id), + split_id: new_split_id, + children: vec![ + ( + cx.create_rw_signal(1.0), + SplitContent::EditorTab(editor_tab_id), + ), + ( + cx.create_rw_signal(1.0), + SplitContent::EditorTab(new_editor_tab_id), + ), + ], + direction, + window_origin: Point::ZERO, + layout_rect: Rect::ZERO, + }; + cx.create_rw_signal(new_split) + }; + self.splits.update(|splits| { + splits.insert(new_split_id, new_split); + }); + split.update(|split| { + let size = split.children[index].0.get_untracked(); + split.children[index] = ( + split.scope.create_rw_signal(size), + SplitContent::Split(new_split_id), + ); + }); + } + + Some(()) + } + + fn split_editor_tab( + &self, + cx: Scope, + split_id: SplitId, + editor_tab: &EditorTabData, + ) -> Option> { + let (_, _, child) = editor_tab.children.get(editor_tab.active)?; + + let editor_tab_id = EditorTabId::next(); + + let new_child = match child { + EditorTabChild::Editor(editor_id) => { + let editor_id = self + .editors + .copy(*editor_id, cx, Some(editor_tab_id), None, None) + .unwrap(); + + EditorTabChild::Editor(editor_id) + } + EditorTabChild::DiffEditor(diff_editor_id) => { + let new_diff_editor_id = DiffEditorId::next(); + let diff_editor = self + .diff_editors + .get_untracked() + .get(diff_editor_id)? + .copy(cx, editor_tab_id, new_diff_editor_id, self.editors); + self.diff_editors.update(|diff_editors| { + diff_editors.insert(new_diff_editor_id, diff_editor); + }); + EditorTabChild::DiffEditor(new_diff_editor_id) + } + EditorTabChild::Settings(_) => { + EditorTabChild::Settings(SettingsId::next()) + } + EditorTabChild::ThemeColorSettings(_) => { + EditorTabChild::ThemeColorSettings(ThemeColorSettingsId::next()) + } + EditorTabChild::Keymap(_) => EditorTabChild::Keymap(KeymapId::next()), + EditorTabChild::Volt(_, id) => { + EditorTabChild::Volt(VoltViewId::next(), id.to_owned()) + } + }; + + let editor_tab = { + let cx = self.scope.create_child(); + let editor_tab = EditorTabData { + scope: cx, + split: split_id, + editor_tab_id, + active: 0, + children: vec![( + cx.create_rw_signal(0), + cx.create_rw_signal(Rect::ZERO), + new_child, + )], + window_origin: Point::ZERO, + layout_rect: Rect::ZERO, + locations: cx.create_rw_signal(editor_tab.locations.get_untracked()), + current_location: cx + .create_rw_signal(editor_tab.current_location.get_untracked()), + }; + cx.create_rw_signal(editor_tab) + }; + self.editor_tabs.update(|editor_tabs| { + editor_tabs.insert(editor_tab_id, editor_tab); + }); + Some(editor_tab) + } + + pub fn split_move( + &self, + direction: SplitMoveDirection, + editor_tab_id: EditorTabId, + ) -> Option<()> { + let editor_tabs = self.editor_tabs.get_untracked(); + let editor_tab = editor_tabs.get(&editor_tab_id).copied()?; + + let rect = editor_tab.with_untracked(|editor_tab| { + editor_tab.layout_rect.with_origin(editor_tab.window_origin) + }); + + match direction { + SplitMoveDirection::Up => { + for (_, e) in editor_tabs.iter() { + let current_rect = e.with_untracked(|e| { + e.layout_rect.with_origin(e.window_origin) + }); + if (current_rect.y1 - rect.y0).abs() < 3.0 + && current_rect.x0 <= rect.x0 + && rect.x0 < current_rect.x1 + { + let new_editor_tab_id = + e.with_untracked(|e| e.editor_tab_id); + self.active_editor_tab.set(Some(new_editor_tab_id)); + return Some(()); + } + } + } + SplitMoveDirection::Down => { + for (_, e) in editor_tabs.iter() { + let current_rect = e.with_untracked(|e| { + e.layout_rect.with_origin(e.window_origin) + }); + if (current_rect.y0 - rect.y1).abs() < 3.0 + && current_rect.x0 <= rect.x0 + && rect.x0 < current_rect.x1 + { + let new_editor_tab_id = + e.with_untracked(|e| e.editor_tab_id); + self.active_editor_tab.set(Some(new_editor_tab_id)); + return Some(()); + } + } + } + SplitMoveDirection::Right => { + for (_, e) in editor_tabs.iter() { + let current_rect = e.with_untracked(|e| { + e.layout_rect.with_origin(e.window_origin) + }); + if (rect.x1 - current_rect.x0).abs() < 3.0 + && current_rect.y0 <= rect.y0 + && rect.y0 < current_rect.y1 + { + let new_editor_tab_id = + e.with_untracked(|e| e.editor_tab_id); + self.active_editor_tab.set(Some(new_editor_tab_id)); + return Some(()); + } + } + } + SplitMoveDirection::Left => { + for (_, e) in editor_tabs.iter() { + let current_rect = e.with_untracked(|e| { + e.layout_rect.with_origin(e.window_origin) + }); + if (current_rect.x1 - rect.x0).abs() < 3.0 + && current_rect.y0 <= rect.y0 + && rect.y0 < current_rect.y1 + { + let new_editor_tab_id = + e.with_untracked(|e| e.editor_tab_id); + self.active_editor_tab.set(Some(new_editor_tab_id)); + return Some(()); + } + } + } + } + + Some(()) + } + + pub fn split_exchange(&self, editor_tab_id: EditorTabId) -> Option<()> { + let editor_tabs = self.editor_tabs.get_untracked(); + let editor_tab = editor_tabs.get(&editor_tab_id).copied()?; + + let split_id = editor_tab.with_untracked(|editor_tab| editor_tab.split); + let splits = self.splits.get_untracked(); + let split = splits.get(&split_id).copied()?; + + split.update(|split| { + let index = split + .children + .iter() + .position(|(_, c)| c == &SplitContent::EditorTab(editor_tab_id)); + if let Some(index) = index { + if index < split.children.len() - 1 { + split.children.swap(index, index + 1); + } + self.split_content_focus(&split.children[index].1); + } + }); + + Some(()) + } + + fn split_content_focus(&self, content: &SplitContent) { + match content { + SplitContent::EditorTab(editor_tab_id) => { + self.active_editor_tab.set(Some(*editor_tab_id)); + } + SplitContent::Split(split_id) => { + self.split_focus(*split_id); + } + } + } + + fn split_focus(&self, split_id: SplitId) -> Option<()> { + let splits = self.splits.get_untracked(); + let split = splits.get(&split_id).copied()?; + + let split_children = split.with_untracked(|split| split.children.clone()); + let content = split_children.first()?; + self.split_content_focus(&content.1); + + Some(()) + } + + fn split_remove(&self, split_id: SplitId) -> Option<()> { + if split_id == self.root_split { + return Some(()); + } + + let splits = self.splits.get_untracked(); + let split = splits.get(&split_id).copied()?; + self.splits.update(|splits| { + splits.remove(&split_id); + }); + let parent_split_id = split.with_untracked(|split| split.parent_split)?; + let parent_split = splits.get(&parent_split_id).copied()?; + + let split_len = parent_split + .try_update(|split| { + split + .children + .retain(|(_, c)| c != &SplitContent::Split(split_id)); + split.children.len() + }) + .unwrap(); + if split_len == 0 { + self.split_remove(parent_split_id); + } else if split_len == 1 { + let parent_parent_split_id = + parent_split.with_untracked(|split| split.parent_split)?; + let parent_parent_split = + splits.get(&parent_parent_split_id).copied()?; + let parent_split_index = + parent_parent_split.with_untracked(|split| { + split.content_index(&SplitContent::Split(parent_split_id)) + })?; + let orphan = parent_split + .try_update(|split| split.children.remove(0)) + .unwrap(); + self.split_content_set_parent(&orphan.1, parent_parent_split_id); + parent_parent_split.update(|parent_parent_split| { + parent_parent_split.children[parent_split_index] = orphan; + }); + self.split_remove(parent_split_id); + } + + Some(()) + } + + fn editor_tab_remove(&self, editor_tab_id: EditorTabId) -> Option<()> { + let editor_tabs = self.editor_tabs.get_untracked(); + let editor_tab = editor_tabs.get(&editor_tab_id).copied()?; + self.editor_tabs.update(|editor_tabs| { + editor_tabs.remove(&editor_tab_id); + }); + + let split_id = editor_tab.with_untracked(|editor_tab| editor_tab.split); + let splits = self.splits.get_untracked(); + let split = splits.get(&split_id).copied()?; + let parent_split_id = split.with_untracked(|split| split.parent_split); + + let is_active = self + .active_editor_tab + .with_untracked(|active| active == &Some(editor_tab_id)); + + let index = split.with_untracked(|split| { + split + .children + .iter() + .position(|(_, c)| c == &SplitContent::EditorTab(editor_tab_id)) + })?; + split.update(|split| { + split.children.remove(index); + for (size, _) in &split.children { + size.set(1.0); + } + }); + let split_children = split.with_untracked(|split| split.children.clone()); + + if is_active { + if split_children.is_empty() { + let new_focus = parent_split_id + .and_then(|split_id| splits.get(&split_id)) + .and_then(|split| { + let index = split.with_untracked(|split| { + split.children.iter().position(|(_, c)| { + c == &SplitContent::Split(split_id) + }) + })?; + Some((index, split)) + }) + .and_then(|(index, split)| { + split.with_untracked(|split| { + if index == split.children.len() - 1 { + if index > 0 { + Some(split.children[index - 1]) + } else { + None + } + } else { + Some(split.children[index + 1]) + } + }) + }); + if let Some((_, content)) = new_focus { + self.split_content_focus(&content); + } + } else { + let (_, content) = + split_children[index.min(split_children.len() - 1)]; + self.split_content_focus(&content); + } + } + + if split_children.is_empty() { + self.split_remove(split_id); + } else if split_children.len() == 1 { + if let Some(parent_split_id) = parent_split_id { + let parent_split = splits.get(&parent_split_id).copied()?; + let split_index = parent_split.with_untracked(|split| { + split.content_index(&SplitContent::Split(split_id)) + })?; + let (_, orphan) = + split.try_update(|split| split.children.remove(0)).unwrap(); + self.split_content_set_parent(&orphan, parent_split_id); + parent_split.update(|parent_split| { + let size = parent_split.children[split_index].0.get_untracked(); + parent_split.children[split_index] = + (parent_split.scope.create_rw_signal(size), orphan); + }); + self.split_remove(split_id); + } + } + + Some(()) + } + + pub fn editor_tab_close(&self, editor_tab_id: EditorTabId) -> Option<()> { + let editor_tabs = self.editor_tabs.get_untracked(); + let editor_tab = editor_tabs.get(&editor_tab_id).copied()?; + let editor_tab = editor_tab.get_untracked(); + for (_, _, child) in editor_tab.children { + self.editor_tab_child_close(editor_tab_id, child, false); + } + + Some(()) + } + + fn editor_tab_child_close_warning( + &self, + child: &EditorTabChild, + ) -> Option<(String, Rc, EditorData)> { + match child { + EditorTabChild::Editor(editor_id) => { + let editor = self.editors.editor_untracked(*editor_id)?; + let doc = editor.doc(); + let doc_content = doc.content.get_untracked(); + let is_dirty = !doc.is_pristine(); + if is_dirty { + let exists = self.editors.with_editors_untracked(|editors| { + editors.iter().any(|(id, editor)| { + let doc = editor.doc(); + id != editor_id + && doc.content.with_untracked(|content| { + content == &doc_content + }) + }) + }); + if !exists { + return match doc_content { + DocContent::File { path, .. } => Some(( + path.file_name()?.to_str()?.to_string(), + doc, + editor, + )), + DocContent::Local => None, + DocContent::History(_) => None, + DocContent::Scratch { name, .. } => { + Some((name, doc, editor)) + } + }; + } + } + None + } + EditorTabChild::DiffEditor(_) => None, + EditorTabChild::Settings(_) => None, + EditorTabChild::ThemeColorSettings(_) => None, + EditorTabChild::Keymap(_) => None, + EditorTabChild::Volt(_, _) => None, + } + } + + pub fn split_exchange_active(&self) -> Option<()> { + let active_editor_tab = self.active_editor_tab.get_untracked()?; + self.split_exchange(active_editor_tab)?; + Some(()) + } + + pub fn split_move_active(&self, direction: SplitMoveDirection) -> Option<()> { + let active_editor_tab = self.active_editor_tab.get_untracked()?; + self.split_move(direction, active_editor_tab)?; + Some(()) + } + + pub fn split_active(&self, direction: SplitDirection) -> Option<()> { + let active_editor_tab = self.active_editor_tab.get_untracked()?; + self.split(direction, active_editor_tab)?; + Some(()) + } + + pub fn editor_tab_child_close_active(&self) -> Option<()> { + let active_editor_tab = self.active_editor_tab.get_untracked()?; + let editor_tab = self.editor_tabs.with_untracked(|editor_tabs| { + editor_tabs.get(&active_editor_tab).copied() + })?; + let (_, _, child) = editor_tab.with_untracked(|editor_tab| { + editor_tab.children.get(editor_tab.active).cloned() + })?; + self.editor_tab_child_close(active_editor_tab, child, false); + Some(()) + } + + pub fn editor_tab_child_close_by_kind( + &self, + editor_tab_id: EditorTabId, + child: EditorTabChild, + kind: TabCloseKind, + ) -> Option<()> { + let tabs_to_close: Vec = { + let editor_tabs = self.editor_tabs.get_untracked(); + + let editor_tab = editor_tabs.get(&editor_tab_id).copied()?; + let editor_tab = editor_tab.get_untracked(); + match kind { + TabCloseKind::CloseOther => editor_tab + .children + .iter() + .filter_map(|x| { + if x.2 != child { + Some(x.2.clone()) + } else { + None + } + }) + .collect(), + TabCloseKind::CloseToLeft => { + let mut tabs_to_close = Vec::new(); + for child_tab in &editor_tab.children { + if child_tab.2 != child { + tabs_to_close.push(child_tab.2.clone()); + } else { + break; + } + } + tabs_to_close + } + TabCloseKind::CloseToRight => { + let mut tabs_to_close = Vec::new(); + let mut add_to_tabs = false; + for child_tab in &editor_tab.children { + if child_tab.2 != child && add_to_tabs { + tabs_to_close.push(child_tab.2.clone()); + } else { + add_to_tabs = true; + } + } + tabs_to_close + } + } + }; + for child_tab in tabs_to_close { + self.editor_tab_child_close(editor_tab_id, child_tab, false); + } + Some(()) + } + + pub fn editor_tab_child_close( + &self, + editor_tab_id: EditorTabId, + child: EditorTabChild, + force: bool, + ) -> Option<()> { + if !force { + if let Some((name, doc, editor)) = + self.editor_tab_child_close_warning(&child) + { + let internal_command = self.common.internal_command; + let main_split = self.clone(); + + let doc_content = doc.content.get_untracked(); + let save_button = match doc_content { + DocContent::Scratch { .. } => { + let child = child.clone(); + let doc = doc.clone(); + let save_action = Rc::new(move || { + let child = child.clone(); + let main_split = main_split.clone(); + let doc = doc.clone(); + internal_command.send(InternalCommand::HideAlert); + save_as( + FileDialogOptions::new().title("Save File"), + move |file: Option| { + let main_split = main_split.clone(); + let child = child.clone(); + let local_main_split = main_split.clone(); + if let Some(mut file) = file { + main_split.save_as( + doc.clone(), + if let Some(path) = file.path.pop() { + path + } else { + tracing::error!("No path"); + return; + }, + move || { + local_main_split + .clone() + .editor_tab_child_close( + editor_tab_id, + child.clone(), + false, + ); + }, + ); + } + }, + ); + }); + Some(AlertButton { + text: "Save".to_string(), + action: save_action, + }) + } + DocContent::File { .. } => { + let editor = editor.clone(); + let editors = self.editors; + let editor_id = editor.id(); + let save_action = Rc::new(move || { + internal_command.send(InternalCommand::HideAlert); + editor.save(false, move || { + if let Some(editor) = + editors.editor_untracked(editor_id) + { + editor.clone().run_focus_command( + &FocusCommand::SplitClose, + None, + Modifiers::empty(), + ); + } + }); + }); + Some(AlertButton { + text: "Save".to_string(), + action: save_action, + }) + } + DocContent::Local => None, + DocContent::History(_) => None, + }; + if let Some(save_button) = save_button { + let main_split = self.clone(); + let child = child.clone(); + self.common + .internal_command + .send(InternalCommand::ShowAlert { + title: format!( + "Do you want to save the changes you made to {name}?" + ), + msg: "Your changes will be lost if you don't save them." + .to_string(), + buttons: vec![ + save_button, + AlertButton { + text: "Don't Save".to_string(), + action: Rc::new(move || { + internal_command + .send(InternalCommand::HideAlert); + main_split.editor_tab_child_close( + editor_tab_id, + child.clone(), + true, + ); + }), + }, + ], + }); + } + + return Some(()); + } + } + + let editor_tabs = self.editor_tabs.get_untracked(); + let editor_tab = editor_tabs.get(&editor_tab_id).copied()?; + + let index = editor_tab.with_untracked(|editor_tab| { + editor_tab.children.iter().position(|(_, _, c)| c == &child) + })?; + + let editor_tab_children_len = editor_tab + .try_update(|editor_tab| { + editor_tab.children.remove(index); + editor_tab.active = + index.min(editor_tab.children.len().saturating_sub(1)); + editor_tab.children.len() + }) + .unwrap(); + + match child { + EditorTabChild::Editor(editor_id) => { + self.remove_editor(editor_id); + } + EditorTabChild::DiffEditor(diff_editor_id) => { + let removed_diff_editor = self + .diff_editors + .try_update(|diff_editors| diff_editors.remove(&diff_editor_id)) + .unwrap(); + if let Some(diff_editor) = removed_diff_editor { + diff_editor.right.save_doc_position(); + self.editors.remove(diff_editor.right.editor.id()); + self.editors.remove(diff_editor.left.editor.id()); + } + } + EditorTabChild::Settings(_) => {} + EditorTabChild::ThemeColorSettings(_) => {} + EditorTabChild::Keymap(_) => {} + EditorTabChild::Volt(_, _) => {} + } + + if editor_tab_children_len == 0 { + self.editor_tab_remove(editor_tab_id); + } + + Some(()) + } + + pub fn editor_tab_update_layout( + &self, + editor_tab_id: &EditorTabId, + window_origin: Option, + rect: Option, + ) -> Option<()> { + let editor_tabs = self.editor_tabs.get_untracked(); + let editor_tab = editor_tabs.get(editor_tab_id).copied()?; + editor_tab.update(|editor_tab| { + if let Some(window_origin) = window_origin { + editor_tab.window_origin = window_origin; + } + if let Some(rect) = rect { + editor_tab.layout_rect = rect; + } + }); + Some(()) + } + + pub fn run_code_action(&self, plugin_id: PluginId, action: CodeActionOrCommand) { + match action { + CodeActionOrCommand::Command(command) => { + self.run_code_lens( + &command.command, + command.arguments.unwrap_or_default(), + ); + } + CodeActionOrCommand::CodeAction(action) => { + if let Some(edit) = action.edit.as_ref() { + self.apply_workspace_edit(edit); + } else { + self.resolve_code_action(plugin_id, action); + } + } + } + } + + pub fn run_code_lens(&self, command: &str, args: Vec) { + self.code_lens.get_untracked().run(command, args); + } + + /// Resolve a code action and apply its held workspace edit + fn resolve_code_action(&self, plugin_id: PluginId, action: CodeAction) { + let main_split = self.clone(); + let send = create_ext_action(self.scope, move |edit| { + main_split.apply_workspace_edit(&edit); + }); + self.common + .proxy + .code_action_resolve(action, plugin_id, move |result| { + if let Ok(ProxyResponse::CodeActionResolveResponse { item }) = result + { + if let Some(edit) = item.edit { + send(edit); + } + } + }); + } + + /// Perform a workspace edit, which are from the LSP (such as code actions, or symbol renaming) + pub fn apply_workspace_edit(&self, edit: &WorkspaceEdit) { + if let Some(DocumentChanges::Operations(_op)) = + edit.document_changes.as_ref() + { + // TODO + } + + if let Some(edits) = workspace_edits(edit) { + for (url, edits) in edits { + if let Ok(path) = url.to_file_path() { + let active_path = self + .active_editor + .get_untracked() + .map(|editor| editor.doc()) + .map(|doc| doc.content.get_untracked()) + .and_then(|content| content.path().cloned()); + let position = if active_path.as_ref() == Some(&path) { + None + } else { + edits + .first() + .map(|edit| EditorPosition::Position(edit.range.start)) + }; + let location = EditorLocation { + path, + position, + scroll_offset: None, + ignore_unconfirmed: true, + same_editor_tab: false, + }; + self.jump_to_location(location, Some(edits)); + } + } + } + } + + pub fn next_error(&self) { + let file_diagnostics = + self.file_diagnostics_items(DiagnosticSeverity::ERROR); + if file_diagnostics.is_empty() { + return; + } + let active_editor = self.active_editor.get_untracked(); + let active_path = active_editor + .map(|editor| (editor.doc(), editor.cursor())) + .and_then(|(doc, cursor)| { + let offset = cursor.with_untracked(|c| c.offset()); + let (path, position) = ( + doc.content.get_untracked().path().cloned(), + doc.buffer.with_untracked(|b| b.offset_to_position(offset)), + ); + path.map(|path| (path, offset, position)) + }); + let (path, position) = + next_in_file_errors_offset(active_path, &file_diagnostics); + let location = EditorLocation { + path, + position: Some(position), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }; + self.jump_to_location(location, None); + } + + fn file_diagnostics_items( + &self, + severity: DiagnosticSeverity, + ) -> Vec<(PathBuf, Vec)> { + let diagnostics = self.diagnostics.get_untracked(); + diagnostics + .into_iter() + .filter_map(|(path, diagnostic)| { + let span = diagnostic.diagnostics_span.get_untracked(); + if !span.is_empty() { + let diags = span + .iter() + .filter_map(|(iv, diag)| { + if diag.severity == Some(severity) { + Some(EditorDiagnostic { + range: Some((iv.start, iv.end)), + diagnostic: diag.to_owned(), + }) + } else { + None + } + }) + .collect::>(); + if !diags.is_empty() { + Some((path, diags)) + } else { + None + } + } else { + let diagnostics = diagnostic.diagnostics.get_untracked(); + let diagnostics: Vec = diagnostics + .into_iter() + .filter(|d| d.severity == Some(severity)) + .map(|d| EditorDiagnostic { + range: None, + diagnostic: d, + }) + .collect(); + if !diagnostics.is_empty() { + Some((path, diagnostics)) + } else { + None + } + } + }) + .sorted_by_key(|(path, _)| path.clone()) + .collect() + } + + pub fn get_diagnostic_data(&self, path: &Path) -> DiagnosticData { + if let Some(d) = self.diagnostics.with_untracked(|d| d.get(path).cloned()) { + d + } else { + let diagnostic_data = DiagnosticData { + expanded: self.scope.create_rw_signal(true), + diagnostics: self.scope.create_rw_signal(im::Vector::new()), + diagnostics_span: self + .scope + .create_rw_signal(SpansBuilder::new(0).build()), + }; + self.diagnostics.update(|d| { + d.insert(path.to_path_buf(), diagnostic_data.clone()); + }); + diagnostic_data + } + } + + pub fn open_file_changed(&self, path: &Path, content: &FileChanged) { + tracing::debug!("open_file_changed {:?}", path); + match content { + FileChanged::Change(content) => { + let doc = self.docs.with_untracked(|docs| docs.get(path).cloned()); + let doc = match doc { + Some(doc) => doc, + None => return, + }; + doc.handle_file_changed(Rope::from(content)); + } + FileChanged::Delete => { + if self.docs.with_untracked(|x| x.get(path).is_none()) { + return; + } + let Some(editor_id) = self.editors.get_editor_id_by_path(path) + else { + return; + }; + let id = editor_id.to_raw(); + if let Some(tab_id) = self.editor_tabs.with_untracked(|x| { + for (tab_id, tab_data) in x { + if tab_data.with_untracked(|x| { + x.children.iter().any(|(_, _, child)| child.id() == id) + }) { + return Some(*tab_id); + } + } + None + }) { + self.editor_tab_close(tab_id); + } + self.editors.remove(editor_id); + self.docs.update(|x| { + x.remove(path); + }); + } + } + } + + pub fn set_find_pattern(&self, pattern: Option) { + if let Some(pattern) = pattern { + self.find_editor.doc().reload(Rope::from(pattern), true); + } + let pattern_len = self + .find_editor + .doc() + .buffer + .with_untracked(|buffer| buffer.len()); + self.find_editor + .cursor() + .update(|cursor| cursor.set_insert(Selection::region(0, pattern_len))); + } + + pub fn open_volt_view(&self, id: VoltID) { + self.get_editor_tab_child(EditorTabChildSource::Volt(id), false, false); + } + + pub fn open_settings(&self) { + self.get_editor_tab_child(EditorTabChildSource::Settings, false, false); + } + + pub fn open_theme_color_settings(&self) { + self.get_editor_tab_child( + EditorTabChildSource::ThemeColorSettings, + false, + false, + ); + } + + pub fn open_keymap(&self) { + self.get_editor_tab_child(EditorTabChildSource::Keymap, false, false); + } + + pub fn new_file(&self) -> EditorTabChild { + self.get_editor_tab_child(EditorTabChildSource::NewFileEditor, false, false) + } + + pub fn save_as(&self, doc: Rc, path: PathBuf, action: impl Fn() + 'static) { + let (buffer_id, doc_content, rev, content) = ( + doc.buffer_id, + doc.content.get_untracked(), + doc.rev(), + doc.buffer.with_untracked(|b| b.to_string()), + ); + match doc_content { + DocContent::Scratch { .. } => { + let send = { + let path = path.clone(); + create_ext_action(self.scope, move |result| { + if let Err(err) = result { + event!( + Level::WARN, + "Failed to save as a file: {:?}", + err + ); + } else { + let syntax = Syntax::init(&path); + doc.content.set(DocContent::File { + path: path.clone(), + read_only: false, + }); + doc.buffer.update(|buffer| { + buffer.set_pristine(); + }); + doc.set_syntax(syntax); + doc.trigger_syntax_change(None); + action(); + } + }) + }; + self.common.proxy.save_buffer_as( + buffer_id, + path, + rev, + content, + true, + Box::new(move |result| { + send(result); + }), + ); + } + DocContent::Local => {} + DocContent::File { .. } => {} + DocContent::History(_) => {} + } + } + + pub fn save_as2( + &self, + doc: Rc, + path: PathBuf, + action: impl Fn() + 'static, + ) { + let (buffer_id, doc_content, rev, content) = ( + doc.buffer_id, + doc.content.get_untracked(), + doc.rev(), + doc.buffer.with_untracked(|b| b.to_string()), + ); + match doc_content { + DocContent::Scratch { .. } => { + let send = { + let path = path.clone(); + create_ext_action(self.scope, move |result| { + if let Err(err) = result { + event!( + Level::WARN, + "Failed to save as a file: {:?}", + err + ); + } else { + let syntax = Syntax::init(&path); + doc.content.set(DocContent::File { + path: path.clone(), + read_only: false, + }); + doc.buffer.update(|buffer| { + buffer.set_pristine(); + }); + doc.set_syntax(syntax); + doc.trigger_syntax_change(None); + action(); + } + }) + }; + self.common.proxy.save_buffer_as( + buffer_id, + path, + rev, + content, + true, + Box::new(move |result| { + send(result); + }), + ); + } + DocContent::Local => {} + DocContent::File { .. } => {} + DocContent::History(_) => {} + } + } + + fn get_name_for_new_file(&self) -> String { + const PREFIX: &str = "Untitled-"; + + // Checking just the current scratch_docs rather than all the different document + // collections seems to be the right thing to do. The user may have genuine 'new N' + // files tucked away somewhere in their workspace. + let new_num = self.scratch_docs.with_untracked(|scratch_docs| { + scratch_docs + .values() + .filter_map(|doc| { + doc.content.with_untracked(|content| match content { + DocContent::Scratch { name, .. } => { + // The unwraps are safe because scratch docs are always + // titled the same format and the user cannot change the name. + let num_part = name.strip_prefix(PREFIX).unwrap(); + let num = num_part.parse::().unwrap(); + Some(num) + } + _ => None, + }) + }) + .max() + .unwrap_or(0) + + 1 + }); + + format!("{PREFIX}{new_num}") + } + + pub fn can_jump_location_backward(&self, tracked: bool) -> bool { + if tracked { + self.current_location.get() >= 1 + } else { + self.current_location.get_untracked() >= 1 + } + } + + pub fn can_jump_location_forward(&self, tracked: bool) -> bool { + if tracked { + !(self.locations.with(|l| l.is_empty()) + || self.current_location.get() + >= self.locations.with(|l| l.len()) - 1) + } else { + !(self.locations.with_untracked(|l| l.is_empty()) + || self.current_location.get_untracked() + >= self.locations.with_untracked(|l| l.len()) - 1) + } + } + + pub fn save_scratch_doc(&self, doc: Rc) { + let main_split = self.clone(); + save_as( + FileDialogOptions::new().title("Save File"), + move |file: Option| { + if let Some(mut file) = file { + main_split.save_as( + doc.clone(), + if let Some(path) = file.path.pop() { + path + } else { + tracing::error!("No path"); + return; + }, + move || {}, + ); + } + }, + ); + } + + pub fn save_scratch_doc2(&self, doc: Rc) { + let main_split = self.clone(); + save_as( + FileDialogOptions::new().title("Save File"), + move |file: Option| { + if let Some(mut file) = file { + main_split.save_as2( + doc.clone(), + if let Some(path) = file.path.pop() { + path + } else { + tracing::error!("No path"); + return; + }, + move || {}, + ); + } + }, + ); + } + + pub fn move_editor_tab_child( + &self, + from_tab: EditorTabId, + to_tab: EditorTabId, + from_index: usize, + to_index: usize, + ) -> Option<()> { + let from_editor_tab = self + .editor_tabs + .with_untracked(|editor_tabs| editor_tabs.get(&from_tab).cloned())?; + + if from_tab == to_tab { + if from_index == to_index { + return Some(()); + } + + let to_index = if from_index < to_index { + to_index - 1 + } else { + to_index + }; + + from_editor_tab.update(|tab| { + let child = tab.children.remove(from_index); + tab.children.insert(to_index, child); + tab.active = to_index; + }); + } else { + let to_editor_tab = self + .editor_tabs + .with_untracked(|editor_tabs| editor_tabs.get(&to_tab).cloned())?; + + let (_, _, child) = from_editor_tab + .try_update(|tab| { + let child = tab.children.remove(from_index); + tab.active = + tab.active.min(tab.children.len().saturating_sub(1)); + child + }) + .unwrap(); + + self.editor_tab_child_set_parent(&child, to_tab); + to_editor_tab.update(|tab| { + tab.children.insert( + to_index, + ( + tab.scope.create_rw_signal(to_index), + tab.scope.create_rw_signal(Rect::ZERO), + child, + ), + ); + tab.active = to_index; + }); + self.active_editor_tab.set(Some(to_tab)); + + if from_editor_tab.with_untracked(|tab| tab.children.is_empty()) { + self.editor_tab_remove(from_tab); + } + } + + Some(()) + } + + fn split_content_set_parent( + &self, + content: &SplitContent, + parent_split_id: SplitId, + ) -> Option<()> { + match content { + SplitContent::EditorTab(editor_tab_id) => { + let editor_tab = self.editor_tabs.with_untracked(|editor_tabs| { + editor_tabs.get(editor_tab_id).copied() + })?; + editor_tab.update(|editor_tab| { + editor_tab.split = parent_split_id; + }); + } + SplitContent::Split(split_id) => { + let split = self + .splits + .with_untracked(|splits| splits.get(split_id).copied())?; + split.update(|split| { + split.parent_split = Some(parent_split_id); + }); + } + } + Some(()) + } + + fn editor_tab_child_set_parent( + &self, + child: &EditorTabChild, + editor_tab_id: EditorTabId, + ) -> Option<()> { + match child { + EditorTabChild::Editor(editor_id) => { + let editor = self.editors.editor(*editor_id)?; + editor.editor_tab_id.set(Some(editor_tab_id)); + } + EditorTabChild::DiffEditor(diff_editor_id) => { + let diff_editor = + self.diff_editors.with_untracked(|diff_editors| { + diff_editors.get(diff_editor_id).cloned() + })?; + diff_editor.editor_tab_id.set(editor_tab_id); + diff_editor + .left + .diff_editor_id + .set(Some((editor_tab_id, *diff_editor_id))); + diff_editor + .right + .diff_editor_id + .set(Some((editor_tab_id, *diff_editor_id))); + } + EditorTabChild::Settings(_) => {} + EditorTabChild::ThemeColorSettings(_) => {} + EditorTabChild::Keymap(_) => {} + EditorTabChild::Volt(_, _) => {} + } + Some(()) + } + + pub fn move_editor_tab_child_to_new_split( + &self, + from_tab: EditorTabId, + from_index: usize, + to_tab: EditorTabId, + split: SplitMoveDirection, + ) -> Option<()> { + let from_editor_tab = self + .editor_tabs + .with_untracked(|editor_tabs| editor_tabs.get(&from_tab).cloned())?; + let to_editor_tab = self + .editor_tabs + .with_untracked(|editor_tabs| editor_tabs.get(&to_tab).cloned())?; + let to_split_id = + to_editor_tab.with_untracked(|editor_tab| editor_tab.split); + let to_split = self + .splits + .with_untracked(|splits| splits.get(&to_split_id).cloned())?; + { + let to_split_direction = + to_split.with_untracked(|split| split.direction); + if split.direction() != to_split_direction { + let children_len = + to_split.with_untracked(|split| split.children.len()); + if children_len <= 1 { + to_split.update(|to_split| { + to_split.direction = split.direction(); + }); + } + } + } + + let to_split_direction = to_split.with_untracked(|split| split.direction); + if split.direction() == to_split_direction { + let index = + to_split.with_untracked(|split| split.editor_tab_index(to_tab))?; + let index = match split { + SplitMoveDirection::Up => index, + SplitMoveDirection::Down => index + 1, + SplitMoveDirection::Right => index + 1, + SplitMoveDirection::Left => index, + }; + let new_editor_tab_id = EditorTabId::next(); + + let (_, _, child) = from_editor_tab + .try_update(|tab| { + let child = tab.children.remove(from_index); + tab.active = + tab.active.min(tab.children.len().saturating_sub(1)); + child + }) + .unwrap(); + + self.editor_tab_child_set_parent(&child, new_editor_tab_id); + + let cx = self.scope.create_child(); + let new_editor_tab = EditorTabData { + scope: cx, + split: to_split_id, + editor_tab_id: new_editor_tab_id, + active: 0, + children: vec![( + cx.create_rw_signal(0), + cx.create_rw_signal(Rect::ZERO), + child, + )], + window_origin: Point::ZERO, + layout_rect: Rect::ZERO, + locations: cx.create_rw_signal(im::Vector::new()), + current_location: cx.create_rw_signal(0), + }; + self.editor_tabs.update(|editor_tabs| { + editor_tabs.insert( + new_editor_tab.editor_tab_id, + new_editor_tab.scope.create_rw_signal(new_editor_tab), + ); + }); + to_split.update(|split| { + for (size, _) in &split.children { + size.set(1.0); + } + split.children.insert( + index, + ( + split.scope.create_rw_signal(1.0), + SplitContent::EditorTab(new_editor_tab_id), + ), + ); + }); + self.active_editor_tab.set(Some(new_editor_tab_id)); + } else { + let index = + to_split.with_untracked(|split| split.editor_tab_index(to_tab))?; + let (size, existing_editor_tab) = to_split + .try_update(|split| split.children.remove(index)) + .unwrap(); + + let new_split_id = SplitId::next(); + + if let SplitContent::EditorTab(existing_editor_tab_id) = + existing_editor_tab + { + let editor_tab = self.editor_tabs.with_untracked(|editor_tabs| { + editor_tabs.get(&existing_editor_tab_id).cloned() + })?; + editor_tab.update(|editor_tab| { + editor_tab.split = new_split_id; + }); + } + + let new_editor_tab_id = EditorTabId::next(); + + let (_, _, child) = from_editor_tab + .try_update(|tab| { + let child = tab.children.remove(from_index); + tab.active = + tab.active.min(tab.children.len().saturating_sub(1)); + child + }) + .unwrap(); + self.editor_tab_child_set_parent(&child, new_editor_tab_id); + + let new_editor_tab = { + let cx = self.scope.create_child(); + EditorTabData { + scope: cx, + split: new_split_id, + editor_tab_id: new_editor_tab_id, + active: 0, + children: vec![( + cx.create_rw_signal(0), + cx.create_rw_signal(Rect::ZERO), + child, + )], + window_origin: Point::ZERO, + layout_rect: Rect::ZERO, + locations: cx.create_rw_signal(im::Vector::new()), + current_location: cx.create_rw_signal(0), + } + }; + self.editor_tabs.update(|editor_tabs| { + editor_tabs.insert( + new_editor_tab.editor_tab_id, + new_editor_tab.scope.create_rw_signal(new_editor_tab), + ); + }); + + let scope = self.scope.create_child(); + let new_split_children = match split { + SplitMoveDirection::Up | SplitMoveDirection::Left => { + vec![ + ( + scope.create_rw_signal(1.0), + SplitContent::EditorTab(new_editor_tab_id), + ), + (scope.create_rw_signal(1.0), existing_editor_tab), + ] + } + SplitMoveDirection::Down | SplitMoveDirection::Right => { + vec![ + (scope.create_rw_signal(1.0), existing_editor_tab), + ( + scope.create_rw_signal(1.0), + SplitContent::EditorTab(new_editor_tab_id), + ), + ] + } + }; + let new_split = SplitData { + scope, + split_id: new_split_id, + parent_split: Some(to_split_id), + children: new_split_children, + direction: split.direction(), + window_origin: Point::ZERO, + layout_rect: Rect::ZERO, + }; + self.splits.update(|splits| { + splits.insert( + new_split_id, + new_split.scope.create_rw_signal(new_split), + ); + }); + to_split.update(|split| { + split.children.insert( + index, + ( + split.scope.create_rw_signal(size.get_untracked()), + SplitContent::Split(new_split_id), + ), + ); + }); + self.active_editor_tab.set(Some(new_editor_tab_id)); + } + + if from_editor_tab.with_untracked(|tab| tab.children.is_empty()) { + self.editor_tab_remove(from_tab); + } + + Some(()) + } + + pub fn export_theme(&self) { + let child = self.new_file(); + if let EditorTabChild::Editor(id) = child { + if let Some(editor) = self.editors.editor_untracked(id) { + let doc = editor.doc(); + doc.reload( + Rope::from(self.common.config.get_untracked().export_theme()), + true, + ); + } + } + } + + pub fn show_env(&self) { + let child = self.new_file(); + if let EditorTabChild::Editor(id) = child { + if let Some(editor) = self.editors.editor_untracked(id) { + let doc = editor.doc(); + doc.reload( + Rope::from( + std::env::vars().map(|(k, v)| format!("{k}={v}")).join("\n"), + ), + true, + ); + } + } + } + + pub fn get_active_editor(&self) -> Option { + let active_editor_tab = self.active_editor_tab.get()?; + let editor_tabs = self.editor_tabs; + let editor_tab = editor_tabs + .with(|editor_tabs| editor_tabs.get(&active_editor_tab).copied())?; + let (_, _, child) = editor_tab.with(|editor_tab| { + editor_tab.children.get(editor_tab.active).cloned() + })?; + match child { + EditorTabChild::Editor(editor_id) => self.editors.editor(editor_id), + _ => None, + } + } +} + +fn workspace_edits(edit: &WorkspaceEdit) -> Option>> { + if let Some(changes) = edit.changes.as_ref() { + return Some(changes.clone()); + } + + let changes = edit.document_changes.as_ref()?; + let edits = match changes { + DocumentChanges::Edits(edits) => edits + .iter() + .map(|e| { + ( + e.text_document.uri.clone(), + e.edits + .iter() + .map(|e| match e { + OneOf::Left(e) => e.clone(), + OneOf::Right(e) => e.text_edit.clone(), + }) + .collect(), + ) + }) + .collect::>>(), + DocumentChanges::Operations(ops) => ops + .iter() + .filter_map(|o| match o { + DocumentChangeOperation::Op(_op) => None, + DocumentChangeOperation::Edit(e) => Some(( + e.text_document.uri.clone(), + e.edits + .iter() + .map(|e| match e { + OneOf::Left(e) => e.clone(), + OneOf::Right(e) => e.text_edit.clone(), + }) + .collect(), + )), + }) + .collect::>>(), + }; + Some(edits) +} + +fn next_in_file_errors_offset( + active_path: Option<(PathBuf, usize, Position)>, + file_diagnostics: &[(PathBuf, Vec)], +) -> (PathBuf, EditorPosition) { + if let Some((active_path, offset, position)) = active_path { + for (current_path, diagnostics) in file_diagnostics { + if &active_path == current_path { + for diagnostic in diagnostics { + if let Some((start, _)) = diagnostic.range { + if start > offset { + return ( + (*current_path).clone(), + EditorPosition::Offset(start), + ); + } + } + + if diagnostic.diagnostic.range.start.line > position.line + || (diagnostic.diagnostic.range.start.line == position.line + && diagnostic.diagnostic.range.start.character + > position.character) + { + return ( + (*current_path).clone(), + EditorPosition::Position( + diagnostic.diagnostic.range.start, + ), + ); + } + } + } + if current_path > &active_path { + if let Some((start, _)) = diagnostics[0].range { + return ((*current_path).clone(), EditorPosition::Offset(start)); + } + return ( + (*current_path).clone(), + if let Some((start, _)) = diagnostics[0].range { + EditorPosition::Offset(start) + } else { + EditorPosition::Position( + diagnostics[0].diagnostic.range.start, + ) + }, + ); + } + } + } + + ( + file_diagnostics[0].0.clone(), + if let Some((start, _)) = file_diagnostics[0].1[0].range { + EditorPosition::Offset(start) + } else { + EditorPosition::Position(file_diagnostics[0].1[0].diagnostic.range.start) + }, + ) +} + +#[derive(Clone, Copy, Debug)] +pub enum TabCloseKind { + CloseOther, + CloseToLeft, + CloseToRight, +} diff --git a/lapce-app/src/markdown.rs b/lapce-app/src/markdown.rs new file mode 100644 index 0000000..cd2843e --- /dev/null +++ b/lapce-app/src/markdown.rs @@ -0,0 +1,344 @@ +use floem::text::{ + Attrs, AttrsList, FamilyOwned, LineHeightValue, Style, TextLayout, Weight, +}; +use lapce_core::{language::LapceLanguage, syntax::Syntax}; +use lapce_xi_rope::Rope; +use lsp_types::MarkedString; +use pulldown_cmark::{CodeBlockKind, CowStr, Event, Options, Parser, Tag}; +use smallvec::SmallVec; + +use crate::config::{LapceConfig, color::LapceColor}; + +#[derive(Clone)] +pub enum MarkdownContent { + Text(TextLayout), + Image { url: String, title: String }, + Separator, +} + +pub fn parse_markdown( + text: &str, + line_height: f64, + config: &LapceConfig, +) -> Vec { + let mut res = Vec::new(); + + let mut current_text = String::new(); + let code_font_family: Vec = + FamilyOwned::parse_list(&config.editor.font_family).collect(); + + let default_attrs = Attrs::new() + .color(config.color(LapceColor::EDITOR_FOREGROUND)) + .font_size(config.ui.font_size() as f32) + .line_height(LineHeightValue::Normal(line_height as f32)); + let mut attr_list = AttrsList::new(default_attrs.clone()); + + let mut builder_dirty = false; + + let mut pos = 0; + + let mut tag_stack: SmallVec<[(usize, Tag); 4]> = SmallVec::new(); + + let parser = Parser::new_ext( + text, + Options::ENABLE_TABLES + | Options::ENABLE_FOOTNOTES + | Options::ENABLE_STRIKETHROUGH + | Options::ENABLE_TASKLISTS + | Options::ENABLE_HEADING_ATTRIBUTES, + ); + let mut last_text = CowStr::from(""); + // Whether we should add a newline on the next entry + // This is used so that we don't emit newlines at the very end of the generation + let mut add_newline = false; + for event in parser { + // Add the newline since we're going to be outputting more + if add_newline { + current_text.push('\n'); + builder_dirty = true; + pos += 1; + add_newline = false; + } + + match event { + Event::Start(tag) => { + tag_stack.push((pos, tag)); + } + Event::End(end_tag) => { + if let Some((start_offset, tag)) = tag_stack.pop() { + if end_tag != tag.to_end() { + tracing::warn!("Mismatched markdown tag"); + continue; + } + + if let Some(attrs) = attribute_for_tag( + default_attrs.clone(), + &tag, + &code_font_family, + config, + ) { + attr_list + .add_span(start_offset..pos.max(start_offset), attrs); + } + + if should_add_newline_after_tag(&tag) { + add_newline = true; + } + + match &tag { + Tag::CodeBlock(kind) => { + let language = + if let CodeBlockKind::Fenced(language) = kind { + md_language_to_lapce_language(language) + } else { + None + }; + + highlight_as_code( + &mut attr_list, + default_attrs.clone().family(&code_font_family), + language, + &last_text, + start_offset, + config, + ); + builder_dirty = true; + } + Tag::Image { + link_type: _, + dest_url: dest, + title, + id: _, + } => { + // TODO: Are there any link types that would change how the + // image is rendered? + + if builder_dirty { + let mut text_layout = TextLayout::new(); + text_layout.set_text(¤t_text, attr_list, None); + res.push(MarkdownContent::Text(text_layout)); + attr_list = AttrsList::new(default_attrs.clone()); + current_text.clear(); + pos = 0; + builder_dirty = false; + } + + res.push(MarkdownContent::Image { + url: dest.to_string(), + title: title.to_string(), + }); + } + _ => { + // Presumably? + builder_dirty = true; + } + } + } else { + tracing::warn!("Unbalanced markdown tag") + } + } + Event::Text(text) => { + if let Some((_, tag)) = tag_stack.last() { + if should_skip_text_in_tag(tag) { + continue; + } + } + current_text.push_str(&text); + pos += text.len(); + last_text = text; + builder_dirty = true; + } + Event::Code(text) => { + attr_list.add_span( + pos..pos + text.len(), + default_attrs.clone().family(&code_font_family), + ); + current_text.push_str(&text); + pos += text.len(); + builder_dirty = true; + } + // TODO: Some minimal 'parsing' of html could be useful here, since some things use + // basic html like `text`. + Event::Html(text) => { + attr_list.add_span( + pos..pos + text.len(), + default_attrs + .clone() + .family(&code_font_family) + .color(config.color(LapceColor::MARKDOWN_BLOCKQUOTE)), + ); + current_text.push_str(&text); + pos += text.len(); + builder_dirty = true; + } + Event::HardBreak => { + current_text.push('\n'); + pos += 1; + builder_dirty = true; + } + Event::SoftBreak => { + current_text.push(' '); + pos += 1; + builder_dirty = true; + } + Event::Rule => {} + Event::FootnoteReference(_text) => {} + Event::TaskListMarker(_text) => {} + Event::InlineHtml(_) => {} // TODO(panekj): Implement + Event::InlineMath(_) => {} // TODO(panekj): Implement + Event::DisplayMath(_) => {} // TODO(panekj): Implement + } + } + + if builder_dirty { + let mut text_layout = TextLayout::new(); + text_layout.set_text(¤t_text, attr_list, None); + res.push(MarkdownContent::Text(text_layout)); + } + + res +} + +fn attribute_for_tag<'a>( + default_attrs: Attrs<'a>, + tag: &Tag, + code_font_family: &'a [FamilyOwned], + config: &LapceConfig, +) -> Option> { + use pulldown_cmark::HeadingLevel; + match tag { + Tag::Heading { + level, + id: _, + classes: _, + attrs: _, + } => { + // The size calculations are based on the em values given at + // https://drafts.csswg.org/css2/#html-stylesheet + let font_scale = match level { + HeadingLevel::H1 => 2.0, + HeadingLevel::H2 => 1.5, + HeadingLevel::H3 => 1.17, + HeadingLevel::H4 => 1.0, + HeadingLevel::H5 => 0.83, + HeadingLevel::H6 => 0.75, + }; + let font_size = font_scale * config.ui.font_size() as f64; + Some( + default_attrs + .font_size(font_size as f32) + .weight(Weight::BOLD), + ) + } + Tag::BlockQuote(_block_quote) => Some( + default_attrs + .style(Style::Italic) + .color(config.color(LapceColor::MARKDOWN_BLOCKQUOTE)), + ), + Tag::CodeBlock(_) => Some(default_attrs.family(code_font_family)), + Tag::Emphasis => Some(default_attrs.style(Style::Italic)), + Tag::Strong => Some(default_attrs.weight(Weight::BOLD)), + // TODO: Strikethrough support + Tag::Link { + link_type: _, + dest_url: _, + title: _, + id: _, + } => { + // TODO: Link support + Some(default_attrs.color(config.color(LapceColor::EDITOR_LINK))) + } + // All other tags are currently ignored + _ => None, + } +} + +/// Decides whether newlines should be added after a specific markdown tag +fn should_add_newline_after_tag(tag: &Tag) -> bool { + !matches!( + tag, + Tag::Emphasis | Tag::Strong | Tag::Strikethrough | Tag::Link { .. } + ) +} + +/// Whether it should skip the text node after a specific tag +/// For example, images are skipped because it emits their title as a separate text node. +fn should_skip_text_in_tag(tag: &Tag) -> bool { + matches!(tag, Tag::Image { .. }) +} + +fn md_language_to_lapce_language(lang: &str) -> Option { + // TODO: There are many other names commonly used that should be supported + LapceLanguage::from_name(lang) +} + +/// Highlight the text in a richtext builder like it was a markdown codeblock +pub fn highlight_as_code( + attr_list: &mut AttrsList, + default_attrs: Attrs, + language: Option, + text: &str, + start_offset: usize, + config: &LapceConfig, +) { + let syntax = language.map(Syntax::from_language); + + let styles = syntax + .map(|mut syntax| { + syntax.parse(0, Rope::from(text), None); + syntax.styles + }) + .unwrap_or(None); + + if let Some(styles) = styles { + for (range, style) in styles.iter() { + if let Some(color) = style + .fg_color + .as_ref() + .and_then(|fg| config.style_color(fg)) + { + attr_list.add_span( + start_offset + range.start..start_offset + range.end, + default_attrs.clone().color(color), + ); + } + } + } +} + +pub fn from_marked_string( + text: MarkedString, + config: &LapceConfig, +) -> Vec { + match text { + MarkedString::String(text) => parse_markdown(&text, 1.8, config), + // This is a short version of a code block + MarkedString::LanguageString(code) => { + // TODO: We could simply construct the MarkdownText directly + // Simply construct the string as if it was written directly + parse_markdown( + &format!("```{}\n{}\n```", code.language, code.value), + 1.8, + config, + ) + } + } +} + +pub fn from_plaintext( + text: &str, + line_height: f64, + config: &LapceConfig, +) -> Vec { + let mut text_layout = TextLayout::new(); + text_layout.set_text( + text, + AttrsList::new( + Attrs::new() + .font_size(config.ui.font_size() as f32) + .line_height(LineHeightValue::Normal(line_height as f32)), + ), + None, + ); + vec![MarkdownContent::Text(text_layout)] +} diff --git a/lapce-app/src/palette.rs b/lapce-app/src/palette.rs new file mode 100644 index 0000000..fb85013 --- /dev/null +++ b/lapce-app/src/palette.rs @@ -0,0 +1,1700 @@ +use std::{ + cell::RefCell, + collections::{HashMap, HashSet}, + path::PathBuf, + rc::Rc, + sync::{ + Arc, + atomic::{AtomicU64, Ordering}, + mpsc::{Receiver, Sender, TryRecvError, channel}, + }, + time::Instant, +}; + +use anyhow::Result; +use floem::{ + ext_event::{create_ext_action, create_signal_from_channel}, + keyboard::Modifiers, + reactive::{ + ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith, + use_context, + }, +}; +use im::Vector; +use itertools::Itertools; +use lapce_core::{ + buffer::rope_text::RopeText, command::FocusCommand, language::LapceLanguage, + line_ending::LineEnding, mode::Mode, movement::Movement, selection::Selection, + syntax::Syntax, +}; +use lapce_rpc::proxy::ProxyResponse; +use lapce_xi_rope::Rope; +use lsp_types::{DocumentSymbol, DocumentSymbolResponse}; +use nucleo::Utf32Str; +use strum::{EnumMessage, IntoEnumIterator}; +use tracing::error; + +use self::{ + item::{PaletteItem, PaletteItemContent}, + kind::PaletteKind, +}; +use crate::{ + command::{ + CommandExecuted, CommandKind, InternalCommand, LapceCommand, WindowCommand, + }, + db::LapceDb, + debug::{RunDebugConfigs, RunDebugMode}, + editor::{ + EditorData, + location::{EditorLocation, EditorPosition}, + }, + keypress::{KeyPressData, KeyPressFocus, condition::Condition}, + lsp::path_from_url, + main_split::MainSplitData, + source_control::SourceControlData, + window_tab::{CommonData, Focus}, + workspace::{LapceWorkspace, LapceWorkspaceType, SshHost}, +}; + +pub mod item; +pub mod kind; + +pub const DEFAULT_RUN_TOML: &str = include_str!("../../defaults/run.toml"); + +#[derive(Clone, PartialEq, Eq)] +pub enum PaletteStatus { + Inactive, + Started, + Done, +} + +#[derive(Clone, Debug)] +pub struct PaletteInput { + pub input: String, + pub kind: PaletteKind, +} + +impl PaletteInput { + /// Update the current input in the palette, and the kind of palette it is + pub fn update_input(&mut self, input: String, kind: PaletteKind) { + self.kind = kind.get_palette_kind(&input); + self.input = self.kind.get_input(&input).to_string(); + } +} + +#[derive(Clone)] +pub struct PaletteData { + run_id_counter: Arc, + pub run_id: RwSignal, + pub workspace: Arc, + pub status: RwSignal, + pub index: RwSignal, + pub preselect_index: RwSignal>, + pub items: RwSignal>, + pub filtered_items: ReadSignal>, + pub input: RwSignal, + kind: RwSignal, + pub input_editor: EditorData, + pub preview_editor: EditorData, + pub has_preview: RwSignal, + pub keypress: ReadSignal, + /// Listened on for which entry in the palette has been clicked + pub clicked_index: RwSignal>, + pub executed_commands: Rc>>, + pub executed_run_configs: Rc>>, + pub main_split: MainSplitData, + pub references: RwSignal>, + pub source_control: SourceControlData, + pub common: Rc, + left_diff_path: RwSignal>, +} + +impl std::fmt::Debug for PaletteData { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("PaletteData").finish() + } +} + +impl PaletteData { + pub fn new( + cx: Scope, + workspace: Arc, + main_split: MainSplitData, + keypress: ReadSignal, + source_control: SourceControlData, + common: Rc, + ) -> Self { + let status = cx.create_rw_signal(PaletteStatus::Inactive); + let items = cx.create_rw_signal(im::Vector::new()); + let preselect_index = cx.create_rw_signal(None); + let index = cx.create_rw_signal(0); + let references = cx.create_rw_signal(Vec::new()); + let input = cx.create_rw_signal(PaletteInput { + input: "".to_string(), + kind: PaletteKind::File, + }); + let kind = cx.create_rw_signal(PaletteKind::File); + let input_editor = main_split.editors.make_local(cx, common.clone()); + let preview_editor = main_split.editors.make_local(cx, common.clone()); + let has_preview = cx.create_rw_signal(false); + let run_id = cx.create_rw_signal(0); + let run_id_counter = Arc::new(AtomicU64::new(0)); + + let (run_tx, run_rx) = channel(); + { + let run_id = run_id.read_only(); + let input = input.read_only(); + let items = items.read_only(); + let tx = run_tx; + { + let tx = tx.clone(); + // this effect only monitors items change + cx.create_effect(move |_| { + let items = items.get(); + let input = input.get_untracked(); + let run_id = run_id.get_untracked(); + let preselect_index = + preselect_index.try_update(|i| i.take()).unwrap(); + if let Err(err) = + tx.send((run_id, input.input, items, preselect_index)) + { + tracing::error!("{:?}", err); + } + }); + } + // this effect only monitors input change + cx.create_effect(move |last_kind| { + let input = input.get(); + let kind = input.kind; + if last_kind != Some(kind) { + return kind; + } + let items = items.get_untracked(); + let run_id = run_id.get_untracked(); + if let Err(err) = tx.send((run_id, input.input, items, None)) { + tracing::error!("{:?}", err); + } + kind + }); + } + let (resp_tx, resp_rx) = channel(); + { + let run_id = run_id_counter.clone(); + std::thread::Builder::new() + .name("PaletteUpdateProcess".to_owned()) + .spawn(move || { + Self::update_process(run_id, run_rx, resp_tx); + }) + .unwrap(); + } + let (filtered_items, set_filtered_items) = + cx.create_signal(im::Vector::new()); + { + let resp = create_signal_from_channel(resp_rx); + let run_id = run_id.read_only(); + let input = input.read_only(); + cx.create_effect(move |_| { + if let Some(( + filter_run_id, + filter_input, + new_items, + preselect_index, + )) = resp.get() + { + if run_id.get_untracked() == filter_run_id + && input.get_untracked().input == filter_input + { + set_filtered_items.set(new_items); + let i = preselect_index.unwrap_or(0); + index.set(i); + } + } + }); + } + + let clicked_index = cx.create_rw_signal(Option::::None); + let left_diff_path = cx.create_rw_signal(None); + + let palette = Self { + run_id_counter, + main_split, + run_id, + workspace, + status, + index, + preselect_index, + items, + filtered_items, + input_editor, + preview_editor, + has_preview, + input, + kind, + keypress, + clicked_index, + executed_commands: Rc::new(RefCell::new(HashMap::new())), + executed_run_configs: Rc::new(RefCell::new(HashMap::new())), + references, + source_control, + common, + left_diff_path, + }; + + { + let palette = palette.clone(); + let clicked_index = clicked_index.read_only(); + let index = index.write_only(); + cx.create_effect(move |_| { + if let Some(clicked_index) = clicked_index.get() { + index.set(clicked_index); + palette.select(); + } + }); + } + + { + let palette = palette.clone(); + let doc = palette.input_editor.doc(); + let input = palette.input; + let status = palette.status.read_only(); + let preset_kind = palette.kind.read_only(); + // Monitors when the palette's input changes, so that it can update the stored input + // and kind of palette. + cx.create_effect(move |last_input| { + // TODO(minor, perf): this could have perf issues if the user accidentally pasted a huge amount of text into the palette. + let new_input = doc.buffer.with(|buffer| buffer.to_string()); + + let status = status.get_untracked(); + if status == PaletteStatus::Inactive { + // If the status is inactive, we set the input to None, + // so that when we actually run the palette, the input + // can be compared with this None. + return None; + } + + let last_input = last_input.flatten(); + + // If the input is not equivalent to the current input, or not initialized, then we + // need to update the information about the palette. + let changed = last_input.as_deref() != Some(new_input.as_str()); + + if changed { + let new_kind = input + .try_update(|input| { + let kind = input.kind; + input.update_input( + new_input.clone(), + preset_kind.get_untracked(), + ); + if last_input.is_none() || kind != input.kind { + Some(input.kind) + } else { + None + } + }) + .unwrap(); + if let Some(new_kind) = new_kind { + palette.run_inner(new_kind); + } else if input + .with_untracked(|i| i.kind == PaletteKind::WorkspaceSymbol) + { + palette.run_inner(PaletteKind::WorkspaceSymbol); + } + } + Some(new_input) + }); + } + + { + let palette = palette.clone(); + cx.create_effect(move |_| { + let _ = palette.index.get(); + palette.preview(); + }); + } + + { + let palette = palette.clone(); + cx.create_effect(move |_| { + let focus = palette.common.focus.get(); + if focus != Focus::Palette + && palette.status.get_untracked() != PaletteStatus::Inactive + { + palette.cancel(); + } + }); + } + + palette + } + + /// Start and focus the palette for the given kind. + pub fn run(&self, kind: PaletteKind) { + self.common.focus.set(Focus::Palette); + self.status.set(PaletteStatus::Started); + let symbol = kind.symbol(); + self.kind.set(kind); + // Refresh the palette input with only the symbol prefix, losing old content. + self.input_editor.doc().reload(Rope::from(symbol), true); + self.input_editor + .cursor() + .update(|cursor| cursor.set_insert(Selection::caret(symbol.len()))); + } + + /// Get the placeholder text to use in the palette input field. + pub fn placeholder_text(&self) -> &'static str { + match self.kind.get() { + PaletteKind::SshHost => { + "Type [user@]host or select a previously connected workspace below" + } + PaletteKind::DiffFiles => { + if self.left_diff_path.with(Option::is_some) { + "Select right file" + } else { + "Seleft left file" + } + } + _ => "", + } + } + + /// Execute the internal behavior of the palette for the given kind. This ignores updating and + /// focusing the palette input. + fn run_inner(&self, kind: PaletteKind) { + self.has_preview.set(false); + + let run_id = self.run_id_counter.fetch_add(1, Ordering::Relaxed) + 1; + self.run_id.set(run_id); + + match kind { + PaletteKind::PaletteHelp => self.get_palette_help(), + PaletteKind::File | PaletteKind::DiffFiles => { + self.get_files(); + } + PaletteKind::HelpAndFile => self.get_palette_help_and_file(), + PaletteKind::Line => { + self.get_lines(); + } + PaletteKind::Command => { + self.get_commands(); + } + PaletteKind::Workspace => { + self.get_workspaces(); + } + PaletteKind::Reference => { + self.get_references(); + } + PaletteKind::DocumentSymbol => { + self.get_document_symbols(); + } + PaletteKind::WorkspaceSymbol => { + self.get_workspace_symbols(); + } + PaletteKind::SshHost => { + self.get_ssh_hosts(); + } + #[cfg(windows)] + PaletteKind::WslHost => { + self.get_wsl_hosts(); + } + PaletteKind::RunAndDebug => { + self.get_run_configs(); + } + PaletteKind::ColorTheme => { + self.get_color_themes(); + } + PaletteKind::IconTheme => { + self.get_icon_themes(); + } + PaletteKind::Language => { + self.get_languages(); + } + PaletteKind::LineEnding => { + self.get_line_endings(); + } + PaletteKind::SCMReferences => { + self.get_scm_references(); + } + PaletteKind::TerminalProfile => self.get_terminal_profiles(), + } + } + + /// Initialize the palette with a list of the available palette kinds. + fn get_palette_help(&self) { + let items = self.get_palette_help_items(); + self.items.set(items); + } + + fn get_palette_help_items(&self) -> Vector { + PaletteKind::iter() + .filter_map(|kind| { + // Don't include PaletteHelp as the user is already here. + (kind != PaletteKind::PaletteHelp) + .then(|| { + let symbol = kind.symbol(); + + // Only include palette kinds accessible by typing a prefix into the + // palette. + (kind == PaletteKind::File || !symbol.is_empty()) + .then_some(kind) + }) + .flatten() + }) + .filter_map(|kind| kind.command().map(|cmd| (kind, cmd))) + .map(|(kind, cmd)| { + let description = kind.symbol().to_string() + + " " + + cmd.get_message().unwrap_or(""); + + PaletteItem { + content: PaletteItemContent::PaletteHelp { cmd }, + filter_text: description, + score: 0, + indices: vec![], + } + }) + .collect() + } + + fn get_palette_help_and_file(&self) { + let help_items: Vector = self.get_palette_help_items(); + self.get_files_and_prepend(Some(help_items)); + } + + // get the files in the current workspace + // and prepend items if prepend is some + // e.g. help_and_file + fn get_files_and_prepend(&self, prepend: Option>) { + let workspace = self.workspace.clone(); + let set_items = self.items.write_only(); + let send = + create_ext_action(self.common.scope, move |items: Vec| { + let items = items + .into_iter() + .map(|full_path| { + // Strip the workspace prefix off the path, to avoid clutter + let path = + if let Some(workspace_path) = workspace.path.as_ref() { + full_path + .strip_prefix(workspace_path) + .unwrap_or(&full_path) + .to_path_buf() + } else { + full_path.clone() + }; + let filter_text = path.to_string_lossy().into_owned(); + PaletteItem { + content: PaletteItemContent::File { path, full_path }, + filter_text, + score: 0, + indices: Vec::new(), + } + }) + .collect::>(); + let mut new_items = im::Vector::new(); + if let Some(prepend) = prepend { + new_items.append(prepend); + } + new_items.append(items); + set_items.set(new_items); + }); + self.common.proxy.get_files(move |result| { + if let Ok(ProxyResponse::GetFilesResponse { items }) = result { + send(items); + } + }); + } + + /// Initialize the palette with the files in the current workspace. + fn get_files(&self) { + self.get_files_and_prepend(None); + } + + /// Initialize the palette with the lines in the current document. + fn get_lines(&self) { + let editor = self.main_split.active_editor.get_untracked(); + let doc = match editor { + Some(editor) => editor.doc(), + None => { + return; + } + }; + + let buffer = doc.buffer.get_untracked(); + let last_line_number = buffer.last_line() + 1; + let last_line_number_len = last_line_number.to_string().len(); + let items = buffer + .text() + .lines(0..buffer.len()) + .enumerate() + .map(|(i, l)| { + let line_number = i + 1; + let text = format!( + "{}{} {}", + line_number, + vec![" "; last_line_number_len - line_number.to_string().len()] + .join(""), + l + ); + PaletteItem { + content: PaletteItemContent::Line { + line: i, + content: text.clone(), + }, + filter_text: text, + score: 0, + indices: vec![], + } + }) + .collect(); + self.items.set(items); + } + + fn get_commands(&self) { + const EXCLUDED_ITEMS: &[&str] = &["palette.command"]; + + let items = self.keypress.with_untracked(|keypress| { + // Get all the commands we've executed, and sort them by how recently they were + // executed. Ignore commands without descriptions. + let mut items: im::Vector = self + .executed_commands + .borrow() + .iter() + .sorted_by_key(|(_, i)| *i) + .rev() + .filter_map(|(key, _)| { + keypress.commands.get(key).and_then(|c| { + c.kind.desc().as_ref().map(|m| PaletteItem { + content: PaletteItemContent::Command { cmd: c.clone() }, + filter_text: m.to_string(), + score: 0, + indices: vec![], + }) + }) + }) + .collect(); + // Add all the rest of the commands, ignoring palette commands (because we're in it) + // and commands that are sorted earlier due to being executed. + items.extend(keypress.commands.iter().filter_map(|(_, c)| { + if EXCLUDED_ITEMS.contains(&c.kind.str()) { + return None; + } + + if self.executed_commands.borrow().contains_key(c.kind.str()) { + return None; + } + + c.kind.desc().as_ref().map(|m| PaletteItem { + content: PaletteItemContent::Command { cmd: c.clone() }, + filter_text: m.to_string(), + score: 0, + indices: vec![], + }) + })); + + items + }); + + self.items.set(items); + } + + /// Initialize the palette with all the available workspaces, local and remote. + fn get_workspaces(&self) { + let db: Arc = use_context().unwrap(); + let workspaces = db.recent_workspaces().unwrap_or_default(); + + let items = workspaces + .into_iter() + .filter_map(|w| { + let text = w.path.as_ref()?.to_str()?.to_string(); + let filter_text = match &w.kind { + LapceWorkspaceType::Local => text, + LapceWorkspaceType::RemoteSSH(remote) => { + format!("[{remote}] {text}") + } + #[cfg(windows)] + LapceWorkspaceType::RemoteWSL(remote) => { + format!("[{remote}] {text}") + } + }; + Some(PaletteItem { + content: PaletteItemContent::Workspace { workspace: w }, + filter_text, + score: 0, + indices: vec![], + }) + }) + .collect(); + + self.items.set(items); + } + + /// Initialize the list of references in the file, from the current editor location. + fn get_references(&self) { + let items = self + .references + .get_untracked() + .into_iter() + .map(|l| { + let full_path = l.path.clone(); + let mut path = l.path.clone(); + if let Some(workspace_path) = self.workspace.path.as_ref() { + path = path + .strip_prefix(workspace_path) + .unwrap_or(&full_path) + .to_path_buf(); + } + let filter_text = path.to_str().unwrap_or("").to_string(); + PaletteItem { + content: PaletteItemContent::Reference { path, location: l }, + filter_text, + score: 0, + indices: vec![], + } + }) + .collect(); + + self.items.set(items); + } + + fn get_document_symbols(&self) { + let editor = self.main_split.active_editor.get_untracked(); + let doc = match editor { + Some(editor) => editor.doc(), + None => { + self.items.update(|items| items.clear()); + return; + } + }; + let path = doc + .content + .with_untracked(|content| content.path().cloned()); + let path = match path { + Some(path) => path, + None => { + self.items.update(|items| items.clear()); + return; + } + }; + + let set_items = self.items.write_only(); + let send = create_ext_action(self.common.scope, move |result| { + if let Ok(ProxyResponse::GetDocumentSymbols { resp }) = result { + let items = Self::format_document_symbol_resp(resp); + set_items.set(items); + } else { + set_items.update(|items| items.clear()); + } + }); + + self.common.proxy.get_document_symbols(path, move |result| { + send(result); + }); + } + + fn format_document_symbol_resp( + resp: DocumentSymbolResponse, + ) -> im::Vector { + match resp { + DocumentSymbolResponse::Flat(symbols) => symbols + .iter() + .map(|s| { + let mut filter_text = s.name.clone(); + if let Some(container_name) = s.container_name.as_ref() { + filter_text += container_name; + } + PaletteItem { + content: PaletteItemContent::DocumentSymbol { + kind: s.kind, + name: s.name.replace('\n', "↵"), + range: s.location.range, + container_name: s.container_name.clone(), + }, + filter_text, + score: 0, + indices: Vec::new(), + } + }) + .collect(), + DocumentSymbolResponse::Nested(symbols) => { + let mut items = im::Vector::new(); + for s in symbols { + Self::format_document_symbol(&mut items, None, s) + } + items + } + } + } + + fn format_document_symbol( + items: &mut im::Vector, + parent: Option, + s: DocumentSymbol, + ) { + items.push_back(PaletteItem { + content: PaletteItemContent::DocumentSymbol { + kind: s.kind, + name: s.name.replace('\n', "↵"), + range: s.range, + container_name: parent, + }, + filter_text: s.name.clone(), + score: 0, + indices: Vec::new(), + }); + if let Some(children) = s.children { + let parent = Some(s.name.replace('\n', "↵")); + for child in children { + Self::format_document_symbol(items, parent.clone(), child); + } + } + } + + fn get_workspace_symbols(&self) { + let input = self.input.get_untracked().input; + + let set_items = self.items.write_only(); + let send = create_ext_action(self.common.scope, move |result| { + if let Ok(ProxyResponse::GetWorkspaceSymbols { symbols }) = result { + let items: im::Vector = symbols + .iter() + .map(|s| { + // TODO: Should we be using filter text? + let mut filter_text = s.name.clone(); + if let Some(container_name) = s.container_name.as_ref() { + filter_text += container_name; + } + PaletteItem { + content: PaletteItemContent::WorkspaceSymbol { + kind: s.kind, + name: s.name.clone(), + location: EditorLocation { + path: path_from_url(&s.location.uri), + position: Some(EditorPosition::Position( + s.location.range.start, + )), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }, + container_name: s.container_name.clone(), + }, + filter_text, + score: 0, + indices: Vec::new(), + } + }) + .collect(); + set_items.set(items); + } else { + set_items.update(|items| items.clear()); + } + }); + + self.common + .proxy + .get_workspace_symbols(input, move |result| { + send(result); + }); + } + + fn get_ssh_hosts(&self) { + let db: Arc = use_context().unwrap(); + let workspaces = db.recent_workspaces().unwrap_or_default(); + let mut hosts = HashSet::new(); + for workspace in workspaces.iter() { + if let LapceWorkspaceType::RemoteSSH(host) = &workspace.kind { + hosts.insert(host.clone()); + } + } + + let items = hosts + .iter() + .map(|host| PaletteItem { + content: PaletteItemContent::SshHost { host: host.clone() }, + filter_text: host.to_string(), + score: 0, + indices: vec![], + }) + .collect(); + self.items.set(items); + } + + #[cfg(windows)] + fn get_wsl_hosts(&self) { + use std::{os::windows::process::CommandExt, process}; + let cmd = process::Command::new("wsl") + .creation_flags(0x08000000) // CREATE_NO_WINDOW + .arg("-l") + .arg("-v") + .stdout(process::Stdio::piped()) + .output(); + + let distros = if let Ok(proc) = cmd { + let distros = String::from_utf16(bytemuck::cast_slice(&proc.stdout)) + .unwrap_or_default() + .lines() + .skip(1) + .filter_map(|line| { + let line = line.trim_start(); + // let default = line.starts_with('*'); + let name = line + .trim_start_matches('*') + .trim_start() + .split(' ') + .next()?; + Some(name.to_string()) + }) + .collect(); + + distros + } else { + vec![] + }; + + let db: Arc = use_context().unwrap(); + let workspaces = db.recent_workspaces().unwrap_or_default(); + let mut hosts = HashSet::new(); + for distro in distros { + hosts.insert(distro); + } + + for workspace in workspaces.iter() { + if let LapceWorkspaceType::RemoteWSL(host) = &workspace.kind { + hosts.insert(host.host.clone()); + } + } + + let items = hosts + .iter() + .map(|host| PaletteItem { + content: PaletteItemContent::WslHost { + host: crate::workspace::WslHost { host: host.clone() }, + }, + filter_text: host.to_string(), + score: 0, + indices: vec![], + }) + .collect(); + self.items.set(items); + } + + fn set_run_configs(&self, content: String) { + let configs: Option = toml::from_str(&content).ok(); + if configs.is_none() { + if let Some(path) = self.workspace.path.as_ref() { + let path = path.join(".lapce").join("run.toml"); + self.common + .internal_command + .send(InternalCommand::OpenFile { path }); + } + } + + let executed_run_configs = self.executed_run_configs.borrow(); + let mut items = Vec::new(); + if let Some(configs) = configs.as_ref() { + for config in &configs.configs { + items.push(( + executed_run_configs + .get(&(RunDebugMode::Run, config.name.clone())), + PaletteItem { + content: PaletteItemContent::RunAndDebug { + mode: RunDebugMode::Run, + config: config.clone(), + }, + filter_text: format!( + "Run {} {} {}", + config.name, + config.program, + config.args.clone().unwrap_or_default().join(" ") + ), + score: 0, + indices: vec![], + }, + )); + if config.ty.is_some() { + items.push(( + executed_run_configs + .get(&(RunDebugMode::Debug, config.name.clone())), + PaletteItem { + content: PaletteItemContent::RunAndDebug { + mode: RunDebugMode::Debug, + config: config.clone(), + }, + filter_text: format!( + "Debug {} {} {}", + config.name, + config.program, + config.args.clone().unwrap_or_default().join(" ") + ), + score: 0, + indices: vec![], + }, + )); + } + } + } + + items.sort_by_key(|(executed, _item)| std::cmp::Reverse(executed.copied())); + self.items + .set(items.into_iter().map(|(_, item)| item).collect()); + } + + fn get_run_configs(&self) { + if let Some(workspace) = self.common.workspace.path.as_deref() { + let run_toml = workspace.join(".lapce").join("run.toml"); + let (doc, new_doc) = self.main_split.get_doc(run_toml.clone(), None); + if !new_doc { + let content = doc.buffer.with_untracked(|b| b.to_string()); + self.set_run_configs(content); + } else { + let loaded = doc.loaded; + let palette = self.clone(); + self.common.scope.create_effect(move |prev_loaded| { + if prev_loaded == Some(true) { + return true; + } + + let loaded = loaded.get(); + if loaded { + let content = doc.buffer.with_untracked(|b| b.to_string()); + if content.is_empty() { + doc.reload(Rope::from(DEFAULT_RUN_TOML), false); + } + palette.set_run_configs(content); + } + loaded + }); + } + } + } + + fn get_color_themes(&self) { + let config = self.common.config.get_untracked(); + let items = config + .color_theme_list() + .iter() + .map(|name| PaletteItem { + content: PaletteItemContent::ColorTheme { name: name.clone() }, + filter_text: name.clone(), + score: 0, + indices: Vec::new(), + }) + .collect(); + self.preselect_matching( + &items, + &self.common.config.get_untracked().color_theme.name, + ); + self.items.set(items); + } + + fn get_icon_themes(&self) { + let config = self.common.config.get_untracked(); + let items = config + .icon_theme_list() + .iter() + .map(|name| PaletteItem { + content: PaletteItemContent::IconTheme { name: name.clone() }, + filter_text: name.clone(), + score: 0, + indices: Vec::new(), + }) + .collect(); + self.preselect_matching( + &items, + &self.common.config.get_untracked().icon_theme.name, + ); + self.items.set(items); + } + + fn get_languages(&self) { + let langs = LapceLanguage::languages(); + let items = langs + .iter() + .map(|lang| PaletteItem { + content: PaletteItemContent::Language { + name: lang.to_string(), + }, + filter_text: lang.to_string(), + score: 0, + indices: Vec::new(), + }) + .collect(); + if let Some(editor) = self.main_split.active_editor.get_untracked() { + let doc = editor.doc(); + let language = + doc.syntax().with_untracked(|syntax| syntax.language.name()); + self.preselect_matching(&items, language); + } + self.items.set(items); + } + + fn get_line_endings(&self) { + let items = [LineEnding::Lf, LineEnding::CrLf] + .iter() + .map(|l| PaletteItem { + content: PaletteItemContent::LineEnding { kind: *l }, + filter_text: l.as_str().to_string(), + score: 0, + indices: Vec::new(), + }) + .collect(); + if let Some(editor) = self.main_split.active_editor.get_untracked() { + let doc = editor.doc(); + let line_ending = doc.line_ending(); + self.preselect_matching(&items, line_ending.as_str()); + } + self.items.set(items); + } + + fn get_scm_references(&self) { + let branches = self.source_control.branches.get_untracked(); + let tags = self.source_control.tags.get_untracked(); + let mut items: im::Vector = im::Vector::new(); + for refs in branches.into_iter() { + items.push_back(PaletteItem { + content: PaletteItemContent::SCMReference { + name: refs.to_owned(), + }, + filter_text: refs.to_owned(), + score: 0, + indices: Vec::new(), + }); + } + for refs in tags.into_iter() { + items.push_back(PaletteItem { + content: PaletteItemContent::SCMReference { + name: refs.to_owned(), + }, + filter_text: refs.to_owned(), + score: 0, + indices: Vec::new(), + }); + } + self.items.set(items); + } + + fn get_terminal_profiles(&self) { + let profiles = self.common.config.get().terminal.profiles.clone(); + let mut items: im::Vector = im::Vector::new(); + + for (name, profile) in profiles.into_iter() { + let uri = match lsp_types::Url::parse(&format!( + "file://{}", + profile.workdir.unwrap_or_default().display() + )) { + Ok(v) => Some(v), + Err(e) => { + error!("Failed to parse uri: {e}"); + None + } + }; + + items.push_back(PaletteItem { + content: PaletteItemContent::TerminalProfile { + name: name.to_owned(), + profile: lapce_rpc::terminal::TerminalProfile { + name: name.to_owned(), + command: profile.command, + arguments: profile.arguments, + workdir: uri, + environment: profile.environment, + }, + }, + filter_text: name.to_owned(), + score: 0, + indices: Vec::new(), + }); + } + + self.items.set(items); + } + + fn preselect_matching(&self, items: &im::Vector, matching: &str) { + let Some((idx, _)) = items + .iter() + .find_position(|item| item.filter_text == matching) + else { + return; + }; + + self.preselect_index.set(Some(idx)); + } + + fn select(&self) { + let index = self.index.get_untracked(); + let items = self.filtered_items.get_untracked(); + self.close(); + if let Some(item) = items.get(index) { + match &item.content { + PaletteItemContent::PaletteHelp { cmd } => { + let cmd = LapceCommand { + kind: CommandKind::Workbench(cmd.clone()), + data: None, + }; + + self.common.lapce_command.send(cmd); + } + PaletteItemContent::File { full_path, .. } => { + if self.kind.get_untracked() == PaletteKind::DiffFiles { + if let Some(left_path) = + self.left_diff_path.try_update(Option::take).flatten() + { + self.common.internal_command.send( + InternalCommand::OpenDiffFiles { + left_path, + right_path: full_path.clone(), + }, + ); + } else { + self.left_diff_path.set(Some(full_path.clone())); + self.run(PaletteKind::DiffFiles); + } + } else { + self.common.internal_command.send( + InternalCommand::OpenFile { + path: full_path.clone(), + }, + ); + } + } + PaletteItemContent::Line { line, .. } => { + let editor = self.main_split.active_editor.get_untracked(); + let doc = match editor { + Some(editor) => editor.doc(), + None => { + return; + } + }; + let path = doc + .content + .with_untracked(|content| content.path().cloned()); + let path = match path { + Some(path) => path, + None => return, + }; + self.common.internal_command.send( + InternalCommand::JumpToLocation { + location: EditorLocation { + path, + position: Some(EditorPosition::Line(*line)), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }, + }, + ); + } + PaletteItemContent::Command { cmd } => { + self.common.lapce_command.send(cmd.clone()); + } + PaletteItemContent::Workspace { workspace } => { + self.common.window_common.window_command.send( + WindowCommand::SetWorkspace { + workspace: workspace.clone(), + }, + ); + } + PaletteItemContent::Reference { location, .. } => { + self.common.internal_command.send( + InternalCommand::JumpToLocation { + location: location.clone(), + }, + ); + } + PaletteItemContent::SshHost { host } => { + self.common.window_common.window_command.send( + WindowCommand::SetWorkspace { + workspace: LapceWorkspace { + kind: LapceWorkspaceType::RemoteSSH(host.clone()), + path: None, + last_open: 0, + }, + }, + ); + } + #[cfg(windows)] + PaletteItemContent::WslHost { host } => { + self.common.window_common.window_command.send( + WindowCommand::SetWorkspace { + workspace: LapceWorkspace { + kind: LapceWorkspaceType::RemoteWSL(host.clone()), + path: None, + last_open: 0, + }, + }, + ); + } + PaletteItemContent::DocumentSymbol { range, .. } => { + let editor = self.main_split.active_editor.get_untracked(); + let doc = match editor { + Some(editor) => editor.doc(), + None => { + return; + } + }; + let path = doc + .content + .with_untracked(|content| content.path().cloned()); + let path = match path { + Some(path) => path, + None => return, + }; + self.common.internal_command.send( + InternalCommand::JumpToLocation { + location: EditorLocation { + path, + position: Some(EditorPosition::Position( + range.start, + )), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }, + }, + ); + } + PaletteItemContent::WorkspaceSymbol { location, .. } => { + self.common.internal_command.send( + InternalCommand::JumpToLocation { + location: location.clone(), + }, + ); + } + PaletteItemContent::RunAndDebug { mode, config } => { + self.common.internal_command.send( + InternalCommand::RunAndDebug { + mode: *mode, + config: config.clone(), + }, + ); + } + PaletteItemContent::ColorTheme { name } => self + .common + .internal_command + .send(InternalCommand::SetColorTheme { + name: name.clone(), + save: true, + }), + PaletteItemContent::IconTheme { name } => self + .common + .internal_command + .send(InternalCommand::SetIconTheme { + name: name.clone(), + save: true, + }), + PaletteItemContent::Language { name } => { + let editor = self.main_split.active_editor.get_untracked(); + let doc = match editor { + Some(editor) => editor.doc(), + None => { + return; + } + }; + if name.is_empty() || name.to_lowercase().eq("plain text") { + doc.set_syntax(Syntax::plaintext()) + } else { + let lang = match LapceLanguage::from_name(name) { + Some(v) => v, + None => return, + }; + doc.set_language(lang); + } + doc.trigger_syntax_change(None); + } + PaletteItemContent::LineEnding { kind } => { + let Some(editor) = self.main_split.active_editor.get_untracked() + else { + return; + }; + let doc = editor.doc(); + + doc.buffer.update(|buffer| { + buffer.set_line_ending(*kind); + }); + } + PaletteItemContent::SCMReference { name } => { + self.common + .lapce_command + .send(crate::command::LapceCommand { + kind: CommandKind::Workbench( + crate::command::LapceWorkbenchCommand::CheckoutReference, + ), + data: Some(serde_json::json!(name.to_owned())), + }); + } + PaletteItemContent::TerminalProfile { name: _, profile } => self + .common + .internal_command + .send(InternalCommand::NewTerminal { + profile: Some(profile.to_owned()), + }), + } + } else if self.kind.get_untracked() == PaletteKind::SshHost { + let input = self.input.with_untracked(|input| input.input.clone()); + let ssh = SshHost::from_string(&input); + self.common.window_common.window_command.send( + WindowCommand::SetWorkspace { + workspace: LapceWorkspace { + kind: LapceWorkspaceType::RemoteSSH(ssh), + path: None, + last_open: 0, + }, + }, + ); + } + } + + /// Update the preview for the currently active palette item, if it has one. + fn preview(&self) { + if self.status.get_untracked() == PaletteStatus::Inactive { + return; + } + + let index = self.index.get_untracked(); + let items = self.filtered_items.get_untracked(); + if let Some(item) = items.get(index) { + match &item.content { + PaletteItemContent::PaletteHelp { .. } => {} + PaletteItemContent::File { .. } => {} + PaletteItemContent::Line { line, .. } => { + self.has_preview.set(true); + let editor = self.main_split.active_editor.get_untracked(); + let doc = match editor { + Some(editor) => editor.doc(), + None => { + return; + } + }; + let path = doc + .content + .with_untracked(|content| content.path().cloned()); + let path = match path { + Some(path) => path, + None => return, + }; + self.preview_editor.update_doc(doc); + self.preview_editor.go_to_location( + EditorLocation { + path, + position: Some(EditorPosition::Line(*line)), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }, + false, + None, + ); + } + PaletteItemContent::Command { .. } => {} + PaletteItemContent::Workspace { .. } => {} + PaletteItemContent::RunAndDebug { .. } => {} + PaletteItemContent::SshHost { .. } => {} + #[cfg(windows)] + PaletteItemContent::WslHost { .. } => {} + PaletteItemContent::Language { .. } => {} + PaletteItemContent::LineEnding { .. } => {} + PaletteItemContent::Reference { location, .. } => { + self.has_preview.set(true); + let (doc, new_doc) = + self.main_split.get_doc(location.path.clone(), None); + self.preview_editor.update_doc(doc); + self.preview_editor.go_to_location( + location.clone(), + new_doc, + None, + ); + } + PaletteItemContent::DocumentSymbol { range, .. } => { + self.has_preview.set(true); + let editor = self.main_split.active_editor.get_untracked(); + let doc = match editor { + Some(editor) => editor.doc(), + None => { + return; + } + }; + let path = doc + .content + .with_untracked(|content| content.path().cloned()); + let path = match path { + Some(path) => path, + None => return, + }; + self.preview_editor.update_doc(doc); + self.preview_editor.go_to_location( + EditorLocation { + path, + position: Some(EditorPosition::Position(range.start)), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }, + false, + None, + ); + } + PaletteItemContent::WorkspaceSymbol { location, .. } => { + self.has_preview.set(true); + let (doc, new_doc) = + self.main_split.get_doc(location.path.clone(), None); + self.preview_editor.update_doc(doc); + self.preview_editor.go_to_location( + location.clone(), + new_doc, + None, + ); + } + PaletteItemContent::ColorTheme { name } => self + .common + .internal_command + .send(InternalCommand::SetColorTheme { + name: name.clone(), + save: false, + }), + PaletteItemContent::IconTheme { name } => self + .common + .internal_command + .send(InternalCommand::SetIconTheme { + name: name.clone(), + save: false, + }), + PaletteItemContent::SCMReference { .. } => {} + PaletteItemContent::TerminalProfile { .. } => {} + } + } + } + + /// Cancel the palette, doing cleanup specific to the palette kind. + fn cancel(&self) { + if let PaletteKind::ColorTheme | PaletteKind::IconTheme = + self.kind.get_untracked() + { + // TODO(minor): We don't really need to reload the *entire config* here! + self.common + .internal_command + .send(InternalCommand::ReloadConfig); + } + + self.left_diff_path.set(None); + self.close(); + } + + /// Close the palette, reverting focus back to the workbench. + fn close(&self) { + self.status.set(PaletteStatus::Inactive); + if self.common.focus.get_untracked() == Focus::Palette { + self.common.focus.set(Focus::Workbench); + } + self.has_preview.set(false); + self.items.update(|items| items.clear()); + self.input_editor.doc().reload(Rope::from(""), true); + self.input_editor + .cursor() + .update(|cursor| cursor.set_insert(Selection::caret(0))); + } + + /// Move to the next entry in the palette list, wrapping around if needed. + fn next(&self) { + let index = self.index.get_untracked(); + let len = self.filtered_items.with_untracked(|i| i.len()); + let new_index = Movement::Down.update_index(index, len, 1, true); + self.index.set(new_index); + } + + /// Move to the previous entry in the palette list, wrapping around if needed. + fn previous(&self) { + let index = self.index.get_untracked(); + let len = self.filtered_items.with_untracked(|i| i.len()); + let new_index = Movement::Up.update_index(index, len, 1, true); + self.index.set(new_index); + } + + fn next_page(&self) { + // TODO: implement + } + + fn previous_page(&self) { + // TODO: implement + } + + fn run_focus_command(&self, cmd: &FocusCommand) -> CommandExecuted { + match cmd { + FocusCommand::ModalClose => { + self.cancel(); + } + FocusCommand::ListNext => { + self.next(); + } + FocusCommand::ListNextPage => { + self.next_page(); + } + FocusCommand::ListPrevious => { + self.previous(); + } + FocusCommand::ListPreviousPage => { + self.previous_page(); + } + FocusCommand::ListSelect => { + self.select(); + } + _ => return CommandExecuted::No, + } + CommandExecuted::Yes + } + + fn filter_items( + run_id: Arc, + current_run_id: u64, + input: &str, + items: im::Vector, + matcher: &mut nucleo::Matcher, + ) -> Option> { + if input.is_empty() { + return Some(items); + } + + let pattern = nucleo::pattern::Pattern::parse( + input, + nucleo::pattern::CaseMatching::Ignore, + nucleo::pattern::Normalization::Smart, + ); + + // NOTE: We collect into a Vec to sort as we are hitting a worst-case behavior in + // `im::Vector` that can lead to a stack overflow! + let mut filtered_items = Vec::new(); + let mut indices = Vec::new(); + let mut filter_text_buf = Vec::new(); + for i in &items { + // If the run id has ever changed, then we'll just bail out of this filtering to avoid + // wasting effort. This would happen, for example, on the user continuing to type. + if run_id.load(std::sync::atomic::Ordering::Acquire) != current_run_id { + return None; + } + + indices.clear(); + filter_text_buf.clear(); + let filter_text = Utf32Str::new(&i.filter_text, &mut filter_text_buf); + if let Some(score) = pattern.indices(filter_text, matcher, &mut indices) + { + let mut item = i.clone(); + item.score = score; + item.indices = indices.iter().map(|i| *i as usize).collect(); + filtered_items.push(item); + } + } + + filtered_items.sort_by(|a, b| { + let order = b.score.cmp(&a.score); + match order { + std::cmp::Ordering::Equal => a.filter_text.cmp(&b.filter_text), + _ => order, + } + }); + + if run_id.load(std::sync::atomic::Ordering::Acquire) != current_run_id { + return None; + } + Some(filtered_items.into()) + } + + fn update_process( + run_id: Arc, + receiver: Receiver<(u64, String, im::Vector, Option)>, + resp_tx: Sender<(u64, String, im::Vector, Option)>, + ) { + fn receive_batch( + receiver: &Receiver<( + u64, + String, + im::Vector, + Option, + )>, + ) -> Result<(u64, String, im::Vector, Option)> { + let (mut run_id, mut input, mut items, mut preselect_index) = + receiver.recv()?; + loop { + match receiver.try_recv() { + Ok(update) => { + run_id = update.0; + input = update.1; + items = update.2; + preselect_index = update.3; + } + Err(TryRecvError::Empty) => break, + Err(TryRecvError::Disconnected) => break, + } + } + Ok((run_id, input, items, preselect_index)) + } + + let mut matcher = + nucleo::Matcher::new(nucleo::Config::DEFAULT.match_paths()); + loop { + if let Ok((current_run_id, input, items, preselect_index)) = + receive_batch(&receiver) + { + if let Some(filtered_items) = Self::filter_items( + run_id.clone(), + current_run_id, + &input, + items, + &mut matcher, + ) { + if let Err(err) = resp_tx.send(( + current_run_id, + input, + filtered_items, + preselect_index, + )) { + tracing::error!("{:?}", err); + } + } + } else { + return; + } + } + } +} + +impl KeyPressFocus for PaletteData { + fn get_mode(&self) -> lapce_core::mode::Mode { + Mode::Insert + } + + fn check_condition( + &self, + condition: crate::keypress::condition::Condition, + ) -> bool { + matches!( + condition, + Condition::ListFocus | Condition::PaletteFocus | Condition::ModalFocus + ) + } + + fn run_command( + &self, + command: &crate::command::LapceCommand, + count: Option, + mods: Modifiers, + ) -> CommandExecuted { + match &command.kind { + CommandKind::Workbench(_) => {} + CommandKind::Scroll(_) => {} + CommandKind::Focus(cmd) => { + self.run_focus_command(cmd); + } + CommandKind::Edit(_) + | CommandKind::Move(_) + | CommandKind::MultiSelection(_) => { + self.input_editor.run_command(command, count, mods); + } + CommandKind::MotionMode(_) => {} + } + CommandExecuted::Yes + } + + fn receive_char(&self, c: &str) { + self.input_editor.receive_char(c); + } +} diff --git a/lapce-app/src/palette/item.rs b/lapce-app/src/palette/item.rs new file mode 100644 index 0000000..8f0cf04 --- /dev/null +++ b/lapce-app/src/palette/item.rs @@ -0,0 +1,87 @@ +use std::path::PathBuf; + +use lapce_core::line_ending::LineEnding; +use lapce_rpc::dap_types::RunDebugConfig; +use lsp_types::{Range, SymbolKind}; + +use crate::{ + command::{LapceCommand, LapceWorkbenchCommand}, + debug::RunDebugMode, + editor::location::EditorLocation, + workspace::{LapceWorkspace, SshHost}, +}; + +#[derive(Clone, Debug, PartialEq)] +pub struct PaletteItem { + pub content: PaletteItemContent, + pub filter_text: String, + pub score: u32, + pub indices: Vec, +} + +#[derive(Clone, Debug, PartialEq)] +pub enum PaletteItemContent { + PaletteHelp { + cmd: LapceWorkbenchCommand, + }, + File { + path: PathBuf, + full_path: PathBuf, + }, + Line { + line: usize, + content: String, + }, + Command { + cmd: LapceCommand, + }, + Workspace { + workspace: LapceWorkspace, + }, + Reference { + path: PathBuf, + location: EditorLocation, + }, + DocumentSymbol { + kind: SymbolKind, + name: String, + range: Range, + container_name: Option, + }, + WorkspaceSymbol { + kind: SymbolKind, + name: String, + container_name: Option, + location: EditorLocation, + }, + SshHost { + host: SshHost, + }, + #[cfg(windows)] + WslHost { + host: crate::workspace::WslHost, + }, + RunAndDebug { + mode: RunDebugMode, + config: RunDebugConfig, + }, + ColorTheme { + name: String, + }, + IconTheme { + name: String, + }, + Language { + name: String, + }, + LineEnding { + kind: LineEnding, + }, + SCMReference { + name: String, + }, + TerminalProfile { + name: String, + profile: lapce_rpc::terminal::TerminalProfile, + }, +} diff --git a/lapce-app/src/palette/kind.rs b/lapce-app/src/palette/kind.rs new file mode 100644 index 0000000..1a1b894 --- /dev/null +++ b/lapce-app/src/palette/kind.rs @@ -0,0 +1,162 @@ +use strum_macros::EnumIter; + +use crate::command::LapceWorkbenchCommand; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, EnumIter)] +pub enum PaletteKind { + PaletteHelp, + File, + Line, + Command, + Workspace, + Reference, + DocumentSymbol, + WorkspaceSymbol, + SshHost, + #[cfg(windows)] + WslHost, + RunAndDebug, + ColorTheme, + IconTheme, + Language, + LineEnding, + SCMReferences, + TerminalProfile, + DiffFiles, + HelpAndFile, +} + +impl PaletteKind { + /// The symbol/prefix that is used to signify the behavior of the palette. + pub fn symbol(&self) -> &'static str { + match &self { + PaletteKind::PaletteHelp => "?", + PaletteKind::Line => "/", + PaletteKind::DocumentSymbol => "@", + PaletteKind::WorkspaceSymbol => "#", + // PaletteKind::GlobalSearch => "?", + PaletteKind::Workspace => ">", + PaletteKind::Command => ":", + PaletteKind::TerminalProfile => "<", + PaletteKind::File + | PaletteKind::Reference + | PaletteKind::SshHost + | PaletteKind::RunAndDebug + | PaletteKind::ColorTheme + | PaletteKind::IconTheme + | PaletteKind::Language + | PaletteKind::LineEnding + | PaletteKind::SCMReferences + | PaletteKind::HelpAndFile + | PaletteKind::DiffFiles => "", + #[cfg(windows)] + PaletteKind::WslHost => "", + } + } + + /// Extract the palette kind from the input string. This is most often a prefix. + pub fn from_input(input: &str) -> PaletteKind { + match input { + _ if input.starts_with('?') => PaletteKind::PaletteHelp, + _ if input.starts_with('/') => PaletteKind::Line, + _ if input.starts_with('@') => PaletteKind::DocumentSymbol, + _ if input.starts_with('#') => PaletteKind::WorkspaceSymbol, + _ if input.starts_with('>') => PaletteKind::Workspace, + _ if input.starts_with(':') => PaletteKind::Command, + _ if input.starts_with('<') => PaletteKind::TerminalProfile, + _ => PaletteKind::File, + } + } + + /// Get the [`LapceWorkbenchCommand`] that opens this palette kind, if one exists. + pub fn command(self) -> Option { + match self { + PaletteKind::PaletteHelp => Some(LapceWorkbenchCommand::PaletteHelp), + PaletteKind::Line => Some(LapceWorkbenchCommand::PaletteLine), + PaletteKind::DocumentSymbol => { + Some(LapceWorkbenchCommand::PaletteSymbol) + } + PaletteKind::WorkspaceSymbol => { + Some(LapceWorkbenchCommand::PaletteWorkspaceSymbol) + } + PaletteKind::Workspace => Some(LapceWorkbenchCommand::PaletteWorkspace), + PaletteKind::Command => Some(LapceWorkbenchCommand::PaletteCommand), + PaletteKind::File => Some(LapceWorkbenchCommand::Palette), + PaletteKind::HelpAndFile => { + Some(LapceWorkbenchCommand::PaletteHelpAndFile) + } + PaletteKind::Reference => None, // InternalCommand::PaletteReferences + PaletteKind::SshHost => Some(LapceWorkbenchCommand::ConnectSshHost), + #[cfg(windows)] + PaletteKind::WslHost => Some(LapceWorkbenchCommand::ConnectWslHost), + PaletteKind::RunAndDebug => { + Some(LapceWorkbenchCommand::PaletteRunAndDebug) + } + PaletteKind::ColorTheme => Some(LapceWorkbenchCommand::ChangeColorTheme), + PaletteKind::IconTheme => Some(LapceWorkbenchCommand::ChangeIconTheme), + PaletteKind::Language => Some(LapceWorkbenchCommand::ChangeFileLanguage), + PaletteKind::LineEnding => { + Some(LapceWorkbenchCommand::ChangeFileLineEnding) + } + PaletteKind::SCMReferences => { + Some(LapceWorkbenchCommand::PaletteSCMReferences) + } + PaletteKind::TerminalProfile => None, // InternalCommand::NewTerminal + PaletteKind::DiffFiles => Some(LapceWorkbenchCommand::DiffFiles), + } + } + + // pub fn has_preview(&self) -> bool { + // matches!( + // self, + // PaletteType::Line + // | PaletteType::DocumentSymbol + // | PaletteType::WorkspaceSymbol + // | PaletteType::GlobalSearch + // | PaletteType::Reference + // ) + // } + + pub fn get_input<'a>(&self, input: &'a str) -> &'a str { + match self { + #[cfg(windows)] + PaletteKind::WslHost => input, + PaletteKind::File + | PaletteKind::Reference + | PaletteKind::SshHost + | PaletteKind::RunAndDebug + | PaletteKind::ColorTheme + | PaletteKind::IconTheme + | PaletteKind::Language + | PaletteKind::LineEnding + | PaletteKind::SCMReferences | PaletteKind::HelpAndFile + | PaletteKind::DiffFiles => input, + PaletteKind::PaletteHelp + | PaletteKind::Command + | PaletteKind::Workspace + | PaletteKind::DocumentSymbol + | PaletteKind::WorkspaceSymbol + | PaletteKind::Line + | PaletteKind::TerminalProfile + // | PaletteType::GlobalSearch + => input.get(1..).unwrap_or(""), + } + } + + /// Get the palette kind that it should be considered as based on the current + /// [`PaletteKind`] and the current input. + pub fn get_palette_kind(&self, input: &str) -> PaletteKind { + if self == &PaletteKind::HelpAndFile && input.is_empty() { + return *self; + } + + if self != &PaletteKind::File + && self != &PaletteKind::HelpAndFile + && self.symbol() == "" + { + return *self; + } + + PaletteKind::from_input(input) + } +} diff --git a/lapce-app/src/panel/call_hierarchy_view.rs b/lapce-app/src/panel/call_hierarchy_view.rs new file mode 100644 index 0000000..0c4862b --- /dev/null +++ b/lapce-app/src/panel/call_hierarchy_view.rs @@ -0,0 +1,251 @@ +use std::{ops::AddAssign, rc::Rc}; + +use floem::{ + IntoView, View, ViewId, + reactive::{RwSignal, SignalGet, SignalUpdate, SignalWith}, + style::CursorStyle, + views::{ + Decorators, VirtualVector, container, empty, label, scroll, stack, svg, + virtual_stack, + }, +}; +use lsp_types::{CallHierarchyItem, Range}; + +use super::position::PanelPosition; +use crate::{ + command::InternalCommand, + config::{color::LapceColor, icon::LapceIcons}, + editor::location::EditorLocation, + window_tab::{CommonData, WindowTabData}, +}; + +#[derive(Clone, Debug)] +pub struct CallHierarchyData { + pub root: RwSignal>>, + pub common: Rc, + pub scroll_to_line: RwSignal>, +} + +#[derive(Debug, Clone)] +pub struct CallHierarchyItemData { + pub view_id: ViewId, + pub item: Rc, + pub from_range: Range, + pub init: bool, + pub open: RwSignal, + pub children: RwSignal>>, +} + +impl CallHierarchyItemData { + pub fn child_count(&self) -> usize { + let mut count = 1; + if self.open.get() { + for child in self.children.get_untracked() { + count += child.with(|x| x.child_count()) + } + } + count + } + + pub fn find_by_id( + root: RwSignal, + view_id: ViewId, + ) -> Option> { + if root.get_untracked().view_id == view_id { + Some(root) + } else { + root.get_untracked() + .children + .get_untracked() + .into_iter() + .find_map(|x| Self::find_by_id(x, view_id)) + } + } +} + +fn get_children( + data: RwSignal, + next: &mut usize, + min: usize, + max: usize, + level: usize, +) -> Vec<(usize, usize, RwSignal)> { + let mut children = Vec::new(); + if *next >= min && *next < max { + children.push((*next, level, data)); + } else if *next >= max { + return children; + } + next.add_assign(1); + if data.get_untracked().open.get() { + for child in data.get().children.get_untracked() { + let child_children = get_children(child, next, min, max, level + 1); + children.extend(child_children); + if *next > max { + break; + } + } + } + children +} + +pub struct VirtualList { + root: Option>, +} + +impl VirtualList { + pub fn new(root: Option>) -> Self { + Self { root } + } +} + +impl VirtualVector<(usize, usize, RwSignal)> for VirtualList { + fn total_len(&self) -> usize { + if let Some(root) = &self.root { + root.with(|x| x.child_count()) + } else { + 0 + } + } + + fn slice( + &mut self, + range: std::ops::Range, + ) -> impl Iterator)> { + if let Some(root) = &self.root { + let min = range.start; + let max = range.end; + let children = get_children(*root, &mut 0, min, max, 0); + children.into_iter() + } else { + Vec::new().into_iter() + } + } +} +pub fn show_hierarchy_panel( + window_tab_data: Rc, + _position: PanelPosition, +) -> impl View { + let call_hierarchy_data = window_tab_data.call_hierarchy_data.clone(); + let config = call_hierarchy_data.common.config; + let ui_line_height = call_hierarchy_data.common.ui_line_height; + let scroll_to_line = call_hierarchy_data.scroll_to_line; + scroll( + virtual_stack( + move || VirtualList::new(call_hierarchy_data.root.get()), + move |(_, _, item)| item.get_untracked().view_id, + move |(_, level, rw_data)| { + let data = rw_data.get_untracked(); + let open = data.open; + let kind = data.item.kind; + stack(( + container( + svg(move || { + let config = config.get(); + let svg_str = match open.get() { + true => LapceIcons::ITEM_OPENED, + false => LapceIcons::ITEM_CLOSED, + }; + config.ui_svg(svg_str) + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.size(size, size) + .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + }) + ) + .style(|s| s.padding(4.0).margin_left(6.0).margin_right(2.0)) + .on_click_stop({ + let window_tab_data = window_tab_data.clone(); + move |_x| { + open.update(|x| { + *x = !*x; + }); + if !rw_data.get_untracked().init { + window_tab_data.common.internal_command.send( + InternalCommand::CallHierarchyIncoming { + item_id: rw_data.get_untracked().view_id, + }, + ); + } + } + }), + svg(move || { + let config = config.get(); + config + .symbol_svg(&kind) + .unwrap_or_else(|| config.ui_svg(LapceIcons::FILE)) + }).style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.min_width(size) + .size(size, size) + .margin_right(5.0) + .color(config.symbol_color(&kind).unwrap_or_else(|| { + config.color(LapceColor::LAPCE_ICON_ACTIVE) + })) + }), + data.item.name.clone().into_view(), + if data.item.detail.is_some() { + label(move || { + data.item.detail.clone().unwrap_or_default().replace('\n', "↵") + }).style(move |s| s.margin_left(6.0) + .color(config.get().color(LapceColor::EDITOR_DIM)) + ).into_any() + } else { + empty().into_any() + }, + )) + .style(move |s| { + s.padding_right(5.0) + .height(ui_line_height.get()) + .padding_left((level * 10) as f32) + .items_center() + .hover(|s| { + s.background( + config + .get() + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + .cursor(CursorStyle::Pointer) + }) + }) + .on_click_stop({ + let window_tab_data = window_tab_data.clone(); + let data = rw_data; + move |_| { + if !rw_data.get_untracked().init { + window_tab_data.common.internal_command.send( + InternalCommand::CallHierarchyIncoming { item_id: rw_data.get_untracked().view_id }, + ); + } + let data = data.get_untracked(); + if let Ok(path) = data.item.uri.to_file_path() { + window_tab_data + .common + .internal_command + .send(InternalCommand::JumpToLocation { location: EditorLocation { + path, + position: Some(crate::editor::location::EditorPosition::Position(data.from_range.start)), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + } }); + } + } + }) + }, + ).item_size_fixed(move || ui_line_height.get()) + .style(|s| s.flex_col().absolute().min_width_full()), + ) + .style(|s| s.absolute().size_full()) + .scroll_to(move || { + if let Some(line) = scroll_to_line.get() { + let line_height = ui_line_height.get(); + Some((0.0, line * line_height).into()) + } else { + None + } + }) +} diff --git a/lapce-app/src/panel/data.rs b/lapce-app/src/panel/data.rs new file mode 100644 index 0000000..b18f06d --- /dev/null +++ b/lapce-app/src/panel/data.rs @@ -0,0 +1,464 @@ +use std::{rc::Rc, sync::Arc}; + +use floem::{ + kurbo::Size, + reactive::{ + Memo, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith, use_context, + }, +}; +use serde::{Deserialize, Serialize}; + +use super::{ + kind::PanelKind, + position::{PanelContainerPosition, PanelPosition}, + style::PanelStyle, +}; +use crate::{ + db::LapceDb, + window_tab::{CommonData, Focus}, +}; + +pub type PanelOrder = im::HashMap>; + +pub fn default_panel_order() -> PanelOrder { + let mut order = PanelOrder::new(); + order.insert( + PanelPosition::LeftTop, + im::vector![ + PanelKind::FileExplorer, + PanelKind::Plugin, + PanelKind::SourceControl, + PanelKind::Debug, + ], + ); + order.insert( + PanelPosition::BottomLeft, + im::vector![ + PanelKind::Terminal, + PanelKind::Search, + PanelKind::Problem, + PanelKind::CallHierarchy, + PanelKind::References, + PanelKind::Implementation + ], + ); + order.insert( + PanelPosition::RightTop, + im::vector![PanelKind::DocumentSymbol,], + ); + + order +} + +#[derive(Clone, Copy, Serialize, Deserialize, Hash, PartialEq, Eq)] +pub enum PanelSection { + OpenEditor, + FileExplorer, + Error, + Warn, + Changes, + Installed, + Available, + Process, + Variable, + StackFrame, + Breakpoint, +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct PanelSize { + pub left: f64, + pub left_split: f64, + pub bottom: f64, + pub bottom_split: f64, + pub right: f64, + pub right_split: f64, +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct PanelInfo { + pub panels: PanelOrder, + pub styles: im::HashMap, + pub size: PanelSize, + pub sections: im::HashMap, +} + +#[derive(Clone)] +pub struct PanelData { + pub panels: RwSignal, + pub styles: RwSignal>, + pub size: RwSignal, + pub available_size: Memo, + pub sections: RwSignal>>, + pub common: Rc, +} + +impl PanelData { + pub fn new( + cx: Scope, + panels: im::HashMap>, + available_size: Memo, + sections: im::HashMap, + common: Rc, + ) -> Self { + let panels = cx.create_rw_signal(panels); + + let mut styles = im::HashMap::new(); + styles.insert( + PanelPosition::LeftTop, + PanelStyle { + active: 0, + shown: true, + maximized: false, + }, + ); + styles.insert( + PanelPosition::LeftBottom, + PanelStyle { + active: 0, + shown: false, + maximized: false, + }, + ); + styles.insert( + PanelPosition::BottomLeft, + PanelStyle { + active: 0, + shown: true, + maximized: false, + }, + ); + styles.insert( + PanelPosition::BottomRight, + PanelStyle { + active: 0, + shown: false, + maximized: false, + }, + ); + styles.insert( + PanelPosition::RightTop, + PanelStyle { + active: 0, + shown: false, + maximized: false, + }, + ); + styles.insert( + PanelPosition::RightBottom, + PanelStyle { + active: 0, + shown: false, + maximized: false, + }, + ); + let styles = cx.create_rw_signal(styles); + let size = cx.create_rw_signal(PanelSize { + left: 250.0, + left_split: 0.5, + bottom: 300.0, + bottom_split: 0.5, + right: 250.0, + right_split: 0.5, + }); + let sections = cx.create_rw_signal( + sections + .into_iter() + .map(|(key, value)| (key, cx.create_rw_signal(value))) + .collect(), + ); + + Self { + panels, + styles, + size, + available_size, + sections, + common, + } + } + + pub fn panel_info(&self) -> PanelInfo { + PanelInfo { + panels: self.panels.get_untracked(), + styles: self.styles.get_untracked(), + size: self.size.get_untracked(), + sections: self + .sections + .get_untracked() + .into_iter() + .map(|(key, value)| (key, value.get_untracked())) + .collect(), + } + } + + pub fn is_container_shown( + &self, + position: &PanelContainerPosition, + tracked: bool, + ) -> bool { + self.is_position_shown(&position.first(), tracked) + || self.is_position_shown(&position.second(), tracked) + } + + pub fn is_position_empty( + &self, + position: &PanelPosition, + tracked: bool, + ) -> bool { + if tracked { + self.panels + .with(|panels| panels.get(position).map(|p| p.is_empty())) + .unwrap_or(true) + } else { + self.panels + .with_untracked(|panels| panels.get(position).map(|p| p.is_empty())) + .unwrap_or(true) + } + } + + pub fn is_position_shown( + &self, + position: &PanelPosition, + tracked: bool, + ) -> bool { + let styles = if tracked { + self.styles.get() + } else { + self.styles.get_untracked() + }; + styles.get(position).map(|s| s.shown).unwrap_or(false) + } + + pub fn panel_position( + &self, + kind: &PanelKind, + ) -> Option<(usize, PanelPosition)> { + self.panels + .with_untracked(|panels| panel_position(panels, kind)) + } + + pub fn is_panel_visible(&self, kind: &PanelKind) -> bool { + if let Some((index, position)) = self.panel_position(kind) { + if let Some(style) = self + .styles + .with_untracked(|styles| styles.get(&position).cloned()) + { + return style.active == index && style.shown; + } + } + false + } + + pub fn show_panel(&self, kind: &PanelKind) { + if let Some((index, position)) = self.panel_position(kind) { + self.styles.update(|styles| { + if let Some(style) = styles.get_mut(&position) { + style.shown = true; + style.active = index; + } + }); + } + } + + pub fn hide_panel(&self, kind: &PanelKind) { + if let Some((_, position)) = self.panel_position(kind) { + if let Some((active_panel, _)) = + self.active_panel_at_position(&position, false) + { + if &active_panel == kind { + self.set_shown(&position, false); + let peer_position = position.peer(); + if let Some(order) = self + .panels + .with_untracked(|panels| panels.get(&peer_position).cloned()) + { + if order.is_empty() { + self.set_shown(&peer_position, false); + } + } + } + } + } + } + + /// Get the active panel kind at that position, if any. + /// `tracked` decides whether it should track the signal or not. + pub fn active_panel_at_position( + &self, + position: &PanelPosition, + tracked: bool, + ) -> Option<(PanelKind, bool)> { + let style = if tracked { + self.styles.with(|styles| styles.get(position).cloned())? + } else { + self.styles + .with_untracked(|styles| styles.get(position).cloned())? + }; + let order = if tracked { + self.panels.with(|panels| panels.get(position).cloned())? + } else { + self.panels + .with_untracked(|panels| panels.get(position).cloned())? + }; + order + .get(style.active) + .cloned() + .or_else(|| order.last().cloned()) + .map(|p| (p, style.shown)) + } + + pub fn set_shown(&self, position: &PanelPosition, shown: bool) { + self.styles.update(|styles| { + if let Some(style) = styles.get_mut(position) { + style.shown = shown; + } + }); + } + + pub fn toggle_active_maximize(&self) { + let focus = self.common.focus.get_untracked(); + if let Focus::Panel(kind) = focus { + if let Some((_, pos)) = self.panel_position(&kind) { + if pos.is_bottom() { + self.toggle_bottom_maximize(); + } + } + } + } + + pub fn toggle_maximize(&self, kind: &PanelKind) { + if let Some((_, p)) = self.panel_position(kind) { + if p.is_bottom() { + self.toggle_bottom_maximize(); + } + } + } + + pub fn toggle_bottom_maximize(&self) { + let maximized = !self.panel_bottom_maximized(false); + self.styles.update(|styles| { + if let Some(style) = styles.get_mut(&PanelPosition::BottomLeft) { + style.maximized = maximized; + } + if let Some(style) = styles.get_mut(&PanelPosition::BottomRight) { + style.maximized = maximized; + } + }); + } + + pub fn panel_bottom_maximized(&self, tracked: bool) -> bool { + let styles = if tracked { + self.styles.get() + } else { + self.styles.get_untracked() + }; + styles + .get(&PanelPosition::BottomLeft) + .map(|p| p.maximized) + .unwrap_or(false) + || styles + .get(&PanelPosition::BottomRight) + .map(|p| p.maximized) + .unwrap_or(false) + } + + pub fn toggle_container_visual(&self, position: &PanelContainerPosition) { + let is_hidden = !self.is_container_shown(position, false); + if is_hidden { + self.styles.update(|styles| { + let style = styles.entry(position.first()).or_default(); + style.shown = true; + let style = styles.entry(position.second()).or_default(); + style.shown = true; + }); + } else { + if let Some((kind, _)) = + self.active_panel_at_position(&position.second(), false) + { + self.hide_panel(&kind); + } + if let Some((kind, _)) = + self.active_panel_at_position(&position.first(), false) + { + self.hide_panel(&kind); + } + self.styles.update(|styles| { + let style = styles.entry(position.first()).or_default(); + style.shown = false; + let style = styles.entry(position.second()).or_default(); + style.shown = false; + }); + } + } + + pub fn move_panel_to_position(&self, kind: PanelKind, position: &PanelPosition) { + let current_position = self.panel_position(&kind); + if current_position.as_ref().map(|(_, pos)| pos) == Some(position) { + return; + } + + let mut new_index_at_old_position = None; + let index = self + .panels + .try_update(|panels| { + if let Some((index, current_position)) = current_position { + if let Some(panels) = panels.get_mut(¤t_position) { + panels.remove(index); + + let max_index = panels.len().saturating_sub(1); + if index > max_index { + new_index_at_old_position = Some(max_index); + } + } + } + let panels = panels.entry(*position).or_default(); + panels.push_back(kind); + panels.len() - 1 + }) + .unwrap(); + self.styles.update(|styles| { + if let Some((_, current_position)) = current_position { + if let Some(new_index) = new_index_at_old_position { + let style = styles.entry(current_position).or_default(); + style.active = new_index; + } + } + + let style = styles.entry(*position).or_default(); + style.active = index; + style.shown = true; + }); + + let db: Arc = use_context().unwrap(); + db.save_panel_orders(self.panels.get_untracked()); + } + + pub fn section_open(&self, section: PanelSection) -> RwSignal { + let open = self + .sections + .with_untracked(|sections| sections.get(§ion).cloned()); + if let Some(open) = open { + return open; + } + + let open = self.common.scope.create_rw_signal(true); + self.sections.update(|sections| { + sections.insert(section, open); + }); + open + } +} + +pub fn panel_position( + order: &PanelOrder, + kind: &PanelKind, +) -> Option<(usize, PanelPosition)> { + for (pos, panels) in order.iter() { + let index = panels.iter().position(|k| k == kind); + if let Some(index) = index { + return Some((index, *pos)); + } + } + None +} diff --git a/lapce-app/src/panel/debug_view.rs b/lapce-app/src/panel/debug_view.rs new file mode 100644 index 0000000..d23e740 --- /dev/null +++ b/lapce-app/src/panel/debug_view.rs @@ -0,0 +1,758 @@ +use std::{rc::Rc, sync::Arc}; + +use floem::{ + View, + event::EventListener, + peniko::Color, + reactive::{ + ReadSignal, RwSignal, SignalGet, SignalUpdate, SignalWith, create_rw_signal, + }, + style::CursorStyle, + text::Style as FontStyle, + views::{ + Decorators, container, dyn_stack, label, scroll, stack, svg, text, + virtual_stack, + }, +}; +use lapce_rpc::{ + dap_types::{DapId, ThreadId}, + terminal::TermId, +}; + +use super::{data::PanelSection, position::PanelPosition, view::PanelBuilder}; +use crate::{ + app::clickable_icon, + command::InternalCommand, + config::{LapceConfig, color::LapceColor, icon::LapceIcons}, + debug::{DapVariable, RunDebugMode, StackTraceData}, + editor::location::{EditorLocation, EditorPosition}, + listener::Listener, + settings::checkbox, + terminal::panel::TerminalPanelData, + window_tab::WindowTabData, +}; + +pub fn debug_panel( + window_tab_data: Rc, + position: PanelPosition, +) -> impl View { + let config = window_tab_data.common.config; + let terminal = window_tab_data.terminal.clone(); + let internal_command = window_tab_data.common.internal_command; + + PanelBuilder::new(config, position) + .add_height( + "Processes", + 150.0, + debug_processes(terminal.clone(), config), + window_tab_data.panel.section_open(PanelSection::Process), + ) + .add( + "Variables", + variables_view(window_tab_data.clone()), + window_tab_data.panel.section_open(PanelSection::Variable), + ) + .add( + "Stack Frames", + debug_stack_traces(terminal.clone(), internal_command, config), + window_tab_data.panel.section_open(PanelSection::StackFrame), + ) + .add_height( + "Breakpoints", + 150.0, + breakpoints_view(window_tab_data.clone()), + window_tab_data.panel.section_open(PanelSection::Breakpoint), + ) + .build() + .debug_name("Debug Panel") +} + +fn debug_process_icons( + terminal: TerminalPanelData, + term_id: TermId, + dap_id: DapId, + mode: RunDebugMode, + stopped: bool, + config: ReadSignal>, +) -> impl View { + let paused = move || { + let stopped = terminal + .debug + .daps + .with_untracked(|daps| daps.get(&dap_id).map(|dap| dap.stopped)); + stopped.map(|stopped| stopped.get()).unwrap_or(false) + }; + match mode { + RunDebugMode::Run => container(stack(( + { + let terminal = terminal.clone(); + clickable_icon( + || LapceIcons::DEBUG_RESTART, + move || { + terminal.restart_run_debug(term_id); + }, + || false, + || false, + || "Restart", + config, + ) + .style(|s| s.margin_horiz(4.0)) + }, + { + let terminal = terminal.clone(); + clickable_icon( + || LapceIcons::DEBUG_STOP, + move || { + terminal.stop_run_debug(term_id); + }, + || false, + move || stopped, + || "Stop", + config, + ) + .style(|s| s.margin_right(4.0)) + }, + { + let terminal = terminal.clone(); + clickable_icon( + || LapceIcons::CLOSE, + move || { + terminal.close_terminal(&term_id); + }, + || false, + || false, + || "Close", + config, + ) + .style(|s| s.margin_right(4.0)) + }, + ))), + RunDebugMode::Debug => container(stack(( + { + let terminal = terminal.clone(); + clickable_icon( + || LapceIcons::DEBUG_CONTINUE, + move || { + terminal.dap_continue(term_id); + }, + || false, + move || !paused() || stopped, + || "Continue", + config, + ) + .style(|s| s.margin_horiz(6.0)) + }, + { + let terminal = terminal.clone(); + clickable_icon( + || LapceIcons::DEBUG_PAUSE, + move || { + terminal.dap_pause(term_id); + }, + || false, + move || paused() || stopped, + || "Pause", + config, + ) + .style(|s| s.margin_right(4.0)) + }, + { + let terminal = terminal.clone(); + clickable_icon( + || LapceIcons::DEBUG_STEP_OVER, + move || { + terminal.dap_step_over(term_id); + }, + || false, + move || !paused() || stopped, + || "Step Over", + config, + ) + .style(|s| s.margin_right(4.0)) + }, + { + let terminal = terminal.clone(); + clickable_icon( + || LapceIcons::DEBUG_STEP_INTO, + move || { + terminal.dap_step_into(term_id); + }, + || false, + move || !paused() || stopped, + || "Step Into", + config, + ) + .style(|s| s.margin_right(4.0)) + }, + { + let terminal = terminal.clone(); + clickable_icon( + || LapceIcons::DEBUG_STEP_OUT, + move || { + terminal.dap_step_out(term_id); + }, + || false, + move || !paused() || stopped, + || "Step Out", + config, + ) + .style(|s| s.margin_right(4.0)) + }, + { + let terminal = terminal.clone(); + clickable_icon( + || LapceIcons::DEBUG_RESTART, + move || { + terminal.restart_run_debug(term_id); + }, + || false, + || false, + || "Restart", + config, + ) + .style(|s| s.margin_right(4.0)) + }, + { + let terminal = terminal.clone(); + clickable_icon( + || LapceIcons::DEBUG_STOP, + move || { + terminal.stop_run_debug(term_id); + }, + || false, + move || stopped, + || "Stop", + config, + ) + .style(|s| s.margin_right(4.0)) + }, + { + let terminal = terminal.clone(); + clickable_icon( + || LapceIcons::CLOSE, + move || { + terminal.close_terminal(&term_id); + }, + || false, + || false, + || "Close", + config, + ) + .style(|s| s.margin_right(4.0)) + }, + ))), + } +} + +fn debug_processes( + terminal: TerminalPanelData, + config: ReadSignal>, +) -> impl View { + scroll({ + let terminal = terminal.clone(); + let local_terminal = terminal.clone(); + dyn_stack( + move || local_terminal.run_debug_process(true), + |(term_id, p)| (*term_id, p.stopped), + move |(term_id, p)| { + let terminal = terminal.clone(); + let is_active = + move || terminal.debug.active_term.get() == Some(term_id); + let local_terminal = terminal.clone(); + let is_hovered = create_rw_signal(false); + stack(( + { + let svg_str = match (&p.mode, p.stopped) { + (RunDebugMode::Run, false) => LapceIcons::START, + (RunDebugMode::Run, true) => LapceIcons::RUN_ERRORS, + (RunDebugMode::Debug, false) => LapceIcons::DEBUG, + (RunDebugMode::Debug, true) => { + LapceIcons::DEBUG_DISCONNECT + } + }; + svg(move || config.get().ui_svg(svg_str)).style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.size(size, size) + .margin_vert(5.0) + .margin_horiz(10.0) + .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + }) + }, + label(move || p.config.name.clone()).style(|s| { + s.flex_grow(1.0) + .flex_basis(0.0) + .min_width(0.0) + .text_ellipsis() + }), + debug_process_icons( + terminal.clone(), + term_id, + p.config.dap_id, + p.mode, + p.stopped, + config, + ) + .style(move |s| { + s.apply_if(!is_hovered.get() && !is_active(), |s| s.hide()) + }), + )) + .on_click_stop(move |_| { + local_terminal.debug.active_term.set(Some(term_id)); + local_terminal.focus_terminal(term_id); + }) + .on_event_stop(EventListener::PointerEnter, move |_| { + is_hovered.set(true); + }) + .on_event_stop(EventListener::PointerLeave, move |_| { + is_hovered.set(false); + }) + .style(move |s| { + let config = config.get(); + s.padding_vert(6.0) + .width_pct(100.0) + .items_center() + .apply_if(is_active(), |s| { + s.background( + config.color(LapceColor::PANEL_CURRENT_BACKGROUND), + ) + }) + .hover(|s| { + s.cursor(CursorStyle::Pointer).background( + (config.color(LapceColor::PANEL_HOVERED_BACKGROUND)) + .multiply_alpha(0.3), + ) + }) + }) + }, + ) + .style(|s| s.width_pct(100.0).flex_col()) + }) +} + +fn variables_view(window_tab_data: Rc) -> impl View { + let terminal = window_tab_data.terminal.clone(); + let local_terminal = window_tab_data.terminal.clone(); + let ui_line_height = window_tab_data.common.ui_line_height; + let config = window_tab_data.common.config; + container( + scroll( + virtual_stack( + move || { + let dap = terminal.get_active_dap(true); + dap.map(|dap| { + if !dap.stopped.get() { + return DapVariable::default(); + } + let process_stopped = terminal + .get_terminal(&dap.term_id) + .and_then(|t| { + t.run_debug.with(|r| r.as_ref().map(|r| r.stopped)) + }) + .unwrap_or(true); + if process_stopped { + return DapVariable::default(); + } + dap.variables.get() + }) + .unwrap_or_default() + }, + |node| { + ( + node.item.name().to_string(), + node.item.value().map(|v| v.to_string()), + node.item.reference(), + node.expanded, + node.level, + ) + }, + move |node| { + let local_terminal = local_terminal.clone(); + let level = node.level; + let reference = node.item.reference(); + let name = node.item.name(); + let ty = node.item.ty(); + let type_exists = ty.map(|ty| !ty.is_empty()).unwrap_or(false); + stack(( + svg(move || { + let config = config.get(); + let svg_str = match node.expanded { + true => LapceIcons::ITEM_OPENED, + false => LapceIcons::ITEM_CLOSED, + }; + config.ui_svg(svg_str) + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + + let color = if reference > 0 { + config.color(LapceColor::LAPCE_ICON_ACTIVE) + } else { + Color::TRANSPARENT + }; + s.size(size, size).margin_left(10.0).color(color) + }), + text(name), + text(": ").style(move |s| { + s.apply_if(!type_exists || reference == 0, |s| s.hide()) + }), + text(node.item.ty().unwrap_or("")).style(move |s| { + s.color(config.get().style_color("type").unwrap()) + .apply_if(!type_exists || reference == 0, |s| { + s.hide() + }) + }), + text(format!(" = {}", node.item.value().unwrap_or(""))) + .style(move |s| s.apply_if(reference > 0, |s| s.hide())), + )) + .on_click_stop(move |_| { + if reference > 0 { + let dap = local_terminal.get_active_dap(false); + if let Some(dap) = dap { + let process_stopped = local_terminal + .get_terminal(&dap.term_id) + .and_then(|t| { + t.run_debug + .with(|r| r.as_ref().map(|r| r.stopped)) + }) + .unwrap_or(true); + if !process_stopped { + dap.toggle_expand( + node.parent.clone(), + reference, + ); + } + } + } + }) + .style(move |s| { + s.items_center() + .padding_right(10.0) + .padding_left((level * 10) as f32) + .min_width_pct(100.0) + .hover(|s| { + s.apply_if(reference > 0, |s| { + s.background( + config.get().color( + LapceColor::PANEL_HOVERED_BACKGROUND, + ), + ) + }) + }) + }) + }, + ) + .item_size_fixed(move || ui_line_height.get()) + .style(|s| s.flex_col().min_width_full()), + ) + .style(|s| s.absolute().size_full()), + ) + .style(|s| s.width_full().line_height(1.6).flex_grow(1.0).flex_basis(0)) +} + +fn debug_stack_frames( + dap_id: DapId, + thread_id: ThreadId, + stack_trace: StackTraceData, + stopped: RwSignal, + internal_command: Listener, + config: ReadSignal>, +) -> impl View { + let expanded = stack_trace.expanded; + stack(( + container(label(move || thread_id.to_string())) + .on_click_stop(move |_| { + expanded.update(|expanded| { + *expanded = !*expanded; + }); + }) + .style(move |s| { + s.padding_horiz(10.0).min_width_pct(100.0).hover(move |s| { + s.cursor(CursorStyle::Pointer).background( + config.get().color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + }) + }), + dyn_stack( + move || { + let expanded = stack_trace.expanded.get() && stopped.get(); + if expanded { + stack_trace.frames.get() + } else { + im::Vector::new() + } + }, + |frame| frame.id, + move |frame| { + let full_path = frame.source.as_ref().and_then(|s| s.path.clone()); + let line = frame.line.saturating_sub(1); + let col = frame.column.saturating_sub(1); + + let source_path = frame + .source + .as_ref() + .and_then(|s| s.path.as_ref()) + .and_then(|p| p.file_name()) + .and_then(|s| s.to_str()) + .unwrap_or("") + .to_string(); + let has_source = !source_path.is_empty(); + let source_path = format!("{source_path}:{}", frame.line); + + container(stack(( + label(move || frame.name.clone()).style(move |s| { + s.hover(|s| { + s.background( + config + .get() + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + }) + }), + label(move || source_path.clone()).style(move |s| { + s.margin_left(10.0) + .color(config.get().color(LapceColor::EDITOR_DIM)) + .font_style(FontStyle::Italic) + .apply_if(!has_source, |s| s.hide()) + }), + ))) + .on_click_stop(move |_| { + if let Some(path) = full_path.clone() { + internal_command.send(InternalCommand::JumpToLocation { + location: EditorLocation { + path, + position: Some(EditorPosition::Position( + lsp_types::Position { + line: line as u32, + character: col as u32, + }, + )), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }, + }); + } + internal_command.send(InternalCommand::DapFrameScopes { + dap_id, + frame_id: frame.id, + }); + }) + .style(move |s| { + let config = config.get(); + s.padding_left(20.0) + .padding_right(10.0) + .min_width_pct(100.0) + .apply_if(!has_source, |s| { + s.color(config.color(LapceColor::EDITOR_DIM)) + }) + .hover(|s| { + s.background( + config.color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + .apply_if(has_source, |s| s.cursor(CursorStyle::Pointer)) + }) + }) + }, + ) + .style(|s| s.flex_col().min_width_pct(100.0)), + )) + .style(|s| s.flex_col().min_width_pct(100.0)) +} + +fn debug_stack_traces( + terminal: TerminalPanelData, + internal_command: Listener, + config: ReadSignal>, +) -> impl View { + container( + scroll({ + let local_terminal = terminal.clone(); + dyn_stack( + move || { + let dap = local_terminal.get_active_dap(true); + if let Some(dap) = dap { + let process_stopped = local_terminal + .get_terminal(&dap.term_id) + .and_then(|t| { + t.run_debug.with(|r| r.as_ref().map(|r| r.stopped)) + }) + .unwrap_or(true); + if process_stopped { + return Vec::new(); + } + let main_thread = dap.thread_id.get(); + let stack_traces = dap.stack_traces.get(); + let mut traces = stack_traces + .into_iter() + .map(|(thread_id, stack_trace)| { + (dap.dap_id, dap.stopped, thread_id, stack_trace) + }) + .collect::>(); + traces.sort_by_key(|(_, _, id, _)| main_thread != Some(*id)); + traces + } else { + Vec::new() + } + }, + |(dap_id, stopped, thread_id, _)| { + (*dap_id, *thread_id, stopped.get_untracked()) + }, + move |(dap_id, stopped, thread_id, stack_trace)| { + debug_stack_frames( + dap_id, + thread_id, + stack_trace, + stopped, + internal_command, + config, + ) + }, + ) + .style(|s| s.flex_col().min_width_pct(100.0)) + }) + .style(|s| s.absolute().size_pct(100.0, 100.0)), + ) + .style(|s| { + s.width_pct(100.0) + .line_height(1.6) + .flex_grow(1.0) + .flex_basis(0.0) + }) +} + +fn breakpoints_view(window_tab_data: Rc) -> impl View { + let breakpoints = window_tab_data.terminal.debug.breakpoints; + let config = window_tab_data.common.config; + let workspace = window_tab_data.common.workspace.clone(); + let available_width = create_rw_signal(0.0); + let internal_command = window_tab_data.common.internal_command; + container( + scroll( + dyn_stack( + move || { + breakpoints + .get() + .into_iter() + .flat_map(|(path, breakpoints)| { + breakpoints.into_values().map(move |b| (path.clone(), b)) + }) + }, + move |(path, breakpoint)| { + (path.clone(), breakpoint.line, breakpoint.active) + }, + move |(path, breakpoint)| { + let line = breakpoint.line; + let full_path = path.clone(); + let full_path_for_jump = path.clone(); + let full_path_for_close = path.clone(); + let path = if let Some(workspace_path) = workspace.path.as_ref() + { + path.strip_prefix(workspace_path) + .unwrap_or(&full_path) + .to_path_buf() + } else { + path + }; + + let file_name = + path.file_name().and_then(|s| s.to_str()).unwrap_or(""); + let folder = + path.parent().and_then(|s| s.to_str()).unwrap_or(""); + let folder_empty = folder.is_empty(); + + stack(( + clickable_icon( + move || LapceIcons::CLOSE, + move || { + breakpoints.update(|breakpoints| { + if let Some(breakpoints) = + breakpoints.get_mut(&full_path_for_close) + { + breakpoints.remove(&line); + } + }); + }, + || false, + || false, + || "Remove", + config, + ) + .on_event_stop(EventListener::PointerDown, |_| {}), + checkbox(move || breakpoint.active, config) + .style(|s| { + s.margin_right(6.0).cursor(CursorStyle::Pointer) + }) + .on_click_stop(move |_| { + breakpoints.update(|breakpoints| { + if let Some(breakpoints) = + breakpoints.get_mut(&full_path) + { + if let Some(breakpoint) = + breakpoints.get_mut(&line) + { + breakpoint.active = !breakpoint.active; + } + } + }); + }), + text(format!("{file_name}:{}", breakpoint.line + 1)).style( + move |s| { + let size = config.get().ui.icon_size() as f32; + s.text_ellipsis().max_width( + available_width.get() as f32 + - 20.0 + - size + - 6.0 + - size + - 8.0, + ) + }, + ), + text(folder).style(move |s| { + s.text_ellipsis() + .flex_grow(1.0) + .flex_basis(0.0) + .color(config.get().color(LapceColor::EDITOR_DIM)) + .min_width(0.0) + .margin_left(6.0) + .apply_if(folder_empty, |s| s.hide()) + }), + )) + .style(move |s| { + s.items_center().padding_horiz(10.0).width_pct(100.0).hover( + |s| { + s.background( + config + .get() + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + }, + ) + }) + .on_click_stop(move |_| { + internal_command.send(InternalCommand::JumpToLocation { + location: EditorLocation { + path: full_path_for_jump.clone(), + position: Some(EditorPosition::Line(line)), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }, + }); + }) + }, + ) + .style(|s| s.flex_col().line_height(1.6).width_pct(100.0)), + ) + .on_resize(move |rect| { + let width = rect.width(); + if available_width.get_untracked() != width { + available_width.set(width); + } + }) + .style(|s| s.absolute().size_pct(100.0, 100.0)), + ) + .style(|s| s.size_pct(100.0, 100.0)) +} diff --git a/lapce-app/src/panel/document_symbol.rs b/lapce-app/src/panel/document_symbol.rs new file mode 100644 index 0000000..62c8c9d --- /dev/null +++ b/lapce-app/src/panel/document_symbol.rs @@ -0,0 +1,321 @@ +use std::{ops::AddAssign, path::PathBuf, rc::Rc}; + +use floem::{ + View, + peniko::Color, + reactive::{RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, + style::CursorStyle, + views::{ + Decorators, VirtualVector, container, editor::id::Id, label, scroll, stack, + svg, virtual_stack, + }, +}; +use lsp_types::{DocumentSymbol, SymbolKind}; + +use super::position::PanelPosition; +use crate::{ + command::InternalCommand, + config::{color::LapceColor, icon::LapceIcons}, + editor::location::EditorLocation, + window_tab::WindowTabData, +}; + +#[derive(Clone, Debug)] +pub struct SymbolData { + pub path: PathBuf, + pub file: RwSignal, +} + +impl SymbolData { + pub fn new( + items: Vec>, + path: PathBuf, + cx: Scope, + ) -> Self { + let name = path + .file_name() + .and_then(|x| x.to_str()) + .map(|x| x.to_string()) + .unwrap_or_default(); + #[allow(deprecated)] + let file_ds = DocumentSymbol { + name: name.clone(), + detail: None, + kind: SymbolKind::FILE, + tags: None, + deprecated: None, + range: Default::default(), + selection_range: Default::default(), + children: None, + }; + let file = cx.create_rw_signal(SymbolInformationItemData { + id: Id::next(), + name, + detail: None, + item: file_ds, + open: cx.create_rw_signal(true), + children: items, + }); + Self { path, file } + } + fn get_children( + &self, + min: usize, + max: usize, + ) -> Vec<( + usize, + usize, + Rc, + RwSignal, + )> { + let path = Rc::new(self.path.clone()); + let level: usize = 0; + let mut next = 0; + get_children(self.file, &mut next, min, max, level, path.clone()) + } +} + +#[derive(Debug, Clone)] +pub struct SymbolInformationItemData { + pub id: Id, + pub name: String, + pub detail: Option, + pub item: DocumentSymbol, + pub open: RwSignal, + pub children: Vec>, +} + +impl From<(DocumentSymbol, Scope)> for SymbolInformationItemData { + fn from((mut item, cx): (DocumentSymbol, Scope)) -> Self { + let children = if let Some(children) = item.children.take() { + children + .into_iter() + .map(|x| cx.create_rw_signal(Self::from((x, cx)))) + .collect() + } else { + Vec::with_capacity(0) + }; + Self { + id: Id::next(), + name: item.name.clone(), + detail: item.detail.clone(), + item, + open: cx.create_rw_signal(true), + children, + } + } +} + +impl SymbolInformationItemData { + pub fn child_count(&self) -> usize { + let mut count = 1; + if self.open.get() { + for child in &self.children { + count += child.with(|x| x.child_count()) + } + } + count + } +} + +fn get_children( + data: RwSignal, + next: &mut usize, + min: usize, + max: usize, + level: usize, + path: Rc, +) -> Vec<( + usize, + usize, + Rc, + RwSignal, +)> { + let mut children = Vec::new(); + if *next >= min && *next < max { + children.push((*next, level, path.clone(), data)); + } else if *next >= max { + return children; + } + next.add_assign(1); + if data.get_untracked().open.get() { + for child in data.get().children { + let child_children = + get_children(child, next, min, max, level + 1, path.clone()); + children.extend(child_children); + if *next > max { + break; + } + } + } + children +} + +pub struct VirtualList { + root: Option>>, +} + +impl VirtualList { + pub fn new(root: Option>>) -> Self { + Self { root } + } +} + +impl + VirtualVector<( + usize, + usize, + Rc, + RwSignal, + )> for VirtualList +{ + fn total_len(&self) -> usize { + if let Some(root) = self.root.as_ref().and_then(|x| x.get()) { + root.file.get_untracked().child_count() + } else { + 0 + } + } + + fn slice( + &mut self, + range: std::ops::Range, + ) -> impl Iterator< + Item = ( + usize, + usize, + Rc, + RwSignal, + ), + > { + if let Some(root) = self.root.as_ref().and_then(|x| x.get()) { + let min = range.start; + let max = range.end; + let children = root.get_children(min, max); + children.into_iter() + } else { + Vec::new().into_iter() + } + } +} + +pub fn symbol_panel( + window_tab_data: Rc, + _position: PanelPosition, +) -> impl View { + let config = window_tab_data.common.config; + let ui_line_height = window_tab_data.common.ui_line_height; + scroll( + virtual_stack( + { + let window_tab_data = window_tab_data.clone(); + move || { + let editor = window_tab_data.main_split.get_active_editor(); + VirtualList::new(editor.map(|x| x.doc().document_symbol_data)) + } + }, + move |(_, _, _, item)| item.get_untracked().id, + move |(_, level, path, rw_data)| { + let data = rw_data.get_untracked(); + let open = data.open; + let has_child = !data.children.is_empty(); + let kind = data.item.kind; + stack(( + container( + svg(move || { + let config = config.get(); + let svg_str = match open.get() { + true => LapceIcons::ITEM_OPENED, + false => LapceIcons::ITEM_CLOSED, + }; + config.ui_svg(svg_str) + }) + .style(move |s| { + let config = config.get(); + let color = if has_child { + config.color(LapceColor::LAPCE_ICON_ACTIVE) + } else { + Color::TRANSPARENT + }; + let size = config.ui.icon_size() as f32; + s.size(size, size) + .color(color) + }) + ).style(|s| s.padding(4.0).margin_left(6.0).margin_right(2.0)) + .on_click_stop({ + move |_x| { + if has_child { + open.update(|x| { + *x = !*x; + }); + } + } + }), + svg(move || { + let config = config.get(); + config + .symbol_svg(&kind) + .unwrap_or_else(|| config.ui_svg(LapceIcons::FILE)) + }).style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.min_width(size) + .size(size, size) + .margin_right(5.0) + .color(config.symbol_color(&kind).unwrap_or_else(|| { + config.color(LapceColor::LAPCE_ICON_ACTIVE) + })) + }), + label(move || { + data.name.replace('\n', "↵") + }) + .style(move |s| { + s.selectable(false) + }), + label(move || { + data.detail.clone().unwrap_or_default() + }).style(move |s| s.margin_left(6.0) + .color(config.get().color(LapceColor::EDITOR_DIM)) + .selectable(false) + .apply_if( + data.item.detail.clone().is_none(), + |s| s.hide()) + ), + )) + .style(move |s| { + s.padding_right(5.0) + .padding_left((level * 10) as f32) + .items_center() + .height(ui_line_height.get()) + .hover(|s| { + s.background( + config + .get() + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + .cursor(CursorStyle::Pointer) + }) + }) + .on_click_stop({ + let window_tab_data = window_tab_data.clone(); + let data = rw_data; + move |_| { + let data = data.get_untracked(); + window_tab_data + .common + .internal_command + .send(InternalCommand::JumpToLocation { location: EditorLocation { + path: path.to_path_buf(), + position: Some(crate::editor::location::EditorPosition::Position(data.item.selection_range.start)), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + } }); + } + }) + }, + ).item_size_fixed(move || ui_line_height.get()) + .style(|s| s.flex_col().absolute().min_width_full()), + ) + .style(|s| s.absolute().size_full()) +} diff --git a/lapce-app/src/panel/global_search_view.rs b/lapce-app/src/panel/global_search_view.rs new file mode 100644 index 0000000..0cc1edd --- /dev/null +++ b/lapce-app/src/panel/global_search_view.rs @@ -0,0 +1,309 @@ +use std::{path::PathBuf, rc::Rc, sync::Arc}; + +use floem::{ + View, + event::EventListener, + reactive::{ReadSignal, SignalGet, SignalUpdate}, + style::{CursorStyle, Style}, + views::{Decorators, container, label, scroll, stack, svg, virtual_stack}, +}; +use lapce_xi_rope::find::CaseMatching; + +use super::{kind::PanelKind, position::PanelPosition}; +use crate::{ + app::clickable_icon, + command::InternalCommand, + config::{LapceConfig, color::LapceColor, icon::LapceIcons}, + editor::location::{EditorLocation, EditorPosition}, + focus_text::focus_text, + global_search::{GlobalSearchData, SearchMatchData}, + listener::Listener, + text_input::TextInputBuilder, + window_tab::{Focus, WindowTabData}, + workspace::LapceWorkspace, +}; + +pub fn global_search_panel( + window_tab_data: Rc, + _position: PanelPosition, +) -> impl View { + let global_search = window_tab_data.global_search.clone(); + let editor = global_search.editor.clone(); + let config = global_search.common.config; + let workspace = global_search.common.workspace.clone(); + let internal_command = global_search.common.internal_command; + let case_matching = global_search.common.find.case_matching; + let whole_word = global_search.common.find.whole_words; + let is_regex = global_search.common.find.is_regex; + + let focus = global_search.common.focus; + let is_focused = move || focus.get() == Focus::Panel(PanelKind::Search); + + stack(( + container( + stack(( + TextInputBuilder::new() + .is_focused(is_focused) + .build_editor(editor.clone()) + .style(|s| s.width_pct(100.0)), + clickable_icon( + || LapceIcons::SEARCH_CASE_SENSITIVE, + move || { + let new = match case_matching.get_untracked() { + CaseMatching::Exact => CaseMatching::CaseInsensitive, + CaseMatching::CaseInsensitive => CaseMatching::Exact, + }; + case_matching.set(new); + }, + move || case_matching.get() == CaseMatching::Exact, + || false, + || "Case Sensitive", + config, + ) + .style(|s| s.padding_vert(4.0)), + clickable_icon( + || LapceIcons::SEARCH_WHOLE_WORD, + move || { + whole_word.update(|whole_word| { + *whole_word = !*whole_word; + }); + }, + move || whole_word.get(), + || false, + || "Whole Word", + config, + ) + .style(|s| s.padding_left(6.0)), + clickable_icon( + || LapceIcons::SEARCH_REGEX, + move || { + is_regex.update(|is_regex| { + *is_regex = !*is_regex; + }); + }, + move || is_regex.get(), + || false, + || "Use Regex", + config, + ) + .style(|s| s.padding_left(6.0)), + )) + .on_event_cont(EventListener::PointerDown, move |_| { + focus.set(Focus::Panel(PanelKind::Search)); + }) + .style(move |s| { + s.width_pct(100.0) + .padding_right(6.0) + .items_center() + .border(1.0) + .border_radius(6.0) + .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + }), + ) + .style(|s| s.width_pct(100.0).padding(10.0)), + search_result(workspace, global_search, internal_command, config), + )) + .style(|s| s.absolute().size_pct(100.0, 100.0).flex_col()) + .debug_name("Global Search Panel") +} + +fn search_result( + workspace: Arc, + global_search_data: GlobalSearchData, + internal_command: Listener, + config: ReadSignal>, +) -> impl View { + let ui_line_height = global_search_data.common.ui_line_height; + container({ + scroll({ + virtual_stack( + move || global_search_data.clone(), + move |(path, _)| path.to_owned(), + move |(path, match_data)| { + let full_path = path.clone(); + let path = if let Some(workspace_path) = workspace.path.as_ref() + { + path.strip_prefix(workspace_path) + .unwrap_or(&full_path) + .to_path_buf() + } else { + path + }; + let style_path = path.clone(); + + let file_name = path + .file_name() + .and_then(|s| s.to_str()) + .unwrap_or("") + .to_string(); + + let folder = path + .parent() + .and_then(|s| s.to_str()) + .unwrap_or("") + .to_string(); + + let expanded = match_data.expanded; + + stack(( + stack(( + svg(move || { + config.get().ui_svg(if expanded.get() { + LapceIcons::ITEM_OPENED + } else { + LapceIcons::ITEM_CLOSED + }) + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.margin_left(10.0) + .margin_right(6.0) + .size(size, size) + .min_size(size, size) + .color( + config.color(LapceColor::LAPCE_ICON_ACTIVE), + ) + }), + svg(move || config.get().file_svg(&path).0).style( + move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + let color = config.file_svg(&style_path).1; + s.margin_right(6.0) + .size(size, size) + .min_size(size, size) + .apply_opt(color, Style::color) + }, + ), + stack(( + label(move || file_name.clone()).style(|s| { + s.margin_right(6.0) + .max_width_pct(100.0) + .text_ellipsis() + }), + label(move || folder.clone()).style(move |s| { + s.color( + config.get().color(LapceColor::EDITOR_DIM), + ) + .min_width(0.0) + .text_ellipsis() + }), + )) + .style(move |s| s.min_width(0.0).items_center()), + )) + .on_click_stop(move |_| { + expanded.update(|expanded| *expanded = !*expanded); + }) + .style(move |s| { + s.width_pct(100.0) + .min_width_pct(100.0) + .items_center() + .hover(|s| { + s.cursor(CursorStyle::Pointer).background( + config.get().color( + LapceColor::PANEL_HOVERED_BACKGROUND, + ), + ) + }) + }), + virtual_stack( + move || { + if expanded.get() { + match_data.matches.get() + } else { + im::Vector::new() + } + }, + |m| (m.line, m.start, m.end), + move |m| { + let path = full_path.clone(); + let line_number = m.line; + let start = m.start; + let end = m.end; + let line_content = m.line_content.clone(); + + focus_text( + move || { + let config = config.get(); + let content = if config + .ui + .trim_search_results_whitespace + { + m.line_content.trim() + } else { + &m.line_content + }; + format!("{}: {content}", m.line,) + }, + move || { + let config = config.get(); + let mut offset = if config + .ui + .trim_search_results_whitespace + { + line_content.trim_start().len() as i32 + - line_content.len() as i32 + } else { + 0 + }; + offset += + line_number.to_string().len() as i32 + 2; + + ((start as i32 + offset) as usize + ..(end as i32 + offset) as usize) + .collect() + }, + move || { + config.get().color(LapceColor::EDITOR_FOCUS) + }, + ) + .style(move |s| { + let config = config.get(); + let icon_size = config.ui.icon_size() as f32; + s.margin_left(10.0 + icon_size + 6.0).hover( + |s| { + s.cursor(CursorStyle::Pointer) + .background(config.color( + LapceColor::PANEL_HOVERED_BACKGROUND, + )) + }, + ) + }) + .on_click_stop( + move |_| { + internal_command.send( + InternalCommand::JumpToLocation { + location: EditorLocation { + path: path.clone(), + position: Some( + EditorPosition::Line( + line_number + .saturating_sub(1), + ), + ), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }, + }, + ); + }, + ) + }, + ) + .item_size_fixed(move || ui_line_height.get()) + .style(|s| s.flex_col()), + )) + .style(|s| s.flex_col()) + }, + ) + .item_size_fn(|(_, match_data): &(PathBuf, SearchMatchData)| { + match_data.height() + }) + .style(|s| s.flex_col().min_width_pct(100.0).line_height(1.8)) + }) + .style(|s| s.absolute().size_pct(100.0, 100.0)) + }) + .style(|s| s.size_pct(100.0, 100.0)) +} diff --git a/lapce-app/src/panel/implementation_view.rs b/lapce-app/src/panel/implementation_view.rs new file mode 100644 index 0000000..7666397 --- /dev/null +++ b/lapce-app/src/panel/implementation_view.rs @@ -0,0 +1,384 @@ +use std::{ops::AddAssign, path::PathBuf, rc::Rc}; + +use floem::{ + IntoView, View, ViewId, + reactive::{RwSignal, Scope, SignalGet, SignalUpdate}, + style::CursorStyle, + views::{ + Decorators, VirtualVector, container, label, scroll, stack, svg, + virtual_stack, + }, +}; +use im::HashMap; +use itertools::Itertools; +use lapce_rpc::file_line::FileLine; +use lsp_types::{Location, SymbolKind, request::GotoImplementationResponse}; + +use super::position::PanelPosition; +use crate::{ + command::InternalCommand, + config::{color::LapceColor, icon::LapceIcons}, + editor::location::EditorLocation, + window_tab::WindowTabData, +}; + +pub fn implementation_panel( + window_tab_data: Rc, + _position: PanelPosition, +) -> impl View { + common_reference_panel(window_tab_data.clone(), _position, move || { + window_tab_data.main_split.implementations.get() + }) + .debug_name("implementation panel") +} +pub fn common_reference_panel( + window_tab_data: Rc, + _position: PanelPosition, + each_fn: impl Fn() -> ReferencesRoot + 'static, +) -> impl View { + let config = window_tab_data.common.config; + let ui_line_height = window_tab_data.common.ui_line_height; + scroll( + virtual_stack( + each_fn, + move |(_, _, data)| data.view_id(), + move |(_, level, rw_data)| { + match rw_data { + ReferenceLocation::File { path, open, .. } => stack(( + container( + svg(move || { + let config = config.get(); + let svg_str = match open.get() { + true => LapceIcons::ITEM_OPENED, + false => LapceIcons::ITEM_CLOSED, + }; + config.ui_svg(svg_str) + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.size(size, size).color( + config.color(LapceColor::LAPCE_ICON_ACTIVE), + ) + }), + ) + .style(|s| s.padding(4.0).margin_left(6.0).margin_right(2.0)) + .on_click_stop({ + move |_x| { + open.update(|x| { + *x = !*x; + }); + } + }), + svg(move || { + let config = config.get(); + config + .symbol_svg(&SymbolKind::FILE) + .unwrap_or_else(|| config.ui_svg(LapceIcons::FILE)) + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.min_width(size) + .size(size, size) + .margin_right(5.0) + .color( + config + .symbol_color(&SymbolKind::FILE) + .unwrap_or_else(|| { + config + .color(LapceColor::LAPCE_ICON_ACTIVE) + }), + ) + }), + label(move || format!("{:?}", path)) + .style(move |s| { + s.margin_left(6.0).color( + config.get().color(LapceColor::EDITOR_DIM), + ) + }) + .into_any(), + )) + .style(move |s| { + s.padding_right(5.0) + .height(ui_line_height.get()) + .padding_left((level * 10) as f32) + .items_center() + .hover(|s| { + s.background( + config + .get() + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + .cursor(CursorStyle::Pointer) + }) + }), + ReferenceLocation::Line { file_line, .. } => stack((container( + label(move || format!("{} {}", file_line.position.line + 1, file_line.content)) + .style(move |s| { + s.margin_left(6.0).color( + config.get().color(LapceColor::EDITOR_DIM), + ) + }) + .into_any(), + ) + .style(move |s| { + s.padding_right(5.0) + .height(ui_line_height.get()) + .padding_left((level * 20) as f32) + .items_center() + .hover(|s| { + s.background( + config + .get() + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + .cursor(CursorStyle::Pointer) + }) + }),)) + .on_click_stop({ + let window_tab_data = window_tab_data.clone(); + let position = file_line.position; + move |_| { + window_tab_data.common.internal_command.send( + InternalCommand::JumpToLocation { + location: EditorLocation { + path: file_line.path.clone(), + position: Some( + crate::editor::location::EditorPosition::Position( + position, + ), + ), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }, + }, + ); + } + }), + } + .style(move |s| { + s.padding_right(5.0) + .height(ui_line_height.get()) + .padding_left((level * 10) as f32) + .items_center() + .hover(|s| { + s.background( + config + .get() + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + .cursor(CursorStyle::Pointer) + }) + }) + }, + ).item_size_fixed(move || ui_line_height.get()) + .style(|s| s.flex_col().absolute().min_width_full()), + ) + .style(|s| s.absolute().size_full()) +} + +pub fn map_to_location(resp: Option) -> Vec { + let Some(resp) = resp else { + return Vec::new(); + }; + match resp { + GotoImplementationResponse::Scalar(local) => { + vec![local] + } + GotoImplementationResponse::Array(items) => items, + GotoImplementationResponse::Link(items) => items + .into_iter() + .map(|x| Location { + uri: x.target_uri, + range: x.target_range, + }) + .collect(), + } +} + +pub fn init_implementation_root( + items: Vec, + scope: Scope, +) -> ReferencesRoot { + let mut refs_map: HashMap> = HashMap::new(); + for item in items { + let entry = refs_map.entry(item.path.clone()).or_default(); + (*entry).insert( + item.position.line, + Reference::Line { + location: ReferenceLocation::Line { + file_line: item, + view_id: ViewId::new(), + }, + }, + ); + } + + let mut refs = Vec::new(); + for (path, items) in refs_map { + let open = scope.create_rw_signal(true); + let children = items + .into_iter() + .sorted_by(|x, y| x.0.cmp(&y.0)) + .map(|x| x.1) + .collect(); + let ref_item = Reference::File { + location: ReferenceLocation::File { + open, + path, + view_id: ViewId::new(), + }, + children, + open, + }; + refs.push(ref_item); + } + ReferencesRoot { children: refs } +} + +#[derive(Clone, Default)] +pub struct ReferencesRoot { + pub(crate) children: Vec, +} + +impl ReferencesRoot { + pub fn total(&self) -> usize { + let mut total = 0; + for child in &self.children { + total += child.total_len() + } + total + } + + fn get_children( + &self, + next: &mut usize, + min: usize, + max: usize, + level: usize, + ) -> Vec<(usize, usize, ReferenceLocation)> { + let mut children = Vec::new(); + for child in &self.children { + let child_children = child.get_children(next, min, max, level + 1); + if !child_children.is_empty() { + children.extend(child_children); + } + if *next > max { + break; + } + } + children + } +} + +impl VirtualVector<(usize, usize, ReferenceLocation)> for ReferencesRoot { + fn total_len(&self) -> usize { + self.total() + } + + fn slice( + &mut self, + range: std::ops::Range, + ) -> impl Iterator { + let min = range.start; + let max = range.end; + let children = self.get_children(&mut 0, min, max, 0); + children.into_iter() + } +} + +#[derive(Clone)] +pub enum Reference { + File { + location: ReferenceLocation, + open: RwSignal, + children: Vec, + }, + Line { + location: ReferenceLocation, + }, +} + +#[derive(Clone)] +pub enum ReferenceLocation { + File { + path: PathBuf, + open: RwSignal, + view_id: ViewId, + }, + Line { + file_line: FileLine, + view_id: ViewId, + }, +} + +impl ReferenceLocation { + pub fn view_id(&self) -> ViewId { + match self { + ReferenceLocation::File { view_id, .. } => *view_id, + ReferenceLocation::Line { view_id, .. } => *view_id, + } + } +} + +impl Reference { + pub fn location(&self) -> ReferenceLocation { + match self { + Reference::File { location, .. } => location.clone(), + Reference::Line { location } => location.clone(), + } + } + pub fn total_len(&self) -> usize { + match self { + Reference::File { children, .. } => { + let mut total = 1; + for child in children { + total += child.total_len() + } + total + } + Reference::Line { .. } => 1, + } + } + pub fn children(&self) -> Option<&Vec> { + match self { + Reference::File { children, open, .. } => { + if open.get() { + return Some(children); + } + None + } + Reference::Line { .. } => None, + } + } + + fn get_children( + &self, + next: &mut usize, + min: usize, + max: usize, + level: usize, + ) -> Vec<(usize, usize, ReferenceLocation)> { + let mut children = Vec::new(); + if *next >= min && *next < max { + children.push((*next, level, self.location())); + } else if *next >= max { + return children; + } + next.add_assign(1); + if let Some(children_tmp) = self.children() { + for child in children_tmp { + let child_children = child.get_children(next, min, max, level + 1); + if !child_children.is_empty() { + children.extend(child_children); + } + if *next > max { + break; + } + } + } + children + } +} diff --git a/lapce-app/src/panel/kind.rs b/lapce-app/src/panel/kind.rs new file mode 100644 index 0000000..695990e --- /dev/null +++ b/lapce-app/src/panel/kind.rs @@ -0,0 +1,66 @@ +use serde::{Deserialize, Serialize}; +use strum_macros::EnumIter; + +use super::{data::PanelOrder, position::PanelPosition}; +use crate::config::icon::LapceIcons; + +#[derive( + Clone, Copy, PartialEq, Serialize, Deserialize, Hash, Eq, Debug, EnumIter, +)] +pub enum PanelKind { + Terminal, + FileExplorer, + SourceControl, + Plugin, + Search, + Problem, + Debug, + CallHierarchy, + DocumentSymbol, + References, + Implementation, +} + +impl PanelKind { + pub fn svg_name(&self) -> &'static str { + match &self { + PanelKind::Terminal => LapceIcons::TERMINAL, + PanelKind::FileExplorer => LapceIcons::FILE_EXPLORER, + PanelKind::SourceControl => LapceIcons::SCM, + PanelKind::Plugin => LapceIcons::EXTENSIONS, + PanelKind::Search => LapceIcons::SEARCH, + PanelKind::Problem => LapceIcons::PROBLEM, + PanelKind::Debug => LapceIcons::DEBUG, + PanelKind::CallHierarchy => LapceIcons::TYPE_HIERARCHY, + PanelKind::DocumentSymbol => LapceIcons::DOCUMENT_SYMBOL, + PanelKind::References => LapceIcons::REFERENCES, + PanelKind::Implementation => LapceIcons::IMPLEMENTATION, + } + } + + pub fn position(&self, order: &PanelOrder) -> Option<(usize, PanelPosition)> { + for (pos, panels) in order.iter() { + let index = panels.iter().position(|k| k == self); + if let Some(index) = index { + return Some((index, *pos)); + } + } + None + } + + pub fn default_position(&self) -> PanelPosition { + match self { + PanelKind::Terminal => PanelPosition::BottomLeft, + PanelKind::FileExplorer => PanelPosition::LeftTop, + PanelKind::SourceControl => PanelPosition::LeftTop, + PanelKind::Plugin => PanelPosition::LeftTop, + PanelKind::Search => PanelPosition::BottomLeft, + PanelKind::Problem => PanelPosition::BottomLeft, + PanelKind::Debug => PanelPosition::LeftTop, + PanelKind::CallHierarchy => PanelPosition::BottomLeft, + PanelKind::DocumentSymbol => PanelPosition::RightTop, + PanelKind::References => PanelPosition::BottomLeft, + PanelKind::Implementation => PanelPosition::BottomLeft, + } + } +} diff --git a/lapce-app/src/panel/mod.rs b/lapce-app/src/panel/mod.rs new file mode 100644 index 0000000..016192e --- /dev/null +++ b/lapce-app/src/panel/mod.rs @@ -0,0 +1,15 @@ +pub mod call_hierarchy_view; +pub mod data; +pub mod debug_view; +pub mod document_symbol; +pub mod global_search_view; +pub mod implementation_view; +pub mod kind; +pub mod plugin_view; +pub mod position; +pub mod problem_view; +pub mod references_view; +pub mod source_control_view; +pub mod style; +pub mod terminal_view; +pub mod view; diff --git a/lapce-app/src/panel/plugin_view.rs b/lapce-app/src/panel/plugin_view.rs new file mode 100644 index 0000000..4067761 --- /dev/null +++ b/lapce-app/src/panel/plugin_view.rs @@ -0,0 +1,407 @@ +use std::{ops::Range, rc::Rc}; + +use floem::{ + IntoView, View, + event::EventListener, + peniko::kurbo::{Point, Rect, Size}, + reactive::{ + RwSignal, SignalGet, SignalUpdate, SignalWith, create_memo, create_rw_signal, + }, + style::CursorStyle, + views::{ + Decorators, VirtualVector, container, dyn_container, img, label, + scroll::scroll, stack, svg, virtual_stack, + }, +}; +use indexmap::IndexMap; +use lapce_rpc::{ + core::CoreRpcHandler, + plugin::{VoltID, VoltInfo}, +}; + +use super::{ + data::PanelSection, kind::PanelKind, position::PanelPosition, view::PanelBuilder, +}; +use crate::{ + app::not_clickable_icon, + command::InternalCommand, + config::{color::LapceColor, icon::LapceIcons}, + plugin::{AvailableVoltData, InstalledVoltData, PluginData, VoltIcon}, + text_input::TextInputBuilder, + window_tab::{Focus, WindowTabData}, +}; + +pub const VOLT_DEFAULT_PNG: &[u8] = include_bytes!("../../../extra/images/volt.png"); + +struct IndexMapItems(IndexMap); + +impl IndexMapItems { + fn items(&self, range: Range) -> Vec<(K, V)> { + let mut items = Vec::new(); + for i in range { + if let Some((k, v)) = self.0.get_index(i) { + items.push((k.clone(), v.clone())); + } + } + items + } +} + +impl VirtualVector<(usize, K, V)> + for IndexMapItems +{ + fn total_len(&self) -> usize { + self.0.len() + } + + fn slice(&mut self, range: Range) -> impl Iterator { + let start = range.start; + Box::new( + self.items(range) + .into_iter() + .enumerate() + .map(move |(i, (k, v))| (i + start, k, v)), + ) + } +} + +pub fn plugin_panel( + window_tab_data: Rc, + position: PanelPosition, +) -> impl View { + let config = window_tab_data.common.config; + let plugin = window_tab_data.plugin.clone(); + let core_rpc = window_tab_data.proxy.core_rpc.clone(); + + PanelBuilder::new(config, position) + .add( + "Installed", + installed_view(plugin.clone()), + window_tab_data.panel.section_open(PanelSection::Installed), + ) + .add( + "Available", + available_view(plugin.clone(), core_rpc), + window_tab_data.panel.section_open(PanelSection::Available), + ) + .build() + .debug_name("Plugin Panel") +} + +fn installed_view(plugin: PluginData) -> impl View { + let ui_line_height = plugin.common.ui_line_height; + let volts = plugin.installed; + let config = plugin.common.config; + let disabled = plugin.disabled; + let workspace_disabled = plugin.workspace_disabled; + let internal_command = plugin.common.internal_command; + + let view_fn = move |volt: InstalledVoltData, plugin: PluginData| { + let meta = volt.meta.get_untracked(); + let volt_id = meta.id(); + let local_volt_id = volt_id.clone(); + let icon = volt.icon; + stack(( + dyn_container( + move || icon.get(), + move |icon| match icon { + None => img(move || VOLT_DEFAULT_PNG.to_vec()) + .style(|s| s.size_full()) + .into_any(), + Some(VoltIcon::Svg(svg_str)) => svg(move || svg_str.clone()) + .style(|s| s.size_full()) + .into_any(), + Some(VoltIcon::Img(buf)) => { + img(move || buf.clone()).style(|s| s.size_full()).into_any() + } + }, + ) + .style(|s| { + s.min_size(50.0, 50.0) + .size(50.0, 50.0) + .margin_top(5.0) + .margin_right(10.0) + .padding(5) + }), + stack(( + label(move || meta.display_name.clone()).style(|s| { + s.font_bold() + .text_ellipsis() + .min_width(0.0) + .selectable(false) + }), + label(move || meta.description.clone()) + .style(|s| s.text_ellipsis().min_width(0.0).selectable(false)), + stack(( + stack(( + label(move || meta.author.clone()).style(|s| { + s.text_ellipsis().max_width_pct(100.0).selectable(false) + }), + label(move || { + if disabled.with(|d| d.contains(&volt_id)) + || workspace_disabled.with(|d| d.contains(&volt_id)) + { + "Disabled".to_string() + } else if volt.meta.with(|m| { + volt.latest.with(|i| i.version != m.version) + }) { + "Upgrade".to_string() + } else { + format!("v{}", volt.meta.with(|m| m.version.clone())) + } + }) + .style(|s| s.text_ellipsis().selectable(false)), + )) + .style(|s| { + s.justify_between() + .flex_grow(1.0) + .flex_basis(0.0) + .min_width(0.0) + }), + not_clickable_icon( + || LapceIcons::SETTINGS, + || false, + || false, + || "Options", + config, + ) + .style(|s| s.padding_left(6.0)) + .popout_menu(move || { + plugin.plugin_controls(volt.meta.get(), volt.latest.get()) + }), + )) + .style(|s| s.width_pct(100.0).items_center()), + )) + .style(|s| s.flex_col().flex_grow(1.0).flex_basis(0.0).min_width(0.0)), + )) + .on_click_stop(move |_| { + internal_command.send(InternalCommand::OpenVoltView { + volt_id: local_volt_id.clone(), + }); + }) + .style(move |s| { + s.width_pct(100.0) + .padding_horiz(10.0) + .padding_vert(5.0) + .cursor(CursorStyle::Pointer) + .hover(|s| { + s.background( + config.get().color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + }) + }) + }; + + container( + scroll( + virtual_stack( + move || IndexMapItems(volts.get()), + move |(_, id, _)| id.clone(), + move |(_, _, volt)| view_fn(volt, plugin.clone()), + ) + .item_size_fixed(move || ui_line_height.get() * 3.0 + 10.0) + .style(|s| s.flex_col().width_pct(100.0)), + ) + .style(|s| s.absolute().size_pct(100.0, 100.0)), + ) + .style(|s| { + s.width_pct(100.0) + .line_height(1.6) + .flex_grow(1.0) + .flex_basis(0.0) + }) +} + +fn available_view(plugin: PluginData, core_rpc: CoreRpcHandler) -> impl View { + let ui_line_height = plugin.common.ui_line_height; + let volts = plugin.available.volts; + let installed = plugin.installed; + let config = plugin.common.config; + let internal_command = plugin.common.internal_command; + + let local_plugin = plugin.clone(); + let install_button = + move |id: VoltID, info: RwSignal, installing: RwSignal| { + let plugin = local_plugin.clone(); + let installed = create_memo(move |_| { + installed.with(|installed| installed.contains_key(&id)) + }); + label(move || { + if installed.get() { + "Installed".to_string() + } else if installing.get() { + "Installing".to_string() + } else { + "Install".to_string() + } + }) + .disabled(move || installed.get() || installing.get()) + .on_click_stop(move |_| { + plugin.install_volt(info.get_untracked()); + }) + .style(move |s| { + let config = config.get(); + s.color(config.color(LapceColor::LAPCE_BUTTON_PRIMARY_FOREGROUND)) + .background( + config.color(LapceColor::LAPCE_BUTTON_PRIMARY_BACKGROUND), + ) + .margin_left(6.0) + .padding_horiz(6.0) + .border_radius(6.0) + .hover(|s| { + s.cursor(CursorStyle::Pointer).background( + config + .color(LapceColor::LAPCE_BUTTON_PRIMARY_BACKGROUND) + .multiply_alpha(0.8), + ) + }) + .active(|s| { + s.background( + config + .color(LapceColor::LAPCE_BUTTON_PRIMARY_BACKGROUND) + .multiply_alpha(0.6), + ) + }) + .disabled(|s| s.background(config.color(LapceColor::EDITOR_DIM))) + }) + }; + + let view_fn = move |(_, id, volt): (usize, VoltID, AvailableVoltData)| { + let info = volt.info.get_untracked(); + let icon = volt.icon; + let volt_id = info.id(); + stack(( + dyn_container( + move || icon.get(), + move |icon| match icon { + None => img(move || VOLT_DEFAULT_PNG.to_vec()) + .style(|s| s.size_full()) + .into_any(), + Some(VoltIcon::Svg(svg_str)) => svg(move || svg_str.clone()) + .style(|s| s.size_full()) + .into_any(), + Some(VoltIcon::Img(buf)) => { + img(move || buf.clone()).style(|s| s.size_full()).into_any() + } + }, + ) + .style(|s| { + s.min_size(50.0, 50.0) + .size(50.0, 50.0) + .margin_top(5.0) + .margin_right(10.0) + .padding(5) + }), + stack(( + label(move || info.display_name.clone()).style(|s| { + s.font_bold() + .text_ellipsis() + .min_width(0.0) + .selectable(false) + }), + label(move || info.description.clone()) + .style(|s| s.text_ellipsis().min_width(0.0).selectable(false)), + stack(( + label(move || info.author.clone()).style(|s| { + s.text_ellipsis() + .min_width(0.0) + .flex_grow(1.0) + .flex_basis(0.0) + .selectable(false) + }), + install_button(id, volt.info, volt.installing), + )) + .style(|s| s.width_pct(100.0).items_center()), + )) + .style(|s| s.flex_col().flex_grow(1.0).flex_basis(0.0).min_width(0.0)), + )) + .on_click_stop(move |_| { + internal_command.send(InternalCommand::OpenVoltView { + volt_id: volt_id.clone(), + }); + }) + .style(move |s| { + s.width_pct(100.0) + .padding_horiz(10.0) + .padding_vert(5.0) + .cursor(CursorStyle::Pointer) + .hover(|s| { + s.background( + config.get().color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + }) + }) + }; + + let content_rect = create_rw_signal(Rect::ZERO); + + let editor = plugin.available.query_editor.clone(); + let focus = plugin.common.focus; + let is_focused = move || focus.get() == Focus::Panel(PanelKind::Plugin); + let cursor_x = create_rw_signal(0.0); + + stack(( + container({ + scroll( + TextInputBuilder::new() + .is_focused(is_focused) + .build_editor(editor.clone()) + .placeholder(|| "Search extensions".to_string()) + .on_cursor_pos(move |point| { + cursor_x.set(point.x); + }) + .style(|s| { + s.padding_vert(4.0).padding_horiz(10.0).min_width_pct(100.0) + }), + ) + .ensure_visible(move || { + Size::new(20.0, 0.0) + .to_rect() + .with_origin(Point::new(cursor_x.get(), 0.0)) + }) + .on_event_cont(EventListener::PointerDown, move |_| { + focus.set(Focus::Panel(PanelKind::Plugin)); + }) + .scroll_style(|s| s.hide_bars(true)) + .style(move |s| { + let config = config.get(); + s.width_pct(100.0) + .cursor(CursorStyle::Text) + .items_center() + .background(config.color(LapceColor::EDITOR_BACKGROUND)) + .border(1.0) + .border_radius(6.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + }) + }) + .style(|s| s.padding(10.0).width_pct(100.0)), + container({ + scroll({ + virtual_stack( + move || IndexMapItems(volts.get()), + move |(_, id, _)| id.clone(), + view_fn, + ) + .item_size_fixed(move || ui_line_height.get() * 3.0 + 10.0) + .on_resize(move |rect| { + content_rect.set(rect); + }) + .style(|s| s.flex_col().width_pct(100.0)) + }) + .on_scroll(move |rect| { + if rect.y1 + 30.0 > content_rect.get_untracked().y1 { + plugin.load_more_available(core_rpc.clone()); + } + }) + .style(|s| s.absolute().size_pct(100.0, 100.0)) + }) + .style(|s| s.size_pct(100.0, 100.0)), + )) + .style(|s| { + s.width_pct(100.0) + .line_height(1.6) + .flex_grow(1.0) + .flex_basis(0.0) + .flex_col() + }) +} diff --git a/lapce-app/src/panel/position.rs b/lapce-app/src/panel/position.rs new file mode 100644 index 0000000..553319a --- /dev/null +++ b/lapce-app/src/panel/position.rs @@ -0,0 +1,74 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Eq, PartialEq, Hash, Clone, Copy, Debug, Serialize, Deserialize)] +pub enum PanelPosition { + LeftTop, + LeftBottom, + BottomLeft, + BottomRight, + RightTop, + RightBottom, +} + +impl PanelPosition { + pub fn is_bottom(&self) -> bool { + matches!(self, PanelPosition::BottomLeft | PanelPosition::BottomRight) + } + + pub fn is_right(&self) -> bool { + matches!(self, PanelPosition::RightTop | PanelPosition::RightBottom) + } + + pub fn is_left(&self) -> bool { + matches!(self, PanelPosition::LeftTop | PanelPosition::LeftBottom) + } + + pub fn is_first(&self) -> bool { + matches!( + self, + PanelPosition::LeftTop + | PanelPosition::BottomLeft + | PanelPosition::RightTop + ) + } + + pub fn peer(&self) -> PanelPosition { + match &self { + PanelPosition::LeftTop => PanelPosition::LeftBottom, + PanelPosition::LeftBottom => PanelPosition::LeftTop, + PanelPosition::BottomLeft => PanelPosition::BottomRight, + PanelPosition::BottomRight => PanelPosition::BottomLeft, + PanelPosition::RightTop => PanelPosition::RightBottom, + PanelPosition::RightBottom => PanelPosition::RightTop, + } + } +} + +#[derive(Eq, PartialEq, Hash, Clone, Copy, Debug)] +pub enum PanelContainerPosition { + Left, + Bottom, + Right, +} + +impl PanelContainerPosition { + pub fn is_bottom(&self) -> bool { + matches!(self, PanelContainerPosition::Bottom) + } + + pub fn first(&self) -> PanelPosition { + match self { + PanelContainerPosition::Left => PanelPosition::LeftTop, + PanelContainerPosition::Bottom => PanelPosition::BottomLeft, + PanelContainerPosition::Right => PanelPosition::RightTop, + } + } + + pub fn second(&self) -> PanelPosition { + match self { + PanelContainerPosition::Left => PanelPosition::LeftBottom, + PanelContainerPosition::Bottom => PanelPosition::BottomRight, + PanelContainerPosition::Right => PanelPosition::RightBottom, + } + } +} diff --git a/lapce-app/src/panel/problem_view.rs b/lapce-app/src/panel/problem_view.rs new file mode 100644 index 0000000..1ce8819 --- /dev/null +++ b/lapce-app/src/panel/problem_view.rs @@ -0,0 +1,399 @@ +use std::{path::PathBuf, rc::Rc, sync::Arc}; + +use floem::{ + View, + peniko::Color, + reactive::{ + ReadSignal, SignalGet, SignalUpdate, SignalWith, create_effect, + create_rw_signal, + }, + style::{CursorStyle, Style}, + views::{Decorators, container, dyn_stack, label, scroll, stack, svg}, +}; +use lsp_types::{DiagnosticRelatedInformation, DiagnosticSeverity}; + +use super::{data::PanelSection, position::PanelPosition, view::PanelBuilder}; +use crate::{ + command::InternalCommand, + config::{LapceConfig, color::LapceColor, icon::LapceIcons}, + doc::{DiagnosticData, EditorDiagnostic}, + editor::location::{EditorLocation, EditorPosition}, + listener::Listener, + lsp::path_from_url, + window_tab::WindowTabData, + workspace::LapceWorkspace, +}; + +pub fn problem_panel( + window_tab_data: Rc, + position: PanelPosition, +) -> impl View { + let config = window_tab_data.common.config; + let is_bottom = position.is_bottom(); + PanelBuilder::new(config, position) + .add_style( + "Errors", + problem_section(window_tab_data.clone(), DiagnosticSeverity::ERROR), + window_tab_data.panel.section_open(PanelSection::Error), + move |s| { + s.border_color(config.get().color(LapceColor::LAPCE_BORDER)) + .apply_if(is_bottom, |s| s.border_right(1.0)) + .apply_if(!is_bottom, |s| s.border_bottom(1.0)) + }, + ) + .add( + "Warnings", + problem_section(window_tab_data.clone(), DiagnosticSeverity::WARNING), + window_tab_data.panel.section_open(PanelSection::Warn), + ) + .build() + .debug_name("Problem Panel") +} + +fn problem_section( + window_tab_data: Rc, + severity: DiagnosticSeverity, +) -> impl View { + let config = window_tab_data.common.config; + let main_split = window_tab_data.main_split.clone(); + let internal_command = window_tab_data.common.internal_command; + container({ + scroll( + dyn_stack( + move || main_split.diagnostics.get(), + |(p, _)| p.clone(), + move |(path, diagnostic_data)| { + file_view( + main_split.common.workspace.clone(), + path, + diagnostic_data, + severity, + internal_command, + config, + ) + }, + ) + .style(|s| s.flex_col().width_pct(100.0).line_height(1.8)), + ) + .style(|s| s.absolute().size_pct(100.0, 100.0)) + }) + .style(|s| s.size_pct(100.0, 100.0)) +} + +fn file_view( + workspace: Arc, + path: PathBuf, + diagnostic_data: DiagnosticData, + severity: DiagnosticSeverity, + internal_command: Listener, + config: ReadSignal>, +) -> impl View { + let collapsed = create_rw_signal(false); + + let diagnostics = create_rw_signal(im::Vector::new()); + create_effect(move |_| { + let span = diagnostic_data.diagnostics_span.get(); + let d = if !span.is_empty() { + span.iter() + .filter_map(|(iv, diag)| { + if diag.severity == Some(severity) { + Some(EditorDiagnostic { + range: Some((iv.start, iv.end)), + diagnostic: diag.to_owned(), + }) + } else { + None + } + }) + .collect::>() + } else { + let diagnostics = diagnostic_data.diagnostics.get(); + let diagnostics: im::Vector = diagnostics + .into_iter() + .filter_map(|d| { + if d.severity == Some(severity) { + Some(EditorDiagnostic { + range: None, + diagnostic: d, + }) + } else { + None + } + }) + .collect(); + diagnostics + }; + diagnostics.set(d); + }); + + let full_path = path.clone(); + let path = if let Some(workspace_path) = workspace.path.as_ref() { + path.strip_prefix(workspace_path) + .unwrap_or(&full_path) + .to_path_buf() + } else { + path + }; + let style_path = path.clone(); + + let icon = match severity { + DiagnosticSeverity::ERROR => LapceIcons::ERROR, + _ => LapceIcons::WARNING, + }; + let icon_color = move || { + let config = config.get(); + match severity { + DiagnosticSeverity::ERROR => config.color(LapceColor::LAPCE_ERROR), + _ => config.color(LapceColor::LAPCE_WARN), + } + }; + + let file_name = path + .file_name() + .and_then(|s| s.to_str()) + .unwrap_or("") + .to_string(); + + let folder = path + .parent() + .and_then(|s| s.to_str()) + .unwrap_or("") + .to_string(); + + stack(( + stack(( + container( + stack(( + label(move || file_name.clone()).style(|s| { + s.margin_right(6.0) + .max_width_pct(100.0) + .text_ellipsis() + .selectable(false) + }), + label(move || folder.clone()).style(move |s| { + s.color(config.get().color(LapceColor::EDITOR_DIM)) + .min_width(0.0) + .text_ellipsis() + .selectable(false) + }), + )) + .style(move |s| s.width_pct(100.0).min_width(0.0)), + ) + .on_click_stop(move |_| { + collapsed.update(|collapsed| *collapsed = !*collapsed); + }) + .style(move |s| { + let config = config.get(); + s.width_pct(100.0) + .min_width(0.0) + .padding_left(10.0 + (config.ui.icon_size() as f32 + 6.0) * 2.0) + .padding_right(10.0) + .hover(|s| { + s.cursor(CursorStyle::Pointer).background( + config.color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + }) + }), + stack(( + svg(move || { + config.get().ui_svg(if collapsed.get() { + LapceIcons::ITEM_CLOSED + } else { + LapceIcons::ITEM_OPENED + }) + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.margin_right(6.0) + .size(size, size) + .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + }), + svg(move || config.get().file_svg(&path).0).style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + let color = config.file_svg(&style_path).1; + s.min_width(size) + .size(size, size) + .apply_opt(color, Style::color) + }), + label(|| " ".to_string()).style(move |s| s.selectable(false)), + )) + .style(|s| s.absolute().items_center().margin_left(10.0)), + )) + .style(move |s| s.width_pct(100.0).min_width(0.0)), + dyn_stack( + move || { + if collapsed.get() { + im::Vector::new() + } else { + diagnostics.get() + } + }, + |d| (d.range, d.diagnostic.range), + move |d| { + item_view( + full_path.clone(), + d, + icon, + icon_color, + internal_command, + config, + ) + }, + ) + .style(|s| s.flex_col().width_pct(100.0).min_width_pct(0.0)), + )) + .style(move |s| { + s.width_pct(100.0) + .items_start() + .flex_col() + .apply_if(diagnostics.with(|d| d.is_empty()), |s| s.hide()) + }) +} + +fn item_view( + path: PathBuf, + d: EditorDiagnostic, + icon: &'static str, + icon_color: impl Fn() -> Color + 'static, + internal_command: Listener, + config: ReadSignal>, +) -> impl View { + let related = d.diagnostic.related_information.unwrap_or_default(); + let position = if let Some((start, _)) = d.range { + EditorPosition::Offset(start) + } else { + EditorPosition::Position(d.diagnostic.range.start) + }; + let location = EditorLocation { + path, + position: Some(position), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }; + stack(( + container({ + stack(( + label(move || d.diagnostic.message.clone()).style(move |s| { + s.width_pct(100.0) + .min_width(0.0) + .padding_left( + 10.0 + (config.get().ui.icon_size() as f32 + 6.0) * 3.0, + ) + .padding_right(10.0) + }), + stack(( + svg(move || config.get().ui_svg(icon)).style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.size(size, size).color(icon_color()) + }), + label(|| " ".to_string()).style(move |s| s.selectable(false)), + )) + .style(move |s| { + s.absolute().items_center().margin_left( + 10.0 + (config.get().ui.icon_size() as f32 + 6.0) * 2.0, + ) + }), + )) + .style(move |s| { + s.width_pct(100.0).min_width(0.0).hover(|s| { + s.cursor(CursorStyle::Pointer).background( + config.get().color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + }) + }) + }) + .on_click_stop(move |_| { + internal_command.send(InternalCommand::JumpToLocation { + location: location.clone(), + }); + }) + .style(|s| s.width_pct(100.0).min_width_pct(0.0)), + related_view(related, internal_command, config), + )) + .style(|s| s.width_pct(100.0).min_width_pct(0.0).flex_col()) +} + +fn related_view( + related: Vec, + internal_command: Listener, + config: ReadSignal>, +) -> impl View { + let is_empty = related.is_empty(); + stack(( + dyn_stack( + move || related.clone(), + |_| 0, + move |related| { + let full_path = path_from_url(&related.location.uri); + let path = full_path + .file_name() + .and_then(|f| f.to_str()) + .map(|f| { + format!( + "{f} [{}, {}]: ", + related.location.range.start.line, + related.location.range.start.character + ) + }) + .unwrap_or_default(); + let location = EditorLocation { + path: full_path, + position: Some(EditorPosition::Position( + related.location.range.start, + )), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }; + let message = format!("{path}{}", related.message); + container( + label(move || message.clone()) + .style(move |s| s.width_pct(100.0).min_width(0.0)), + ) + .on_click_stop(move |_| { + internal_command.send(InternalCommand::JumpToLocation { + location: location.clone(), + }); + }) + .style(move |s| { + let config = config.get(); + s.padding_left(10.0 + (config.ui.icon_size() as f32 + 6.0) * 4.0) + .padding_right(10.0) + .width_pct(100.0) + .min_width(0.0) + .hover(|s| { + s.cursor(CursorStyle::Pointer).background( + config.color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + }) + }) + }, + ) + .style(|s| s.width_pct(100.0).min_width(0.0).flex_col()), + stack(( + svg(move || config.get().ui_svg(LapceIcons::LINK)).style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.size(size, size) + .color(config.color(LapceColor::EDITOR_DIM)) + }), + label(|| " ".to_string()).style(move |s| s.selectable(false)), + )) + .style(move |s| { + s.absolute() + .items_center() + .margin_left(10.0 + (config.get().ui.icon_size() as f32 + 6.0) * 3.0) + }), + )) + .style(move |s| { + s.width_pct(100.0) + .min_width(0.0) + .items_start() + .color(config.get().color(LapceColor::EDITOR_DIM)) + .apply_if(is_empty, |s| s.hide()) + }) +} diff --git a/lapce-app/src/panel/references_view.rs b/lapce-app/src/panel/references_view.rs new file mode 100644 index 0000000..6e4871a --- /dev/null +++ b/lapce-app/src/panel/references_view.rs @@ -0,0 +1,18 @@ +use std::rc::Rc; + +use floem::{View, reactive::SignalGet, views::Decorators}; + +use super::position::PanelPosition; +use crate::{ + panel::implementation_view::common_reference_panel, window_tab::WindowTabData, +}; + +pub fn references_panel( + window_tab_data: Rc, + _position: PanelPosition, +) -> impl View { + common_reference_panel(window_tab_data.clone(), _position, move || { + window_tab_data.main_split.references.get() + }) + .debug_name("references panel") +} diff --git a/lapce-app/src/panel/source_control_view.rs b/lapce-app/src/panel/source_control_view.rs new file mode 100644 index 0000000..504981e --- /dev/null +++ b/lapce-app/src/panel/source_control_view.rs @@ -0,0 +1,364 @@ +use std::{path::PathBuf, rc::Rc}; + +use floem::{ + View, + action::show_context_menu, + event::{Event, EventListener}, + menu::{Menu, MenuItem}, + peniko::kurbo::Rect, + prelude::SignalTrack, + reactive::{SignalGet, SignalUpdate, SignalWith, create_memo, create_rw_signal}, + style::{CursorStyle, Style}, + views::{ + Decorators, container, dyn_stack, + editor::view::{LineRegion, cursor_caret}, + label, scroll, stack, svg, text, + }, +}; +use lapce_core::buffer::rope_text::RopeText; +use lapce_rpc::source_control::FileDiff; + +use super::{ + data::PanelSection, kind::PanelKind, position::PanelPosition, + view::foldable_panel_section, +}; +use crate::{ + command::{CommandKind, InternalCommand, LapceCommand, LapceWorkbenchCommand}, + config::{color::LapceColor, icon::LapceIcons}, + editor::view::editor_view, + settings::checkbox, + source_control::SourceControlData, + window_tab::{Focus, WindowTabData}, +}; + +pub fn source_control_panel( + window_tab_data: Rc, + _position: PanelPosition, +) -> impl View { + let config = window_tab_data.common.config; + let source_control = window_tab_data.source_control.clone(); + let focus = source_control.common.focus; + let editor = source_control.editor.clone(); + let doc = editor.doc_signal(); + let cursor = editor.cursor(); + let viewport = editor.viewport(); + let window_origin = editor.window_origin(); + let editor = create_rw_signal(editor); + let is_active = move |tracked| { + let focus = if tracked { + focus.get() + } else { + focus.get_untracked() + }; + focus == Focus::Panel(PanelKind::SourceControl) + }; + let is_empty = create_memo(move |_| { + let doc = doc.get(); + doc.buffer.with(|b| b.len() == 0) + }); + let debug_breakline = create_memo(move |_| None); + + stack(( + stack(( + container({ + scroll({ + let view = stack(( + editor_view( + editor.get_untracked(), + debug_breakline, + is_active, + ), + label(|| "Commit Message".to_string()).style(move |s| { + let config = config.get(); + s.absolute() + .items_center() + .height(config.editor.line_height() as f32) + .color(config.color(LapceColor::EDITOR_DIM)) + .apply_if(!is_empty.get(), |s| s.hide()) + .selectable(false) + }), + )) + .style(|s| { + s.absolute() + .min_size_pct(100.0, 100.0) + .padding_left(10.0) + .padding_vert(6.0) + .hover(|s| s.cursor(CursorStyle::Text)) + }); + let id = view.id(); + view.on_event_cont(EventListener::PointerDown, move |event| { + let event = event.clone().offset((10.0, 6.0)); + if let Event::PointerDown(pointer_event) = event { + id.request_active(); + editor.get_untracked().pointer_down(&pointer_event); + } + }) + .on_event_stop(EventListener::PointerMove, move |event| { + let event = event.clone().offset((10.0, 6.0)); + if let Event::PointerMove(pointer_event) = event { + editor.get_untracked().pointer_move(&pointer_event); + } + }) + .on_event_stop( + EventListener::PointerUp, + move |event| { + let event = event.clone().offset((10.0, 6.0)); + if let Event::PointerUp(pointer_event) = event { + editor.get_untracked().pointer_up(&pointer_event); + } + }, + ) + }) + .on_move(move |pos| { + window_origin.set(pos + (10.0, 6.0)); + }) + .on_scroll(move |rect| { + viewport.set(rect); + }) + .ensure_visible(move || { + let cursor = cursor.get(); + let offset = cursor.offset(); + let e_data = editor.get_untracked(); + e_data.doc_signal().track(); + e_data.kind.track(); + let LineRegion { x, width, rvline } = cursor_caret( + &e_data.editor, + offset, + !cursor.is_insert(), + cursor.affinity, + ); + let config = config.get_untracked(); + let line_height = config.editor.line_height(); + // TODO: is there a way to avoid the calculation of the vline here? + let vline = e_data.editor.vline_of_rvline(rvline); + Rect::from_origin_size( + (x, (vline.get() * line_height) as f64), + (width, line_height as f64), + ) + .inflate(30.0, 10.0) + }) + .style(|s| s.absolute().size_pct(100.0, 100.0)) + }) + .style(move |s| { + let config = config.get(); + s.width_pct(100.0) + .height(120.0) + .border(1.0) + .padding(-1.0) + .border_radius(6.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .background(config.color(LapceColor::EDITOR_BACKGROUND)) + }), + { + let source_control = source_control.clone(); + label(|| "Commit".to_string()) + .on_click_stop(move |_| { + source_control.commit(); + }) + .style(move |s| { + let config = config.get(); + s.margin_top(10.0) + .line_height(1.6) + .width_pct(100.0) + .justify_center() + .border(1.0) + .border_radius(6.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .hover(|s| { + s.cursor(CursorStyle::Pointer).background( + config + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + }) + .active(|s| { + s.background(config.color( + LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND, + )) + }) + .selectable(false) + }) + }, + )) + .style(|s| s.flex_col().width_pct(100.0).padding(10.0)), + foldable_panel_section( + text("Changes"), + file_diffs_view(source_control), + window_tab_data.panel.section_open(PanelSection::Changes), + config, + ) + .style(|s| s.flex_col().size_pct(100.0, 100.0)), + )) + .on_event_stop(EventListener::PointerDown, move |_| { + if focus.get_untracked() != Focus::Panel(PanelKind::SourceControl) { + focus.set(Focus::Panel(PanelKind::SourceControl)); + } + }) + .style(|s| s.flex_col().size_pct(100.0, 100.0)) + .debug_name("Source Control Panel") +} + +fn file_diffs_view(source_control: SourceControlData) -> impl View { + let file_diffs = source_control.file_diffs; + let config = source_control.common.config; + let workspace = source_control.common.workspace.clone(); + let panel_rect = create_rw_signal(Rect::ZERO); + let panel_width = create_memo(move |_| panel_rect.get().width()); + let lapce_command = source_control.common.lapce_command; + let internal_command = source_control.common.internal_command; + + let view_fn = move |(path, (diff, checked)): (PathBuf, (FileDiff, bool))| { + let diff_for_style = diff.clone(); + let full_path = path.clone(); + let diff_for_menu = diff.clone(); + let path_for_click = full_path.clone(); + + let path = if let Some(workspace_path) = workspace.path.as_ref() { + path.strip_prefix(workspace_path) + .unwrap_or(&full_path) + .to_path_buf() + } else { + path + }; + let file_name = path + .file_name() + .and_then(|s| s.to_str()) + .unwrap_or("") + .to_string(); + let folder = path + .parent() + .and_then(|s| s.to_str()) + .unwrap_or("") + .to_string(); + let style_path = path.clone(); + stack(( + checkbox(move || checked, config).on_click_stop(move |_| { + file_diffs.update(|diffs| { + if let Some((_, checked)) = diffs.get_mut(&full_path) { + *checked = !*checked; + } + }); + }), + svg(move || config.get().file_svg(&path).0).style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + let color = config.file_svg(&style_path).1; + s.min_width(size) + .size(size, size) + .margin(6.0) + .apply_opt(color, Style::color) + }), + label(move || file_name.clone()).style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + let max_width = panel_width.get() as f32 + - 10.0 + - size + - 6.0 + - size + - 6.0 + - 10.0 + - size + - 6.0; + s.text_ellipsis() + .margin_right(6.0) + .max_width(max_width) + .selectable(false) + }), + label(move || folder.clone()).style(move |s| { + s.text_ellipsis() + .flex_grow(1.0) + .flex_basis(0.0) + .color(config.get().color(LapceColor::EDITOR_DIM)) + .min_width(0.0) + .selectable(false) + }), + container({ + svg(move || { + let svg = match &diff { + FileDiff::Modified(_) => LapceIcons::SCM_DIFF_MODIFIED, + FileDiff::Added(_) => LapceIcons::SCM_DIFF_ADDED, + FileDiff::Deleted(_) => LapceIcons::SCM_DIFF_REMOVED, + FileDiff::Renamed(_, _) => LapceIcons::SCM_DIFF_RENAMED, + }; + config.get().ui_svg(svg) + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + let color = match &diff_for_style { + FileDiff::Modified(_) => LapceColor::SOURCE_CONTROL_MODIFIED, + FileDiff::Added(_) => LapceColor::SOURCE_CONTROL_ADDED, + FileDiff::Deleted(_) => LapceColor::SOURCE_CONTROL_REMOVED, + FileDiff::Renamed(_, _) => { + LapceColor::SOURCE_CONTROL_MODIFIED + } + }; + let color = config.color(color); + s.min_width(size).size(size, size).color(color) + }) + }) + .style(|s| { + s.absolute() + .size_pct(100.0, 100.0) + .padding_right(20.0) + .items_center() + .justify_end() + }), + )) + .on_click_stop(move |_| { + internal_command.send(InternalCommand::OpenFileChanges { + path: path_for_click.clone(), + }); + }) + .on_event_cont(EventListener::PointerDown, move |event| { + let diff_for_menu = diff_for_menu.clone(); + + let discard = move || { + lapce_command.send(LapceCommand { + kind: CommandKind::Workbench( + LapceWorkbenchCommand::SourceControlDiscardTargetFileChanges, + ), + data: Some(serde_json::json!(diff_for_menu.clone())), + }); + }; + + if let Event::PointerDown(pointer_event) = event { + if pointer_event.button.is_secondary() { + let menu = Menu::new("") + .entry(MenuItem::new("Discard Changes").action(discard)); + show_context_menu(menu, None); + } + } + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.padding_left(10.0) + .padding_right(10.0 + size + 6.0) + .width_pct(100.0) + .items_center() + .cursor(CursorStyle::Pointer) + .hover(|s| { + s.background(config.color(LapceColor::PANEL_HOVERED_BACKGROUND)) + }) + }) + }; + + container({ + scroll({ + dyn_stack( + move || file_diffs.get(), + |(path, (diff, checked))| { + (path.to_path_buf(), diff.clone(), *checked) + }, + view_fn, + ) + .style(|s| s.line_height(1.6).flex_col().width_pct(100.0)) + }) + .style(|s| s.absolute().size_pct(100.0, 100.0)) + }) + .on_resize(move |rect| { + panel_rect.set(rect); + }) + .style(|s| s.size_pct(100.0, 100.0)) +} diff --git a/lapce-app/src/panel/style.rs b/lapce-app/src/panel/style.rs new file mode 100644 index 0000000..3123155 --- /dev/null +++ b/lapce-app/src/panel/style.rs @@ -0,0 +1,8 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Serialize, Deserialize, Default)] +pub struct PanelStyle { + pub active: usize, + pub shown: bool, + pub maximized: bool, +} diff --git a/lapce-app/src/panel/terminal_view.rs b/lapce-app/src/panel/terminal_view.rs new file mode 100644 index 0000000..ea1dc9b --- /dev/null +++ b/lapce-app/src/panel/terminal_view.rs @@ -0,0 +1,387 @@ +use std::rc::Rc; + +use floem::{ + View, ViewId, + action::show_context_menu, + event::{Event, EventListener, EventPropagation}, + kurbo::Size, + menu::{Menu, MenuItem}, + reactive::{SignalGet, SignalUpdate, SignalWith, create_rw_signal}, + style::CursorStyle, + views::{ + Decorators, container, dyn_stack, empty, label, + scroll::{Thickness, VerticalScrollAsHorizontal, scroll}, + stack, svg, tab, + }, +}; +use lapce_rpc::terminal::TermId; + +use super::kind::PanelKind; +use crate::{ + app::clickable_icon, + command::{InternalCommand, LapceWorkbenchCommand}, + config::{color::LapceColor, icon::LapceIcons}, + debug::RunDebugMode, + listener::Listener, + terminal::{ + panel::TerminalPanelData, tab::TerminalTabData, view::terminal_view, + }, + window_tab::{Focus, WindowTabData}, +}; + +pub fn terminal_panel(window_tab_data: Rc) -> impl View { + let focus = window_tab_data.common.focus; + stack(( + terminal_tab_header(window_tab_data.clone()), + terminal_tab_content(window_tab_data.clone()), + )) + .on_event_cont(EventListener::PointerDown, move |_| { + if focus.get_untracked() != Focus::Panel(PanelKind::Terminal) { + focus.set(Focus::Panel(PanelKind::Terminal)); + } + }) + .style(|s| s.absolute().size_pct(100.0, 100.0).flex_col()) + .debug_name("Terminal Panel") +} + +fn terminal_tab_header(window_tab_data: Rc) -> impl View { + let terminal = window_tab_data.terminal.clone(); + let config = window_tab_data.common.config; + let focus = window_tab_data.common.focus; + let active_index = move || terminal.tab_info.with(|info| info.active); + let tab_info = terminal.tab_info; + let header_width = create_rw_signal(0.0); + let header_height = create_rw_signal(0.0); + let icon_width = create_rw_signal(0.0); + let scroll_size = create_rw_signal(Size::ZERO); + let workbench_command = window_tab_data.common.workbench_command; + + stack(( + scroll(dyn_stack( + move || { + let tabs = terminal.tab_info.with(|info| info.tabs.clone()); + for (i, (index, _)) in tabs.iter().enumerate() { + if index.get_untracked() != i { + index.set(i); + } + } + tabs + }, + |(_, tab)| tab.terminal_tab_id, + move |(index, tab)| { + let terminal = terminal.clone(); + let local_terminal = terminal.clone(); + let terminal_tab_id = tab.terminal_tab_id; + + let title = { + let tab = tab.clone(); + move || { + let terminal = tab.active_terminal(true); + let run_debug = terminal.as_ref().map(|t| t.run_debug); + if let Some(run_debug) = run_debug { + if let Some(name) = run_debug.with(|run_debug| { + run_debug.as_ref().map(|r| r.config.name.clone()) + }) { + return name; + } + } + + let title = terminal.map(|t| t.title); + let title = title.map(|t| t.get()); + title.unwrap_or_default() + } + }; + + let svg_string = move || { + let terminal = tab.active_terminal(true); + let run_debug = terminal.as_ref().map(|t| t.run_debug); + if let Some(run_debug) = run_debug { + if let Some((mode, stopped)) = run_debug.with(|run_debug| { + run_debug.as_ref().map(|r| (r.mode, r.stopped)) + }) { + let svg = match (mode, stopped) { + (RunDebugMode::Run, false) => LapceIcons::START, + (RunDebugMode::Run, true) => LapceIcons::RUN_ERRORS, + (RunDebugMode::Debug, false) => LapceIcons::DEBUG, + (RunDebugMode::Debug, true) => { + LapceIcons::DEBUG_DISCONNECT + } + }; + return svg; + } + } + LapceIcons::TERMINAL + }; + stack(( + container({ + stack(( + container( + svg(move || config.get().ui_svg(svg_string())) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.size(size, size).color( + config.color( + LapceColor::LAPCE_ICON_ACTIVE, + ), + ) + }), + ) + .style(|s| s.padding_horiz(10.0).padding_vert(12.0)), + label(title).style(|s| { + s.min_width(0.0) + .flex_basis(0.0) + .flex_grow(1.0) + .text_ellipsis() + .selectable(false) + }), + clickable_icon( + || LapceIcons::CLOSE, + move || { + terminal.close_tab(Some(terminal_tab_id)); + }, + || false, + || false, + || "Close", + config, + ) + .style(|s| s.margin_horiz(6.0)), + empty().style(move |s| { + s.absolute() + .width_full() + .height(header_height.get() - 15.0) + .border_right(1.0) + .border_color( + config.get().color(LapceColor::LAPCE_BORDER), + ) + .pointer_events_none() + }), + )) + .style(move |s| { + s.items_center().width(200.0).border_color( + config.get().color(LapceColor::LAPCE_BORDER), + ) + }) + }) + .style(|s| s.items_center()), + container({ + label(|| "".to_string()).style(move |s| { + s.size_pct(100.0, 100.0) + .border_bottom(if active_index() == index.get() { + 2.0 + } else { + 0.0 + }) + .border_color(config.get().color( + if focus.get() + == Focus::Panel(PanelKind::Terminal) + { + LapceColor::LAPCE_TAB_ACTIVE_UNDERLINE + } else { + LapceColor::LAPCE_TAB_INACTIVE_UNDERLINE + }, + )) + }) + }) + .style(|s| { + s.absolute() + .padding_horiz(3.0) + .size_pct(100.0, 100.0) + .pointer_events_none() + }), + )) + .style(|s| s.cursor(CursorStyle::Pointer)) + .on_event_cont( + EventListener::PointerDown, + move |_| { + if tab_info.with_untracked(|tab| tab.active) + != index.get_untracked() + { + tab_info.update(|tab| { + tab.active = index.get_untracked(); + }); + local_terminal.update_debug_active_term(); + } + }, + ) + }, + )) + .on_resize(move |rect| { + if rect.size() != scroll_size.get_untracked() { + scroll_size.set(rect.size()); + } + }) + .style(move |s| { + let header_width = header_width.get(); + let icon_width = icon_width.get(); + s.set(VerticalScrollAsHorizontal, true) + .absolute() + .max_width(header_width - icon_width) + .set(Thickness, 3) + }), + empty().style(move |s| { + let size = scroll_size.get(); + s.size(size.width, size.height).pointer_events_none() + }), + container(clickable_icon( + || LapceIcons::ADD, + move || { + workbench_command.send(LapceWorkbenchCommand::NewTerminalTab); + }, + || false, + || false, + || "New Terminal", + config, + )) + .on_resize(move |rect| { + let width = rect.size().width; + if icon_width.get_untracked() != width { + icon_width.set(width); + } + }) + .style(|s| s.padding_horiz(10)), + )) + .on_resize(move |rect| { + let size = rect.size(); + if header_width.get_untracked() != size.width { + header_width.set(size.width); + } + if header_height.get_untracked() != size.height { + header_height.set(size.height); + } + }) + .on_double_click(move |_| { + window_tab_data + .panel + .toggle_maximize(&crate::panel::kind::PanelKind::Terminal); + EventPropagation::Stop + }) + .style(move |s| { + let config = config.get(); + s.width_pct(100.0) + .items_center() + .border_bottom(1.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + }) +} + +fn terminal_tab_split( + terminal_panel_data: TerminalPanelData, + terminal_tab_data: TerminalTabData, + tab_index: usize, +) -> impl View { + let config = terminal_panel_data.common.config; + let internal_command = terminal_panel_data.common.internal_command; + let workspace = terminal_panel_data.workspace.clone(); + let active = terminal_tab_data.active; + let terminal_tab_scope = terminal_tab_data.scope; + dyn_stack( + move || { + let terminals = terminal_tab_data.terminals.get(); + for (i, (index, _)) in terminals.iter().enumerate() { + if index.get_untracked() != i { + index.set(i); + } + } + terminals + }, + |(_, terminal)| terminal.term_id, + move |(index, terminal)| { + let terminal_panel_data = terminal_panel_data.clone(); + let terminal_scope = terminal.scope; + container({ + let terminal_view = terminal_view( + terminal.term_id, + terminal.raw.read_only(), + terminal.mode.read_only(), + terminal.run_debug.read_only(), + terminal_panel_data, + terminal.launch_error, + internal_command, + workspace.clone(), + ); + let view_id = terminal_view.id(); + let have_task = terminal.run_debug.get_untracked().is_some(); + terminal_view + .on_event_cont(EventListener::PointerDown, move |_| { + active.set(index.get_untracked()); + }) + .on_secondary_click_stop(move |_| { + if have_task { + tab_secondary_click( + internal_command, + view_id, + tab_index, + index.get_untracked(), + terminal.term_id, + ); + } + }) + .on_event(EventListener::PointerWheel, move |event| { + if let Event::PointerWheel(pointer_event) = event { + terminal.clone().wheel_scroll(pointer_event.delta.y); + EventPropagation::Stop + } else { + EventPropagation::Continue + } + }) + .on_cleanup(move || { + terminal_scope.dispose(); + }) + .style(|s| s.size_pct(100.0, 100.0)) + }) + .style(move |s| { + s.size_pct(100.0, 100.0).padding_horiz(10.0).apply_if( + index.get() > 0, + |s| { + s.border_left(1.0).border_color( + config.get().color(LapceColor::LAPCE_BORDER), + ) + }, + ) + }) + }, + ) + .on_cleanup(move || { + terminal_tab_scope.dispose(); + }) + .style(|s| s.size_pct(100.0, 100.0)) +} + +fn terminal_tab_content(window_tab_data: Rc) -> impl View { + let terminal = window_tab_data.terminal.clone(); + tab( + move || terminal.tab_info.with(|info| info.active), + move || terminal.tab_info.with(|info| info.tabs.clone()), + |(_, tab)| tab.terminal_tab_id, + move |(tab_index, tab)| { + terminal_tab_split(terminal.clone(), tab, tab_index.get_untracked()) + }, + ) + .style(|s| s.size_pct(100.0, 100.0)) +} + +fn tab_secondary_click( + internal_command: Listener, + view_id: ViewId, + tab_index: usize, + terminal_index: usize, + term_id: TermId, +) { + let mut menu = Menu::new(""); + menu = menu + .entry(MenuItem::new("Stop").action(move || { + internal_command.send(InternalCommand::StopTerminal { term_id }); + })) + .entry(MenuItem::new("Restart").action(move || { + internal_command.send(InternalCommand::RestartTerminal { term_id }); + })) + .entry(MenuItem::new("Clear All").action(move || { + internal_command.send(InternalCommand::ClearTerminalBuffer { + view_id, + tab_index, + terminal_index, + }); + })); + show_context_menu(menu, None); +} diff --git a/lapce-app/src/panel/view.rs b/lapce-app/src/panel/view.rs new file mode 100644 index 0000000..fa1966b --- /dev/null +++ b/lapce-app/src/panel/view.rs @@ -0,0 +1,655 @@ +use std::{rc::Rc, sync::Arc}; + +use floem::{ + AnyView, IntoView, View, + event::{Event, EventListener, EventPropagation}, + kurbo::{Point, Size}, + reactive::{ + ReadSignal, RwSignal, SignalGet, SignalUpdate, SignalWith, create_rw_signal, + }, + style::{CursorStyle, Style}, + taffy::AlignItems, + unit::PxPctAuto, + views::{ + Decorators, container, dyn_stack, empty, h_stack, label, stack, + stack_from_iter, tab, text, + }, +}; + +use super::{ + debug_view::debug_panel, + global_search_view::global_search_panel, + kind::PanelKind, + plugin_view::plugin_panel, + position::{PanelContainerPosition, PanelPosition}, + problem_view::problem_panel, + source_control_view::source_control_panel, + terminal_view::terminal_panel, +}; +use crate::{ + app::{clickable_icon, clickable_icon_base}, + config::{LapceConfig, color::LapceColor, icon::LapceIcons}, + file_explorer::view::file_explorer_panel, + panel::{ + call_hierarchy_view::show_hierarchy_panel, document_symbol::symbol_panel, + implementation_view::implementation_panel, + references_view::references_panel, + }, + window_tab::{DragContent, WindowTabData}, +}; + +pub fn foldable_panel_section( + header: impl View + 'static, + child: impl View + 'static, + open: RwSignal, + config: ReadSignal>, +) -> impl View { + stack(( + h_stack(( + clickable_icon_base( + move || { + if open.get() { + LapceIcons::PANEL_FOLD_DOWN + } else { + LapceIcons::PANEL_FOLD_UP + } + }, + None::>, + || false, + || false, + config, + ), + header.style(|s| s.align_items(AlignItems::Center).padding_left(3.0)), + )) + .style(move |s| { + s.padding_horiz(10.0) + .padding_vert(6.0) + .width_pct(100.0) + .cursor(CursorStyle::Pointer) + .background(config.get().color(LapceColor::EDITOR_BACKGROUND)) + }) + .on_click_stop(move |_| { + open.update(|open| *open = !*open); + }), + child.style(move |s| s.apply_if(!open.get(), |s| s.hide())), + )) +} + +/// A builder for creating a foldable panel out of sections +pub struct PanelBuilder { + views: Vec, + config: ReadSignal>, + position: PanelPosition, +} +impl PanelBuilder { + pub fn new( + config: ReadSignal>, + position: PanelPosition, + ) -> Self { + Self { + views: Vec::new(), + config, + position, + } + } + + fn add_general( + mut self, + name: &'static str, + height: Option, + view: impl View + 'static, + open: RwSignal, + style: impl Fn(Style) -> Style + 'static, + ) -> Self { + let position = self.position; + let view = foldable_panel_section( + text(name).style(move |s| s.selectable(false)), + view, + open, + self.config, + ) + .style(move |s| { + let s = s.width_full().flex_col(); + // Use the manual height if given, otherwise if we're open behave flex, + // otherwise, do nothing so that there's no height + let s = if open.get() { + if let Some(height) = height { + s.height(height) + } else { + s.flex_grow(1.0).flex_basis(0.0) + } + } else if position.is_bottom() { + s.flex_grow(0.3).flex_basis(0.0) + } else { + s + }; + + style(s) + }); + self.views.push(view.into_any()); + self + } + + /// Add a view to the panel + pub fn add( + self, + name: &'static str, + view: impl View + 'static, + open: RwSignal, + ) -> Self { + self.add_general(name, None, view, open, std::convert::identity) + } + + /// Add a view to the panel with a custom style applied to the overall header+section-content + pub fn add_style( + self, + name: &'static str, + view: impl View + 'static, + open: RwSignal, + style: impl Fn(Style) -> Style + 'static, + ) -> Self { + self.add_general(name, None, view, open, style) + } + + /// Add a view to the panel with a custom height that is only used when the panel is open + pub fn add_height( + self, + name: &'static str, + height: impl Into, + view: impl View + 'static, + open: RwSignal, + ) -> Self { + self.add_general( + name, + Some(height.into()), + view, + open, + std::convert::identity, + ) + } + + /// Add a view to the panel with a custom height that is only used when the panel is open + /// and a custom style applied to the overall header+section-content + pub fn add_height_style( + self, + name: &'static str, + height: impl Into, + view: impl View + 'static, + open: RwSignal, + style: impl Fn(Style) -> Style + 'static, + ) -> Self { + self.add_general(name, Some(height.into()), view, open, style) + } + + /// Add a view to the panel with a custom height that is only used when the panel is open + pub fn add_height_pct( + self, + name: &'static str, + height: f64, + view: impl View + 'static, + open: RwSignal, + ) -> Self { + self.add_general( + name, + Some(PxPctAuto::Pct(height)), + view, + open, + std::convert::identity, + ) + } + + /// Build the panel into a view + pub fn build(self) -> impl View { + stack_from_iter(self.views).style(move |s| { + s.width_full() + .apply_if(!self.position.is_bottom(), |s| s.flex_col()) + }) + } +} + +pub fn panel_container_view( + window_tab_data: Rc, + position: PanelContainerPosition, +) -> impl View { + let panel = window_tab_data.panel.clone(); + let config = window_tab_data.common.config; + let dragging = window_tab_data.common.dragging; + let current_size = create_rw_signal(Size::ZERO); + let available_size = window_tab_data.panel.available_size; + let is_dragging_panel = move || { + dragging + .with(|d| d.as_ref().map(|d| d.is_panel())) + .unwrap_or(false) + }; + let drop_view = { + let panel = panel.clone(); + move |position: PanelPosition| { + let panel = panel.clone(); + let dragging_over = create_rw_signal(false); + empty() + .on_event(EventListener::DragEnter, move |_| { + if is_dragging_panel() { + dragging_over.set(true); + EventPropagation::Stop + } else { + EventPropagation::Continue + } + }) + .on_event(EventListener::DragLeave, move |_| { + if is_dragging_panel() { + dragging_over.set(false); + EventPropagation::Stop + } else { + EventPropagation::Continue + } + }) + .on_event(EventListener::Drop, move |_| { + if let Some(DragContent::Panel(kind)) = dragging.get_untracked() + { + dragging_over.set(false); + panel.move_panel_to_position(kind, &position); + EventPropagation::Stop + } else { + EventPropagation::Continue + } + }) + .style(move |s| { + s.size_pct(100.0, 100.0).apply_if(dragging_over.get(), |s| { + s.background( + config + .get() + .color(LapceColor::EDITOR_DRAG_DROP_BACKGROUND), + ) + }) + }) + } + }; + + let resize_drag_view = { + let panel = panel.clone(); + let panel_size = panel.size; + move |position: PanelContainerPosition| { + panel.panel_info(); + let view = empty(); + let view_id = view.id(); + let drag_start: RwSignal> = create_rw_signal(None); + view.on_event_stop(EventListener::PointerDown, move |event| { + view_id.request_active(); + if let Event::PointerDown(pointer_event) = event { + drag_start.set(Some(pointer_event.pos)); + } + }) + .on_event_stop(EventListener::PointerMove, move |event| { + if let Event::PointerMove(pointer_event) = event { + if let Some(drag_start_point) = drag_start.get_untracked() { + let current_size = current_size.get_untracked(); + let available_size = available_size.get_untracked(); + match position { + PanelContainerPosition::Left => { + let new_size = current_size.width + + pointer_event.pos.x + - drag_start_point.x; + let current_panel_size = panel_size.get_untracked(); + let new_size = new_size + .max(150.0) + .min(available_size.width - 150.0 - 150.0); + if new_size != current_panel_size.left { + panel_size.update(|size| { + size.left = new_size; + size.right = size.right.min( + available_size.width - new_size - 150.0, + ) + }) + } + } + PanelContainerPosition::Bottom => { + let new_size = current_size.height + - (pointer_event.pos.y - drag_start_point.y); + let maximized = panel.panel_bottom_maximized(false); + if (maximized + && new_size < available_size.height - 50.0) + || (!maximized + && new_size > available_size.height - 50.0) + { + panel.toggle_bottom_maximize(); + } + + let new_size = new_size + .max(100.0) + .min(available_size.height - 100.0); + let current_size = + panel_size.with_untracked(|s| s.bottom); + if current_size != new_size { + panel_size.update(|size| { + size.bottom = new_size; + }) + } + } + PanelContainerPosition::Right => { + let new_size = current_size.width + - (pointer_event.pos.x - drag_start_point.x); + let current_panel_size = panel_size.get_untracked(); + let new_size = new_size + .max(150.0) + .min(available_size.width - 150.0 - 150.0); + if new_size != current_panel_size.right { + panel_size.update(|size| { + size.right = new_size; + size.left = size.left.min( + available_size.width - new_size - 150.0, + ) + }) + } + } + } + } + } + }) + .on_event_stop(EventListener::PointerUp, move |_| { + drag_start.set(None); + }) + .style(move |s| { + let is_dragging = drag_start.get().is_some(); + let current_size = current_size.get(); + let config = config.get(); + s.absolute() + .apply_if(position == PanelContainerPosition::Bottom, |s| { + s.width_pct(100.0).height(4.0).margin_top(-2.0) + }) + .apply_if(position == PanelContainerPosition::Left, |s| { + s.width(4.0) + .margin_left(current_size.width as f32 - 2.0) + .height_pct(100.0) + }) + .apply_if(position == PanelContainerPosition::Right, |s| { + s.width(4.0).margin_left(-2.0).height_pct(100.0) + }) + .apply_if(is_dragging, |s| { + s.background(config.color(LapceColor::EDITOR_CARET)) + .apply_if( + position == PanelContainerPosition::Bottom, + |s| s.cursor(CursorStyle::RowResize), + ) + .apply_if( + position != PanelContainerPosition::Bottom, + |s| s.cursor(CursorStyle::ColResize), + ) + .z_index(2) + }) + .hover(|s| { + s.background(config.color(LapceColor::EDITOR_CARET)) + .apply_if( + position == PanelContainerPosition::Bottom, + |s| s.cursor(CursorStyle::RowResize), + ) + .apply_if( + position != PanelContainerPosition::Bottom, + |s| s.cursor(CursorStyle::ColResize), + ) + .z_index(2) + }) + }) + } + }; + + let is_bottom = position.is_bottom(); + stack(( + panel_picker(window_tab_data.clone(), position.first()), + panel_view(window_tab_data.clone(), position.first()), + panel_view(window_tab_data.clone(), position.second()), + panel_picker(window_tab_data.clone(), position.second()), + resize_drag_view(position), + stack((drop_view(position.first()), drop_view(position.second()))).style( + move |s| { + let is_dragging_panel = is_dragging_panel(); + s.absolute() + .size_pct(100.0, 100.0) + .apply_if(!is_bottom, |s| s.flex_col()) + .apply_if(!is_dragging_panel, |s| s.pointer_events_none()) + }, + ), + )) + .on_resize(move |rect| { + let size = rect.size(); + if size != current_size.get_untracked() { + current_size.set(size); + } + }) + .style(move |s| { + let size = panel.size.with(|s| match position { + PanelContainerPosition::Left => s.left, + PanelContainerPosition::Bottom => s.bottom, + PanelContainerPosition::Right => s.right, + }); + let is_maximized = panel.panel_bottom_maximized(true); + let config = config.get(); + s.apply_if(!panel.is_container_shown(&position, true), |s| s.hide()) + .apply_if(position == PanelContainerPosition::Bottom, |s| { + s.width_pct(100.0) + .apply_if(!is_maximized, |s| { + s.border_top(1.0).height(size as f32) + }) + .apply_if(is_maximized, |s| s.flex_grow(1.0)) + }) + .apply_if(position == PanelContainerPosition::Left, |s| { + s.border_right(1.0) + .width(size as f32) + .height_pct(100.0) + .background(config.color(LapceColor::PANEL_BACKGROUND)) + }) + .apply_if(position == PanelContainerPosition::Right, |s| { + s.border_left(1.0) + .width(size as f32) + .height_pct(100.0) + .background(config.color(LapceColor::PANEL_BACKGROUND)) + }) + .apply_if(!is_bottom, |s| s.flex_col()) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .color(config.color(LapceColor::PANEL_FOREGROUND)) + }) + .debug_name(format!("{:?} Panel Container View", position)) +} + +fn panel_view( + window_tab_data: Rc, + position: PanelPosition, +) -> impl View { + let panel = window_tab_data.panel.clone(); + let panels = move || { + panel + .panels + .with(|p| p.get(&position).cloned().unwrap_or_default()) + }; + let active_fn = move || { + panel + .styles + .with(|s| s.get(&position).map(|s| s.active).unwrap_or(0)) + }; + tab( + active_fn, + panels, + |p| *p, + move |kind| { + let view = match kind { + PanelKind::Terminal => { + terminal_panel(window_tab_data.clone()).into_any() + } + PanelKind::FileExplorer => { + file_explorer_panel(window_tab_data.clone(), position).into_any() + } + PanelKind::SourceControl => { + source_control_panel(window_tab_data.clone(), position) + .into_any() + } + PanelKind::Plugin => { + plugin_panel(window_tab_data.clone(), position).into_any() + } + PanelKind::Search => { + global_search_panel(window_tab_data.clone(), position).into_any() + } + PanelKind::Problem => { + problem_panel(window_tab_data.clone(), position).into_any() + } + PanelKind::Debug => { + debug_panel(window_tab_data.clone(), position).into_any() + } + PanelKind::CallHierarchy => { + show_hierarchy_panel(window_tab_data.clone(), position) + .into_any() + } + PanelKind::DocumentSymbol => { + symbol_panel(window_tab_data.clone(), position).into_any() + } + PanelKind::References => { + references_panel(window_tab_data.clone(), position).into_any() + } + PanelKind::Implementation => { + implementation_panel(window_tab_data.clone(), position) + .into_any() + } + }; + view.style(|s| s.size_pct(100.0, 100.0)) + }, + ) + .style(move |s| { + s.size_pct(100.0, 100.0).apply_if( + !panel.is_position_shown(&position, true) + || panel.is_position_empty(&position, true), + |s| s.hide(), + ) + }) +} + +pub fn panel_header( + header: String, + config: ReadSignal>, +) -> impl View { + container(label(move || header.clone())).style(move |s| { + s.padding_horiz(10.0) + .padding_vert(6.0) + .width_pct(100.0) + .background(config.get().color(LapceColor::EDITOR_BACKGROUND)) + }) +} + +fn panel_picker( + window_tab_data: Rc, + position: PanelPosition, +) -> impl View { + let panel = window_tab_data.panel.clone(); + let panels = panel.panels; + let config = window_tab_data.common.config; + let dragging = window_tab_data.common.dragging; + let is_bottom = position.is_bottom(); + let is_first = position.is_first(); + dyn_stack( + move || { + panel + .panels + .with(|panels| panels.get(&position).cloned().unwrap_or_default()) + }, + |p| *p, + move |p| { + let window_tab_data = window_tab_data.clone(); + let tooltip = match p { + PanelKind::Terminal => "Terminal", + PanelKind::FileExplorer => "File Explorer", + PanelKind::SourceControl => "Source Control", + PanelKind::Plugin => "Plugins", + PanelKind::Search => "Search", + PanelKind::Problem => "Problems", + PanelKind::Debug => "Debug", + PanelKind::CallHierarchy => "Call Hierarchy", + PanelKind::DocumentSymbol => "Document Symbol", + PanelKind::References => "References", + PanelKind::Implementation => "Implementation", + }; + let icon = p.svg_name(); + let is_active = { + let window_tab_data = window_tab_data.clone(); + move || { + if let Some((active_panel, shown)) = window_tab_data + .panel + .active_panel_at_position(&position, true) + { + shown && active_panel == p + } else { + false + } + } + }; + container(stack(( + clickable_icon( + || icon, + move || { + window_tab_data.toggle_panel_visual(p); + }, + || false, + || false, + move || tooltip, + config, + ) + .draggable() + .on_event_stop(EventListener::DragStart, move |_| { + dragging.set(Some(DragContent::Panel(p))); + }) + .on_event_stop(EventListener::DragEnd, move |_| { + dragging.set(None); + }) + .dragging_style(move |s| { + let config = config.get(); + s.border(1.0) + .border_radius(6.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .padding(6.0) + .background( + config + .color(LapceColor::PANEL_BACKGROUND) + .multiply_alpha(0.7), + ) + }) + .style(|s| s.padding(1.0)), + label(|| "".to_string()).style(move |s| { + s.selectable(false) + .pointer_events_none() + .absolute() + .size_pct(100.0, 100.0) + .apply_if(!is_bottom && is_first, |s| s.margin_top(2.0)) + .apply_if(!is_bottom && !is_first, |s| s.margin_top(-2.0)) + .apply_if(is_bottom && is_first, |s| s.margin_left(-2.0)) + .apply_if(is_bottom && !is_first, |s| s.margin_left(2.0)) + .apply_if(is_active(), |s| { + s.apply_if(!is_bottom && is_first, |s| { + s.border_bottom(2.0) + }) + .apply_if(!is_bottom && !is_first, |s| s.border_top(2.0)) + .apply_if(is_bottom && is_first, |s| s.border_left(2.0)) + .apply_if(is_bottom && !is_first, |s| { + s.border_right(2.0) + }) + }) + .border_color( + config + .get() + .color(LapceColor::LAPCE_TAB_ACTIVE_UNDERLINE), + ) + }), + ))) + .style(|s| s.padding(6.0)) + }, + ) + .style(move |s| { + s.border_color(config.get().color(LapceColor::LAPCE_BORDER)) + .apply_if( + panels.with(|p| { + p.get(&position).map(|p| p.is_empty()).unwrap_or(true) + }), + |s| s.hide(), + ) + .apply_if(is_bottom, |s| s.flex_col()) + .apply_if(is_bottom && is_first, |s| s.border_right(1.0)) + .apply_if(is_bottom && !is_first, |s| s.border_left(1.0)) + .apply_if(!is_bottom && is_first, |s| s.border_bottom(1.0)) + .apply_if(!is_bottom && !is_first, |s| s.border_top(1.0)) + }) +} diff --git a/lapce-app/src/plugin.rs b/lapce-app/src/plugin.rs new file mode 100644 index 0000000..c229528 --- /dev/null +++ b/lapce-app/src/plugin.rs @@ -0,0 +1,1023 @@ +use std::{ + collections::HashSet, + rc::Rc, + sync::{Arc, atomic::AtomicU64}, +}; + +use anyhow::Result; +use floem::{ + IntoView, View, + action::show_context_menu, + ext_event::create_ext_action, + keyboard::Modifiers, + kurbo::Rect, + menu::{Menu, MenuItem}, + reactive::{ + RwSignal, Scope, SignalGet, SignalUpdate, SignalWith, create_effect, + create_memo, create_rw_signal, use_context, + }, + style::CursorStyle, + views::{ + Decorators, container, dyn_container, dyn_stack, empty, img, label, + rich_text, scroll, stack, svg, text, + }, +}; +use indexmap::IndexMap; +use lapce_core::{command::EditCommand, directory::Directory, mode::Mode}; +use lapce_proxy::plugin::{download_volt, volt_icon, wasi::find_all_volts}; +use lapce_rpc::{ + core::{CoreNotification, CoreRpcHandler}, + plugin::{VoltID, VoltInfo, VoltMetadata}, +}; +use lsp_types::MessageType; +use serde::{Deserialize, Serialize}; +use sha2::{Digest, Sha256}; + +use crate::{ + command::{CommandExecuted, CommandKind}, + config::{LapceConfig, color::LapceColor}, + db::LapceDb, + editor::EditorData, + keypress::{KeyPressFocus, condition::Condition}, + main_split::Editors, + markdown::{MarkdownContent, parse_markdown}, + panel::plugin_view::VOLT_DEFAULT_PNG, + web_link::web_link, + window_tab::CommonData, +}; + +type PluginInfo = Option<( + Option, + VoltInfo, + Option, + Option, + Option>, +)>; + +#[derive(Clone, PartialEq, Eq)] +pub enum VoltIcon { + Svg(String), + Img(Vec), +} + +impl VoltIcon { + pub fn from_bytes(buf: &[u8]) -> Result { + if let Ok(s) = std::str::from_utf8(buf) { + Ok(VoltIcon::Svg(s.to_string())) + } else { + Ok(VoltIcon::Img(buf.to_vec())) + } + } +} + +#[derive(Deserialize, Serialize)] +pub struct VoltsInfo { + pub plugins: Vec, + pub total: usize, +} + +#[derive(Clone)] +pub struct InstalledVoltData { + pub meta: RwSignal, + pub icon: RwSignal>, + pub latest: RwSignal, +} + +#[derive(Clone, PartialEq)] +pub struct AvailableVoltData { + pub info: RwSignal, + pub icon: RwSignal>, + pub installing: RwSignal, +} + +#[derive(Clone, Debug)] +pub struct AvailableVoltList { + pub loading: RwSignal, + pub query_id: RwSignal, + pub query_editor: EditorData, + pub volts: RwSignal>, + pub total: RwSignal, +} + +#[derive(Clone, Debug)] +pub struct PluginData { + pub installed: RwSignal>, + pub available: AvailableVoltList, + pub all: RwSignal>, + pub disabled: RwSignal>, + pub workspace_disabled: RwSignal>, + pub common: Rc, +} + +impl KeyPressFocus for PluginData { + fn get_mode(&self) -> Mode { + Mode::Insert + } + + fn check_condition(&self, condition: Condition) -> bool { + matches!(condition, Condition::PanelFocus) + } + + fn run_command( + &self, + command: &crate::command::LapceCommand, + count: Option, + mods: Modifiers, + ) -> CommandExecuted { + match &command.kind { + CommandKind::Workbench(_) => {} + CommandKind::Scroll(_) => {} + CommandKind::Focus(_) => {} + CommandKind::Edit(_) + | CommandKind::Move(_) + | CommandKind::MultiSelection(_) => { + #[allow(clippy::single_match)] + match command.kind { + CommandKind::Edit(EditCommand::InsertNewLine) => { + return CommandExecuted::Yes; + } + _ => {} + } + + return self + .available + .query_editor + .run_command(command, count, mods); + } + CommandKind::MotionMode(_) => {} + } + CommandExecuted::No + } + + fn receive_char(&self, c: &str) { + self.available.query_editor.receive_char(c); + } +} + +impl PluginData { + pub fn new( + cx: Scope, + disabled: HashSet, + workspace_disabled: HashSet, + editors: Editors, + common: Rc, + core_rpc: CoreRpcHandler, + ) -> Self { + let installed = cx.create_rw_signal(IndexMap::new()); + let available = AvailableVoltList { + loading: cx.create_rw_signal(false), + volts: cx.create_rw_signal(IndexMap::new()), + total: cx.create_rw_signal(0), + query_id: cx.create_rw_signal(0), + query_editor: editors.make_local(cx, common.clone()), + }; + let disabled = cx.create_rw_signal(disabled); + let workspace_disabled = cx.create_rw_signal(workspace_disabled); + + let plugin = Self { + installed, + available, + all: cx.create_rw_signal(im::HashMap::new()), + disabled, + workspace_disabled, + common, + }; + + plugin.load_available_volts("", 0, core_rpc.clone()); + + { + let plugin = plugin.clone(); + let extra_plugin_paths = + plugin.common.window_common.extra_plugin_paths.clone(); + + let send = create_ext_action( + cx, + move |volts: Vec<(Option>, VoltMetadata)>| { + for (icon, meta) in volts { + plugin.volt_installed(&meta, &icon); + } + }, + ); + std::thread::Builder::new() + .name("FindAllVolts".to_owned()) + .spawn(move || { + let volts = find_all_volts(&extra_plugin_paths); + let volts = volts + .into_iter() + .filter_map(|meta| { + if meta.wasm.is_none() { + Some((volt_icon(&meta), meta)) + } else { + None + } + }) + .collect::>(); + send(volts); + }) + .unwrap(); + } + + { + let plugin = plugin.clone(); + cx.create_effect(move |s| { + let query = plugin + .available + .query_editor + .doc_signal() + .get() + .buffer + .with(|buffer| buffer.to_string()); + if s.as_ref() == Some(&query) { + return query; + } + plugin.available.query_id.update(|id| *id += 1); + plugin.available.loading.set(false); + plugin.available.volts.update(|v| v.clear()); + plugin.load_available_volts(&query, 0, core_rpc.clone()); + query + }); + } + + plugin + } + + pub fn volt_installed(&self, volt: &VoltMetadata, icon: &Option>) { + let volt_id = volt.id(); + let (existing, is_latest, volt_data) = self + .installed + .try_update(|installed| { + if let Some(v) = installed.get(&volt_id) { + (true, true, v.to_owned()) + } else { + let (info, is_latest) = if let Some(volt) = self + .available + .volts + .with_untracked(|all| all.get(&volt_id).cloned()) + { + (volt.info.get_untracked(), true) + } else { + (volt.info(), false) + }; + + let latest = self.common.scope.create_rw_signal(info); + let data = InstalledVoltData { + meta: self.common.scope.create_rw_signal(volt.clone()), + icon: self.common.scope.create_rw_signal( + icon.as_ref() + .and_then(|icon| VoltIcon::from_bytes(icon).ok()), + ), + latest, + }; + installed.insert(volt_id, data.clone()); + + (false, is_latest, data) + } + }) + .unwrap(); + + if existing { + volt_data.meta.set(volt.clone()); + volt_data.icon.set( + icon.as_ref() + .and_then(|icon| VoltIcon::from_bytes(icon).ok()), + ); + } + + let latest = volt_data.latest; + if !is_latest { + let url = format!( + "https://plugins.lapce.dev/api/v1/plugins/{}/{}/latest", + volt.author, volt.name + ); + let send = create_ext_action(self.common.scope, move |info| { + if let Some(info) = info { + latest.set(info); + } + }); + std::thread::spawn(move || { + let info: Option = lapce_proxy::get_url(url, None) + .ok() + .and_then(|r| r.json().ok()); + send(info); + }); + } + } + + pub fn volt_removed(&self, volt: &VoltInfo) { + let id = volt.id(); + self.installed.update(|installed| { + installed.swap_remove(&id); + }); + + if self.disabled.with_untracked(|d| d.contains(&id)) { + self.disabled.update(|d| { + d.remove(&id); + }); + let db: Arc = use_context().unwrap(); + db.save_disabled_volts( + self.disabled.get_untracked().into_iter().collect(), + ); + } + + if self.workspace_disabled.with_untracked(|d| d.contains(&id)) { + self.workspace_disabled.update(|d| { + d.remove(&id); + }); + let db: Arc = use_context().unwrap(); + db.save_workspace_disabled_volts( + self.common.workspace.clone(), + self.workspace_disabled + .get_untracked() + .into_iter() + .collect(), + ); + } + } + + fn load_available_volts( + &self, + query: &str, + offset: usize, + core_rpc: CoreRpcHandler, + ) { + if self.available.loading.get_untracked() { + return; + } + self.available.loading.set(true); + + let volts = self.available.volts; + let volts_total = self.available.total; + let cx = self.common.scope; + let loading = self.available.loading; + let query_id = self.available.query_id; + let current_query_id = self.available.query_id.get_untracked(); + let all = self.all; + let send = + create_ext_action(self.common.scope, move |new: Result| { + loading.set(false); + if query_id.get_untracked() != current_query_id { + return; + } + + match new { + Ok(new) => { + volts.update(|volts| { + volts.extend(new.plugins.into_iter().map(|volt| { + let icon = cx.create_rw_signal(None); + let send = create_ext_action(cx, move |result| { + if let Ok(i) = result { + icon.set(Some(i)); + } + }); + { + let volt = volt.clone(); + std::thread::spawn(move || { + let result = Self::load_icon(&volt); + send(result); + }); + } + + let data = AvailableVoltData { + info: cx.create_rw_signal(volt.clone()), + icon, + installing: cx.create_rw_signal(false), + }; + all.update(|all| { + all.insert(volt.id(), data.clone()); + }); + + (volt.id(), data) + })); + }); + volts_total.set(new.total); + } + Err(err) => { + tracing::error!("{:?}", err); + core_rpc.notification(CoreNotification::ShowMessage { + title: "Request Available Plugins".to_string(), + message: lsp_types::ShowMessageParams { + typ: MessageType::ERROR, + message: err.to_string(), + }, + }); + } + } + }); + + let query = query.to_string(); + std::thread::spawn(move || { + let volts = Self::query_volts(&query, offset); + send(volts); + }); + } + + fn load_icon(volt: &VoltInfo) -> Result { + let url = format!( + "https://plugins.lapce.dev/api/v1/plugins/{}/{}/{}/icon?id={}", + volt.author, volt.name, volt.version, volt.updated_at_ts + ); + + let cache_file_path = Directory::cache_directory().map(|cache_dir| { + let mut hasher = Sha256::new(); + hasher.update(url.as_bytes()); + let filename = format!("{:x}", hasher.finalize()); + cache_dir.join(filename) + }); + + let cache_content = + cache_file_path.as_ref().and_then(|p| std::fs::read(p).ok()); + + let content = match cache_content { + Some(content) => content, + None => { + let resp = lapce_proxy::get_url(&url, None)?; + if !resp.status().is_success() { + return Err(anyhow::anyhow!("can't download icon")); + } + let buf = resp.bytes()?.to_vec(); + + if let Some(path) = cache_file_path.as_ref() { + if let Err(err) = std::fs::write(path, &buf) { + tracing::error!("{:?}", err); + } + } + + buf + } + }; + + VoltIcon::from_bytes(&content) + } + + fn download_readme( + volt: &VoltInfo, + config: &LapceConfig, + ) -> Result> { + let url = format!( + "https://plugins.lapce.dev/api/v1/plugins/{}/{}/{}/readme", + volt.author, volt.name, volt.version + ); + let resp = lapce_proxy::get_url(&url, None)?; + if resp.status() != 200 { + let text = parse_markdown("Plugin doesn't have a README", 2.0, config); + return Ok(text); + } + let text = resp.text()?; + let text = parse_markdown(&text, 2.0, config); + Ok(text) + } + + fn query_volts(query: &str, offset: usize) -> Result { + let url = format!( + "https://plugins.lapce.dev/api/v1/plugins?q={query}&offset={offset}" + ); + let plugins: VoltsInfo = lapce_proxy::get_url(url, None)?.json()?; + Ok(plugins) + } + + fn all_loaded(&self) -> bool { + self.available.volts.with_untracked(|v| v.len()) + >= self.available.total.get_untracked() + } + + pub fn load_more_available(&self, core_rpc: CoreRpcHandler) { + if self.all_loaded() { + return; + } + + let query = self + .available + .query_editor + .doc() + .buffer + .with_untracked(|buffer| buffer.to_string()); + let offset = self.available.volts.with_untracked(|v| v.len()); + self.load_available_volts(&query, offset, core_rpc); + } + + pub fn install_volt(&self, info: VoltInfo) { + self.available.volts.with_untracked(|volts| { + if let Some(volt) = volts.get(&info.id()) { + volt.installing.set(true); + }; + }); + if info.wasm { + self.common.proxy.install_volt(info); + } else { + let plugin = self.clone(); + let send = create_ext_action(self.common.scope, move |result| { + if let Ok((meta, icon)) = result { + plugin.volt_installed(&meta, &icon); + } + }); + std::thread::spawn(move || { + let download = || -> Result<(VoltMetadata, Option>)> { + let download_volt_result = download_volt(&info); + let meta = download_volt_result?; + let icon = volt_icon(&meta); + Ok((meta, icon)) + }; + send(download()); + }); + } + } + + pub fn plugin_disabled(&self, id: &VoltID) -> bool { + self.disabled.with_untracked(|d| d.contains(id)) + || self.workspace_disabled.with_untracked(|d| d.contains(id)) + } + + pub fn enable_volt(&self, volt: VoltInfo) { + let id = volt.id(); + self.disabled.update(|d| { + d.remove(&id); + }); + if !self.plugin_disabled(&id) { + self.common.proxy.enable_volt(volt); + } + let db: Arc = use_context().unwrap(); + db.save_disabled_volts(self.disabled.get_untracked().into_iter().collect()); + } + + pub fn disable_volt(&self, volt: VoltInfo) { + let id = volt.id(); + self.disabled.update(|d| { + d.insert(id); + }); + self.common.proxy.disable_volt(volt); + let db: Arc = use_context().unwrap(); + db.save_disabled_volts(self.disabled.get_untracked().into_iter().collect()); + } + + pub fn enable_volt_for_ws(&self, volt: VoltInfo) { + let id = volt.id(); + self.workspace_disabled.update(|d| { + d.remove(&id); + }); + if !self.plugin_disabled(&id) { + self.common.proxy.enable_volt(volt); + } + let db: Arc = use_context().unwrap(); + db.save_workspace_disabled_volts( + self.common.workspace.clone(), + self.disabled.get_untracked().into_iter().collect(), + ); + } + + pub fn disable_volt_for_ws(&self, volt: VoltInfo) { + let id = volt.id(); + self.workspace_disabled.update(|d| { + d.insert(id); + }); + self.common.proxy.disable_volt(volt); + let db: Arc = use_context().unwrap(); + db.save_workspace_disabled_volts( + self.common.workspace.clone(), + self.disabled.get_untracked().into_iter().collect(), + ); + } + + pub fn uninstall_volt(&self, volt: VoltMetadata) { + if volt.wasm.is_some() { + self.common.proxy.remove_volt(volt); + } else { + let plugin = self.clone(); + let info = volt.info(); + let send = + create_ext_action(self.common.scope, move |result: Result<()>| { + if let Ok(()) = result { + plugin.volt_removed(&info); + } + }); + std::thread::spawn(move || { + let uninstall = || -> Result<()> { + let path = volt + .dir + .as_ref() + .ok_or_else(|| anyhow::anyhow!("don't have dir"))?; + std::fs::remove_dir_all(path)?; + Ok(()) + }; + send(uninstall()); + }); + } + } + + pub fn reload_volt(&self, volt: VoltMetadata) { + self.common.proxy.reload_volt(volt); + } + + pub fn plugin_controls(&self, meta: VoltMetadata, latest: VoltInfo) -> Menu { + let volt_id = meta.id(); + let mut menu = Menu::new(""); + if meta.version != latest.version { + menu = menu + .entry(MenuItem::new("Upgrade Plugin").action({ + let plugin = self.clone(); + let info = latest.clone(); + move || { + plugin.install_volt(info.clone()); + } + })) + .separator(); + } + menu = menu + .entry(MenuItem::new("Reload Plugin").action({ + let plugin = self.clone(); + let meta = meta.clone(); + move || { + plugin.reload_volt(meta.clone()); + } + })) + .separator() + .entry( + MenuItem::new("Enable") + .enabled( + self.disabled + .with_untracked(|disabled| disabled.contains(&volt_id)), + ) + .action({ + let plugin = self.clone(); + let volt = meta.info(); + move || { + plugin.enable_volt(volt.clone()); + } + }), + ) + .entry( + MenuItem::new("Disable") + .enabled( + self.disabled + .with_untracked(|disabled| !disabled.contains(&volt_id)), + ) + .action({ + let plugin = self.clone(); + let volt = meta.info(); + move || { + plugin.disable_volt(volt.clone()); + } + }), + ) + .separator() + .entry( + MenuItem::new("Enable For Workspace") + .enabled( + self.workspace_disabled + .with_untracked(|disabled| disabled.contains(&volt_id)), + ) + .action({ + let plugin = self.clone(); + let volt = meta.info(); + move || { + plugin.enable_volt_for_ws(volt.clone()); + } + }), + ) + .entry( + MenuItem::new("Disable For Workspace") + .enabled( + self.workspace_disabled + .with_untracked(|disabled| !disabled.contains(&volt_id)), + ) + .action({ + let plugin = self.clone(); + let volt = meta.info(); + move || { + plugin.disable_volt_for_ws(volt.clone()); + } + }), + ) + .separator() + .entry(MenuItem::new("Uninstall").action({ + let plugin = self.clone(); + move || { + plugin.uninstall_volt(meta.clone()); + } + })); + menu + } +} + +pub fn plugin_info_view(plugin: PluginData, volt: VoltID) -> impl View { + let config = plugin.common.config; + let header_rect = create_rw_signal(Rect::ZERO); + let scroll_width: RwSignal = create_rw_signal(0.0); + let internal_command = plugin.common.internal_command; + let local_plugin = plugin.clone(); + let plugin_info = create_memo(move |_| { + plugin + .installed + .with(|volts| { + volts.get(&volt).map(|v| { + ( + Some(v.meta.get()), + v.meta.get().info(), + v.icon.get(), + Some(v.latest.get()), + None, + ) + }) + }) + .or_else(|| { + plugin.all.with(|volts| { + volts.get(&volt).map(|v| { + (None, v.info.get(), v.icon.get(), None, Some(v.installing)) + }) + }) + }) + }); + + let version_view = move |plugin: PluginData, plugin_info: PluginInfo| { + let version_info = plugin_info.as_ref().map(|(_, volt, _, latest, _)| { + ( + volt.version.clone(), + latest.as_ref().map(|i| i.version.clone()), + ) + }); + let installing = plugin_info + .as_ref() + .and_then(|(_, _, _, _, installing)| *installing); + let local_version_info = version_info.clone(); + let control = { + move |version_info: Option<(String, Option)>| match version_info + .as_ref() + .map(|(v, l)| match l { + Some(l) => (true, l == v), + None => (false, false), + }) { + Some((true, true)) => "Installed ▼", + Some((true, false)) => "Upgrade ▼", + _ => { + if installing.map(|i| i.get()).unwrap_or(false) { + "Installing" + } else { + "Install" + } + } + } + }; + let local_plugin_info = plugin_info.clone(); + let local_plugin = plugin.clone(); + stack(( + text( + version_info + .as_ref() + .map(|(v, _)| format!("v{v}")) + .unwrap_or_default(), + ), + label(move || control(local_version_info.clone())) + .style(move |s| { + let config = config.get(); + s.margin_left(10) + .padding_horiz(10) + .border_radius(6.0) + .color( + config + .color(LapceColor::LAPCE_BUTTON_PRIMARY_FOREGROUND), + ) + .background( + config + .color(LapceColor::LAPCE_BUTTON_PRIMARY_BACKGROUND), + ) + .hover(|s| { + s.cursor(CursorStyle::Pointer).background( + config + .color( + LapceColor::LAPCE_BUTTON_PRIMARY_BACKGROUND, + ) + .multiply_alpha(0.8), + ) + }) + .active(|s| { + s.background( + config + .color( + LapceColor::LAPCE_BUTTON_PRIMARY_BACKGROUND, + ) + .multiply_alpha(0.6), + ) + }) + .disabled(|s| { + s.background(config.color(LapceColor::EDITOR_DIM)) + }) + .selectable(false) + }) + .disabled(move || installing.map(|i| i.get()).unwrap_or(false)) + .on_click_stop(move |_| { + if let Some((meta, info, _, latest, _)) = + local_plugin_info.as_ref() + { + if let Some(meta) = meta { + let menu = local_plugin.plugin_controls( + meta.to_owned(), + latest.clone().unwrap_or_else(|| info.to_owned()), + ); + show_context_menu(menu, None); + } else { + local_plugin.install_volt(info.to_owned()); + } + } + }), + )) + }; + + scroll( + dyn_container( + move || plugin_info.get(), + move |plugin_info| { + stack(( + stack(( + match plugin_info + .as_ref() + .and_then(|(_, _, icon, _, _)| icon.clone()) + { + None => container( + img(move || VOLT_DEFAULT_PNG.to_vec()) + .style(|s| s.size_full()), + ), + Some(VoltIcon::Svg(svg_str)) => container( + svg(move || svg_str.clone()) + .style(|s| s.size_full()), + ), + Some(VoltIcon::Img(buf)) => container( + img(move || buf.clone()).style(|s| s.size_full()), + ), + } + .style(|s| { + s.min_size(150.0, 150.0).size(150.0, 150.0).padding(20) + }), + stack(( + text( + plugin_info + .as_ref() + .map(|(_, volt, _, _, _)| { + volt.display_name.as_str() + }) + .unwrap_or(""), + ) + .style(move |s| { + s.font_bold().font_size( + (config.get().ui.font_size() as f32 * 1.6) + .round(), + ) + }), + text( + plugin_info + .as_ref() + .map(|(_, volt, _, _, _)| { + volt.description.as_str() + }) + .unwrap_or(""), + ) + .style(move |s| { + let scroll_width = scroll_width.get(); + s.max_width( + scroll_width + .clamp(200.0 + 60.0 * 2.0 + 200.0, 800.0) + - 60.0 * 2.0 + - 200.0, + ) + }), + { + let repo = plugin_info + .as_ref() + .and_then(|(_, volt, _, _, _)| { + volt.repository.as_deref() + }) + .unwrap_or("") + .to_string(); + let local_repo = repo.clone(); + stack(( + text("Repository: "), + web_link( + move || repo.clone(), + move || local_repo.clone(), + move || { + config + .get() + .color(LapceColor::EDITOR_LINK) + }, + internal_command, + ), + )) + }, + text( + plugin_info + .as_ref() + .map(|(_, volt, _, _, _)| volt.author.as_str()) + .unwrap_or(""), + ) + .style(move |s| { + s.color(config.get().color(LapceColor::EDITOR_DIM)) + }), + version_view(local_plugin.clone(), plugin_info.clone()), + )) + .style(|s| s.flex_col().line_height(1.6)), + )) + .style(|s| s.absolute()) + .on_resize(move |rect| { + if header_rect.get_untracked() != rect { + header_rect.set(rect); + } + }), + empty().style(move |s| { + let rect = header_rect.get(); + s.size(rect.width(), rect.height()).pointer_events_none() + }), + empty().style(move |s| { + s.margin_vert(6) + .height(1) + .width_full() + .background(config.get().color(LapceColor::LAPCE_BORDER)) + }), + { + let readme = create_rw_signal(None); + let info = plugin_info + .as_ref() + .map(|(_, info, _, _, _)| info.to_owned()); + create_effect(move |_| { + let config = config.get(); + let info = info.clone(); + if let Some(info) = info { + let cx = Scope::current(); + let send = create_ext_action(cx, move |result| { + if let Ok(md) = result { + readme.set(Some(md)); + } + }); + std::thread::spawn(move || { + let result = + PluginData::download_readme(&info, &config); + send(result); + }); + } + }); + { + let id = AtomicU64::new(0); + dyn_stack( + move || { + readme.get().unwrap_or_else(|| { + parse_markdown( + "Loading README", + 2.0, + &config.get(), + ) + }) + }, + move |_| { + id.fetch_add( + 1, + std::sync::atomic::Ordering::Relaxed, + ) + }, + move |content| match content { + MarkdownContent::Text(text_layout) => container( + rich_text(move || text_layout.clone()) + .style(|s| s.width_full()), + ) + .style(|s| s.width_full()), + MarkdownContent::Image { .. } => { + container(empty()) + } + MarkdownContent::Separator => { + container(empty().style(move |s| { + s.width_full() + .margin_vert(5.0) + .height(1.0) + .background( + config.get().color( + LapceColor::LAPCE_BORDER, + ), + ) + })) + } + }, + ) + .style(|s| s.flex_col().width_full()) + } + }, + )) + .style(move |s| { + let padding = 60.0; + s.flex_col() + .width( + scroll_width + .get() + .min(800.0) + .max(header_rect.get().width() + padding * 2.0), + ) + .padding(padding) + }) + .into_any() + }, + ) + .style(|s| s.min_width_full().justify_center()), + ) + .on_resize(move |rect| { + if scroll_width.get_untracked() != rect.width() { + scroll_width.set(rect.width()); + } + }) + .style(|s| s.absolute().size_full()) + .debug_name("Plugin Info") +} diff --git a/lapce-app/src/proxy.rs b/lapce-app/src/proxy.rs new file mode 100644 index 0000000..c417224 --- /dev/null +++ b/lapce-app/src/proxy.rs @@ -0,0 +1,171 @@ +use std::{ + collections::HashMap, + path::PathBuf, + process::Command, + sync::{Arc, mpsc::Sender}, +}; + +use floem::{ext_event::create_signal_from_channel, reactive::ReadSignal}; +use lapce_proxy::dispatch::Dispatcher; +use lapce_rpc::{ + core::{CoreHandler, CoreNotification, CoreRpcHandler}, + plugin::VoltID, + proxy::{ProxyRpcHandler, ProxyStatus}, + terminal::TermId, +}; +use tracing::error; + +use self::{remote::start_remote, ssh::SshRemote}; +use crate::{ + terminal::event::TermEvent, + workspace::{LapceWorkspace, LapceWorkspaceType}, +}; + +mod remote; +mod ssh; +#[cfg(windows)] +mod wsl; + +pub struct Proxy { + pub tx: Sender, + pub term_tx: Sender<(TermId, TermEvent)>, +} + +#[derive(Clone)] +pub struct ProxyData { + pub proxy_rpc: ProxyRpcHandler, + pub core_rpc: CoreRpcHandler, + pub notification: ReadSignal>, +} + +impl ProxyData { + pub fn shutdown(&self) { + self.proxy_rpc.shutdown(); + self.core_rpc.shutdown(); + } +} + +pub fn new_proxy( + workspace: Arc, + disabled_volts: Vec, + extra_plugin_paths: Vec, + plugin_configurations: HashMap>, + term_tx: Sender<(TermId, TermEvent)>, +) -> ProxyData { + let proxy_rpc = ProxyRpcHandler::new(); + let core_rpc = CoreRpcHandler::new(); + + { + let core_rpc = core_rpc.clone(); + let proxy_rpc = proxy_rpc.clone(); + std::thread::Builder::new() + .name("ProxyRpcHandler".to_owned()) + .spawn(move || { + core_rpc.notification(CoreNotification::ProxyStatus { + status: ProxyStatus::Connecting, + }); + proxy_rpc.initialize( + workspace.path.clone(), + disabled_volts, + extra_plugin_paths, + plugin_configurations, + 1, + 1, + ); + + match &workspace.kind { + LapceWorkspaceType::Local => { + let core_rpc = core_rpc.clone(); + let proxy_rpc = proxy_rpc.clone(); + let mut dispatcher = Dispatcher::new(core_rpc, proxy_rpc); + let proxy_rpc = dispatcher.proxy_rpc.clone(); + proxy_rpc.mainloop(&mut dispatcher); + } + LapceWorkspaceType::RemoteSSH(remote) => { + if let Err(e) = start_remote( + SshRemote { + ssh: remote.clone(), + }, + core_rpc.clone(), + proxy_rpc.clone(), + ) { + error!("Failed to start SSH remote: {e}"); + } + } + #[cfg(windows)] + LapceWorkspaceType::RemoteWSL(remote) => { + if let Err(e) = start_remote( + wsl::WslRemote { + wsl: remote.clone(), + }, + core_rpc.clone(), + proxy_rpc.clone(), + ) { + error!("Failed to start SSH remote: {e}"); + } + } + } + core_rpc.notification(CoreNotification::ProxyStatus { + status: ProxyStatus::Disconnected, + }); + }) + .unwrap(); + } + + let (tx, rx) = std::sync::mpsc::channel(); + { + let core_rpc = core_rpc.clone(); + std::thread::Builder::new() + .name("CoreRpcHandler".to_owned()) + .spawn(move || { + let mut proxy = Proxy { tx, term_tx }; + core_rpc.mainloop(&mut proxy); + core_rpc.notification(CoreNotification::ProxyStatus { + status: ProxyStatus::Disconnected, + }); + }) + .unwrap() + }; + + let notification = create_signal_from_channel(rx); + + ProxyData { + proxy_rpc, + core_rpc, + notification, + } +} + +impl CoreHandler for Proxy { + fn handle_notification(&mut self, rpc: lapce_rpc::core::CoreNotification) { + if let CoreNotification::UpdateTerminal { term_id, content } = &rpc { + if let Err(err) = self + .term_tx + .send((*term_id, TermEvent::UpdateContent(content.to_vec()))) + { + tracing::error!("{:?}", err); + } + return; + } + if let Err(err) = self.tx.send(rpc) { + tracing::error!("{:?}", err); + } + } + + fn handle_request( + &mut self, + _id: lapce_rpc::RequestId, + _rpc: lapce_rpc::core::CoreRequest, + ) { + } +} + +pub fn new_command(program: &str) -> Command { + #[allow(unused_mut)] + let mut cmd = Command::new(program); + #[cfg(target_os = "windows")] + use std::os::windows::process::CommandExt; + #[cfg(target_os = "windows")] + cmd.creation_flags(0x08000000); + cmd +} diff --git a/lapce-app/src/proxy/remote.rs b/lapce-app/src/proxy/remote.rs new file mode 100644 index 0000000..be9e64c --- /dev/null +++ b/lapce-app/src/proxy/remote.rs @@ -0,0 +1,497 @@ +use std::{ + io::{BufReader, Write}, + path::Path, + process::{Command, Stdio}, +}; + +use anyhow::{Result, anyhow}; +use flate2::read::GzDecoder; +use lapce_core::{ + directory::Directory, + meta::{self, ReleaseType}, +}; +use lapce_rpc::{ + RpcMessage, + core::CoreRpcHandler, + proxy::{ProxyRpc, ProxyRpcHandler}, + stdio_transport, +}; +use thiserror::Error; +use tracing::{debug, error}; + +const UNIX_PROXY_SCRIPT: &[u8] = include_bytes!("../../../extra/proxy.sh"); +const WINDOWS_PROXY_SCRIPT: &[u8] = include_bytes!("../../../extra/proxy.ps1"); + +#[derive(Clone, Copy, Error, Debug, PartialEq, Eq, strum_macros::Display)] +#[strum(ascii_case_insensitive)] +enum HostPlatform { + UnknownOS, + #[strum(serialize = "windows")] + Windows, + #[strum(serialize = "linux")] + Linux, + #[strum(serialize = "darwin")] + Darwin, + #[strum(serialize = "bsd")] + Bsd, +} + +/// serialise via strum to arch name that is used +/// in CI artefacts +#[derive(Clone, Copy, Error, Debug, PartialEq, Eq, strum_macros::Display)] +#[strum(ascii_case_insensitive)] +enum HostArchitecture { + UnknownArch, + #[strum(serialize = "x86_64")] + AMD64, + #[strum(serialize = "x86")] + X86, + #[strum(serialize = "aarch64")] + ARM64, + #[strum(serialize = "armv7")] + ARM32v7, + #[strum(serialize = "armhf")] + ARM32v6, +} + +pub trait Remote: Sized { + #[allow(unused)] + fn home_dir(&self) -> Result { + let cmd = self + .command_builder() + .arg("echo") + .arg("-n") + .arg("$HOME") + .stdout(Stdio::piped()) + .output()?; + + Ok(String::from_utf8(cmd.stdout)?) + } + + fn upload_file(&self, local: impl AsRef, remote: &str) -> Result<()>; + + fn command_builder(&self) -> Command; +} + +pub fn start_remote( + remote: impl Remote, + core_rpc: CoreRpcHandler, + proxy_rpc: ProxyRpcHandler, +) -> Result<()> { + // Note about platforms: + // Windows can use either cmd.exe, powershell.exe or pwsh.exe as + // SSH shell, syntax logic varies significantly that's why we bet on + // cmd.exe as it doesn't add unwanted newlines and use powershell only + // for proxy install + // + // Unix-like systems due to POSIX, always have /bin/sh which should not + // be necessary to use explicitly most of the time, as many wide-spread + // shells retain similar syntax, although shells like Nushell might not + // work (hopefully no one uses it as login shell) + use HostPlatform::*; + let (platform, architecture) = host_specification(&remote).unwrap(); + + if platform == UnknownOS || architecture == HostArchitecture::UnknownArch { + error!("detected remote host: {platform}/{architecture}"); + return Err(anyhow!("Unknown OS and/or architecture")); + } + + // ! Below paths have to be synced with what is + // ! returned by Config::proxy_directory() + let remote_proxy_path = match platform { + Windows => format!( + "%HOMEDRIVE%%HOMEPATH%\\AppData\\Local\\lapce\\{}\\data\\proxy", + meta::NAME + ), + Darwin => format!( + "~/Library/Application\\ Support/dev.lapce.{}/proxy", + meta::NAME + ), + _ => { + format!("~/.local/share/{}/proxy", meta::NAME.to_lowercase()) + } + }; + + let remote_proxy_file = match platform { + Windows => format!("{remote_proxy_path}\\lapce.exe"), + _ => format!("{remote_proxy_path}/lapce"), + }; + + if !remote + .command_builder() + .args([&remote_proxy_file, "--version"]) + .output() + .map(|output| { + if meta::RELEASE == ReleaseType::Debug { + String::from_utf8_lossy(&output.stdout).starts_with("Lapce-proxy") + } else { + String::from_utf8_lossy(&output.stdout).trim() + == format!("Lapce-proxy {}", meta::VERSION) + } + }) + .unwrap_or(false) + { + download_remote( + &remote, + &platform, + &architecture, + &remote_proxy_path, + &remote_proxy_file, + )?; + }; + + debug!("remote proxy path: {remote_proxy_path}"); + + let mut child = match platform { + // Force cmd.exe usage to resolve %envvar% variables + Windows => remote + .command_builder() + .args(["cmd", "/c"]) + .arg(&remote_proxy_file) + .arg("--proxy") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn()?, + _ => remote + .command_builder() + .arg(&remote_proxy_file) + .arg("--proxy") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn()?, + }; + let stdin = child + .stdin + .take() + .ok_or_else(|| anyhow!("can't find stdin"))?; + let stdout = BufReader::new( + child + .stdout + .take() + .ok_or_else(|| anyhow!("can't find stdout"))?, + ); + debug!("process id: {}", child.id()); + + let (writer_tx, writer_rx) = crossbeam_channel::unbounded(); + let (reader_tx, reader_rx) = crossbeam_channel::unbounded(); + stdio_transport(stdin, writer_rx, stdout, reader_tx); + + let local_proxy_rpc = proxy_rpc.clone(); + let local_writer_tx = writer_tx.clone(); + std::thread::Builder::new() + .name("ProxyRpcHandler".to_owned()) + .spawn(move || { + for msg in local_proxy_rpc.rx() { + match msg { + ProxyRpc::Request(id, rpc) => { + if let Err(err) = + local_writer_tx.send(RpcMessage::Request(id, rpc)) + { + tracing::error!("{:?}", err); + } + } + ProxyRpc::Notification(rpc) => { + if let Err(err) = + local_writer_tx.send(RpcMessage::Notification(rpc)) + { + tracing::error!("{:?}", err); + } + } + ProxyRpc::Shutdown => { + if let Err(err) = child.kill() { + tracing::error!("{:?}", err); + } + if let Err(err) = child.wait() { + tracing::error!("{:?}", err); + } + return; + } + } + } + }) + .unwrap(); + + for msg in reader_rx { + match msg { + RpcMessage::Request(id, req) => { + let writer_tx = writer_tx.clone(); + let core_rpc = core_rpc.clone(); + std::thread::spawn(move || match core_rpc.request(req) { + Ok(resp) => { + if let Err(err) = + writer_tx.send(RpcMessage::Response(id, resp)) + { + tracing::error!("{:?}", err); + } + } + Err(e) => { + if let Err(err) = writer_tx.send(RpcMessage::Error(id, e)) { + tracing::error!("{:?}", err); + } + } + }); + } + RpcMessage::Notification(n) => { + core_rpc.notification(n); + } + RpcMessage::Response(id, resp) => { + proxy_rpc.handle_response(id, Ok(resp)); + } + RpcMessage::Error(id, err) => { + proxy_rpc.handle_response(id, Err(err)); + } + } + } + + Ok(()) +} + +fn download_remote( + remote: &impl Remote, + platform: &HostPlatform, + architecture: &HostArchitecture, + remote_proxy_path: &str, + remote_proxy_file: &str, +) -> Result<()> { + use base64::{Engine as _, engine::general_purpose}; + + let script_install = match platform { + HostPlatform::Windows => { + let local_proxy_script = + Directory::proxy_directory().unwrap().join("proxy.ps1"); + + let mut proxy_script = std::fs::OpenOptions::new() + .create(true) + .write(true) + .truncate(true) + .open(&local_proxy_script)?; + proxy_script.write_all(WINDOWS_PROXY_SCRIPT)?; + + let remote_proxy_script = "${env:TEMP}\\lapce-proxy.ps1"; + remote.upload_file(local_proxy_script, remote_proxy_script)?; + + let cmd = remote + .command_builder() + .args([ + "powershell", + "-c", + remote_proxy_script, + "-version", + meta::VERSION, + "-directory", + remote_proxy_path, + ]) + .output()?; + debug!("{}", String::from_utf8_lossy(&cmd.stderr)); + debug!("{}", String::from_utf8_lossy(&cmd.stdout)); + + cmd.status + } + _ => { + let proxy_script = general_purpose::STANDARD.encode(UNIX_PROXY_SCRIPT); + + let version = match meta::RELEASE { + ReleaseType::Debug => "nightly".to_string(), + ReleaseType::Nightly => "nightly".to_string(), + ReleaseType::Stable => format!("v{}", meta::VERSION), + }; + let cmd = remote + .command_builder() + .args([ + "echo", + &proxy_script, + "|", + "base64", + "-d", + "|", + "sh", + "/dev/stdin", + &version, + remote_proxy_path, + ]) + .output()?; + + debug!("{}", String::from_utf8_lossy(&cmd.stderr)); + debug!("{}", String::from_utf8_lossy(&cmd.stdout)); + + cmd.status + } + }; + + if !script_install.success() { + let cmd = match platform { + HostPlatform::Windows => remote + .command_builder() + .args(["dir", remote_proxy_file]) + .status()?, + _ => remote + .command_builder() + .arg("test") + .arg("-e") + .arg(remote_proxy_file) + .status()?, + }; + if !cmd.success() { + let proxy_filename = format!("lapce-proxy-{platform}-{architecture}"); + let local_proxy_file = Directory::proxy_directory() + .ok_or_else(|| anyhow!("can't find proxy directory"))? + .join(&proxy_filename); + // remove possibly outdated proxy + if local_proxy_file.exists() { + // TODO: add proper proxy version detection and update proxy + // when needed + std::fs::remove_file(&local_proxy_file)?; + } + let proxy_version = match meta::RELEASE { + meta::ReleaseType::Stable => meta::VERSION, + _ => "nightly", + }; + let url = format!( + "https://github.com/lapce/lapce/releases/download/{proxy_version}/{proxy_filename}.gz" + ); + debug!("proxy download URI: {url}"); + let mut resp = lapce_proxy::get_url(url, None).expect("request failed"); + if resp.status().is_success() { + let mut out = std::fs::File::create(&local_proxy_file) + .expect("failed to create file"); + let mut gz = GzDecoder::new(&mut resp); + std::io::copy(&mut gz, &mut out).expect("failed to copy content"); + } else { + error!("proxy download failed with: {}", resp.status()); + } + + match platform { + // Windows creates all dirs in provided path + HostPlatform::Windows => remote + .command_builder() + .arg("mkdir") + .arg(remote_proxy_path) + .status()?, + // Unix needs -p to do same + _ => remote + .command_builder() + .arg("mkdir") + .arg("-p") + .arg(remote_proxy_path) + .status()?, + }; + + remote.upload_file(&local_proxy_file, remote_proxy_file)?; + if platform != &HostPlatform::Windows { + remote + .command_builder() + .arg("chmod") + .arg("+x") + .arg(remote_proxy_file) + .status()?; + } + } + } + + Ok(()) +} + +fn host_specification( + remote: &impl Remote, +) -> Result<(HostPlatform, HostArchitecture)> { + use HostArchitecture::*; + use HostPlatform::*; + + let cmd = remote.command_builder().args(["uname", "-sm"]).output(); + + let spec = match cmd { + Ok(cmd) => { + let stdout = String::from_utf8_lossy(&cmd.stdout).to_lowercase(); + let stdout = stdout.trim(); + debug!("{}", &stdout); + match stdout { + // If empty, then we probably deal with Windows and not Unix + // or something went wrong with command output + "" => { + // Try cmd explicitly + let cmd = remote + .command_builder() + .args(["cmd", "/c", "echo %OS% %PROCESSOR_ARCHITECTURE%"]) + .output(); + match cmd { + Ok(cmd) => { + let stdout = + String::from_utf8_lossy(&cmd.stdout).to_lowercase(); + let stdout = stdout.trim(); + debug!("{}", &stdout); + match stdout.split_once(' ') { + Some((os, arch)) => (parse_os(os), parse_arch(arch)), + None => { + // PowerShell fallback + let cmd = remote + .command_builder() + .args(["echo", "\"${env:OS} ${env:PROCESSOR_ARCHITECTURE}\""]) + .output(); + match cmd { + Ok(cmd) => { + let stdout = + String::from_utf8_lossy(&cmd.stdout) + .to_lowercase(); + let stdout = stdout.trim(); + debug!("{}", &stdout); + match stdout.split_once(' ') { + Some((os, arch)) => { + (parse_os(os), parse_arch(arch)) + } + None => (UnknownOS, UnknownArch), + } + } + Err(e) => { + error!("{e}"); + (UnknownOS, UnknownArch) + } + } + } + } + } + Err(e) => { + error!("{e}"); + (UnknownOS, UnknownArch) + } + } + } + v => { + if let Some((os, arch)) = v.split_once(' ') { + (parse_os(os), parse_arch(arch)) + } else { + (UnknownOS, UnknownArch) + } + } + } + } + Err(e) => { + error!("{e}"); + (UnknownOS, UnknownArch) + } + }; + Ok(spec) +} + +fn parse_arch(arch: &str) -> HostArchitecture { + use HostArchitecture::*; + // processor architectures be like that + match arch { + "amd64" | "x64" | "x86_64" => AMD64, + "x86" | "i386" | "i586" | "i686" => X86, + "arm" | "armhf" | "armv6" => ARM32v6, + "armv7" | "armv7l" => ARM32v7, + "arm64" | "armv8" | "aarch64" => ARM64, + _ => UnknownArch, + } +} + +fn parse_os(os: &str) -> HostPlatform { + use HostPlatform::*; + match os { + "linux" => Linux, + "darwin" => Darwin, + "windows_nt" => Windows, + v if v.ends_with("bsd") => Bsd, + _ => UnknownOS, + } +} diff --git a/lapce-app/src/proxy/ssh.rs b/lapce-app/src/proxy/ssh.rs new file mode 100644 index 0000000..f22bd39 --- /dev/null +++ b/lapce-app/src/proxy/ssh.rs @@ -0,0 +1,67 @@ +use std::{path::Path, process::Command}; + +use anyhow::Result; +use tracing::debug; + +use super::remote::Remote; +use crate::{proxy::new_command, workspace::SshHost}; + +pub struct SshRemote { + pub ssh: SshHost, +} + +impl SshRemote { + #[cfg(windows)] + const SSH_ARGS: &'static [&'static str] = &[]; + + #[cfg(unix)] + const SSH_ARGS: &'static [&'static str] = &[ + "-o", + "ControlMaster=auto", + "-o", + "ControlPath=~/.ssh/cm_%C", + "-o", + "ControlPersist=30m", + "-o", + "ConnectTimeout=15", + ]; +} + +impl Remote for SshRemote { + fn upload_file(&self, local: impl AsRef, remote: &str) -> Result<()> { + let mut cmd = new_command("scp"); + + cmd.args(Self::SSH_ARGS); + + if let Some(port) = self.ssh.port { + cmd.arg("-P").arg(port.to_string()); + } + + let output = cmd + .arg(local.as_ref()) + .arg(dbg!(format!("{}:{remote}", self.ssh.user_host()))) + .output()?; + + debug!("{}", String::from_utf8_lossy(&output.stderr)); + debug!("{}", String::from_utf8_lossy(&output.stdout)); + + Ok(()) + } + + fn command_builder(&self) -> Command { + let mut cmd = new_command("ssh"); + cmd.args(Self::SSH_ARGS); + + if let Some(port) = self.ssh.port { + cmd.arg("-p").arg(port.to_string()); + } + + cmd.arg(self.ssh.user_host()); + + if !std::env::var("LAPCE_DEBUG").unwrap_or_default().is_empty() { + cmd.arg("-v"); + } + + cmd + } +} diff --git a/lapce-app/src/proxy/wsl.rs b/lapce-app/src/proxy/wsl.rs new file mode 100644 index 0000000..8eff13c --- /dev/null +++ b/lapce-app/src/proxy/wsl.rs @@ -0,0 +1,33 @@ +use std::{path::Path, process::Command}; + +use anyhow::Result; + +use super::{new_command, remote::Remote}; +use crate::workspace::WslHost; + +pub struct WslRemote { + pub wsl: WslHost, +} + +impl Remote for WslRemote { + fn upload_file(&self, local: impl AsRef, remote: &str) -> Result<()> { + let mut wsl_path = Path::new(r"\\wsl.localhost\").join(&self.wsl.host); + if !wsl_path.exists() { + wsl_path = Path::new(r"\\wsl$").join(&self.wsl.host); + } + wsl_path = if remote.starts_with('~') { + let home_dir = self.home_dir()?; + wsl_path.join(remote.replacen('~', &home_dir, 1)) + } else { + wsl_path.join(remote) + }; + std::fs::copy(local, wsl_path)?; + Ok(()) + } + + fn command_builder(&self) -> Command { + let mut cmd = new_command("wsl"); + cmd.arg("-d").arg(&self.wsl.host).arg("--"); + cmd + } +} diff --git a/lapce-app/src/rename.rs b/lapce-app/src/rename.rs new file mode 100644 index 0000000..7d1c706 --- /dev/null +++ b/lapce-app/src/rename.rs @@ -0,0 +1,154 @@ +use std::{path::PathBuf, rc::Rc}; + +use floem::{ + ext_event::create_ext_action, + keyboard::Modifiers, + peniko::kurbo::Rect, + reactive::{RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, +}; +use lapce_core::{command::FocusCommand, mode::Mode, selection::Selection}; +use lapce_rpc::proxy::ProxyResponse; +use lapce_xi_rope::Rope; +use lsp_types::Position; + +use crate::{ + command::{CommandExecuted, CommandKind, InternalCommand, LapceCommand}, + editor::EditorData, + keypress::{KeyPressFocus, condition::Condition}, + main_split::Editors, + window_tab::{CommonData, Focus}, +}; + +#[derive(Clone, Debug)] +pub struct RenameData { + pub active: RwSignal, + pub editor: EditorData, + pub start: RwSignal, + pub position: RwSignal, + pub path: RwSignal, + pub layout_rect: RwSignal, + pub common: Rc, +} + +impl KeyPressFocus for RenameData { + fn get_mode(&self) -> Mode { + Mode::Insert + } + + fn check_condition(&self, condition: Condition) -> bool { + matches!(condition, Condition::RenameFocus | Condition::ModalFocus) + } + + fn run_command( + &self, + command: &LapceCommand, + count: Option, + mods: Modifiers, + ) -> CommandExecuted { + match &command.kind { + CommandKind::Workbench(_) => {} + CommandKind::Scroll(_) => {} + CommandKind::Focus(cmd) => { + self.run_focus_command(cmd); + } + CommandKind::Edit(_) + | CommandKind::Move(_) + | CommandKind::MultiSelection(_) => { + self.editor.run_command(command, count, mods); + } + CommandKind::MotionMode(_) => {} + } + CommandExecuted::Yes + } + + fn receive_char(&self, c: &str) { + self.editor.receive_char(c); + } +} + +impl RenameData { + pub fn new(cx: Scope, editors: Editors, common: Rc) -> Self { + let active = cx.create_rw_signal(false); + let start = cx.create_rw_signal(0); + let position = cx.create_rw_signal(Position::default()); + let layout_rect = cx.create_rw_signal(Rect::ZERO); + let path = cx.create_rw_signal(PathBuf::new()); + let editor = editors.make_local(cx, common.clone()); + Self { + active, + editor, + start, + position, + layout_rect, + path, + common, + } + } + + pub fn start( + &self, + path: PathBuf, + placeholder: String, + start: usize, + position: Position, + ) { + self.editor.doc().reload(Rope::from(&placeholder), true); + self.editor.cursor().update(|cursor| { + cursor.set_insert(Selection::region(0, placeholder.len())) + }); + self.path.set(path); + self.start.set(start); + self.position.set(position); + self.active.set(true); + self.common.focus.set(Focus::Rename); + } + + fn run_focus_command(&self, cmd: &FocusCommand) -> CommandExecuted { + match cmd { + FocusCommand::ModalClose => { + self.cancel(); + } + FocusCommand::ConfirmRename => { + self.confirm(); + } + _ => return CommandExecuted::No, + } + CommandExecuted::Yes + } + + fn cancel(&self) { + self.active.set(false); + if let Focus::Rename = self.common.focus.get_untracked() { + self.common.focus.set(Focus::Workbench); + } + } + + fn confirm(&self) { + let new_name = self + .editor + .doc() + .buffer + .with_untracked(|buffer| buffer.to_string()); + let new_name = new_name.trim(); + if !new_name.is_empty() { + let path = self.path.get_untracked(); + let position = self.position.get_untracked(); + let internal_command = self.common.internal_command; + let send = create_ext_action(self.common.scope, move |result| { + if let Ok(ProxyResponse::Rename { edit }) = result { + internal_command + .send(InternalCommand::ApplyWorkspaceEdit { edit }); + } + }); + self.common.proxy.rename( + path, + position, + new_name.to_string(), + move |result| { + send(result); + }, + ); + } + self.cancel(); + } +} diff --git a/lapce-app/src/settings.rs b/lapce-app/src/settings.rs new file mode 100644 index 0000000..f688fd0 --- /dev/null +++ b/lapce-app/src/settings.rs @@ -0,0 +1,1400 @@ +use std::{collections::BTreeMap, rc::Rc, sync::Arc, time::Duration}; + +use floem::{ + IntoView, View, + action::{TimerToken, add_overlay, exec_after, remove_overlay}, + event::EventListener, + keyboard::Modifiers, + peniko::kurbo::{Point, Rect, Size}, + reactive::{ + Memo, ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith, + create_effect, create_memo, create_rw_signal, + }, + style::CursorStyle, + text::{Attrs, AttrsList, FamilyOwned, TextLayout}, + views::{ + Decorators, VirtualVector, container, dyn_stack, empty, label, + scroll::{PropagatePointerWheel, scroll}, + stack, svg, text, virtual_stack, + }, +}; +use indexmap::IndexMap; +use inflector::Inflector; +use lapce_core::{buffer::rope_text::RopeText, mode::Mode}; +use lapce_rpc::plugin::VoltID; +use lapce_xi_rope::Rope; +use serde::Serialize; +use serde_json::Value; + +use crate::{ + command::CommandExecuted, + config::{ + DropdownInfo, LapceConfig, color::LapceColor, core::CoreConfig, + editor::EditorConfig, icon::LapceIcons, terminal::TerminalConfig, + ui::UIConfig, + }, + keypress::KeyPressFocus, + main_split::Editors, + plugin::InstalledVoltData, + text_input::TextInputBuilder, + window_tab::CommonData, +}; + +#[derive(Debug, Clone)] +pub enum SettingsValue { + Float(f64), + Integer(i64), + String(String), + Bool(bool), + Dropdown(DropdownInfo), + Empty, +} + +impl From for SettingsValue { + fn from(v: serde_json::Value) -> Self { + match v { + serde_json::Value::Number(n) => { + if n.is_f64() { + SettingsValue::Float(n.as_f64().unwrap()) + } else { + SettingsValue::Integer(n.as_i64().unwrap()) + } + } + serde_json::Value::String(s) => SettingsValue::String(s), + serde_json::Value::Bool(b) => SettingsValue::Bool(b), + _ => SettingsValue::Empty, + } + } +} + +#[derive(Clone, Debug)] +struct SettingsItem { + kind: String, + name: String, + field: String, + description: String, + filter_text: String, + value: SettingsValue, + serde_value: Value, + pos: RwSignal, + size: RwSignal, + // this is only the header that give an visual separation between different type of settings + header: bool, +} + +#[derive(Clone, Debug)] +struct SettingsData { + items: RwSignal>, + kinds: RwSignal)>>, + plugin_items: RwSignal>, + plugin_kinds: RwSignal)>>, + filtered_items: RwSignal>, + common: Rc, +} + +impl KeyPressFocus for SettingsData { + fn get_mode(&self) -> lapce_core::mode::Mode { + Mode::Insert + } + + fn check_condition( + &self, + _condition: crate::keypress::condition::Condition, + ) -> bool { + false + } + + fn run_command( + &self, + _command: &crate::command::LapceCommand, + _count: Option, + _mods: Modifiers, + ) -> crate::command::CommandExecuted { + CommandExecuted::No + } + + fn receive_char(&self, _c: &str) {} +} + +impl VirtualVector for SettingsData { + fn total_len(&self) -> usize { + self.filtered_items.get_untracked().len() + } + + fn slice( + &mut self, + _range: std::ops::Range, + ) -> impl Iterator { + Box::new(self.filtered_items.get().into_iter()) + } +} + +impl SettingsData { + pub fn new( + cx: Scope, + installed_plugin: RwSignal>, + common: Rc, + ) -> Self { + fn into_settings_map( + data: &impl Serialize, + ) -> serde_json::Map { + match serde_json::to_value(data).unwrap() { + serde_json::Value::Object(h) => h, + _ => serde_json::Map::default(), + } + } + + let config = common.config; + let plugin_items = cx.create_rw_signal(im::Vector::new()); + let plugin_kinds = cx.create_rw_signal(im::Vector::new()); + let filtered_items = cx.create_rw_signal(im::Vector::new()); + let items = cx.create_rw_signal(im::Vector::new()); + let kinds = cx.create_rw_signal(im::Vector::new()); + cx.create_effect(move |_| { + let config = config.get(); + + let mut data_items = im::Vector::new(); + let mut data_kinds = im::Vector::new(); + let mut item_height_accum = 0.0; + for (kind, fields, descs, mut settings_map) in [ + ( + "Core", + &CoreConfig::FIELDS[..], + &CoreConfig::DESCS[..], + into_settings_map(&config.core), + ), + ( + "Editor", + &EditorConfig::FIELDS[..], + &EditorConfig::DESCS[..], + into_settings_map(&config.editor), + ), + ( + "UI", + &UIConfig::FIELDS[..], + &UIConfig::DESCS[..], + into_settings_map(&config.ui), + ), + ( + "Terminal", + &TerminalConfig::FIELDS[..], + &TerminalConfig::DESCS[..], + into_settings_map(&config.terminal), + ), + ] { + let pos = cx.create_rw_signal(Point::new(0.0, item_height_accum)); + data_items.push_back(SettingsItem { + kind: kind.to_string(), + name: "".to_string(), + field: "".to_string(), + filter_text: "".to_string(), + description: "".to_string(), + value: SettingsValue::Empty, + serde_value: Value::Null, + pos, + size: cx.create_rw_signal(Size::ZERO), + header: true, + }); + data_kinds.push_back((kind.to_string(), pos)); + for (name, desc) in fields.iter().zip(descs.iter()) { + let field = name.replace('_', "-"); + + let (value, serde_value) = if let Some(dropdown) = + config.get_dropdown_info(&kind.to_lowercase(), &field) + { + let index = dropdown.active_index; + ( + SettingsValue::Dropdown(dropdown), + Value::Number(index.into()), + ) + } else { + let value = settings_map.remove(&field).unwrap(); + (SettingsValue::from(value.clone()), value) + }; + + let name = format!( + "{kind}: {}", + name.replace('_', " ").to_title_case() + ); + let kind = kind.to_lowercase(); + let filter_text = format!("{kind} {name} {desc}").to_lowercase(); + let filter_text = + format!("{filter_text}{}", filter_text.replace(' ', "")); + data_items.push_back(SettingsItem { + kind, + name, + field, + filter_text, + description: desc.to_string(), + value, + pos: cx.create_rw_signal(Point::ZERO), + size: cx.create_rw_signal(Size::ZERO), + serde_value, + header: false, + }); + item_height_accum += 50.0; + } + } + + filtered_items.set(data_items.clone()); + items.set(data_items); + + let plugins = installed_plugin.get(); + let mut setting_items = im::Vector::new(); + let mut plugin_kinds_tmp = im::Vector::new(); + for (_, volt) in plugins { + let meta = volt.meta.get(); + let kind = meta.name; + let plugin_config = config.plugins.get(&kind); + if let Some(config) = meta.config { + let pos = + cx.create_rw_signal(Point::new(0.0, item_height_accum)); + setting_items.push_back(SettingsItem { + kind: meta.display_name.clone(), + name: "".to_string(), + field: "".to_string(), + filter_text: "".to_string(), + description: "".to_string(), + value: SettingsValue::Empty, + serde_value: Value::Null, + pos, + size: cx.create_rw_signal(Size::ZERO), + header: true, + }); + plugin_kinds_tmp.push_back((meta.display_name.clone(), pos)); + + { + let mut local_items = Vec::new(); + for (name, config) in config { + let field = name.clone(); + + let name = format!( + "{}: {}", + meta.display_name, + name.replace('_', " ").to_title_case() + ); + let desc = config.description; + let filter_text = + format!("{kind} {name} {desc}").to_lowercase(); + let filter_text = format!( + "{filter_text}{}", + filter_text.replace(' ', "") + ); + + let value = plugin_config + .and_then(|config| config.get(&field).cloned()) + .unwrap_or(config.default); + let value = SettingsValue::from(value); + + let item = SettingsItem { + kind: kind.clone(), + name, + field, + filter_text, + description: desc.to_string(), + value, + pos: cx.create_rw_signal(Point::ZERO), + size: cx.create_rw_signal(Size::ZERO), + serde_value: Value::Null, + header: false, + }; + local_items.push(item); + item_height_accum += 50.0; + } + local_items.sort_by_key(|i| i.name.clone()); + setting_items.extend(local_items.into_iter()); + } + } + } + plugin_items.set(setting_items); + plugin_kinds.set(plugin_kinds_tmp); + kinds.set(data_kinds); + }); + + Self { + filtered_items, + plugin_items, + plugin_kinds, + items, + kinds, + common, + } + } +} + +pub fn settings_view( + installed_plugins: RwSignal>, + editors: Editors, + common: Rc, +) -> impl View { + let config = common.config; + + let cx = Scope::current(); + let settings_data = SettingsData::new(cx, installed_plugins, common.clone()); + let view_settings_data = settings_data.clone(); + let plugin_kinds = settings_data.plugin_kinds; + + let search_editor = editors.make_local(cx, common); + let doc = search_editor.doc_signal(); + + let items = settings_data.items; + let kinds = settings_data.kinds; + let filtered_items_signal = settings_data.filtered_items; + create_effect(move |_| { + let doc = doc.get(); + let pattern = doc.buffer.with(|b| b.to_string().to_lowercase()); + let plugin_items = settings_data.plugin_items.get(); + let mut items = items.get(); + if pattern.is_empty() { + items.extend(plugin_items); + filtered_items_signal.set(items); + return; + } + + let mut filtered_items = im::Vector::new(); + for item in &items { + if item.header || item.filter_text.contains(&pattern) { + filtered_items.push_back(item.clone()); + } + } + for item in plugin_items { + if item.header || item.filter_text.contains(&pattern) { + filtered_items.push_back(item); + } + } + filtered_items_signal.set(filtered_items); + }); + + let ensure_visible = create_rw_signal(Rect::ZERO); + let settings_content_size = create_rw_signal(Size::ZERO); + let scroll_pos = create_rw_signal(Point::ZERO); + + let current_kind = { + create_memo(move |_| { + let scroll_pos = scroll_pos.get(); + let scroll_y = scroll_pos.y + 30.0; + + let plugin_kinds = plugin_kinds.get_untracked(); + for (kind, pos) in plugin_kinds.iter().rev() { + if pos.get_untracked().y < scroll_y { + return kind.to_string(); + } + } + + let kinds = kinds.get(); + for (kind, pos) in kinds.iter().rev() { + if pos.get_untracked().y < scroll_y { + return kind.to_string(); + } + } + + kinds.get(0).unwrap().0.to_string() + }) + }; + + let switcher_item = move |k: String, + pos: Box Option>>, + margin: f32| { + let kind = k.clone(); + container( + label(move || k.clone()) + .style(move |s| s.text_ellipsis().padding_left(margin)), + ) + .on_click_stop(move |_| { + if let Some(pos) = pos() { + ensure_visible.set( + settings_content_size + .get_untracked() + .to_rect() + .with_origin(pos.get_untracked()), + ); + } + }) + .style(move |s| { + let config = config.get(); + s.padding_horiz(20.0) + .width_pct(100.0) + .apply_if(kind == current_kind.get(), |s| { + s.background(config.color(LapceColor::PANEL_CURRENT_BACKGROUND)) + }) + .hover(|s| { + s.cursor(CursorStyle::Pointer).background( + config.color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + }) + .active(|s| { + s.background( + config.color(LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND), + ) + }) + }) + }; + + let switcher = || { + stack(( + dyn_stack( + move || kinds.get().clone(), + |(k, _)| k.clone(), + move |(k, pos)| switcher_item(k, Box::new(move || Some(pos)), 0.0), + ) + .style(|s| s.flex_col().width_pct(100.0)), + stack(( + switcher_item( + "Plugin Settings".to_string(), + Box::new(move || { + plugin_kinds + .with_untracked(|k| k.get(0).map(|(_, pos)| *pos)) + }), + 0.0, + ), + dyn_stack( + move || plugin_kinds.get(), + |(k, _)| k.clone(), + move |(k, pos)| { + switcher_item(k, Box::new(move || Some(pos)), 10.0) + }, + ) + .style(|s| s.flex_col().width_pct(100.0)), + )) + .style(move |s| { + s.width_pct(100.0) + .flex_col() + .apply_if(plugin_kinds.with(|k| k.is_empty()), |s| s.hide()) + }), + )) + .style(move |s| { + s.width_pct(100.0) + .flex_col() + .line_height(1.8) + .font_size(config.get().ui.font_size() as f32 + 1.0) + }) + }; + + stack(( + container({ + scroll({ + container(switcher()) + .style(|s| s.padding_vert(20.0).width_pct(100.0)) + }) + .style(|s| s.absolute().size_pct(100.0, 100.0)) + }) + .style(move |s| { + s.height_pct(100.0) + .width(200.0) + .border_right(1.0) + .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + }), + stack(( + container({ + TextInputBuilder::new() + .build_editor(search_editor) + .placeholder(|| "Search Settings".to_string()) + .keyboard_navigable() + .style(move |s| { + s.width_pct(100.0) + .border_radius(6.0) + .border(1.0) + .border_color( + config.get().color(LapceColor::LAPCE_BORDER), + ) + }) + .request_focus(|| {}) + }) + .style(|s| s.padding_horiz(50.0).padding_vert(20.0)), + container({ + scroll({ + dyn_stack( + move || filtered_items_signal.get(), + |item| { + ( + item.kind.clone(), + item.name.clone(), + item.serde_value.clone(), + ) + }, + move |item| { + settings_item_view( + editors, + view_settings_data.clone(), + item, + ) + }, + ) + .style(|s| { + s.flex_col() + .padding_horiz(50.0) + .min_width_pct(100.0) + .max_width(400.0) + }) + }) + .on_scroll(move |rect| { + scroll_pos.set(rect.origin()); + }) + .ensure_visible(move || ensure_visible.get()) + .on_resize(move |rect| { + settings_content_size.set(rect.size()); + }) + .style(|s| s.absolute().size_pct(100.0, 100.0)) + }) + .style(|s| s.size_pct(100.0, 100.0)), + )) + .style(|s| s.flex_col().size_pct(100.0, 100.0)), + )) + .style(|s| s.absolute().size_pct(100.0, 100.0)) + .debug_name("Settings") +} + +fn settings_item_view( + editors: Editors, + settings_data: SettingsData, + item: SettingsItem, +) -> impl View + use<> { + let config = settings_data.common.config; + + let is_ticked = if let SettingsValue::Bool(is_ticked) = &item.value { + Some(*is_ticked) + } else { + None + }; + + let timer = create_rw_signal(TimerToken::INVALID); + + let editor_value = match &item.value { + SettingsValue::Float(n) => Some(n.to_string()), + SettingsValue::Integer(n) => Some(n.to_string()), + SettingsValue::String(s) => Some(s.to_string()), + SettingsValue::Bool(_) => None, + SettingsValue::Dropdown(_) => None, + SettingsValue::Empty => None, + }; + + let view = { + let item = item.clone(); + move || { + let cx = Scope::current(); + if let Some(editor_value) = editor_value { + let text_input_view = TextInputBuilder::new() + .value(editor_value) + .build(cx, editors, settings_data.common); + + let doc = text_input_view.doc_signal(); + + let kind = item.kind.clone(); + let field = item.field.clone(); + let item_value = item.value.clone(); + create_effect(move |last| { + let doc = doc.get_untracked(); + let rev = doc.buffer.with(|b| b.rev()); + if last.is_none() { + return rev; + } + if last == Some(rev) { + return rev; + } + let kind = kind.clone(); + let field = field.clone(); + let buffer = doc.buffer; + let item_value = item_value.clone(); + let token = + exec_after(Duration::from_millis(500), move |token| { + let Some(timer) = timer.try_get_untracked() else { + return; + }; + if timer != token { + return; + } + + let value = buffer.with_untracked(|b| b.to_string()); + // FIXME: Figure out how to block certain keys in inputs and not hate myself + let value = value.trim(); + let value = match &item_value { + SettingsValue::Float(_) => { + value.parse::().ok().and_then(|v| { + serde::Serialize::serialize( + &v, + toml_edit::ser::ValueSerializer::new(), + ) + .ok() + }) + } + SettingsValue::Integer(_) => { + value.parse::().ok().and_then(|v| { + serde::Serialize::serialize( + &v, + toml_edit::ser::ValueSerializer::new(), + ) + .ok() + }) + } + _ => serde::Serialize::serialize( + &value, + toml_edit::ser::ValueSerializer::new(), + ) + .ok(), + }; + + if let Some(value) = value { + LapceConfig::update_file(&kind, &field, value); + } + }); + timer.set(token); + + rev + }); + + text_input_view + .keyboard_navigable() + .style(move |s| { + s.width(300.0).border(1.0).border_radius(6.0).border_color( + config.get().color(LapceColor::LAPCE_BORDER), + ) + }) + .into_any() + } else if let SettingsValue::Dropdown(dropdown) = &item.value { + let expanded = create_rw_signal(false); + let current_value = dropdown + .items + .get(dropdown.active_index) + .or_else(|| dropdown.items.last()) + .map(|s| s.to_string()) + .unwrap_or_default(); + let current_value = create_rw_signal(current_value); + + dropdown_view( + &item, + current_value, + dropdown, + expanded, + settings_data.common.window_common.size, + config, + ) + .into_any() + } else if item.header { + label(move || item.kind.clone()) + .style(move |s| { + let config = config.get(); + s.line_height(2.0) + .font_bold() + .width_pct(100.0) + .padding_horiz(10.0) + .font_size(config.ui.font_size() as f32 + 2.0) + .background(config.color(LapceColor::PANEL_BACKGROUND)) + }) + .into_any() + } else { + empty().into_any() + } + } + }; + + stack(( + label(move || item.name.clone()).style(move |s| { + s.font_bold() + .text_ellipsis() + .min_width(0.0) + .max_width_pct(100.0) + .line_height(1.8) + .font_size(config.get().ui.font_size() as f32 + 1.0) + }), + stack(( + label(move || item.description.clone()).style(move |s| { + s.min_width(0.0) + .max_width_pct(100.0) + .line_height(1.8) + .apply_if(is_ticked.is_some(), |s| { + s.margin_left(config.get().ui.font_size() as f32 + 8.0) + }) + .apply_if(item.header, |s| s.hide()) + }), + if let Some(is_ticked) = is_ticked { + let checked = create_rw_signal(is_ticked); + + let kind = item.kind.clone(); + let field = item.field.clone(); + create_effect(move |last| { + let checked = checked.get(); + if last.is_none() { + return; + } + if let Ok(value) = serde::Serialize::serialize( + &checked, + toml_edit::ser::ValueSerializer::new(), + ) { + LapceConfig::update_file(&kind, &field, value); + } + }); + + container( + stack(( + checkbox(move || checked.get(), config), + label(|| " ".to_string()).style(|s| s.line_height(1.8)), + )) + .style(|s| s.items_center()), + ) + .on_click_stop(move |_| { + checked.update(|checked| { + *checked = !*checked; + }); + }) + .style(|s| { + s.absolute() + .cursor(CursorStyle::Pointer) + .size_pct(100.0, 100.0) + .items_start() + }) + } else { + container(empty()).style(|s| s.hide()) + }, + )), + view().style(move |s| s.apply_if(!item.header, |s| s.margin_top(6.0))), + )) + .on_resize(move |rect| { + if item.header { + item.pos.set(rect.origin()); + } + let old_size = item.size.get_untracked(); + let new_size = rect.size(); + if old_size != new_size { + item.size.set(new_size); + } + }) + .style(|s| { + s.flex_col() + .padding_vert(10.0) + .min_width_pct(100.0) + .max_width(300.0) + }) +} + +pub fn checkbox( + checked: impl Fn() -> bool + 'static, + config: ReadSignal>, +) -> impl View { + const CHECKBOX_SVG: &str = r#""#; + let svg_str = move || if checked() { CHECKBOX_SVG } else { "" }.to_string(); + + svg(svg_str).style(move |s| { + let config = config.get(); + let size = config.ui.font_size() as f32; + let color = config.color(LapceColor::EDITOR_FOREGROUND); + + s.min_width(size) + .size(size, size) + .color(color) + .border_color(color) + .border(1.) + .border_radius(2.) + }) +} + +struct BTreeMapVirtualList(BTreeMap); + +impl VirtualVector<(String, String)> for BTreeMapVirtualList { + fn total_len(&self) -> usize { + self.0.len() + } + + fn slice( + &mut self, + range: std::ops::Range, + ) -> impl Iterator { + Box::new( + self.0 + .iter() + .enumerate() + .filter_map(|(index, (k, v))| { + if range.contains(&index) { + Some((k.to_string(), v.to_string())) + } else { + None + } + }) + .collect::>() + .into_iter(), + ) + } +} + +fn color_section_list( + kind: &str, + header: &str, + list: impl Fn() -> BTreeMap + 'static, + max_width: Memo, + text_height: Memo, + editors: Editors, + common: Rc, +) -> impl View { + let config = common.config; + + let kind = kind.to_string(); + stack(( + text(header).style(|s| { + s.margin_top(10) + .margin_horiz(20) + .font_bold() + .line_height(2.0) + }), + virtual_stack( + move || BTreeMapVirtualList(list()), + move |(key, _)| key.to_owned(), + move |(key, value)| { + let cx = Scope::current(); + let text_input_view = TextInputBuilder::new() + .value(value.clone()) + .build(cx, editors, common.clone()); + let doc = text_input_view.doc_signal(); + + { + let kind = kind.clone(); + let key = key.clone(); + let doc = text_input_view.doc_signal(); + create_effect(move |_| { + let doc = doc.get_untracked(); + let config = config.get(); + let current = doc.buffer.with_untracked(|b| b.to_string()); + + let value = match kind.as_str() { + "base" => config.color_theme.base.get(&key), + "ui" => config.color_theme.ui.get(&key), + "syntax" => config.color_theme.syntax.get(&key), + _ => None, + }; + + if let Some(value) = value { + if value != ¤t { + doc.reload(Rope::from(value.to_string()), true); + } + } + }); + } + + { + let timer = create_rw_signal(TimerToken::INVALID); + let kind = kind.clone(); + let field = key.clone(); + create_effect(move |last| { + let doc = doc.get_untracked(); + + let rev = doc.buffer.with(|b| b.rev()); + if last.is_none() { + return rev; + } + if last == Some(rev) { + return rev; + } + let kind = kind.clone(); + let field = field.clone(); + let buffer = doc.buffer; + let token = + exec_after(Duration::from_millis(500), move |token| { + if let Some(timer) = timer.try_get_untracked() { + if timer == token { + let value = + buffer.with_untracked(|b| b.to_string()); + + let config = config.get_untracked(); + let default = match kind.as_str() { + "base" => config + .default_color_theme() + .base + .get(&field), + "ui" => config + .default_color_theme() + .ui + .get(&field), + "syntax" => config + .default_color_theme() + .syntax + .get(&field), + _ => None, + }; + + if default != Some(&value) { + let value = serde::Serialize::serialize( + &value, + toml_edit::ser::ValueSerializer::new( + ), + ) + .ok(); + + if let Some(value) = value { + LapceConfig::update_file( + &format!("color-theme.{kind}"), + &field, + value, + ); + } + } else { + LapceConfig::reset_setting( + &format!("color-theme.{kind}"), + &field, + ); + } + } + } + }); + timer.set(token); + + rev + }); + } + + let local_kind = kind.clone(); + let local_key = key.clone(); + stack(( + text(&key).style(move |s| { + s.width(max_width.get()).margin_left(20).margin_right(10) + }), + text_input_view.keyboard_navigable().style(move |s| { + s.width(150.0) + .margin_vert(6) + .border(1) + .border_radius(6) + .border_color( + config.get().color(LapceColor::LAPCE_BORDER), + ) + }), + empty().style(move |s| { + let size = text_height.get() + 12.0; + let config = config.get(); + let color = match local_kind.as_str() { + "base" => config.color.base.get(&local_key), + "ui" => config.color.ui.get(&local_key).copied(), + "syntax" => config.color.syntax.get(&local_key).copied(), + _ => None, + }; + s.border(1) + .border_radius(6) + .size(size, size) + .margin_left(10) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .background(color.unwrap_or_else(|| { + config.color(LapceColor::EDITOR_FOREGROUND) + })) + }), + { + let kind = kind.clone(); + let key = key.clone(); + let local_key = key.clone(); + let local_kind = kind.clone(); + text("Reset") + .on_click_stop(move |_| { + LapceConfig::reset_setting( + &format!("color-theme.{local_kind}"), + &local_key, + ); + }) + .style(move |s| { + let doc = doc.get_untracked(); + let config = config.get(); + let buffer = doc.buffer; + let content = buffer.with(|b| b.to_string()); + + let same = match kind.as_str() { + "base" => { + config.default_color_theme().base.get(&key) + == Some(&content) + } + "ui" => { + config.default_color_theme().ui.get(&key) + == Some(&content) + } + "syntax" => { + config.default_color_theme().syntax.get(&key) + == Some(&content) + } + _ => false, + }; + + s.margin_left(10) + .padding(6) + .cursor(CursorStyle::Pointer) + .border(1) + .border_radius(6) + .border_color( + config.color(LapceColor::LAPCE_BORDER), + ) + .apply_if(same, |s| s.hide()) + .active(|s| { + s.background( + config + .color(LapceColor::PANEL_BACKGROUND), + ) + }) + }) + }, + )) + .style(|s| s.items_center()) + }, + ) + .item_size_fixed(move || text_height.get() + 24.0) + .style(|s| s.flex_col().padding_right(20)), + )) + .style(|s| s.flex_col()) +} + +pub fn theme_color_settings_view( + editors: Editors, + common: Rc, +) -> impl View { + let config = common.config; + + let text_height = create_memo(move |_| { + let mut text_layout = TextLayout::new(); + let config = config.get(); + let family: Vec = + FamilyOwned::parse_list(&config.ui.font_family).collect(); + let attrs = Attrs::new() + .family(&family) + .font_size(config.ui.font_size() as f32); + let attrs_list = AttrsList::new(attrs); + text_layout.set_text("W", attrs_list, None); + text_layout.size().height + }); + + let max_width = create_memo(move |_| { + let mut text_layout = TextLayout::new(); + let config = config.get(); + let family: Vec = + FamilyOwned::parse_list(&config.ui.font_family).collect(); + let attrs = Attrs::new() + .family(&family) + .font_size(config.ui.font_size() as f32); + let attrs_list = AttrsList::new(attrs); + + let mut max_width = 0.0; + for key in config.color_theme.ui.keys() { + text_layout.set_text(key, attrs_list.clone(), None); + let width = text_layout.size().width; + if width > max_width { + max_width = width; + } + } + for key in config.color_theme.syntax.keys() { + text_layout.set_text(key, attrs_list.clone(), None); + let width = text_layout.size().width; + if width > max_width { + max_width = width; + } + } + max_width + }); + + let cx = Scope::current(); + let search_editor = editors.make_local(cx, common.clone()); + let buffer = search_editor.doc_signal().get_untracked().buffer; + + scroll( + stack(( + container({ + TextInputBuilder::new() + .build_editor(search_editor) + .placeholder(|| "Search Settings".to_string()) + .keyboard_navigable() + .style(move |s| { + s.width_pct(100.0) + .border_radius(6.0) + .border(1.0) + .border_color( + config.get().color(LapceColor::LAPCE_BORDER), + ) + }) + .request_focus(|| {}) + }) + .style(|s| s.padding_vert(20.0).padding_horiz(20.0)), + color_section_list( + "base", + "Base Colors", + move || { + let filter = buffer.get().text().to_string(); + config.with(|c| { + c.color_theme + .base + .0 + .iter() + .filter_map(|x| { + if x.0.contains(&filter) { + Some((x.0.clone(), x.1.clone())) + } else { + None + } + }) + .collect::>() + }) + }, + max_width, + text_height, + editors, + common.clone(), + ), + color_section_list( + "syntax", + "Syntax Colors", + move || { + let filter = buffer.get().text().to_string(); + config.with(|c| { + c.color_theme + .syntax + .iter() + .filter_map(|x| { + if x.0.contains(&filter) { + Some((x.0.clone(), x.1.clone())) + } else { + None + } + }) + .collect::>() + }) + }, + max_width, + text_height, + editors, + common.clone(), + ), + color_section_list( + "ui", + "UI Colors", + move || { + let filter = buffer.get().text().to_string(); + config.with(|c| { + c.color_theme + .ui + .iter() + .filter_map(|x| { + if x.0.contains(&filter) { + Some((x.0.clone(), x.1.clone())) + } else { + None + } + }) + .collect::>() + }) + }, + max_width, + text_height, + editors, + common.clone(), + ), + )) + .style(|s| s.flex_col()), + ) + .style(|s| s.absolute().size_full()) + .debug_name("Theme Color Settings") +} + +fn dropdown_view( + item: &SettingsItem, + current_value: RwSignal, + dropdown: &DropdownInfo, + expanded: RwSignal, + window_size: RwSignal, + config: ReadSignal>, +) -> impl View + use<> { + let window_origin = create_rw_signal(Point::ZERO); + let size = create_rw_signal(Size::ZERO); + let overlay_id = create_rw_signal(None); + let dropdown_input_focus = create_rw_signal(false); + let dropdown_scroll_focus = create_rw_signal(true); + + { + let item = item.to_owned(); + let dropdown = dropdown.to_owned(); + create_effect(move |_| { + if expanded.get() { + let item = item.clone(); + let dropdown = dropdown.clone(); + let id = add_overlay(Point::ZERO, move |_| { + dropdown_scroll( + &item.clone(), + current_value, + &dropdown.clone(), + expanded, + dropdown_scroll_focus, + dropdown_input_focus, + window_origin, + size, + window_size, + config, + ) + }); + overlay_id.set(Some(id)); + } else if let Some(id) = overlay_id.get_untracked() { + remove_overlay(id); + overlay_id.set(None); + } + }); + } + + stack(( + label(move || current_value.get()).style(move |s| { + s.text_ellipsis() + .width_pct(100.0) + .padding_horiz(10.0) + .selectable(false) + }), + container( + svg(move || { + if expanded.get() { + config.get().ui_svg(LapceIcons::CLOSE) + } else { + config.get().ui_svg(LapceIcons::DROPDOWN_ARROW) + } + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.size(size, size) + .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + }), + ) + .style(|s| s.padding_right(4.0)), + )) + .on_click_stop(move |_| { + expanded.update(|expanded| { + *expanded = !*expanded; + }); + }) + .on_move(move |point| { + window_origin.set(point); + if expanded.get_untracked() { + expanded.set(false); + } + }) + .on_resize(move |rect| { + size.set(rect.size()); + }) + .style(move |s| { + s.items_center() + .cursor(CursorStyle::Pointer) + .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + .border(1.0) + .border_radius(6.0) + .width(250.0) + .line_height(1.8) + }) + .keyboard_navigable() + .on_event_stop(EventListener::FocusGained, move |_| { + dropdown_input_focus.set(true); + }) + .on_event_stop(EventListener::FocusLost, move |_| { + dropdown_input_focus.set(false); + if expanded.get_untracked() && !dropdown_scroll_focus.get_untracked() { + expanded.set(false); + } + }) + .on_cleanup(move || { + if let Some(id) = overlay_id.get_untracked() { + remove_overlay(id); + } + }) +} + +#[allow(clippy::too_many_arguments)] +fn dropdown_scroll( + item: &SettingsItem, + current_value: RwSignal, + dropdown: &DropdownInfo, + expanded: RwSignal, + dropdown_scroll_focus: RwSignal, + dropdown_input_focus: RwSignal, + window_origin: RwSignal, + input_size: RwSignal, + window_size: RwSignal, + config: ReadSignal>, +) -> impl View + use<> { + dropdown_scroll_focus.set(true); + + let kind = item.kind.clone(); + let field = item.field.clone(); + let view_fn = move |item_string: String| { + let kind = kind.clone(); + let field = field.clone(); + let local_item_string = item_string.clone(); + label(move || local_item_string.clone()) + .on_click_stop(move |_| { + current_value.set(item_string.clone()); + if let Ok(value) = serde::Serialize::serialize( + &item_string, + toml_edit::ser::ValueSerializer::new(), + ) { + LapceConfig::update_file(&kind, &field, value); + } + expanded.set(false); + }) + .style(move |s| { + s.text_ellipsis().padding_horiz(10.0).hover(|s| { + s.cursor(CursorStyle::Pointer).background( + config.get().color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + }) + }) + }; + + let items = dropdown.items.clone(); + + let scroll_size = create_rw_signal(Size::ZERO); + + scroll({ + dyn_stack(move || items.clone(), |item| item.to_string(), view_fn) + .style(|s| s.flex_col().width_pct(100.0).cursor(CursorStyle::Pointer)) + }) + .style(move |s| { + s.width_pct(100.0) + .max_height(200.0) + .set(PropagatePointerWheel, false) + }) + .keyboard_navigable() + .request_focus(|| {}) + .on_event_stop(EventListener::FocusGained, move |_| { + dropdown_scroll_focus.set(true); + }) + .on_event_stop(EventListener::FocusLost, move |_| { + dropdown_scroll_focus.set(false); + if expanded.get_untracked() && !dropdown_input_focus.get_untracked() { + expanded.set(false); + } + }) + .on_event_stop(EventListener::PointerMove, move |_| {}) + .on_event_stop(EventListener::PointerDown, move |_| {}) + .on_resize(move |rect| { + scroll_size.set(rect.size()); + }) + .style(move |s| { + let config = config.get(); + let window_origin = window_origin.get(); + let window_size = window_size.get(); + let input_size = input_size.get(); + let scroll_size = scroll_size.get(); + + let x = if window_origin.x + scroll_size.width + 5.0 > window_size.width { + window_size.width - scroll_size.width - 5.0 + } else { + window_origin.x + }; + + let y = if window_origin.y + input_size.height + scroll_size.height + 5.0 + > window_size.height + { + window_origin.y - scroll_size.height + 1.0 + } else { + window_origin.y + input_size.height - 1.0 + }; + + s.width(250.0) + .line_height(1.8) + .font_size(config.ui.font_size() as f32) + .font_family(config.ui.font_family.clone()) + .color(config.color(LapceColor::EDITOR_FOREGROUND)) + .background(config.color(LapceColor::EDITOR_BACKGROUND)) + .class(floem::views::scroll::Handle, |s| { + s.background(config.color(LapceColor::LAPCE_SCROLL_BAR)) + }) + .border(1) + .border_radius(6.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .box_shadow_blur(3.0) + .box_shadow_color(config.color(LapceColor::LAPCE_DROPDOWN_SHADOW)) + .inset_left(x) + .inset_top(y) + }) +} diff --git a/lapce-app/src/snippet.rs b/lapce-app/src/snippet.rs new file mode 100644 index 0000000..1980bc5 --- /dev/null +++ b/lapce-app/src/snippet.rs @@ -0,0 +1,859 @@ +use core::fmt; +use std::{fmt::Display, str::FromStr}; + +use anyhow::Error; +use once_cell::sync::Lazy; +use regex::Regex; + +#[derive(Debug, PartialEq)] +pub enum SnippetElement { + Text(String), + PlaceHolder(usize, Vec), + Tabstop(usize), +} + +impl Display for SnippetElement { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match &self { + SnippetElement::Text(text) => f.write_str(text), + SnippetElement::PlaceHolder(tab, elements) => { + // Trying to write to the provided buffer in the form "${tab:text}" + write!(f, "${{{tab}:")?; + for child_snippet_elm in elements { + // call ourselves recursively + fmt::Display::fmt(child_snippet_elm, f)?; + } + f.write_str("}") + } + SnippetElement::Tabstop(tab) => write!(f, "${tab}"), + } + } +} + +impl SnippetElement { + pub fn len(&self) -> usize { + match &self { + SnippetElement::Text(text) => text.len(), + SnippetElement::PlaceHolder(_, elements) => { + elements.iter().map(|e| e.len()).sum() + } + SnippetElement::Tabstop(_) => 0, + } + } + + #[inline] + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + #[inline] + pub fn text(&self) -> String { + let mut buf = String::new(); + self.write_text_to(&mut buf) + .expect("a write_to function returned an error unexpectedly"); + buf + } + + fn write_text_to(&self, buf: &mut Buffer) -> fmt::Result { + match self { + SnippetElement::Text(text) => buf.write_str(text), + SnippetElement::PlaceHolder(_, elements) => { + for child_snippet_elm in elements { + // call ourselves recursively + child_snippet_elm.write_text_to(buf)?; + } + fmt::Result::Ok(()) + } + SnippetElement::Tabstop(_) => fmt::Result::Ok(()), + } + } +} + +#[derive(Debug, PartialEq)] +pub struct Snippet { + elements: Vec, +} + +impl FromStr for Snippet { + type Err = Error; + + #[inline] + fn from_str(s: &str) -> Result { + let (elements, _) = Self::extract_elements(s, 0, &['$', '\\'], &['}']); + Ok(Snippet { elements }) + } +} + +impl Display for Snippet { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for snippet_element in self.elements.iter() { + fmt::Display::fmt(snippet_element, f)?; + } + fmt::Result::Ok(()) + } +} + +impl Snippet { + #[inline] + fn extract_elements( + s: &str, + pos: usize, + escs: &[char], + loose_escs: &[char], + ) -> (Vec, usize) { + let mut elements = Vec::new(); + let mut pos = pos; + loop { + if s.len() == pos { + break; + } else if let Some((ele, end)) = Self::extract_tabstop(s, pos) { + elements.push(ele); + pos = end; + } else if let Some((ele, end)) = Self::extract_placeholder(s, pos) { + elements.push(ele); + pos = end; + } else if let Some((ele, end)) = + Self::extract_text(s, pos, escs, loose_escs) + { + elements.push(ele); + pos = end; + } else { + break; + } + } + (elements, pos) + } + + #[inline] + fn extract_tabstop(str: &str, pos: usize) -> Option<(SnippetElement, usize)> { + // Regex for `$...` pattern, where `...` is some number (for example `$1`) + static REGEX_FIRST: Lazy = + Lazy::new(|| Regex::new(r"^\$(\d+)").unwrap()); + // Regex for `${...}` pattern, where `...` is some number (for example `${1}`) + static REGEX_SECOND: Lazy = + Lazy::new(|| Regex::new(r"^\$\{(\d+)\}").unwrap()); + + let str = &str[pos..]; + if let Some(matched) = REGEX_FIRST.find(str) { + // SAFETY: + // * The start index is guaranteed not to exceed the end index, since we + // compare with the `$ ...` pattern, and, therefore, the first element + // is always equal to the symbol `$`; + // * The indices are within the bounds of the original slice and lie on + // UTF-8 sequence boundaries, since we take the entire slice, with the + // exception of the first `$` char which is 1 byte in accordance with + // the UTF-8 standard. + let n = unsafe { + matched.as_str().get_unchecked(1..).parse::().ok()? + }; + let end = pos + matched.end(); + return Some((SnippetElement::Tabstop(n), end)); + } + if let Some(matched) = REGEX_SECOND.find(str) { + let matched = matched.as_str(); + // SAFETY: + // * The start index is guaranteed not to exceed the end index, since we + // compare with the `${...}` pattern, and, therefore, the first two elements + // are always equal to the `${` and the last one is equal to `}`; + // * The indices are within the bounds of the original slice and lie on UTF-8 + // sequence boundaries, since we take the entire slice, with the exception + // of the first two `${` and last one `}` chars each of which is 1 byte in + // accordance with the UTF-8 standard. + let n = unsafe { + matched + .get_unchecked(2..matched.len() - 1) + .parse::() + .ok()? + }; + let end = pos + matched.len(); + return Some((SnippetElement::Tabstop(n), end)); + } + None + } + + #[inline] + fn extract_placeholder(s: &str, pos: usize) -> Option<(SnippetElement, usize)> { + // Regex for `${num:text}` pattern, where text can be empty (for example `${1:first}` + // and `${2:}`) + static REGEX: Lazy = + Lazy::new(|| Regex::new(r"^\$\{(\d+):(.*?)\}").unwrap()); + + let caps = REGEX.captures(&s[pos..])?; + + let tab = caps.get(1)?.as_str().parse::().ok()?; + + let m = caps.get(2)?; + let content = m.as_str(); + if content.is_empty() { + return Some(( + SnippetElement::PlaceHolder( + tab, + vec![SnippetElement::Text(String::new())], + ), + pos + caps.get(0).unwrap().end(), + )); + } + let (els, pos) = + Self::extract_elements(s, pos + m.start(), &['$', '}', '\\'], &[]); + Some((SnippetElement::PlaceHolder(tab, els), pos + 1)) + } + + #[inline] + fn extract_text( + s: &str, + pos: usize, + escs: &[char], + loose_escs: &[char], + ) -> Option<(SnippetElement, usize)> { + let mut ele = String::new(); + let mut end = pos; + let mut chars_iter = s[pos..].chars().peekable(); + + while let Some(char) = chars_iter.next() { + if char == '\\' { + if let Some(&next) = chars_iter.peek() { + if escs.iter().chain(loose_escs.iter()).any(|c| *c == next) { + chars_iter.next(); + ele.push(next); + end += 1 + next.len_utf8(); + continue; + } + } + } + if escs.contains(&char) { + break; + } + ele.push(char); + end += char.len_utf8(); + } + if ele.is_empty() { + return None; + } + Some((SnippetElement::Text(ele), end)) + } + + #[inline] + pub fn text(&self) -> String { + let mut buf = String::new(); + self.write_text_to(&mut buf) + .expect("Snippet::write_text_to function unexpectedly return error"); + buf + } + + #[inline] + fn write_text_to(&self, buf: &mut Buffer) -> fmt::Result { + for snippet_element in self.elements.iter() { + snippet_element.write_text_to(buf)? + } + fmt::Result::Ok(()) + } + + #[inline] + pub fn tabs(&self, pos: usize) -> Vec<(usize, (usize, usize))> { + Self::elements_tabs(&self.elements, pos) + } + + pub fn elements_tabs( + elements: &[SnippetElement], + start: usize, + ) -> Vec<(usize, (usize, usize))> { + let mut tabs = Vec::new(); + let mut pos = start; + for el in elements { + match el { + SnippetElement::Text(t) => { + pos += t.len(); + } + SnippetElement::PlaceHolder(tab, els) => { + let placeholder_tabs = Self::elements_tabs(els, pos); + let end = pos + els.iter().map(|e| e.len()).sum::(); + tabs.push((*tab, (pos, end))); + tabs.extend_from_slice(&placeholder_tabs); + pos = end; + } + SnippetElement::Tabstop(tab) => { + tabs.push((*tab, (pos, pos))); + } + } + } + tabs + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_snippet() { + use SnippetElement::*; + + let s = "start $1${2:second ${3:third}} $0"; + let parsed = Snippet::from_str(s).unwrap(); + assert_eq!(s, parsed.to_string()); + + let text = "start second third "; + assert_eq!(text, parsed.text()); + + assert_eq!( + vec![(1, (6, 6)), (2, (6, 18)), (3, (13, 18)), (0, (19, 19))], + parsed.tabs(0) + ); + + let s = "start ${1}${2:second ${3:third}} $0and ${4}fourth"; + + let parsed = Snippet::from_str(s).unwrap(); + assert_eq!( + "start $1${2:second ${3:third}} $0and $4fourth", + parsed.to_string() + ); + + let text = "start second third and fourth"; + assert_eq!(text, parsed.text()); + + assert_eq!( + vec![ + (1, (6, 6)), + (2, (6, 18)), + (3, (13, 18)), + (0, (19, 19)), + (4, (23, 23)) + ], + parsed.tabs(0) + ); + + let s = "${1:first $6${2:second ${7}${3:third ${4:fourth ${5:fifth}}}}}"; + + let parsed = Snippet::from_str(s).unwrap(); + assert_eq!( + "${1:first $6${2:second $7${3:third ${4:fourth ${5:fifth}}}}}", + parsed.to_string() + ); + + let text = "first second third fourth fifth"; + assert_eq!(text, parsed.text()); + + assert_eq!( + vec![ + (1, (0, 31)), + (6, (6, 6)), + (2, (6, 31)), + (7, (13, 13)), + (3, (13, 31)), + (4, (19, 31)), + (5, (26, 31)) + ], + parsed.tabs(0) + ); + + assert_eq!( + Snippet { + elements: vec![PlaceHolder( + 1, + vec![ + Text("first ".into()), + Tabstop(6), + PlaceHolder( + 2, + vec![ + Text("second ".into()), + Tabstop(7), + PlaceHolder( + 3, + vec![ + Text("third ".into()), + PlaceHolder( + 4, + vec![ + Text("fourth ".into()), + PlaceHolder( + 5, + vec![Text("fifth".into())] + ) + ] + ) + ] + ) + ] + ) + ] + )] + }, + parsed + ); + + let s = "\\$1 start \\$2$3${4}${5:some text\\${6:third\\} $7}"; + + let parsed = Snippet::from_str(s).unwrap(); + assert_eq!( + "$1 start $2$3$4${5:some text${6:third} $7}", + parsed.to_string() + ); + + let text = "$1 start $2some text${6:third} "; + assert_eq!(text, parsed.text()); + + assert_eq!( + vec![(3, (11, 11)), (4, (11, 11)), (5, (11, 31)), (7, (31, 31))], + parsed.tabs(0) + ); + + assert_eq!( + Snippet { + elements: vec![ + Text("$1 start $2".into()), + Tabstop(3), + Tabstop(4), + PlaceHolder( + 5, + vec![Text("some text${6:third} ".into()), Tabstop(7)] + ) + ] + }, + parsed + ); + } + + #[test] + fn test_extract_tabstop() { + fn vec_of_tab_elms(s: &str) -> Vec<(usize, usize)> { + let mut pos = 0; + let mut vec = Vec::new(); + for char in s.chars() { + if let Some((SnippetElement::Tabstop(stop), end)) = + Snippet::extract_tabstop(s, pos) + { + vec.push((stop, end)); + } + pos += char.len_utf8(); + } + vec + } + + let s = "start $1${2:second ${3:third}} $0"; + assert_eq!(&[(1, 8), (0, 33)][..], &vec_of_tab_elms(s)[..]); + + let s = "start ${1}${2:second ${3:third}} $0and ${4}fourth"; + assert_eq!(&[(1, 10), (0, 35), (4, 43)][..], &vec_of_tab_elms(s)[..]); + + let s = "$s$1first${2}$second$3${4}${5}$6and${7}$8fourth$9$$$10$$${11}$$$12$$$13$$${14}$$${15}"; + assert_eq!( + &[ + (1, 4), + (2, 13), + (3, 22), + (4, 26), + (5, 30), + (6, 32), + (7, 39), + (8, 41), + (9, 49), + (10, 54), + (11, 61), + (12, 66), + (13, 71), + (14, 78), + (15, 85) + ][..], + &vec_of_tab_elms(s)[..] + ); + + let s = "$s$1ένα${2}$τρία$3${4}${5}$6τέσσερα${7}$8πέντε$9$$$10$$${11}$$$12$$$13$$${14}$$${15}"; + assert_eq!( + &[ + (1, 4), + (2, 14), + (3, 25), + (4, 29), + (5, 33), + (6, 35), + (7, 53), + (8, 55), + (9, 67), + (10, 72), + (11, 79), + (12, 84), + (13, 89), + (14, 96), + (15, 103) + ][..], + &vec_of_tab_elms(s)[..] + ); + } + + #[test] + fn test_extract_placeholder() { + use super::SnippetElement::*; + let s1 = "${1:first ${2:second ${3:third ${4:fourth ${5:fifth}}}}}"; + + assert_eq!( + ( + PlaceHolder( + 1, + vec![ + Text("first ".into()), + PlaceHolder( + 2, + vec![ + Text("second ".into()), + PlaceHolder( + 3, + vec![ + Text("third ".into()), + PlaceHolder( + 4, + vec![ + Text("fourth ".into()), + PlaceHolder( + 5, + vec![Text("fifth".into())] + ) + ] + ) + ] + ) + ] + ) + ] + ), + 56 + ), + Snippet::extract_placeholder(s1, 0).unwrap() + ); + + let s1 = "${1:first}${2:second}${3:third }${4:fourth ${5:fifth}}}}}"; + assert_eq!( + (PlaceHolder(1, vec![Text("first".to_owned())]), 10), + Snippet::extract_placeholder(s1, 0).unwrap() + ); + assert_eq!( + (PlaceHolder(2, vec![Text("second".to_owned())]), 21), + Snippet::extract_placeholder(s1, 10).unwrap() + ); + assert_eq!( + (PlaceHolder(3, vec![Text("third ".to_owned())]), 32), + Snippet::extract_placeholder(s1, 21).unwrap() + ); + + assert_eq!( + ( + PlaceHolder( + 4, + vec![ + Text("fourth ".into()), + PlaceHolder(5, vec![Text("fifth".into())]) + ] + ), + 54 + ), + Snippet::extract_placeholder(s1, 32).unwrap() + ); + } + + #[test] + fn test_extract_text() { + use SnippetElement::*; + + // 1. ==================================================================================== + + let s = "start $1${2:second ${3:third}} $0"; + let (snip_elm, end) = Snippet::extract_text(s, 0, &['$'], &[]).unwrap(); + assert_eq!((Text("start ".to_owned()), 6), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$'], &[]).unwrap(); + assert_eq!((Text("1".to_owned()), 8), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$'], &[]).unwrap(); + assert_eq!((Text("{2:second ".to_owned()), 19), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$'], &[]).unwrap(); + assert_eq!((Text("{3:third}} ".to_owned()), 31), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$'], &[]).unwrap(); + assert_eq!((Text("0".to_owned()), 33), (snip_elm, end)); + + // 2. ==================================================================================== + + let s = "start $1${2:second ${3:third}} $0"; + + let (snip_elm, end) = Snippet::extract_text(s, 0, &['{'], &[]).unwrap(); + assert_eq!((Text("start $1$".to_owned()), 9), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['{'], &[]).unwrap(); + assert_eq!((Text("2:second $".to_owned()), 20), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['{'], &[]).unwrap(); + assert_eq!((Text("3:third}} $0".to_owned()), 33), (snip_elm, end)); + + // 3. ==================================================================================== + + let s = "start $1${2:second ${3:third}} $0"; + + let (snip_elm, end) = Snippet::extract_text(s, 0, &['}'], &[]).unwrap(); + assert_eq!( + (Text("start $1${2:second ${3:third".to_owned()), 28), + (snip_elm, end) + ); + + assert_eq!(None, Snippet::extract_text(s, end + 1, &['}'], &[])); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 2, &['}'], &[]).unwrap(); + assert_eq!((Text(" $0".to_owned()), 33), (snip_elm, end)); + + // 4. ==================================================================================== + + let s = "start $1${2:second ${3:third}} $0"; + + let (snip_elm, end) = Snippet::extract_text(s, 0, &['\\'], &[]).unwrap(); + assert_eq!((Text(s.to_owned()), 33), (snip_elm, end)); + + // 5. ==================================================================================== + + let s = "start \\$1${2:second \\${3:third}} $0"; + + let (snip_elm, end) = + Snippet::extract_text(s, 0, &['$', '\\'], &[]).unwrap(); + assert_eq!((Text("start $1".to_owned()), 9), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$', '\\'], &[]).unwrap(); + assert_eq!( + (Text("{2:second ${3:third}} ".to_owned()), 33), + (snip_elm, end) + ); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$', '\\'], &[]).unwrap(); + assert_eq!((Text("0".to_owned()), 35), (snip_elm, end)); + + // 6. ==================================================================================== + + let s = "\\{start $1${2:second $\\{3:third}} $0}"; + + let (snip_elm, end) = + Snippet::extract_text(s, 0, &['{', '\\'], &[]).unwrap(); + assert_eq!((Text("{start $1$".to_owned()), 11), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['{', '\\'], &[]).unwrap(); + assert_eq!( + (Text("2:second ${3:third}} $0}".to_owned()), 37), + (snip_elm, end) + ); + + // 7. ==================================================================================== + + let s = "{start $1${2}:second $\\{3:third}} $0}"; + + let (snip_elm, end) = + Snippet::extract_text(s, 0, &['}', '\\'], &[]).unwrap(); + assert_eq!((Text("{start $1${2".to_owned()), 12), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['}', '\\'], &[]).unwrap(); + assert_eq!((Text(":second $".to_owned()), 22), (snip_elm, end)); + + assert_eq!(None, Snippet::extract_text(s, end, &['}', '\\'], &[])); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['}', '\\'], &[]).unwrap(); + assert_eq!((Text("{3:third".to_owned()), 31), (snip_elm, end)); + + assert_eq!(None, Snippet::extract_text(s, end + 1, &['}', '\\'], &[])); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 2, &['}', '\\'], &[]).unwrap(); + assert_eq!((Text(" $0".to_owned()), 36), (snip_elm, end)); + + // 8. ==================================================================================== + + let s = "{start $1${2}:second $\\{3:third}} $0}"; + + let (snip_elm, end) = + Snippet::extract_text(s, 0, &['$', '\\'], &['}']).unwrap(); + assert_eq!((Text("{start ".to_owned()), 7), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$', '\\'], &['}']).unwrap(); + assert_eq!((Text("1".to_owned()), 9), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$', '\\'], &['}']).unwrap(); + assert_eq!((Text("{2}:second ".to_owned()), 21), (snip_elm, end)); + + assert_eq!( + None, + Snippet::extract_text(s, end + 1, &['$', '\\'], &['}']) + ); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 2, &['$', '\\'], &['}']).unwrap(); + assert_eq!((Text("{3:third}} ".to_owned()), 34), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$', '\\'], &['}']).unwrap(); + assert_eq!((Text("0}".to_owned()), 37), (snip_elm, end)); + + // 9. ==================================================================================== + + let s = "{start $1${2}:second $\\{3:third}} $0}"; + + let (snip_elm, end) = + Snippet::extract_text(s, 0, &['$', '}', '\\'], &[]).unwrap(); + assert_eq!((Text("{start ".to_owned()), 7), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$', '}', '\\'], &[]).unwrap(); + assert_eq!((Text("1".to_owned()), 9), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$', '}', '\\'], &[]).unwrap(); + assert_eq!((Text("{2".to_owned()), 12), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$', '}', '\\'], &[]).unwrap(); + assert_eq!((Text(":second ".to_owned()), 21), (snip_elm, end)); + + assert_eq!( + None, + Snippet::extract_text(s, end + 1, &['$', '}', '\\'], &[]) + ); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 2, &['$', '}', '\\'], &[]).unwrap(); + assert_eq!((Text("{3:third".to_owned()), 31), (snip_elm, end)); + + assert_eq!( + None, + Snippet::extract_text(s, end + 1, &['$', '}', '\\'], &[]) + ); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 2, &['$', '}', '\\'], &[]).unwrap(); + assert_eq!((Text(" ".to_owned()), 34), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$', '}', '\\'], &[]).unwrap(); + assert_eq!((Text("0".to_owned()), 36), (snip_elm, end)); + + assert_eq!( + None, + Snippet::extract_text(s, end + 1, &['$', '}', '\\'], &[]) + ); + + // 10. ==================================================================================== + + let s = "{start $1${2}:second $\\{3:third}} $0}"; + + assert_eq!( + None, + Snippet::extract_text(s, 0, &['$', '{', '}', '\\'], &[]) + ); + + let (snip_elm, end) = + Snippet::extract_text(s, 1, &['$', '{', '}', '\\'], &[]).unwrap(); + assert_eq!((Text("start ".to_owned()), 7), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$', '{', '}', '\\'], &[]).unwrap(); + assert_eq!((Text("1".to_owned()), 9), (snip_elm, end)); + + assert_eq!( + None, + Snippet::extract_text(s, end + 1, &['$', '{', '}', '\\'], &[]) + ); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 2, &['$', '{', '}', '\\'], &[]).unwrap(); + assert_eq!((Text("2".to_owned()), 12), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$', '{', '}', '\\'], &[]).unwrap(); + assert_eq!((Text(":second ".to_owned()), 21), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$', '{', '}', '\\'], &[]).unwrap(); + assert_eq!((Text("{3:third".to_owned()), 31), (snip_elm, end)); + + assert_eq!( + None, + Snippet::extract_text(s, end + 1, &['$', '{', '}', '\\'], &[]) + ); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 2, &['$', '{', '}', '\\'], &[]).unwrap(); + assert_eq!((Text(" ".to_owned()), 34), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$', '{', '}', '\\'], &[]).unwrap(); + assert_eq!((Text("0".to_owned()), 36), (snip_elm, end)); + + assert_eq!( + None, + Snippet::extract_text(s, end + 1, &['$', '{', '}', '\\'], &[]) + ); + + // 11. ==================================================================================== + + let s = "{start\\\\ $1${2}:second\\ $\\{3:third}} $0}"; + + assert_eq!( + None, + Snippet::extract_text(s, 0, &['$', '{', '}', '\\'], &[]) + ); + + let (snip_elm, end) = + Snippet::extract_text(s, 1, &['$', '{', '}', '\\'], &[]).unwrap(); + assert_eq!((Text("start\\ ".to_owned()), 9), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$', '{', '}', '\\'], &[]).unwrap(); + assert_eq!((Text("1".to_owned()), 11), (snip_elm, end)); + + assert_eq!( + None, + Snippet::extract_text(s, end + 1, &['$', '{', '}', '\\'], &[]) + ); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 2, &['$', '{', '}', '\\'], &[]).unwrap(); + assert_eq!((Text("2".to_owned()), 14), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$', '{', '}', '\\'], &[]).unwrap(); + assert_eq!((Text(":second".to_owned()), 22), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$', '{', '}', '\\'], &[]).unwrap(); + assert_eq!((Text(" ".to_owned()), 24), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$', '{', '}', '\\'], &[]).unwrap(); + assert_eq!((Text("{3:third".to_owned()), 34), (snip_elm, end)); + + assert_eq!( + None, + Snippet::extract_text(s, end + 1, &['$', '{', '}', '\\'], &[]) + ); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 2, &['$', '{', '}', '\\'], &[]).unwrap(); + assert_eq!((Text(" ".to_owned()), 37), (snip_elm, end)); + + let (snip_elm, end) = + Snippet::extract_text(s, end + 1, &['$', '{', '}', '\\'], &[]).unwrap(); + assert_eq!((Text("0".to_owned()), 39), (snip_elm, end)); + + assert_eq!( + None, + Snippet::extract_text(s, end + 1, &['$', '{', '}', '\\'], &[]) + ); + } +} diff --git a/lapce-app/src/source_control.rs b/lapce-app/src/source_control.rs new file mode 100644 index 0000000..fc27b55 --- /dev/null +++ b/lapce-app/src/source_control.rs @@ -0,0 +1,104 @@ +use std::{path::PathBuf, rc::Rc}; + +use floem::{ + keyboard::Modifiers, + reactive::{RwSignal, Scope, SignalWith}, +}; +use indexmap::IndexMap; +use lapce_core::mode::Mode; +use lapce_rpc::source_control::FileDiff; + +use crate::{ + command::{CommandExecuted, CommandKind}, + editor::EditorData, + keypress::{KeyPressFocus, condition::Condition}, + main_split::Editors, + window_tab::CommonData, +}; + +#[derive(Clone, Debug)] +pub struct SourceControlData { + // VCS modified files & whether they should be included in the next commit + pub file_diffs: RwSignal>, + pub branch: RwSignal, + pub branches: RwSignal>, + pub tags: RwSignal>, + pub editor: EditorData, + pub common: Rc, +} + +impl KeyPressFocus for SourceControlData { + fn get_mode(&self) -> Mode { + Mode::Insert + } + + fn check_condition(&self, condition: Condition) -> bool { + matches!( + condition, + Condition::PanelFocus | Condition::SourceControlFocus + ) + } + + fn run_command( + &self, + command: &crate::command::LapceCommand, + count: Option, + mods: Modifiers, + ) -> CommandExecuted { + match &command.kind { + CommandKind::Edit(_) + | CommandKind::Move(_) + | CommandKind::MultiSelection(_) => { + self.editor.run_command(command, count, mods) + } + _ => CommandExecuted::No, + } + } + + fn receive_char(&self, c: &str) { + self.editor.receive_char(c); + } +} + +impl SourceControlData { + pub fn new(cx: Scope, editors: Editors, common: Rc) -> Self { + Self { + file_diffs: cx.create_rw_signal(IndexMap::new()), + branch: cx.create_rw_signal("".to_string()), + branches: cx.create_rw_signal(im::Vector::new()), + tags: cx.create_rw_signal(im::Vector::new()), + editor: editors.make_local(cx, common.clone()), + common, + } + } + + pub fn commit(&self) { + let diffs: Vec = self.file_diffs.with_untracked(|file_diffs| { + file_diffs + .iter() + .filter_map( + |(_, (diff, checked))| { + if *checked { Some(diff) } else { None } + }, + ) + .cloned() + .collect() + }); + if diffs.is_empty() { + return; + } + + let message = self + .editor + .doc() + .buffer + .with_untracked(|buffer| buffer.to_string()); + let message = message.trim(); + if message.is_empty() { + return; + } + + self.editor.reset(); + self.common.proxy.git_commit(message.to_string(), diffs); + } +} diff --git a/lapce-app/src/status.rs b/lapce-app/src/status.rs new file mode 100644 index 0000000..707affd --- /dev/null +++ b/lapce-app/src/status.rs @@ -0,0 +1,473 @@ +use std::{ + rc::Rc, + sync::{Arc, atomic::AtomicU64}, +}; + +use floem::{ + View, + event::EventPropagation, + reactive::{ + Memo, ReadSignal, RwSignal, SignalGet, SignalUpdate, SignalWith, create_memo, + }, + style::{AlignItems, CursorStyle, Display}, + views::{Decorators, dyn_stack, label, stack, svg}, +}; +use indexmap::IndexMap; +use lapce_core::mode::{Mode, VisualMode}; +use lsp_types::{DiagnosticSeverity, ProgressToken}; + +use crate::{ + app::clickable_icon, + command::LapceWorkbenchCommand, + config::{LapceConfig, color::LapceColor, icon::LapceIcons}, + editor::EditorData, + listener::Listener, + palette::kind::PaletteKind, + panel::{kind::PanelKind, position::PanelContainerPosition}, + source_control::SourceControlData, + window_tab::{WindowTabData, WorkProgress}, +}; + +pub fn status( + window_tab_data: Rc, + source_control: SourceControlData, + workbench_command: Listener, + status_height: RwSignal, + _config: ReadSignal>, +) -> impl View { + let config = window_tab_data.common.config; + let diagnostics = window_tab_data.main_split.diagnostics; + let editor = window_tab_data.main_split.active_editor; + let panel = window_tab_data.panel.clone(); + let palette = window_tab_data.palette.clone(); + let diagnostic_count = create_memo(move |_| { + let mut errors = 0; + let mut warnings = 0; + for (_, diagnostics) in diagnostics.get().iter() { + for diagnostic in diagnostics.diagnostics.get().iter() { + if let Some(severity) = diagnostic.severity { + match severity { + DiagnosticSeverity::ERROR => errors += 1, + DiagnosticSeverity::WARNING => warnings += 1, + _ => (), + } + } + } + } + (errors, warnings) + }); + let branch = source_control.branch; + let file_diffs = source_control.file_diffs; + let branch = move || { + format!( + "{}{}", + branch.get(), + if file_diffs.with(|diffs| diffs.is_empty()) { + "" + } else { + "*" + } + ) + }; + + let progresses = window_tab_data.progresses; + let mode = create_memo(move |_| window_tab_data.mode()); + let pointer_down = floem::reactive::create_rw_signal(false); + + stack(( + stack(( + label(move || match mode.get() { + Mode::Normal => "Normal".to_string(), + Mode::Insert => "Insert".to_string(), + Mode::Visual(mode) => match mode { + VisualMode::Normal => "Visual".to_string(), + VisualMode::Linewise => "Visual Line".to_string(), + VisualMode::Blockwise => "Visual Block".to_string(), + }, + Mode::Terminal => "Terminal".to_string(), + }) + .style(move |s| { + let config = config.get(); + let display = if config.core.modal { + Display::Flex + } else { + Display::None + }; + + let (bg, fg) = match mode.get() { + Mode::Normal => ( + LapceColor::STATUS_MODAL_NORMAL_BACKGROUND, + LapceColor::STATUS_MODAL_NORMAL_FOREGROUND, + ), + Mode::Insert => ( + LapceColor::STATUS_MODAL_INSERT_BACKGROUND, + LapceColor::STATUS_MODAL_INSERT_FOREGROUND, + ), + Mode::Visual(_) => ( + LapceColor::STATUS_MODAL_VISUAL_BACKGROUND, + LapceColor::STATUS_MODAL_VISUAL_FOREGROUND, + ), + Mode::Terminal => ( + LapceColor::STATUS_MODAL_TERMINAL_BACKGROUND, + LapceColor::STATUS_MODAL_TERMINAL_FOREGROUND, + ), + }; + + let bg = config.color(bg); + let fg = config.color(fg); + + s.display(display) + .padding_horiz(10.0) + .color(fg) + .background(bg) + .height_pct(100.0) + .align_items(Some(AlignItems::Center)) + .selectable(false) + }), + stack(( + svg(move || config.get().ui_svg(LapceIcons::SCM)).style(move |s| { + let config = config.get(); + let icon_size = config.ui.icon_size() as f32; + s.size(icon_size, icon_size) + .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + }), + label(branch).style(move |s| { + s.margin_left(10.0) + .color(config.get().color(LapceColor::STATUS_FOREGROUND)) + .selectable(false) + }), + )) + .style(move |s| { + s.display(if branch().is_empty() { + Display::None + } else { + Display::Flex + }) + .height_pct(100.0) + .padding_horiz(10.0) + .align_items(Some(AlignItems::Center)) + .hover(|s| { + s.cursor(CursorStyle::Pointer).background( + config.get().color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + }) + }) + .on_event_cont(floem::event::EventListener::PointerDown, move |_| { + pointer_down.set(true); + }) + .on_event( + floem::event::EventListener::PointerUp, + move |_| { + if pointer_down.get() { + workbench_command + .send(LapceWorkbenchCommand::PaletteSCMReferences); + } + pointer_down.set(false); + EventPropagation::Continue + }, + ), + { + let panel = panel.clone(); + stack(( + svg(move || config.get().ui_svg(LapceIcons::ERROR)).style( + move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.size(size, size) + .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + }, + ), + label(move || diagnostic_count.get().0.to_string()).style( + move |s| { + s.margin_left(5.0) + .color( + config + .get() + .color(LapceColor::STATUS_FOREGROUND), + ) + .selectable(false) + }, + ), + svg(move || config.get().ui_svg(LapceIcons::WARNING)).style( + move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.size(size, size) + .margin_left(5.0) + .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + }, + ), + label(move || diagnostic_count.get().1.to_string()).style( + move |s| { + s.margin_left(5.0) + .color( + config + .get() + .color(LapceColor::STATUS_FOREGROUND), + ) + .selectable(false) + }, + ), + )) + .on_click_stop(move |_| { + panel.show_panel(&PanelKind::Problem); + }) + .style(move |s| { + s.height_pct(100.0) + .padding_horiz(10.0) + .items_center() + .hover(|s| { + s.cursor(CursorStyle::Pointer).background( + config + .get() + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + }) + }) + }, + progress_view(config, progresses), + )) + .style(|s| { + s.height_pct(100.0) + .min_width(0.0) + .flex_basis(0.0) + .flex_grow(1.0) + .items_center() + }), + stack(( + { + let panel = panel.clone(); + let icon = { + let panel = panel.clone(); + move || { + if panel + .is_container_shown(&PanelContainerPosition::Left, true) + { + LapceIcons::SIDEBAR_LEFT + } else { + LapceIcons::SIDEBAR_LEFT_OFF + } + } + }; + clickable_icon( + icon, + move || { + panel.toggle_container_visual(&PanelContainerPosition::Left) + }, + || false, + || false, + || "Toggle Left Panel", + config, + ) + }, + { + let panel = panel.clone(); + let icon = { + let panel = panel.clone(); + move || { + if panel.is_container_shown( + &PanelContainerPosition::Bottom, + true, + ) { + LapceIcons::LAYOUT_PANEL + } else { + LapceIcons::LAYOUT_PANEL_OFF + } + } + }; + clickable_icon( + icon, + move || { + panel + .toggle_container_visual(&PanelContainerPosition::Bottom) + }, + || false, + || false, + || "Toggle Bottom Panel", + config, + ) + }, + { + let panel = panel.clone(); + let icon = { + let panel = panel.clone(); + move || { + if panel + .is_container_shown(&PanelContainerPosition::Right, true) + { + LapceIcons::SIDEBAR_RIGHT + } else { + LapceIcons::SIDEBAR_RIGHT_OFF + } + } + }; + clickable_icon( + icon, + move || { + panel.toggle_container_visual(&PanelContainerPosition::Right) + }, + || false, + || false, + || "Toggle Right Panel", + config, + ) + }, + )) + .style(move |s| { + s.height_pct(100.0) + .items_center() + .color(config.get().color(LapceColor::STATUS_FOREGROUND)) + }), + stack({ + let palette_clone = palette.clone(); + let cursor_info = status_text(config, editor, move || { + if let Some(editor) = editor.get() { + let mut status = String::new(); + let cursor = editor.cursor().get(); + if let Some((line, column, character)) = editor + .doc_signal() + .get() + .buffer + .with(|buffer| cursor.get_line_col_char(buffer)) + { + status = format!( + "Ln {}, Col {}, Char {}", + line + 1, + column + 1, + character, + ); + } + if let Some(selection) = cursor.get_selection() { + let selection_range = selection.0.abs_diff(selection.1); + + if selection.0 != selection.1 { + status = + format!("{status} ({selection_range} selected)"); + } + } + let selection_count = cursor.get_selection_count(); + if selection_count > 1 { + status = format!("{status} {selection_count} selections"); + } + return status; + } + String::new() + }) + .on_click_stop(move |_| { + palette_clone.run(PaletteKind::Line); + }); + let palette_clone = palette.clone(); + let line_ending_info = status_text(config, editor, move || { + if let Some(editor) = editor.get() { + let doc = editor.doc_signal().get(); + doc.buffer.with(|b| b.line_ending()).as_str() + } else { + "" + } + }) + .on_click_stop(move |_| { + palette_clone.run(PaletteKind::LineEnding); + }); + let palette_clone = palette.clone(); + let language_info = status_text(config, editor, move || { + if let Some(editor) = editor.get() { + let doc = editor.doc_signal().get(); + doc.syntax().with(|s| s.language.name()) + } else { + "unknown" + } + }) + .on_click_stop(move |_| { + palette_clone.run(PaletteKind::Language); + }); + (cursor_info, line_ending_info, language_info) + }) + .style(|s| { + s.height_pct(100.0) + .flex_basis(0.0) + .flex_grow(1.0) + .justify_end() + }), + )) + .on_resize(move |rect| { + let height = rect.height(); + if height != status_height.get_untracked() { + status_height.set(height); + } + }) + .style(move |s| { + let config = config.get(); + s.border_top(1.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .background(config.color(LapceColor::STATUS_BACKGROUND)) + .flex_basis(config.ui.status_height() as f32) + .flex_grow(0.0) + .flex_shrink(0.0) + .items_center() + }) + .debug_name("Status/Bottom Bar") +} + +fn progress_view( + config: ReadSignal>, + progresses: RwSignal>, +) -> impl View { + let id = AtomicU64::new(0); + dyn_stack( + move || progresses.get(), + move |_| id.fetch_add(1, std::sync::atomic::Ordering::Relaxed), + move |(_, p)| { + let progress = match p.message { + Some(message) if !message.is_empty() => { + format!("{}: {}", p.title, message) + } + _ => p.title, + }; + label(move || progress.clone()).style(move |s| { + s.height_pct(100.0) + .min_width(0.0) + .margin_left(10.0) + .text_ellipsis() + .selectable(false) + .items_center() + .color(config.get().color(LapceColor::STATUS_FOREGROUND)) + }) + }, + ) + .style(move |s| s.flex_row().height_pct(100.0).min_width(0.0)) +} + +fn status_text( + config: ReadSignal>, + editor: Memo>, + text: impl Fn() -> S + 'static, +) -> impl View { + label(text).style(move |s| { + let config = config.get(); + let display = if editor + .get() + .map(|editor| { + editor.doc_signal().get().content.with(|c| { + use crate::doc::DocContent; + matches!(c, DocContent::File { .. } | DocContent::Scratch { .. }) + }) + }) + .unwrap_or(false) + { + Display::Flex + } else { + Display::None + }; + + s.display(display) + .height_full() + .padding_horiz(10.0) + .items_center() + .color(config.color(LapceColor::STATUS_FOREGROUND)) + .hover(|s| { + s.cursor(CursorStyle::Pointer) + .background(config.color(LapceColor::PANEL_HOVERED_BACKGROUND)) + }) + .selectable(false) + }) +} diff --git a/lapce-app/src/terminal/data.rs b/lapce-app/src/terminal/data.rs new file mode 100644 index 0000000..51badf7 --- /dev/null +++ b/lapce-app/src/terminal/data.rs @@ -0,0 +1,861 @@ +use std::{collections::HashMap, path::PathBuf, rc::Rc, sync::Arc}; + +use alacritty_terminal::{ + Term, + grid::{Dimensions, Scroll}, + selection::{Selection, SelectionType}, + term::{TermMode, test::TermSize}, + vi_mode::ViMotion, +}; +use anyhow::anyhow; +use floem::{ + keyboard::{Key, KeyEvent, Modifiers, NamedKey}, + reactive::{RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, + views::editor::text::SystemClipboard, +}; +use lapce_core::{ + command::{EditCommand, FocusCommand, ScrollCommand}, + mode::{Mode, VisualMode}, + movement::{LinePosition, Movement}, + register::Clipboard, +}; +use lapce_rpc::{ + dap_types::RunDebugConfig, + terminal::{TermId, TerminalProfile}, +}; +use parking_lot::RwLock; +use url::Url; + +use super::{ + event::TermEvent, + raw::{EventProxy, RawTerminal}, +}; +use crate::{ + command::{CommandExecuted, CommandKind, InternalCommand}, + debug::{RunDebugMode, RunDebugProcess}, + keypress::{KeyPressFocus, condition::Condition}, + window_tab::CommonData, + workspace::LapceWorkspace, +}; + +#[derive(Clone, Debug)] +pub struct TerminalData { + pub scope: Scope, + pub term_id: TermId, + pub workspace: Arc, + pub title: RwSignal, + pub launch_error: RwSignal>, + pub mode: RwSignal, + pub visual_mode: RwSignal, + pub raw: RwSignal>>, + pub run_debug: RwSignal>, + pub common: Rc, +} + +impl KeyPressFocus for TerminalData { + fn get_mode(&self) -> Mode { + self.mode.get_untracked() + } + + fn check_condition(&self, condition: Condition) -> bool { + matches!(condition, Condition::TerminalFocus | Condition::PanelFocus) + } + + fn run_command( + &self, + command: &crate::command::LapceCommand, + count: Option, + _mods: Modifiers, + ) -> crate::command::CommandExecuted { + self.common.view_id.get_untracked().request_paint(); + let config = self.common.config.get_untracked(); + match &command.kind { + CommandKind::Move(cmd) => { + let movement = cmd.to_movement(count); + let raw = self.raw.get_untracked(); + let mut raw = raw.write(); + let term = &mut raw.term; + match movement { + Movement::Left => { + term.vi_motion(ViMotion::Left); + } + Movement::Right => { + term.vi_motion(ViMotion::Right); + } + Movement::Up => { + term.vi_motion(ViMotion::Up); + } + Movement::Down => { + term.vi_motion(ViMotion::Down); + } + Movement::FirstNonBlank => { + term.vi_motion(ViMotion::FirstOccupied); + } + Movement::StartOfLine => { + term.vi_motion(ViMotion::First); + } + Movement::EndOfLine => { + term.vi_motion(ViMotion::Last); + } + Movement::WordForward => { + term.vi_motion(ViMotion::SemanticRight); + } + Movement::WordEndForward => { + term.vi_motion(ViMotion::SemanticRightEnd); + } + Movement::WordBackward => { + term.vi_motion(ViMotion::SemanticLeft); + } + Movement::Line(line) => { + match line { + LinePosition::First => { + term.scroll_display(Scroll::Top); + term.vi_mode_cursor.point.line = term.topmost_line(); + } + LinePosition::Last => { + term.scroll_display(Scroll::Bottom); + term.vi_mode_cursor.point.line = + term.bottommost_line(); + } + LinePosition::Line(_) => {} + }; + } + _ => (), + }; + } + CommandKind::Edit(cmd) => match cmd { + EditCommand::NormalMode => { + if !config.core.modal { + return CommandExecuted::Yes; + } + self.mode.set(Mode::Normal); + let raw = self.raw.get_untracked(); + let mut raw = raw.write(); + let term = &mut raw.term; + if !term.mode().contains(TermMode::VI) { + term.toggle_vi_mode(); + } + term.selection = None; + } + EditCommand::ToggleVisualMode => { + self.toggle_visual(VisualMode::Normal); + } + EditCommand::ToggleLinewiseVisualMode => { + self.toggle_visual(VisualMode::Linewise); + } + EditCommand::ToggleBlockwiseVisualMode => { + self.toggle_visual(VisualMode::Blockwise); + } + EditCommand::InsertMode => { + self.mode.set(Mode::Terminal); + let raw = self.raw.get_untracked(); + let mut raw = raw.write(); + let term = &mut raw.term; + if term.mode().contains(TermMode::VI) { + term.toggle_vi_mode(); + } + let scroll = alacritty_terminal::grid::Scroll::Bottom; + term.scroll_display(scroll); + term.selection = None; + } + EditCommand::ClipboardCopy => { + let mut clipboard = SystemClipboard::new(); + if matches!(self.mode.get_untracked(), Mode::Visual(_)) { + self.mode.set(Mode::Normal); + } + let raw = self.raw.get_untracked(); + let mut raw = raw.write(); + let term = &mut raw.term; + if let Some(content) = term.selection_to_string() { + clipboard.put_string(content); + } + if self.mode.get_untracked() != Mode::Terminal { + term.selection = None; + } + } + EditCommand::ClipboardPaste => { + let mut clipboard = SystemClipboard::new(); + let mut check_bracketed_paste: bool = false; + if self.mode.get_untracked() == Mode::Terminal { + let raw = self.raw.get_untracked(); + let mut raw = raw.write(); + let term = &mut raw.term; + term.selection = None; + if term.mode().contains(TermMode::BRACKETED_PASTE) { + check_bracketed_paste = true; + } + } + if let Some(s) = clipboard.get_string() { + if check_bracketed_paste { + self.receive_char("\x1b[200~"); + self.receive_char(&s.replace('\x1b', "")); + self.receive_char("\x1b[201~"); + } else { + self.receive_char(&s); + } + } + } + _ => return CommandExecuted::No, + }, + CommandKind::Scroll(cmd) => match cmd { + ScrollCommand::PageUp => { + let raw = self.raw.get_untracked(); + let mut raw = raw.write(); + let term = &mut raw.term; + let scroll_lines = term.screen_lines() as i32 / 2; + term.vi_mode_cursor = + term.vi_mode_cursor.scroll(term, scroll_lines); + + term.scroll_display(alacritty_terminal::grid::Scroll::Delta( + scroll_lines, + )); + } + ScrollCommand::PageDown => { + let raw = self.raw.get_untracked(); + let mut raw = raw.write(); + let term = &mut raw.term; + let scroll_lines = -(term.screen_lines() as i32 / 2); + term.vi_mode_cursor = + term.vi_mode_cursor.scroll(term, scroll_lines); + + term.scroll_display(alacritty_terminal::grid::Scroll::Delta( + scroll_lines, + )); + } + _ => return CommandExecuted::No, + }, + CommandKind::Focus(cmd) => match cmd { + FocusCommand::SplitVertical => { + self.common.internal_command.send( + InternalCommand::SplitTerminal { + term_id: self.term_id, + }, + ); + } + FocusCommand::SplitHorizontal => { + self.common.internal_command.send( + InternalCommand::SplitTerminal { + term_id: self.term_id, + }, + ); + } + FocusCommand::SplitLeft => { + self.common.internal_command.send( + InternalCommand::SplitTerminalPrevious { + term_id: self.term_id, + }, + ); + } + FocusCommand::SplitRight => { + self.common.internal_command.send( + InternalCommand::SplitTerminalNext { + term_id: self.term_id, + }, + ); + } + FocusCommand::SplitExchange => { + self.common.internal_command.send( + InternalCommand::SplitTerminalExchange { + term_id: self.term_id, + }, + ); + } + FocusCommand::SearchForward => { + // if let Some(search_string) = self.find.search_string.as_ref() { + // let mut raw = self.terminal.raw.lock(); + // let term = &mut raw.term; + // self.terminal.search_next( + // term, + // search_string, + // Direction::Right, + // ); + // } + } + FocusCommand::SearchBackward => { + // if let Some(search_string) = self.find.search_string.as_ref() { + // let mut raw = self.terminal.raw.lock(); + // let term = &mut raw.term; + // self.terminal.search_next( + // term, + // search_string, + // Direction::Left, + // ); + // } + } + _ => return CommandExecuted::No, + }, + _ => return CommandExecuted::No, + }; + CommandExecuted::Yes + } + + fn receive_char(&self, c: &str) { + if self.mode.get_untracked() == Mode::Terminal { + self.common + .proxy + .terminal_write(self.term_id, c.to_string()); + self.raw + .get_untracked() + .write() + .term + .scroll_display(Scroll::Bottom); + } + } +} + +impl TerminalData { + pub fn new( + cx: Scope, + workspace: Arc, + profile: Option, + common: Rc, + ) -> Self { + Self::new_run_debug(cx, workspace, None, profile, common) + } + + pub fn new_run_debug( + cx: Scope, + workspace: Arc, + run_debug: Option, + profile: Option, + common: Rc, + ) -> Self { + let cx = cx.create_child(); + let term_id = TermId::next(); + + let title = if let Some(profile) = &profile { + cx.create_rw_signal(profile.name.to_owned()) + } else { + cx.create_rw_signal(String::from("Default")) + }; + + let launch_error = cx.create_rw_signal(None); + + let raw = Self::new_raw_terminal( + &workspace, + term_id, + run_debug.as_ref(), + profile, + common.clone(), + launch_error, + ); + + let run_debug = cx.create_rw_signal(run_debug); + let mode = cx.create_rw_signal(Mode::Terminal); + let visual_mode = cx.create_rw_signal(VisualMode::Normal); + let raw = cx.create_rw_signal(raw); + + Self { + scope: cx, + term_id, + workspace, + raw, + title, + run_debug, + mode, + visual_mode, + common, + launch_error, + } + } + + fn new_raw_terminal( + workspace: &LapceWorkspace, + term_id: TermId, + run_debug: Option<&RunDebugProcess>, + profile: Option, + common: Rc, + launch_error: RwSignal>, + ) -> Arc> { + let raw = Arc::new(RwLock::new(RawTerminal::new( + term_id, + common.proxy.clone(), + common.term_notification_tx.clone(), + ))); + + let mut profile = profile.unwrap_or_default(); + + if profile.workdir.is_none() { + profile.workdir = url::Url::from_file_path( + workspace.path.as_ref().cloned().unwrap_or_default(), + ) + .ok(); + } + + let exp_run_debug = run_debug + .as_ref() + .map(|run_debug| { + ExpandedRunDebug::expand( + workspace, + &run_debug.config, + run_debug.is_prelaunch, + ) + }) + .transpose(); + + let exp_run_debug = exp_run_debug.unwrap_or_else(|e| { + let r_name = run_debug + .as_ref() + .map(|r| r.config.name.as_str()) + .unwrap_or("Unknown"); + launch_error.set(Some(format!( + "Failed to expand variables in run debug definition {r_name}: {e}" + ))); + None + }); + + if let Some(run_debug) = exp_run_debug { + if let Some(work_dir) = run_debug.work_dir { + profile.workdir = Some(work_dir); + } + + profile.environment = run_debug.env; + + profile.command = Some(run_debug.program); + profile.arguments = run_debug.args; + } + + { + let raw = raw.clone(); + if let Err(err) = + common.term_tx.send((term_id, TermEvent::NewTerminal(raw))) + { + tracing::error!("{:?}", err); + } + common.proxy.new_terminal(term_id, profile); + } + + raw + } + + pub fn send_keypress(&self, key: &KeyEvent) -> bool { + if let Some(command) = Self::resolve_key_event(key) { + self.receive_char(command); + true + } else if key.modifiers == Modifiers::ALT + && matches!(&key.key.logical_key, Key::Character(_)) + { + if let Key::Character(c) = &key.key.logical_key { + // In terminal emulators, when the Alt key is combined with another character + // (such as Alt+a), a leading ESC (Escape, ASCII code 0x1B) character is usually + // sent followed by a sequence of that character. For example, + // Alt+a sends \x1Ba. + self.receive_char("\x1b"); + self.receive_char(c.as_str()); + } + true + } else { + false + } + } + + pub fn resolve_key_event(key: &KeyEvent) -> Option<&str> { + let key = key.clone(); + + // Generates a `Modifiers` value to check against. + macro_rules! modifiers { + (ctrl) => { + Modifiers::CONTROL + }; + + (alt) => { + Modifiers::ALT + }; + + (shift) => { + Modifiers::SHIFT + }; + + ($mod:ident $(| $($mods:ident)|+)?) => { + modifiers!($mod) $(| modifiers!($($mods)|+) )? + }; + } + + // Generates modifier values for ANSI sequences. + macro_rules! modval { + (shift) => { + // 1 + "2" + }; + (alt) => { + // 2 + "3" + }; + (alt | shift) => { + // 1 + 2 + "4" + }; + (ctrl) => { + // 4 + "5" + }; + (ctrl | shift) => { + // 1 + 4 + "6" + }; + (alt | ctrl) => { + // 2 + 4 + "7" + }; + (alt | ctrl | shift) => { + // 1 + 2 + 4 + "8" + }; + } + + // Generates ANSI sequences to move the cursor by one position. + macro_rules! term_sequence { + // Generate every modifier combination (except meta) + ([all], $evt:ident, $no_mod:literal, $pre:literal, $post:literal) => { + { + term_sequence!([], $evt, $no_mod); + term_sequence!([shift, alt, ctrl], $evt, $pre, $post); + term_sequence!([alt | shift, ctrl | shift, alt | ctrl], $evt, $pre, $post); + term_sequence!([alt | ctrl | shift], $evt, $pre, $post); + return None; + } + }; + // No modifiers + ([], $evt:ident, $no_mod:literal) => { + if $evt.modifiers.is_empty() { + return Some($no_mod); + } + }; + // A single modifier combination + ([$($mod:ident)|+], $evt:ident, $pre:literal, $post:literal) => { + if $evt.modifiers == modifiers!($($mod)|+) { + return Some(concat!($pre, modval!($($mod)|+), $post)); + } + }; + // Break down multiple modifiers into a series of single combination branches + ([$($($mod:ident)|+),+], $evt:ident, $pre:literal, $post:literal) => { + $( + term_sequence!([$($mod)|+], $evt, $pre, $post); + )+ + }; + } + + match key.key.logical_key { + Key::Character(ref c) => { + if key.modifiers == Modifiers::CONTROL { + // Convert the character into its index (into a control character). + // In essence, this turns `ctrl+h` into `^h` + let str = match c.as_str() { + "@" => "\x00", + "a" => "\x01", + "b" => "\x02", + "c" => "\x03", + "d" => "\x04", + "e" => "\x05", + "f" => "\x06", + "g" => "\x07", + "h" => "\x08", + "i" => "\x09", + "j" => "\x0a", + "k" => "\x0b", + "l" => "\x0c", + "m" => "\x0d", + "n" => "\x0e", + "o" => "\x0f", + "p" => "\x10", + "q" => "\x11", + "r" => "\x12", + "s" => "\x13", + "t" => "\x14", + "u" => "\x15", + "v" => "\x16", + "w" => "\x17", + "x" => "\x18", + "y" => "\x19", + "z" => "\x1a", + "[" => "\x1b", + "\\" => "\x1c", + "]" => "\x1d", + "^" => "\x1e", + "_" => "\x1f", + _ => return None, + }; + + Some(str) + } else { + None + } + } + Key::Named(NamedKey::Backspace) => { + Some(if key.modifiers.control() { + "\x08" // backspace + } else if key.modifiers.alt() { + "\x1b\x7f" + } else { + "\x7f" + }) + } + + Key::Named(NamedKey::Tab) => Some("\x09"), + Key::Named(NamedKey::Enter) => Some("\r"), + Key::Named(NamedKey::Escape) => Some("\x1b"), + + // The following either expands to `\x1b[X` or `\x1b[1;NX` where N is a modifier value + Key::Named(NamedKey::ArrowUp) => { + term_sequence!([all], key, "\x1b[A", "\x1b[1;", "A") + } + Key::Named(NamedKey::ArrowDown) => { + term_sequence!([all], key, "\x1b[B", "\x1b[1;", "B") + } + Key::Named(NamedKey::ArrowRight) => { + term_sequence!([all], key, "\x1b[C", "\x1b[1;", "C") + } + Key::Named(NamedKey::ArrowLeft) => { + term_sequence!([all], key, "\x1b[D", "\x1b[1;", "D") + } + Key::Named(NamedKey::Home) => { + term_sequence!([all], key, "\x1bOH", "\x1b[1;", "H") + } + Key::Named(NamedKey::End) => { + term_sequence!([all], key, "\x1bOF", "\x1b[1;", "F") + } + Key::Named(NamedKey::Insert) => { + term_sequence!([all], key, "\x1b[2~", "\x1b[2;", "~") + } + Key::Named(NamedKey::Delete) => { + term_sequence!([all], key, "\x1b[3~", "\x1b[3;", "~") + } + Key::Named(NamedKey::PageUp) => { + term_sequence!([all], key, "\x1b[5~", "\x1b[5;", "~") + } + Key::Named(NamedKey::PageDown) => { + term_sequence!([all], key, "\x1b[6~", "\x1b[6;", "~") + } + _ => None, + } + } + + pub fn wheel_scroll(&self, delta: f64) { + let config = self.common.config.get_untracked(); + let step = config.terminal_line_height() as f64; + let raw = self.raw.get_untracked(); + let mut raw = raw.write(); + raw.scroll_delta -= delta; + let delta = (raw.scroll_delta / step) as i32; + raw.scroll_delta -= delta as f64 * step; + if delta != 0 { + let scroll = alacritty_terminal::grid::Scroll::Delta(delta); + raw.term.scroll_display(scroll); + } + } + + fn toggle_visual(&self, visual_mode: VisualMode) { + let config = self.common.config.get_untracked(); + if !config.core.modal { + return; + } + + match self.mode.get_untracked() { + Mode::Normal => { + self.mode.set(Mode::Visual(visual_mode)); + self.visual_mode.set(visual_mode); + } + Mode::Visual(_) => { + if self.visual_mode.get_untracked() == visual_mode { + self.mode.set(Mode::Normal); + } else { + self.visual_mode.set(visual_mode); + } + } + _ => (), + } + + let raw = self.raw.get_untracked(); + let mut raw = raw.write(); + let term = &mut raw.term; + if !term.mode().contains(TermMode::VI) { + term.toggle_vi_mode(); + } + let ty = match visual_mode { + VisualMode::Normal => SelectionType::Simple, + VisualMode::Linewise => SelectionType::Lines, + VisualMode::Blockwise => SelectionType::Block, + }; + let point = term.renderable_content().cursor.point; + self.toggle_selection( + term, + ty, + point, + alacritty_terminal::index::Side::Left, + ); + if let Some(selection) = term.selection.as_mut() { + selection.include_all(); + } + } + + pub fn toggle_selection( + &self, + term: &mut Term, + ty: SelectionType, + point: alacritty_terminal::index::Point, + side: alacritty_terminal::index::Side, + ) { + match &mut term.selection { + Some(selection) if selection.ty == ty && !selection.is_empty() => { + term.selection = None; + } + Some(selection) if !selection.is_empty() => { + selection.ty = ty; + } + _ => self.start_selection(term, ty, point, side), + } + } + + fn start_selection( + &self, + term: &mut Term, + ty: SelectionType, + point: alacritty_terminal::index::Point, + side: alacritty_terminal::index::Side, + ) { + term.selection = Some(Selection::new(ty, point, side)); + } + + pub fn new_process(&self, run_debug: Option) { + let (width, height) = { + let raw = self.raw.get_untracked(); + let raw = raw.read(); + let width = raw.term.columns(); + let height = raw.term.screen_lines(); + (width, height) + }; + + let raw = Self::new_raw_terminal( + &self.workspace, + self.term_id, + run_debug.as_ref(), + None, + self.common.clone(), + self.launch_error, + ); + + self.raw.set(raw); + self.run_debug.set(run_debug); + + let term_size = TermSize::new(width, height); + self.raw.get_untracked().write().term.resize(term_size); + self.common + .proxy + .terminal_resize(self.term_id, width, height); + } + + pub fn stop(&self) { + if let Some(dap_id) = self.run_debug.with_untracked(|x| { + if let Some(process) = x { + if !process.is_prelaunch && process.mode == RunDebugMode::Debug { + return Some(process.config.dap_id); + } + } + None + }) { + self.common.proxy.dap_stop(dap_id); + } + self.common.proxy.terminal_close(self.term_id); + } +} + +/// [`RunDebugConfig`] with expanded out program/arguments/etc. Used for creating the terminal. +#[derive(Debug, Clone)] +pub struct ExpandedRunDebug { + pub work_dir: Option, + pub env: Option>, + pub program: String, + pub args: Option>, +} +impl ExpandedRunDebug { + pub fn expand( + workspace: &LapceWorkspace, + run_debug: &RunDebugConfig, + is_prelaunch: bool, + ) -> anyhow::Result { + // Get the current working directory variable, which can container ${workspace} + let work_dir = Self::expand_work_dir(workspace, run_debug); + + let prelaunch = is_prelaunch + .then_some(run_debug.prelaunch.as_ref()) + .flatten(); + + let env = run_debug.env.clone(); + + // TODO: replace some variables in the args + let (program, mut args) = + if let Some(debug_command) = run_debug.debug_command.as_ref() { + let mut args = debug_command.to_owned(); + let command = args.first().cloned().unwrap_or_default(); + if !args.is_empty() { + args.remove(0); + } + + let args = if !args.is_empty() { Some(args) } else { None }; + (command, args) + } else if let Some(prelaunch) = prelaunch { + (prelaunch.program.clone(), prelaunch.args.clone()) + } else { + (run_debug.program.clone(), run_debug.args.clone()) + }; + let mut program = if program == "${lapce}" { + std::env::current_exe() + .map_err(|e| { + anyhow!( + "Failed to get current exe for ${{lapce}} run and debug: {e}" + ) + })? + .to_str() + .ok_or_else(|| anyhow!("Failed to convert ${{lapce}} path to str"))? + .to_string() + } else { + program + }; + + if program.contains("${workspace}") { + if let Some(workspace) = workspace.path.as_ref().and_then(|x| x.to_str()) + { + program = program.replace("${workspace}", workspace); + } + } + + if let Some(args) = &mut args { + for arg in args { + // Replace all mentions of ${workspace} with the current workspace path + if arg.contains("${workspace}") { + if let Some(workspace) = + workspace.path.as_ref().and_then(|x| x.to_str()) + { + *arg = arg.replace("${workspace}", workspace); + } + } + } + } + + Ok(ExpandedRunDebug { + work_dir, + env, + program, + args, + }) + } + + fn expand_work_dir( + workspace: &LapceWorkspace, + run_debug: &RunDebugConfig, + ) -> Option { + let path = run_debug.cwd.as_ref()?; + + if path.contains("${workspace}") { + if let Some(workspace) = workspace.path.as_ref().and_then(|x| x.to_str()) + { + let path = path.replace("${workspace}", workspace); + if let Ok(as_url) = Url::from_file_path(PathBuf::from(path)) { + return Some(as_url); + } + } + } + + Url::from_file_path(PathBuf::from(path)).ok() + } +} diff --git a/lapce-app/src/terminal/event.rs b/lapce-app/src/terminal/event.rs new file mode 100644 index 0000000..9dd45a1 --- /dev/null +++ b/lapce-app/src/terminal/event.rs @@ -0,0 +1,77 @@ +use std::{ + collections::HashMap, + sync::{ + Arc, + mpsc::{Receiver, Sender}, + }, + time::Instant, +}; + +use lapce_rpc::terminal::TermId; +use parking_lot::RwLock; + +use super::raw::RawTerminal; + +/// The notifications for terminals to send back to main thread +pub enum TermNotification { + SetTitle { term_id: TermId, title: String }, + RequestPaint, +} + +pub enum TermEvent { + NewTerminal(Arc>), + UpdateContent(Vec), + CloseTerminal, +} + +pub fn terminal_update_process( + receiver: Receiver<(TermId, TermEvent)>, + term_notification_tx: Sender, +) { + let mut terminals = HashMap::new(); + let mut last_redraw = Instant::now(); + let mut last_event = None; + loop { + let (term_id, event) = if let Some((term_id, event)) = last_event.take() { + (term_id, event) + } else { + match receiver.recv() { + Ok((term_id, event)) => (term_id, event), + Err(_) => return, + } + }; + match event { + TermEvent::CloseTerminal => { + terminals.remove(&term_id); + } + TermEvent::NewTerminal(raw) => { + terminals.insert(term_id, raw); + } + TermEvent::UpdateContent(content) => { + if let Some(raw) = terminals.get(&term_id) { + { + raw.write().update_content(content); + } + last_event = receiver.try_recv().ok(); + if last_event.is_some() { + if last_redraw.elapsed().as_millis() > 10 { + last_redraw = Instant::now(); + if let Err(err) = term_notification_tx + .send(TermNotification::RequestPaint) + { + tracing::error!("{:?}", err); + } + } + } else { + last_redraw = Instant::now(); + if let Err(err) = + term_notification_tx.send(TermNotification::RequestPaint) + { + tracing::error!("{:?}", err); + } + } + } + } + } + } +} diff --git a/lapce-app/src/terminal/mod.rs b/lapce-app/src/terminal/mod.rs new file mode 100644 index 0000000..455305f --- /dev/null +++ b/lapce-app/src/terminal/mod.rs @@ -0,0 +1,6 @@ +pub mod data; +pub mod event; +pub mod panel; +pub mod raw; +pub mod tab; +pub mod view; diff --git a/lapce-app/src/terminal/panel.rs b/lapce-app/src/terminal/panel.rs new file mode 100644 index 0000000..81455b2 --- /dev/null +++ b/lapce-app/src/terminal/panel.rs @@ -0,0 +1,820 @@ +use std::{collections::HashMap, path::PathBuf, rc::Rc, sync::Arc}; + +use floem::{ + ext_event::create_ext_action, + reactive::{Memo, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, +}; +use lapce_core::mode::Mode; +use lapce_rpc::{ + dap_types::{ + self, DapId, RunDebugConfig, StackFrame, Stopped, ThreadId, Variable, + }, + proxy::ProxyResponse, + terminal::{TermId, TerminalProfile}, +}; + +use super::{data::TerminalData, tab::TerminalTabData}; +use crate::{ + debug::{ + DapData, DapVariable, RunDebugConfigs, RunDebugData, RunDebugMode, + RunDebugProcess, ScopeOrVar, + }, + id::TerminalTabId, + keypress::{EventRef, KeyPressData, KeyPressFocus, KeyPressHandle}, + main_split::MainSplitData, + panel::kind::PanelKind, + window_tab::{CommonData, Focus}, + workspace::LapceWorkspace, +}; + +pub struct TerminalTabInfo { + pub active: usize, + pub tabs: im::Vector<(RwSignal, TerminalTabData)>, +} + +#[derive(Clone)] +pub struct TerminalPanelData { + pub cx: Scope, + pub workspace: Arc, + pub tab_info: RwSignal, + pub debug: RunDebugData, + pub breakline: Memo>, + pub common: Rc, + pub main_split: MainSplitData, +} + +impl TerminalPanelData { + pub fn new( + workspace: Arc, + profile: Option, + common: Rc, + main_split: MainSplitData, + ) -> Self { + let terminal_tab = + TerminalTabData::new(workspace.clone(), profile, common.clone()); + + let cx = common.scope; + + let tabs = + im::vector![(terminal_tab.scope.create_rw_signal(0), terminal_tab)]; + let tab_info = TerminalTabInfo { active: 0, tabs }; + let tab_info = cx.create_rw_signal(tab_info); + + let debug = RunDebugData::new(cx, common.breakpoints); + + let breakline = { + let active_term = debug.active_term; + let daps = debug.daps; + cx.create_memo(move |_| { + let active_term = active_term.get(); + let active_term = match active_term { + Some(active_term) => active_term, + None => return None, + }; + + let term = tab_info.with_untracked(|info| { + for (_, tab) in &info.tabs { + let terminal = tab.terminals.with_untracked(|terminals| { + terminals + .iter() + .find(|(_, t)| t.term_id == active_term) + .cloned() + }); + if let Some(terminal) = terminal { + return Some(terminal.1); + } + } + None + }); + let term = match term { + Some(term) => term, + None => return None, + }; + let stopped = term + .run_debug + .with(|run_debug| run_debug.as_ref().map(|r| r.stopped)) + .unwrap_or(true); + if stopped { + return None; + } + + let daps = daps.get(); + let dap = daps.values().find(|d| d.term_id == active_term); + dap.and_then(|dap| dap.breakline.get()) + }) + }; + + Self { + cx, + workspace, + tab_info, + debug, + breakline, + common, + main_split, + } + } + + pub fn active_tab(&self, tracked: bool) -> Option { + if tracked { + self.tab_info.with(|info| { + info.tabs + .get(info.active) + .or_else(|| info.tabs.last()) + .cloned() + .map(|(_, tab)| tab) + }) + } else { + self.tab_info.with_untracked(|info| { + info.tabs + .get(info.active) + .or_else(|| info.tabs.last()) + .cloned() + .map(|(_, tab)| tab) + }) + } + } + + pub fn key_down<'a>( + &self, + event: impl Into> + Copy, + keypress: &KeyPressData, + ) -> Option { + if self.tab_info.with_untracked(|info| info.tabs.is_empty()) { + self.new_tab(None); + } + + let tab = self.active_tab(false); + let terminal = tab.and_then(|tab| tab.active_terminal(false)); + if let Some(terminal) = terminal { + let handle = keypress.key_down(event, &terminal); + let mode = terminal.get_mode(); + + if !handle.handled && mode == Mode::Terminal { + if let EventRef::Keyboard(key_event) = event.into() { + if terminal.send_keypress(key_event) { + return Some(KeyPressHandle { + handled: true, + keymatch: handle.keymatch, + keypress: handle.keypress, + }); + } + } + } + Some(handle) + } else { + None + } + } + + pub fn new_tab(&self, profile: Option) { + self.new_tab_run_debug(None, profile); + } + + /// Create a new terminal tab with the given run debug process. + /// Errors if expanding out the run debug process failed. + pub fn new_tab_run_debug( + &self, + run_debug: Option, + profile: Option, + ) -> TerminalTabData { + let terminal_tab = TerminalTabData::new_run_debug( + self.workspace.clone(), + run_debug, + profile, + self.common.clone(), + ); + + self.tab_info.update(|info| { + info.tabs.insert( + if info.tabs.is_empty() { + 0 + } else { + (info.active + 1).min(info.tabs.len()) + }, + (terminal_tab.scope.create_rw_signal(0), terminal_tab.clone()), + ); + let new_active = (info.active + 1).min(info.tabs.len() - 1); + info.active = new_active; + }); + + terminal_tab + } + + pub fn next_tab(&self) { + self.tab_info.update(|info| { + if info.active >= info.tabs.len().saturating_sub(1) { + info.active = 0; + } else { + info.active += 1; + } + }); + self.update_debug_active_term(); + } + + pub fn previous_tab(&self) { + self.tab_info.update(|info| { + if info.active == 0 { + info.active = info.tabs.len().saturating_sub(1); + } else { + info.active -= 1; + } + }); + self.update_debug_active_term(); + } + + pub fn close_tab(&self, terminal_tab_id: Option) { + if let Some(close_tab) = self + .tab_info + .try_update(|info| { + let mut close_tab = None; + if let Some(terminal_tab_id) = terminal_tab_id { + if let Some(index) = + info.tabs.iter().enumerate().find_map(|(index, (_, t))| { + if t.terminal_tab_id == terminal_tab_id { + Some(index) + } else { + None + } + }) + { + close_tab = Some( + info.tabs.remove(index).1.terminals.get_untracked(), + ); + } + } else { + let active = info.active.min(info.tabs.len().saturating_sub(1)); + if !info.tabs.is_empty() { + info.tabs.remove(active); + } + } + let new_active = info.active.min(info.tabs.len().saturating_sub(1)); + info.active = new_active; + close_tab + }) + .flatten() + { + for (_, data) in close_tab { + data.stop(); + } + } + self.update_debug_active_term(); + } + + pub fn set_title(&self, term_id: &TermId, title: &str) { + if let Some(t) = self.get_terminal(term_id) { + t.title.set(title.to_string()); + } + } + + pub fn get_terminal(&self, term_id: &TermId) -> Option { + self.tab_info.with_untracked(|info| { + for (_, tab) in &info.tabs { + let terminal = tab.terminals.with_untracked(|terminals| { + terminals + .iter() + .find(|(_, t)| &t.term_id == term_id) + .cloned() + }); + if let Some(terminal) = terminal { + return Some(terminal.1); + } + } + None + }) + } + + fn get_terminal_in_tab( + &self, + term_id: &TermId, + ) -> Option<(usize, TerminalTabData, usize, TerminalData)> { + self.tab_info.with_untracked(|info| { + for (tab_index, (_, tab)) in info.tabs.iter().enumerate() { + let result = tab.terminals.with_untracked(|terminals| { + terminals + .iter() + .enumerate() + .find(|(_, (_, t))| &t.term_id == term_id) + .map(|(i, (_, terminal))| (i, terminal.clone())) + }); + if let Some((index, terminal)) = result { + return Some((tab_index, tab.clone(), index, terminal)); + } + } + None + }) + } + + pub fn split(&self, term_id: TermId) { + if let Some((_, tab, index, _)) = self.get_terminal_in_tab(&term_id) { + let terminal_data = TerminalData::new( + tab.scope, + self.workspace.clone(), + None, + self.common.clone(), + ); + let i = terminal_data.scope.create_rw_signal(0); + tab.terminals.update(|terminals| { + terminals.insert(index + 1, (i, terminal_data)); + }); + } + } + + pub fn split_next(&self, term_id: TermId) { + if let Some((_, tab, index, _)) = self.get_terminal_in_tab(&term_id) { + let max = tab.terminals.with_untracked(|t| t.len() - 1); + let new_index = (index + 1).min(max); + if new_index != index { + tab.active.set(new_index); + self.update_debug_active_term(); + } + } + } + + pub fn split_previous(&self, term_id: TermId) { + if let Some((_, tab, index, _)) = self.get_terminal_in_tab(&term_id) { + let new_index = index.saturating_sub(1); + if new_index != index { + tab.active.set(new_index); + self.update_debug_active_term(); + } + } + } + + pub fn split_exchange(&self, term_id: TermId) { + if let Some((_, tab, index, _)) = self.get_terminal_in_tab(&term_id) { + let max = tab.terminals.with_untracked(|t| t.len() - 1); + if index < max { + tab.terminals.update(|terminals| { + terminals.swap(index, index + 1); + }); + self.update_debug_active_term(); + } + } + } + + pub fn close_terminal(&self, term_id: &TermId) { + if let Some((_, tab, index, _)) = self.get_terminal_in_tab(term_id) { + let active = tab.active.get_untracked(); + let len = tab + .terminals + .try_update(|terminals| { + terminals.remove(index); + terminals.len() + }) + .unwrap(); + if len == 0 { + self.close_tab(Some(tab.terminal_tab_id)); + } else { + let new_active = active.min(len.saturating_sub(1)); + if new_active != active { + tab.active.set(new_active); + self.update_debug_active_term(); + } + } + } + } + + pub fn launch_failed(&self, term_id: &TermId, error: &str) { + if let Some(terminal) = self.get_terminal(term_id) { + terminal.launch_error.set(Some(error.to_string())); + } + } + + pub fn terminal_stopped(&self, term_id: &TermId, exit_code: Option) { + if let Some(terminal) = self.get_terminal(term_id) { + if terminal.run_debug.with_untracked(|r| r.is_some()) { + let was_prelaunch = terminal + .run_debug + .try_update(|run_debug| { + if let Some(run_debug) = run_debug.as_mut() { + if run_debug.is_prelaunch + && run_debug.config.prelaunch.is_some() + { + run_debug.is_prelaunch = false; + if run_debug.mode == RunDebugMode::Debug { + // set it to be stopped so that the dap can pick the same terminal session + run_debug.stopped = true; + } + Some(true) + } else { + run_debug.stopped = true; + Some(false) + } + } else { + None + } + }) + .unwrap(); + let exit_code = exit_code.unwrap_or(0); + if was_prelaunch == Some(true) && exit_code == 0 { + let run_debug = terminal.run_debug.get_untracked(); + if let Some(run_debug) = run_debug { + if run_debug.mode == RunDebugMode::Debug { + self.common.proxy.dap_start( + run_debug.config, + self.debug.source_breakpoints(), + ) + } else { + terminal.new_process(Some(run_debug)); + } + } + } + } else { + self.close_terminal(term_id); + } + } + } + + pub fn get_stopped_run_debug_terminal( + &self, + mode: &RunDebugMode, + config: &RunDebugConfig, + ) -> Option { + self.tab_info.with_untracked(|info| { + for (_, tab) in &info.tabs { + let terminal = tab.terminals.with_untracked(|terminals| { + for (_, terminal) in terminals { + if let Some(run_debug) = + terminal.run_debug.get_untracked().as_ref() + { + if run_debug.stopped && &run_debug.mode == mode { + match run_debug.mode { + RunDebugMode::Run => { + if run_debug.config.name == config.name { + return Some(terminal.clone()); + } + } + RunDebugMode::Debug => { + if run_debug.config.dap_id == config.dap_id { + return Some(terminal.clone()); + } + } + } + } + } + } + None + }); + if let Some(terminal) = terminal { + return Some(terminal); + } + } + None + }) + } + + /// Return whether it is in debug mode. + pub fn restart_run_debug(&self, term_id: TermId) -> Option { + let (_, terminal_tab, index, terminal) = + self.get_terminal_in_tab(&term_id)?; + let mut run_debug = terminal.run_debug.get_untracked()?; + if run_debug.config.config_source.from_palette() { + if let Some(new_config) = + self.get_run_config_by_name(&run_debug.config.name) + { + run_debug.config = new_config; + } + } + let mut is_debug = false; + let new_term_id = match run_debug.mode { + RunDebugMode::Run => { + self.common.proxy.terminal_close(term_id); + let mut run_debug = run_debug; + run_debug.stopped = false; + run_debug.is_prelaunch = true; + let new_terminal = TerminalData::new_run_debug( + terminal_tab.scope, + self.workspace.clone(), + Some(run_debug), + None, + self.common.clone(), + ); + let new_term_id = new_terminal.term_id; + terminal_tab.terminals.update(|terminals| { + terminals[index] = + (new_terminal.scope.create_rw_signal(0), new_terminal); + }); + self.debug.active_term.set(Some(new_term_id)); + new_term_id + } + RunDebugMode::Debug => { + is_debug = true; + let dap_id = + terminal.run_debug.get_untracked().as_ref()?.config.dap_id; + let daps = self.debug.daps.get_untracked(); + let dap = daps.get(&dap_id)?; + self.common + .proxy + .dap_restart(dap.dap_id, self.debug.source_breakpoints()); + term_id + } + }; + + self.focus_terminal(new_term_id); + + Some(is_debug) + } + + fn get_run_config_by_name(&self, name: &str) -> Option { + if let Some(workspace) = self.common.workspace.path.as_deref() { + let run_toml = workspace.join(".lapce").join("run.toml"); + let (doc, new_doc) = self.main_split.get_doc(run_toml.clone(), None); + if !new_doc { + let content = doc.buffer.with_untracked(|b| b.to_string()); + match toml::from_str::(&content) { + Ok(configs) => { + return configs.configs.into_iter().find(|x| x.name == name); + } + Err(err) => { + // todo show message window + tracing::error!("deser fail {:?}", err); + } + } + } + } + None + } + + pub fn focus_terminal(&self, term_id: TermId) { + if let Some((tab_index, terminal_tab, index, _terminal)) = + self.get_terminal_in_tab(&term_id) + { + self.tab_info.update(|info| { + info.active = tab_index; + }); + terminal_tab.active.set(index); + self.common.focus.set(Focus::Panel(PanelKind::Terminal)); + + self.update_debug_active_term(); + } + } + + pub fn update_debug_active_term(&self) { + let tab = self.active_tab(false); + let terminal = tab.and_then(|tab| tab.active_terminal(false)); + if let Some(terminal) = terminal { + let term_id = terminal.term_id; + let is_run_debug = + terminal.run_debug.with_untracked(|run| run.is_some()); + let current_active = self.debug.active_term.get_untracked(); + if is_run_debug { + if current_active != Some(term_id) { + self.debug.active_term.set(Some(term_id)); + } + } else if let Some(active) = current_active { + if self.get_terminal(&active).is_none() { + self.debug.active_term.set(None); + } + } + } else { + self.debug.active_term.set(None); + } + } + + pub fn stop_run_debug(&self, term_id: TermId) -> Option<()> { + let terminal = self.get_terminal(&term_id)?; + let run_debug = terminal.run_debug.get_untracked()?; + + match run_debug.mode { + RunDebugMode::Run => { + self.common.proxy.terminal_close(term_id); + } + RunDebugMode::Debug => { + let dap_id = run_debug.config.dap_id; + let daps = self.debug.daps.get_untracked(); + let dap = daps.get(&dap_id)?; + self.common.proxy.dap_stop(dap.dap_id); + } + } + + self.focus_terminal(term_id); + Some(()) + } + + pub fn run_debug_process( + &self, + tracked: bool, + ) -> Vec<(TermId, RunDebugProcess)> { + let mut processes = Vec::new(); + if tracked { + self.tab_info.with(|info| { + for (_, tab) in &info.tabs { + tab.terminals.with(|terminals| { + for (_, terminal) in terminals { + if let Some(run_debug) = terminal.run_debug.get() { + processes.push((terminal.term_id, run_debug)); + } + } + }) + } + }); + } else { + self.tab_info.with_untracked(|info| { + for (_, tab) in &info.tabs { + tab.terminals.with_untracked(|terminals| { + for (_, terminal) in terminals { + if let Some(run_debug) = terminal.run_debug.get() { + processes.push((terminal.term_id, run_debug)); + } + } + }) + } + }); + } + processes.sort_by_key(|(_, process)| process.created); + processes + } + + pub fn set_process_id(&self, term_id: &TermId, process_id: Option) { + if let Some(terminal) = self.get_terminal(term_id) { + terminal.run_debug.with_untracked(|run_debug| { + if let Some(run_debug) = run_debug.as_ref() { + if run_debug.config.debug_command.is_some() { + let dap_id = run_debug.config.dap_id; + self.common + .proxy + .dap_process_id(dap_id, process_id, *term_id); + } + } + }); + } + } + + pub fn dap_continued(&self, dap_id: &DapId) { + let dap = self + .debug + .daps + .with_untracked(|daps| daps.get(dap_id).cloned()); + if let Some(dap) = dap { + dap.thread_id.set(None); + dap.stopped.set(false); + } + } + + pub fn dap_stopped( + &self, + dap_id: &DapId, + stopped: &Stopped, + stack_frames: &HashMap>, + variables: &[(dap_types::Scope, Vec)], + ) { + let dap = self + .debug + .daps + .with_untracked(|daps| daps.get(dap_id).cloned()); + if let Some(dap) = dap { + dap.stopped(self.cx, stopped, stack_frames, variables); + } + floem::action::focus_window(); + } + + pub fn dap_continue(&self, term_id: TermId) -> Option<()> { + let terminal = self.get_terminal(&term_id)?; + let dap_id = terminal + .run_debug + .with_untracked(|r| r.as_ref().map(|r| r.config.dap_id))?; + let thread_id = self.debug.daps.with_untracked(|daps| { + daps.get(&dap_id) + .and_then(|dap| dap.thread_id.get_untracked()) + }); + let thread_id = thread_id.unwrap_or_default(); + self.common.proxy.dap_continue(dap_id, thread_id); + Some(()) + } + + pub fn dap_pause(&self, term_id: TermId) -> Option<()> { + let terminal = self.get_terminal(&term_id)?; + let dap_id = terminal + .run_debug + .with_untracked(|r| r.as_ref().map(|r| r.config.dap_id))?; + let thread_id = self.debug.daps.with_untracked(|daps| { + daps.get(&dap_id) + .and_then(|dap| dap.thread_id.get_untracked()) + }); + let thread_id = thread_id.unwrap_or_default(); + self.common.proxy.dap_pause(dap_id, thread_id); + Some(()) + } + + pub fn dap_step_over(&self, term_id: TermId) -> Option<()> { + let terminal = self.get_terminal(&term_id)?; + let dap_id = terminal + .run_debug + .with_untracked(|r| r.as_ref().map(|r| r.config.dap_id))?; + let thread_id = self.debug.daps.with_untracked(|daps| { + daps.get(&dap_id) + .and_then(|dap| dap.thread_id.get_untracked()) + }); + let thread_id = thread_id.unwrap_or_default(); + self.common.proxy.dap_step_over(dap_id, thread_id); + Some(()) + } + + pub fn dap_step_into(&self, term_id: TermId) -> Option<()> { + let terminal = self.get_terminal(&term_id)?; + let dap_id = terminal + .run_debug + .with_untracked(|r| r.as_ref().map(|r| r.config.dap_id))?; + let thread_id = self.debug.daps.with_untracked(|daps| { + daps.get(&dap_id) + .and_then(|dap| dap.thread_id.get_untracked()) + }); + let thread_id = thread_id.unwrap_or_default(); + self.common.proxy.dap_step_into(dap_id, thread_id); + Some(()) + } + + pub fn dap_step_out(&self, term_id: TermId) -> Option<()> { + let terminal = self.get_terminal(&term_id)?; + let dap_id = terminal + .run_debug + .with_untracked(|r| r.as_ref().map(|r| r.config.dap_id))?; + let thread_id = self.debug.daps.with_untracked(|daps| { + daps.get(&dap_id) + .and_then(|dap| dap.thread_id.get_untracked()) + }); + let thread_id = thread_id.unwrap_or_default(); + self.common.proxy.dap_step_out(dap_id, thread_id); + Some(()) + } + + pub fn get_active_dap(&self, tracked: bool) -> Option { + let active_term = if tracked { + self.debug.active_term.get()? + } else { + self.debug.active_term.get_untracked()? + }; + self.get_dap(active_term, tracked) + } + + pub fn get_dap(&self, term_id: TermId, tracked: bool) -> Option { + let terminal = self.get_terminal(&term_id)?; + let dap_id = if tracked { + terminal + .run_debug + .with(|r| r.as_ref().map(|r| r.config.dap_id))? + } else { + terminal + .run_debug + .with_untracked(|r| r.as_ref().map(|r| r.config.dap_id))? + }; + + if tracked { + self.debug.daps.with(|daps| daps.get(&dap_id).cloned()) + } else { + self.debug + .daps + .with_untracked(|daps| daps.get(&dap_id).cloned()) + } + } + + pub fn dap_frame_scopes(&self, dap_id: DapId, frame_id: usize) { + if let Some(dap) = self.debug.daps.get_untracked().get(&dap_id) { + let variables = dap.variables; + let send = create_ext_action(self.common.scope, move |result| { + if let Ok(ProxyResponse::DapGetScopesResponse { scopes }) = result { + variables.update(|dap_var| { + dap_var.children = scopes + .iter() + .enumerate() + .map(|(i, (scope, vars))| DapVariable { + item: ScopeOrVar::Scope(scope.to_owned()), + parent: Vec::new(), + expanded: i == 0, + read: i == 0, + children: vars + .iter() + .map(|var| DapVariable { + item: ScopeOrVar::Var(var.to_owned()), + parent: vec![scope.variables_reference], + expanded: false, + read: false, + children: Vec::new(), + children_expanded_count: 0, + }) + .collect(), + children_expanded_count: if i == 0 { + vars.len() + } else { + 0 + }, + }) + .collect(); + dap_var.children_expanded_count = dap_var + .children + .iter() + .map(|v| v.children_expanded_count + 1) + .sum::(); + }); + } + }); + + self.common + .proxy + .dap_get_scopes(dap_id, frame_id, move |result| { + send(result); + }); + } + } +} diff --git a/lapce-app/src/terminal/raw.rs b/lapce-app/src/terminal/raw.rs new file mode 100644 index 0000000..f37db8d --- /dev/null +++ b/lapce-app/src/terminal/raw.rs @@ -0,0 +1,149 @@ +use std::sync::mpsc::Sender; + +use alacritty_terminal::{ + Term, + event::EventListener, + grid::Dimensions, + index::{Column, Direction, Line, Point}, + term::{ + cell::{Flags, LineLength}, + search::{Match, RegexIter, RegexSearch}, + test::TermSize, + }, + vte::ansi, +}; +use lapce_rpc::{proxy::ProxyRpcHandler, terminal::TermId}; + +use super::event::TermNotification; + +pub struct EventProxy { + term_id: TermId, + proxy: ProxyRpcHandler, + term_notification_tx: Sender, +} + +impl EventListener for EventProxy { + fn send_event(&self, event: alacritty_terminal::event::Event) { + match event { + alacritty_terminal::event::Event::PtyWrite(s) => { + self.proxy.terminal_write(self.term_id, s); + } + alacritty_terminal::event::Event::MouseCursorDirty => { + if let Err(err) = self + .term_notification_tx + .send(TermNotification::RequestPaint) + { + tracing::error!("{:?}", err); + } + } + alacritty_terminal::event::Event::Title(s) => { + if let Err(err) = + self.term_notification_tx.send(TermNotification::SetTitle { + term_id: self.term_id, + title: s, + }) + { + tracing::error!("{:?}", err); + } + } + _ => (), + } + } +} + +pub struct RawTerminal { + pub parser: ansi::Processor, + pub term: Term, + pub scroll_delta: f64, +} + +impl RawTerminal { + pub fn new( + term_id: TermId, + proxy: ProxyRpcHandler, + term_notification_tx: Sender, + ) -> Self { + let config = alacritty_terminal::term::Config { + semantic_escape_chars: ",│`|\"' ()[]{}<>\t".to_string(), + ..Default::default() + }; + let event_proxy = EventProxy { + term_id, + proxy, + term_notification_tx, + }; + + let size = TermSize::new(50, 30); + let term = Term::new(config, &size, event_proxy); + let parser = ansi::Processor::new(); + + Self { + parser, + term, + scroll_delta: 0.0, + } + } + + pub fn update_content(&mut self, content: Vec) { + for byte in content { + self.parser.advance(&mut self.term, byte); + } + } + + pub fn output(&self, line_num: usize) -> Vec { + let grid = self.term.grid(); + let mut lines = Vec::with_capacity(5); + let mut rows = Vec::new(); + for line in (grid.topmost_line().0..=grid.bottommost_line().0) + .map(Line) + .rev() + { + let row_cell = &grid[line]; + if row_cell[Column(row_cell.len() - 1)] + .flags + .contains(Flags::WRAPLINE) + { + rows.push(row_cell); + } else { + if !rows.is_empty() { + let mut new_line = Vec::new(); + std::mem::swap(&mut rows, &mut new_line); + let line_str: String = new_line + .into_iter() + .rev() + .flat_map(|x| { + x.into_iter().take(x.line_length().0).map(|x| x.c) + }) + .collect(); + lines.push(line_str); + if lines.len() >= line_num { + break; + } + } + rows.push(row_cell); + } + } + for line in &lines { + tracing::info!("{}", line); + } + lines + } +} + +pub fn visible_regex_match_iter<'a, EventProxy>( + term: &'a Term, + regex: &'a mut RegexSearch, +) -> impl Iterator + 'a { + let viewport_start = Line(-(term.grid().display_offset() as i32)); + let viewport_end = viewport_start + term.bottommost_line(); + let mut start = term.line_search_left(Point::new(viewport_start, Column(0))); + let mut end = term.line_search_right(Point::new(viewport_end, Column(0))); + start.line = start.line.max(viewport_start - MAX_SEARCH_LINES); + end.line = end.line.min(viewport_end + MAX_SEARCH_LINES); + + RegexIter::new(start, end, Direction::Right, term, regex) + .skip_while(move |rm| rm.end().line < viewport_start) + .take_while(move |rm| rm.start().line <= viewport_end) +} +/// todo:should be improved +pub const MAX_SEARCH_LINES: usize = 100; diff --git a/lapce-app/src/terminal/tab.rs b/lapce-app/src/terminal/tab.rs new file mode 100644 index 0000000..32214b7 --- /dev/null +++ b/lapce-app/src/terminal/tab.rs @@ -0,0 +1,68 @@ +use std::{rc::Rc, sync::Arc}; + +use floem::reactive::{RwSignal, Scope, SignalGet, SignalWith}; +use lapce_rpc::terminal::TerminalProfile; + +use super::data::TerminalData; +use crate::{ + debug::RunDebugProcess, id::TerminalTabId, window_tab::CommonData, + workspace::LapceWorkspace, +}; + +#[derive(Clone)] +pub struct TerminalTabData { + pub scope: Scope, + pub terminal_tab_id: TerminalTabId, + pub active: RwSignal, + pub terminals: RwSignal, TerminalData)>>, +} + +impl TerminalTabData { + pub fn new( + workspace: Arc, + profile: Option, + common: Rc, + ) -> Self { + TerminalTabData::new_run_debug(workspace, None, profile, common) + } + + /// Create the information for a terminal tab, which can contain multiple terminals. + pub fn new_run_debug( + workspace: Arc, + run_debug: Option, + profile: Option, + common: Rc, + ) -> Self { + let cx = common.scope.create_child(); + let terminal_data = + TerminalData::new_run_debug(cx, workspace, run_debug, profile, common); + let terminals = im::vector![(cx.create_rw_signal(0), terminal_data)]; + let terminals = cx.create_rw_signal(terminals); + let active = cx.create_rw_signal(0); + let terminal_tab_id = TerminalTabId::next(); + Self { + scope: cx, + terminal_tab_id, + active, + terminals, + } + } + + pub fn active_terminal(&self, tracked: bool) -> Option { + let active = if tracked { + self.active.get() + } else { + self.active.get_untracked() + }; + + if tracked { + self.terminals + .with(|t| t.get(active).or_else(|| t.last()).cloned()) + .map(|(_, t)| t) + } else { + self.terminals + .with_untracked(|t| t.get(active).or_else(|| t.last()).cloned()) + .map(|(_, t)| t) + } + } +} diff --git a/lapce-app/src/terminal/view.rs b/lapce-app/src/terminal/view.rs new file mode 100644 index 0000000..09b1310 --- /dev/null +++ b/lapce-app/src/terminal/view.rs @@ -0,0 +1,799 @@ +use std::{sync::Arc, time::SystemTime}; + +use alacritty_terminal::{ + grid::Dimensions, + index::Side, + selection::{Selection, SelectionType}, + term::{RenderableContent, cell::Flags, test::TermSize}, +}; +use floem::{ + Renderer, View, ViewId, + context::{EventCx, PaintCx}, + event::{Event, EventPropagation}, + kurbo::Stroke, + peniko::{ + Color, + kurbo::{Point, Rect, Size}, + }, + pointer::PointerInputEvent, + prelude::SignalTrack, + reactive::{ReadSignal, RwSignal, SignalGet, SignalWith, create_effect}, + text::{Attrs, AttrsList, FamilyOwned, TextLayout, Weight}, + views::editor::{core::register::Clipboard, text::SystemClipboard}, +}; +use lapce_core::mode::Mode; +use lapce_rpc::{proxy::ProxyRpcHandler, terminal::TermId}; +use lsp_types::Position; +use parking_lot::RwLock; +use regex::Regex; +use unicode_width::UnicodeWidthChar; + +use super::{panel::TerminalPanelData, raw::RawTerminal}; +use crate::{ + command::InternalCommand, + config::{LapceConfig, color::LapceColor}, + debug::RunDebugProcess, + editor::location::{EditorLocation, EditorPosition}, + listener::Listener, + panel::kind::PanelKind, + window_tab::Focus, + workspace::LapceWorkspace, +}; + +/// Threshold used for double_click/triple_click. +const CLICK_THRESHOLD: u128 = 400; + +enum TerminalViewState { + Config, + Focus(bool), + Raw(Arc>), +} + +struct TerminalLineContent<'a> { + y: f64, + bg: Vec<(usize, usize, Color)>, + underline: Vec<(usize, usize, Color, f64)>, + chars: Vec<(char, Attrs<'a>, f64, f64)>, + cursor: Option<(char, f64)>, +} + +pub struct TerminalView { + id: ViewId, + term_id: TermId, + raw: Arc>, + mode: ReadSignal, + size: Size, + is_focused: bool, + config: ReadSignal>, + run_config: ReadSignal>, + proxy: ProxyRpcHandler, + launch_error: RwSignal>, + internal_command: Listener, + workspace: Arc, + hyper_regs: Vec, + previous_mouse_action: MouseAction, + current_mouse_action: MouseAction, +} + +#[allow(clippy::too_many_arguments)] +pub fn terminal_view( + term_id: TermId, + raw: ReadSignal>>, + mode: ReadSignal, + run_config: ReadSignal>, + terminal_panel_data: TerminalPanelData, + launch_error: RwSignal>, + internal_command: Listener, + workspace: Arc, +) -> TerminalView { + let id = ViewId::new(); + + create_effect(move |_| { + let raw = raw.get(); + id.update_state(TerminalViewState::Raw(raw)); + }); + + create_effect(move |_| { + launch_error.track(); + id.request_paint(); + }); + + let config = terminal_panel_data.common.config; + create_effect(move |_| { + config.with(|_c| {}); + id.update_state(TerminalViewState::Config); + }); + + let proxy = terminal_panel_data.common.proxy.clone(); + + create_effect(move |last| { + let focus = terminal_panel_data.common.focus.get(); + + let mut is_focused = false; + if let Focus::Panel(PanelKind::Terminal) = focus { + let tab = terminal_panel_data.active_tab(true); + if let Some(tab) = tab { + let terminal = tab.active_terminal(true); + is_focused = terminal.map(|t| t.term_id) == Some(term_id); + } + } + + if last != Some(is_focused) { + id.update_state(TerminalViewState::Focus(is_focused)); + } + + is_focused + }); + + // for rust + let reg = regex::Regex::new("[\\w\\\\/-]+\\.(rs)?(toml)?:\\d+(:\\d+)?").unwrap(); + + TerminalView { + id, + term_id, + raw: raw.get_untracked(), + mode, + config, + proxy, + run_config, + size: Size::ZERO, + is_focused: false, + launch_error, + internal_command, + workspace, + hyper_regs: vec![reg], + previous_mouse_action: Default::default(), + current_mouse_action: Default::default(), + } +} + +impl TerminalView { + fn char_size(&self) -> Size { + let config = self.config.get_untracked(); + let font_family = config.terminal_font_family(); + let font_size = config.terminal_font_size(); + let family: Vec = + FamilyOwned::parse_list(font_family).collect(); + let attrs = Attrs::new().family(&family).font_size(font_size as f32); + let attrs_list = AttrsList::new(attrs); + let mut text_layout = TextLayout::new(); + text_layout.set_text("W", attrs_list, None); + text_layout.size() + } + + fn terminal_size(&self) -> (usize, usize) { + let config = self.config.get_untracked(); + let line_height = config.terminal_line_height() as f64; + let char_width = self.char_size().width; + let width = (self.size.width / char_width).floor() as usize; + let height = (self.size.height / line_height).floor() as usize; + (width.max(1), height.max(1)) + } + + fn click(&self, pos: Point) -> Option<()> { + let raw = self.raw.read(); + let position = self.get_terminal_point(pos); + let start_point = raw.term.semantic_search_left(position); + let end_point = raw.term.semantic_search_right(position); + let mut selection = + Selection::new(SelectionType::Simple, start_point, Side::Left); + selection.update(end_point, Side::Right); + selection.include_all(); + if let Some(selection) = selection.to_range(&raw.term) { + let content = raw.term.bounds_to_string(selection.start, selection.end); + if let Some(match_str) = + self.hyper_regs.iter().find_map(|x| x.find(&content)) + { + let hyperlink = match_str.as_str(); + let content: Vec<&str> = hyperlink.split(':').collect(); + let (file, line, col) = ( + content.first()?, + content.get(1).and_then(|x: &&str| x.parse::().ok())?, + content + .get(2) + .and_then(|x: &&str| x.parse::().ok()) + .unwrap_or(0), + ); + let parent_path = self.workspace.path.as_ref()?; + self.internal_command.send(InternalCommand::JumpToLocation { + location: EditorLocation { + path: parent_path.join(file), + position: Some(EditorPosition::Position(Position::new( + line.saturating_sub(1), + col.saturating_sub(1), + ))), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }, + }); + return Some(()); + } + } + None + } + + fn update_mouse_action_by_down(&mut self, mouse: &PointerInputEvent) { + let mut next_action = MouseAction::None; + match self.current_mouse_action { + MouseAction::None + | MouseAction::LeftDouble { .. } + | MouseAction::LeftSelect { .. } + | MouseAction::RightOnce { .. } => { + if mouse.button.is_primary() { + next_action = MouseAction::LeftDown { pos: mouse.pos }; + } else if mouse.button.is_secondary() { + next_action = MouseAction::RightDown { pos: mouse.pos }; + } + } + MouseAction::LeftOnce { pos, time } => { + let during_mills = + time.elapsed().map(|x| x.as_millis()).unwrap_or(u128::MAX); + match ( + mouse.button.is_primary(), + mouse.pos == pos, + during_mills < CLICK_THRESHOLD, + ) { + (true, true, true) => { + next_action = MouseAction::LeftOnceAndDown { pos, time }; + } + (true, _, _) => { + next_action = MouseAction::LeftDown { pos: mouse.pos }; + } + _ => {} + } + } + MouseAction::LeftOnceAndDown { .. } + | MouseAction::LeftDown { .. } + | MouseAction::RightDown { .. } => {} + } + self.current_mouse_action = next_action; + } + + fn update_mouse_action_by_up(&mut self, mouse: &PointerInputEvent) { + let mut next_action = MouseAction::None; + match self.current_mouse_action { + MouseAction::None => {} + MouseAction::LeftDown { pos } => { + match (mouse.button.is_primary(), mouse.pos == pos) { + (true, true) => { + next_action = MouseAction::LeftOnce { + pos, + time: SystemTime::now(), + } + } + (true, false) => { + next_action = MouseAction::LeftSelect { + start_pos: pos, + end_pos: mouse.pos, + }; + } + _ => {} + } + } + MouseAction::LeftOnce { .. } => {} + MouseAction::LeftSelect { .. } => {} + MouseAction::LeftOnceAndDown { pos, time } => { + let during_mills = + time.elapsed().map(|x| x.as_millis()).unwrap_or(u128::MAX); + match ( + mouse.button.is_primary(), + mouse.pos == pos, + during_mills < CLICK_THRESHOLD, + ) { + (true, true, true) => { + next_action = MouseAction::LeftDouble { pos }; + } + (true, true, false) => { + next_action = MouseAction::LeftOnce { + pos: mouse.pos, + time: SystemTime::now(), + }; + } + (true, false, _) => { + next_action = MouseAction::LeftSelect { + start_pos: pos, + end_pos: mouse.pos, + }; + } + _ => {} + } + } + MouseAction::LeftDouble { .. } => {} + MouseAction::RightDown { pos } => { + if mouse.button.is_secondary() && mouse.pos == pos { + next_action = MouseAction::RightOnce { pos }; + } + } + MouseAction::RightOnce { .. } => {} + } + self.previous_mouse_action = self.current_mouse_action; + self.current_mouse_action = next_action; + } + + fn get_terminal_point(&self, pos: Point) -> alacritty_terminal::index::Point { + let raw = self.raw.read(); + let col = (pos.x / self.char_size().width) as usize; + let line_no = pos.y as i32 + / (self.config.get().terminal_line_height() as i32) + - raw.term.grid().display_offset() as i32; + alacritty_terminal::index::Point::new( + alacritty_terminal::index::Line(line_no), + alacritty_terminal::index::Column(col), + ) + } + + fn paint_content( + &self, + cx: &mut PaintCx, + content: RenderableContent, + line_height: f64, + char_size: Size, + config: &LapceConfig, + ) { + let term_bg = config.color(LapceColor::TERMINAL_BACKGROUND); + + let font_size = config.terminal_font_size(); + let font_family = config.terminal_font_family(); + let family: Vec = + FamilyOwned::parse_list(font_family).collect(); + let attrs = Attrs::new().family(&family).font_size(font_size as f32); + + let char_width = char_size.width; + + let cursor_point = &content.cursor.point; + + let mut line_content = TerminalLineContent { + y: 0.0, + bg: Vec::new(), + underline: Vec::new(), + chars: Vec::new(), + cursor: None, + }; + for item in content.display_iter { + let point = item.point; + let cell = item.cell; + let inverse = cell.flags.contains(Flags::INVERSE); + + let x = point.column.0 as f64 * char_width; + let y = + (point.line.0 as f64 + content.display_offset as f64) * line_height; + let char_y = y + (line_height - char_size.height) / 2.0; + if y != line_content.y { + self.paint_line_content( + cx, + &line_content, + line_height, + char_width, + config, + ); + line_content.y = y; + line_content.bg.clear(); + line_content.underline.clear(); + line_content.chars.clear(); + line_content.cursor = None; + } + + let mut bg = config.terminal_get_color(&cell.bg, content.colors); + let mut fg = config.terminal_get_color(&cell.fg, content.colors); + if cell.flags.contains(Flags::DIM) + || cell.flags.contains(Flags::DIM_BOLD) + { + fg = fg.multiply_alpha(0.66); + } + + if inverse { + std::mem::swap(&mut fg, &mut bg); + } + + if term_bg != bg { + let mut extend = false; + if let Some((_, end, color)) = line_content.bg.last_mut() { + if color == &bg && *end == point.column.0 { + *end += 1; + extend = true; + } + } + if !extend { + line_content + .bg + .push((point.column.0, point.column.0 + 1, bg)); + } + } + + if cursor_point == &point { + line_content.cursor = Some((cell.c, x)); + } + + let bold = cell.flags.contains(Flags::BOLD) + || cell.flags.contains(Flags::DIM_BOLD); + + if &point == cursor_point && self.is_focused { + fg = term_bg; + } + + if cell.c != ' ' && cell.c != '\t' { + let mut attrs = attrs.clone().color(fg); + if bold { + attrs = attrs.weight(Weight::BOLD); + } + line_content.chars.push((cell.c, attrs, x, char_y)); + } + } + self.paint_line_content(cx, &line_content, line_height, char_width, config); + } + + fn paint_line_content( + &self, + cx: &mut PaintCx, + line_content: &TerminalLineContent, + line_height: f64, + char_width: f64, + config: &LapceConfig, + ) { + for (start, end, bg) in &line_content.bg { + let rect = Size::new( + char_width * (end.saturating_sub(*start) as f64), + line_height, + ) + .to_rect() + .with_origin(Point::new(*start as f64 * char_width, line_content.y)); + cx.fill(&rect, bg, 0.0); + } + + for (start, end, fg, y) in &line_content.underline { + let rect = + Size::new(char_width * (end.saturating_sub(*start) as f64), 1.0) + .to_rect() + .with_origin(Point::new(*start as f64 * char_width, y - 1.0)); + cx.fill(&rect, fg, 0.0); + } + + if let Some((c, x)) = line_content.cursor { + let rect = + Size::new(char_width * c.width().unwrap_or(1) as f64, line_height) + .to_rect() + .with_origin(Point::new(x, line_content.y)); + let mode = self.mode.get_untracked(); + let cursor_color = if mode == Mode::Terminal { + if self.run_config.with_untracked(|run_config| { + run_config.as_ref().map(|r| r.stopped).unwrap_or(false) + }) { + config.color(LapceColor::LAPCE_ERROR) + } else { + config.color(LapceColor::TERMINAL_CURSOR) + } + } else { + config.color(LapceColor::EDITOR_CARET) + }; + if self.is_focused { + cx.fill(&rect, cursor_color, 0.0); + } else { + cx.stroke(&rect, cursor_color, &Stroke::new(1.0)); + } + } + + for (char, attr, x, y) in &line_content.chars { + let mut text_layout = TextLayout::new(); + text_layout.set_text( + &char.to_string(), + AttrsList::new(attr.clone()), + None, + ); + cx.draw_text(&text_layout, Point::new(*x, *y)); + } + } +} + +impl Drop for TerminalView { + fn drop(&mut self) { + self.proxy.terminal_close(self.term_id); + } +} + +impl View for TerminalView { + fn id(&self) -> ViewId { + self.id + } + + fn event_before_children( + &mut self, + _cx: &mut EventCx, + event: &Event, + ) -> EventPropagation { + match event { + Event::PointerDown(e) => { + self.update_mouse_action_by_down(e); + } + Event::PointerUp(e) => { + self.update_mouse_action_by_up(e); + let mut clear_selection = false; + match self.current_mouse_action { + MouseAction::LeftOnce { pos, .. } => { + clear_selection = true; + if e.modifiers.control() && self.click(pos).is_some() { + return EventPropagation::Stop; + } + } + MouseAction::LeftSelect { start_pos, end_pos } => { + let mut selection = Selection::new( + SelectionType::Simple, + self.get_terminal_point(start_pos), + Side::Left, + ); + selection + .update(self.get_terminal_point(end_pos), Side::Right); + selection.include_all(); + self.raw.write().term.selection = Some(selection); + _cx.app_state_mut().request_paint(self.id); + } + MouseAction::LeftDouble { pos } => { + let position = self.get_terminal_point(pos); + let mut raw = self.raw.write(); + let start_point = raw.term.semantic_search_left(position); + let end_point = raw.term.semantic_search_right(position); + + let mut selection = Selection::new( + SelectionType::Simple, + start_point, + Side::Left, + ); + selection.update(end_point, Side::Right); + selection.include_all(); + raw.term.selection = Some(selection); + _cx.app_state_mut().request_paint(self.id); + } + MouseAction::RightOnce { pos } => { + let position = self.get_terminal_point(pos); + let raw = self.raw.read(); + if let Some(selection) = &raw + .term + .selection + .as_ref() + .and_then(|x| x.to_range(&raw.term)) + { + if selection.contains(position) { + let mut clipboard = SystemClipboard::new(); + let content = raw.term.bounds_to_string( + selection.start, + selection.end, + ); + if !content.is_empty() { + clipboard.put_string(content); + } + } + clear_selection = true; + } + } + _ => { + clear_selection = true; + } + } + if clear_selection { + self.raw.write().term.selection = None; + _cx.app_state_mut().request_paint(self.id); + } + } + _ => {} + } + EventPropagation::Continue + } + + fn update( + &mut self, + cx: &mut floem::context::UpdateCx, + state: Box, + ) { + if let Ok(state) = state.downcast() { + match *state { + TerminalViewState::Config => {} + TerminalViewState::Focus(is_focused) => { + self.is_focused = is_focused; + } + TerminalViewState::Raw(raw) => { + self.raw = raw; + } + } + cx.app_state_mut().request_paint(self.id); + } + } + + fn layout( + &mut self, + cx: &mut floem::context::LayoutCx, + ) -> floem::taffy::prelude::NodeId { + cx.layout_node(self.id, false, |_cx| Vec::new()) + } + + fn compute_layout( + &mut self, + _cx: &mut floem::context::ComputeLayoutCx, + ) -> Option { + let layout = self.id.get_layout().unwrap_or_default(); + let size = layout.size; + let size = Size::new(size.width as f64, size.height as f64); + if size.is_zero_area() { + return None; + } + if size != self.size { + self.size = size; + let (width, height) = self.terminal_size(); + let term_size = TermSize::new(width, height); + self.raw.write().term.resize(term_size); + self.proxy.terminal_resize(self.term_id, width, height); + } + + None + } + + fn paint(&mut self, cx: &mut floem::context::PaintCx) { + let config = self.config.get_untracked(); + let mode = self.mode.get_untracked(); + let line_height = config.terminal_line_height() as f64; + let font_family = config.terminal_font_family(); + let font_size = config.terminal_font_size(); + let char_size = self.char_size(); + let char_width = char_size.width; + + let family: Vec = + FamilyOwned::parse_list(font_family).collect(); + let attrs = Attrs::new().family(&family).font_size(font_size as f32); + + if let Some(error) = self.launch_error.get() { + let mut text_layout = TextLayout::new(); + text_layout.set_text( + &format!("Terminal failed to launch. Error: {error}"), + AttrsList::new( + attrs.color(config.color(LapceColor::EDITOR_FOREGROUND)), + ), + None, + ); + cx.draw_text( + &text_layout, + Point::new(6.0, 0.0 + (line_height - char_size.height) / 2.0), + ); + return; + } + + let raw = self.raw.read(); + let term = &raw.term; + let content = term.renderable_content(); + + // let mut search = RegexSearch::new("[\\w\\\\?]+\\.rs:\\d+:\\d+").unwrap(); + // self.hyper_matches = visible_regex_match_iter(term, &mut search).collect(); + + if let Some(selection) = content.selection.as_ref() { + let start_line = selection.start.line.0 + content.display_offset as i32; + let start_line = if start_line < 0 { + 0 + } else { + start_line as usize + }; + let start_col = selection.start.column.0; + + let end_line = selection.end.line.0 + content.display_offset as i32; + let end_line = if end_line < 0 { 0 } else { end_line as usize }; + let end_col = selection.end.column.0; + + for line in start_line..end_line + 1 { + let left_col = if selection.is_block || line == start_line { + start_col + } else { + 0 + }; + let right_col = if selection.is_block || line == end_line { + end_col + 1 + } else { + term.last_column().0 + }; + let x0 = left_col as f64 * char_width; + let x1 = right_col as f64 * char_width; + let y0 = line as f64 * line_height; + let y1 = y0 + line_height; + cx.fill( + &Rect::new(x0, y0, x1, y1), + config.color(LapceColor::EDITOR_SELECTION), + 0.0, + ); + } + } else if mode != Mode::Terminal { + let y = (content.cursor.point.line.0 as f64 + + content.display_offset as f64) + * line_height; + cx.fill( + &Rect::new(0.0, y, self.size.width, y + line_height), + config.color(LapceColor::EDITOR_CURRENT_LINE), + 0.0, + ); + } + + self.paint_content(cx, content, line_height, char_size, &config); + // if data.find.visual { + // if let Some(search_string) = data.find.search_string.as_ref() { + // if let Ok(dfas) = RegexSearch::new(®ex::escape(search_string)) { + // let mut start = alacritty_terminal::index::Point::new( + // alacritty_terminal::index::Line( + // -(content.display_offset as i32), + // ), + // alacritty_terminal::index::Column(0), + // ); + // let end_line = (start.line + term.screen_lines()) + // .min(term.bottommost_line()); + // let mut max_lines = (end_line.0 - start.line.0) as usize; + + // while let Some(m) = term.search_next( + // &dfas, + // start, + // Direction::Right, + // Side::Left, + // Some(max_lines), + // ) { + // let match_start = m.start(); + // if match_start.line.0 < start.line.0 + // || (match_start.line.0 == start.line.0 + // && match_start.column.0 < start.column.0) + // { + // break; + // } + // let x = match_start.column.0 as f64 * char_width; + // let y = (match_start.line.0 as f64 + // + content.display_offset as f64) + // * line_height; + // let rect = Rect::ZERO + // .with_origin(Point::new(x, y)) + // .with_size(Size::new( + // (m.end().column.0 - m.start().column.0 + // + term.grid()[*m.end()].c.width().unwrap_or(1)) + // as f64 + // * char_width, + // line_height, + // )); + // cx.stroke( + // &rect, + // config.get_color(LapceColor::TERMINAL_FOREGROUND), + // 1.0, + // ); + // start = *m.end(); + // if start.column.0 < term.last_column() { + // start.column.0 += 1; + // } else if start.line.0 < term.bottommost_line() { + // start.column.0 = 0; + // start.line.0 += 1; + // } + // max_lines = (end_line.0 - start.line.0) as usize; + // } + // } + // } + // } + } +} + +#[derive(Debug, Default, Copy, Clone)] +enum MouseAction { + #[default] + None, + LeftDown { + pos: Point, + }, + LeftOnce { + pos: Point, + time: SystemTime, + }, + LeftSelect { + start_pos: Point, + end_pos: Point, + }, + LeftOnceAndDown { + pos: Point, + time: SystemTime, + }, + LeftDouble { + pos: Point, + }, + RightDown { + pos: Point, + }, + RightOnce { + pos: Point, + }, +} diff --git a/lapce-app/src/text_area.rs b/lapce-app/src/text_area.rs new file mode 100644 index 0000000..747dc00 --- /dev/null +++ b/lapce-app/src/text_area.rs @@ -0,0 +1,121 @@ +use floem::{ + View, + peniko::kurbo::Rect, + reactive::{ + SignalGet, SignalUpdate, SignalWith, create_effect, create_rw_signal, + }, + text::{Attrs, AttrsList, LineHeightValue, TextLayout}, + views::{Decorators, container, label, rich_text, scroll, stack}, +}; +use lapce_core::buffer::rope_text::RopeText; + +use crate::{config::color::LapceColor, editor::EditorData}; + +pub fn text_area( + editor: EditorData, + is_active: impl Fn() -> bool + 'static, +) -> impl View { + let config = editor.common.config; + let doc = editor.doc_signal(); + let cursor = editor.cursor(); + let text_area_rect = create_rw_signal(Rect::ZERO); + let text_layout = create_rw_signal(TextLayout::new()); + let line_height = 1.2; + + create_effect(move |_| { + let config = config.get(); + let font_size = config.ui.font_size(); + let font_family = config.ui.font_family(); + let color = config.color(LapceColor::EDITOR_FOREGROUND); + let attrs = Attrs::new() + .color(color) + .family(&font_family) + .font_size(font_size as f32) + .line_height(LineHeightValue::Normal(line_height)); + let attrs_list = AttrsList::new(attrs); + let doc = doc.get(); + let text = doc.buffer.with(|b| b.to_string()); + text_layout.update(|text_layout| { + text_layout.set_text(&text, attrs_list, None); + }); + }); + + create_effect(move |last_rev| { + let rev = doc.with(|doc| doc.rev()); + if last_rev == Some(rev) { + return rev; + } + + let config = config.get_untracked(); + let font_size = config.ui.font_size(); + let font_family = config.ui.font_family(); + let color = config.color(LapceColor::EDITOR_FOREGROUND); + let attrs = Attrs::new() + .color(color) + .family(&font_family) + .font_size(font_size as f32) + .line_height(LineHeightValue::Normal(1.2)); + let attrs_list = AttrsList::new(attrs); + let doc = doc.get(); + let text = doc.buffer.with(|b| b.to_string()); + text_layout.update(|text_layout| { + text_layout.set_text(&text, attrs_list, None); + }); + + rev + }); + + create_effect(move |last_width| { + let width = text_area_rect.get().width(); + if last_width == Some(width) { + return width; + } + + text_layout.update(|text_layout| { + text_layout.set_size(width as f32, f32::MAX); + }); + + width + }); + + let cursor_pos = move || { + let offset = cursor.with(|c| c.offset()); + let (line, col) = doc + .with_untracked(|doc| doc.buffer.with(|b| b.offset_to_line_col(offset))); + text_layout.with(|text_layout| { + let pos = text_layout.line_col_position(line, col); + pos.point - (0.0, pos.glyph_ascent) + }) + }; + + container( + scroll( + stack(( + rich_text(move || text_layout.get()) + .on_resize(move |rect| { + text_area_rect.set(rect); + }) + .style(|s| s.width_pct(100.0)), + label(|| " ".to_string()).style(move |s| { + let cursor_pos = cursor_pos(); + s.absolute() + .line_height(line_height) + .margin_left(cursor_pos.x as f32 - 1.0) + .margin_top(cursor_pos.y as f32) + .border_left(2.0) + .border_color(config.get().color(LapceColor::EDITOR_CARET)) + .apply_if(!is_active(), |s| s.hide()) + }), + )) + .style(|s| s.width_pct(100.0).padding(6.0)), + ) + .style(|s| s.absolute().size_pct(100.0, 100.0)), + ) + .style(move |s| { + let config = config.get(); + s.border(1.0) + .border_radius(6.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .background(config.color(LapceColor::EDITOR_BACKGROUND)) + }) +} diff --git a/lapce-app/src/text_input.rs b/lapce-app/src/text_input.rs new file mode 100644 index 0000000..b6cbbdb --- /dev/null +++ b/lapce-app/src/text_input.rs @@ -0,0 +1,801 @@ +use std::{rc::Rc, sync::Arc}; + +use floem::{ + Renderer, View, ViewId, + action::{set_ime_allowed, set_ime_cursor_area}, + context::EventCx, + event::{Event, EventListener, EventPropagation}, + kurbo::Stroke, + peniko::{ + Color, + kurbo::{Line, Point, Rect, Size, Vec2}, + }, + prop_extractor, + reactive::{ + Memo, ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith, + create_effect, create_memo, create_rw_signal, + }, + style::{ + CursorStyle, FontFamily, FontSize, FontStyle, FontWeight, LineHeight, + PaddingLeft, Style, TextColor, + }, + taffy::prelude::NodeId, + text::{Attrs, AttrsList, FamilyOwned, TextLayout}, + unit::PxPct, + views::Decorators, +}; +use lapce_core::{ + buffer::rope_text::RopeText, + cursor::{Cursor, CursorMode}, + selection::Selection, +}; +use lapce_xi_rope::Rope; + +use crate::{ + config::{LapceConfig, color::LapceColor}, + doc::Doc, + editor::{DocSignal, EditorData, view::editor_style}, + keypress::KeyPressFocus, + main_split::Editors, + window_tab::CommonData, +}; + +prop_extractor! { + Extractor { + color: TextColor, + font_size: FontSize, + font_family: FontFamily, + font_weight: FontWeight, + font_style: FontStyle, + line_height: LineHeight, + } +} + +/// Builder for creating a [`TextInput`] easily. +pub struct TextInputBuilder { + is_focused: Option>, + // TODO: it'd be nice to not need to box this + key_focus: Option>, + value: Option, + keyboard_focus: RwSignal, +} + +impl Default for TextInputBuilder { + fn default() -> Self { + Self::new() + } +} + +impl TextInputBuilder { + pub fn new() -> Self { + Self { + is_focused: None, + key_focus: None, + value: None, + keyboard_focus: create_rw_signal(false), + } + } + + pub fn is_focused(mut self, is_focused: impl Fn() -> bool + 'static) -> Self { + let keyboard_focus = self.keyboard_focus; + self.is_focused = + Some(create_memo(move |_| is_focused() || keyboard_focus.get())); + self + } + + /// Initialize with a specific value. + /// If this is set it will apply the value via reloading the editor's doc as pristine. + pub fn value(mut self, value: impl Into) -> Self { + self.value = Some(value.into()); + self + } + + pub fn key_focus(mut self, key_focus: impl KeyPressFocus + 'static) -> Self { + self.key_focus = Some(Box::new(key_focus)); + self + } + + pub fn build( + self, + cx: Scope, + editors: Editors, + common: Rc, + ) -> TextInput { + let editor = editors.make_local(cx, common); + let id = editor.id(); + + self.build_editor(editor).on_cleanup(move || { + editors.remove(id); + }) + } + + /// Build the text input with a specific editor. + /// This function does *not* perform add/cleanup the editor to/from [`Editors`] + pub fn build_editor(self, editor: EditorData) -> TextInput { + let keyboard_focus = self.keyboard_focus; + let is_focused = if let Some(is_focused) = self.is_focused { + is_focused + } else { + create_memo(move |_| keyboard_focus.get()) + }; + + if let Some(value) = self.value { + editor.doc().reload(value, true); + } + + text_input_full(editor, self.key_focus, is_focused, keyboard_focus) + } +} + +/// Create a basic single line text input +/// `e_data` is the editor data that this input is associated with. +/// `supplied_editor` +/// `key_focus` is what receives the keydown events, leave as `None` to default to editor. +/// `is_focused` is a function that returns if the input is focused, used for certain events. +fn text_input_full( + e_data: EditorData, + key_focus: Option, + is_focused: Memo, + keyboard_focus: RwSignal, +) -> TextInput { + let id = ViewId::new(); + + let doc = e_data.doc_signal(); + let cursor = e_data.cursor(); + let config = e_data.common.config; + let keypress = e_data.common.keypress; + let window_origin = create_rw_signal(Point::ZERO); + let cursor_line = create_rw_signal(Line::new(Point::ZERO, Point::ZERO)); + let local_editor = e_data.clone(); + let editor = local_editor.editor.clone(); + + { + let doc = doc.get(); + create_effect(move |_| { + let offset = cursor.with(|c| c.offset()); + let (content, offset, preedit_range) = { + let content = doc.buffer.with(|b| b.to_string()); + if let Some(preedit) = doc.preedit.preedit.get().as_ref() { + let mut new_content = String::new(); + new_content.push_str(&content[..offset]); + new_content.push_str(&preedit.text); + new_content.push_str(&content[offset..]); + let range = (offset, offset + preedit.text.len()); + let offset = preedit + .cursor + .as_ref() + .map(|(_, end)| offset + *end) + .unwrap_or(offset); + (new_content, offset, Some(range)) + } else { + (content, offset, None) + } + }; + id.update_state(TextInputState::Content { + text: content, + offset, + preedit_range, + }); + }); + } + + { + create_effect(move |_| { + let focus = is_focused.get(); + id.update_state(TextInputState::Focus(focus)); + }); + + let editor = editor.clone(); + let ime_allowed = editor.ime_allowed; + create_effect(move |_| { + let focus = is_focused.get(); + if focus { + if !ime_allowed.get_untracked() { + ime_allowed.set(true); + set_ime_allowed(true); + } + let cursor_line = cursor_line.get(); + + let window_origin = window_origin.get(); + let viewport = editor.viewport.get(); + let origin = window_origin + + Vec2::new( + cursor_line.p1.x - viewport.x0, + cursor_line.p1.y - viewport.y0, + ); + set_ime_cursor_area(origin, Size::new(800.0, 600.0)); + } + }); + } + + let common_keyboard_focus = e_data.common.keyboard_focus; + + let ed1 = editor.clone(); + let ed2 = editor.clone(); + TextInput { + id, + config, + offset: 0, + preedit_range: None, + layout_rect: Rect::ZERO, + content: "".to_string(), + focus: false, + text_node: None, + text_layout: create_rw_signal(None), + text_rect: Rect::ZERO, + text_viewport: Rect::ZERO, + cursor_line, + placeholder: "".to_string(), + placeholder_text_layout: None, + editor: e_data.clone(), + cursor_pos: Point::ZERO, + on_cursor_pos: None, + hide_cursor: editor.cursor_info.hidden, + style: Default::default(), + } + .style(move |s| { + editor_style(config, doc, s) + .cursor(CursorStyle::Text) + .padding_horiz(10.0) + .padding_vert(6.0) + }) + .on_move(move |pos| { + window_origin.set(pos); + }) + .on_event_stop(EventListener::FocusGained, move |_| { + keyboard_focus.set(true); + common_keyboard_focus.set(Some(id)); + }) + .on_event_stop(EventListener::FocusLost, move |_| { + keyboard_focus.set(false); + if common_keyboard_focus.get_untracked() == Some(id) { + common_keyboard_focus.set(None); + } + }) + .on_event(EventListener::KeyDown, move |event| { + if let Event::KeyDown(key_event) = event { + let keypress = keypress.get_untracked(); + let key_focus = key_focus + .as_ref() + .map(|k| k as &dyn KeyPressFocus) + .unwrap_or(&e_data); + if keypress.key_down(key_event, key_focus).handled { + EventPropagation::Stop + } else { + EventPropagation::Continue + } + } else { + EventPropagation::Continue + } + }) + .on_event(EventListener::ImePreedit, move |event| { + if !is_focused.get_untracked() { + return EventPropagation::Continue; + } + + if let Event::ImePreedit { + text, + cursor: ime_cursor, + } = event + { + if text.is_empty() { + ed1.clear_preedit(); + } else { + let offset = cursor.with_untracked(|c| c.offset()); + ed1.set_preedit(text.clone(), ime_cursor.to_owned(), offset); + } + } + EventPropagation::Stop + }) + .on_event(EventListener::ImeCommit, move |event| { + if !is_focused.get_untracked() { + return EventPropagation::Continue; + } + + if let Event::ImeCommit(text) = event { + ed2.clear_preedit(); + ed2.receive_char(text.as_str()); + } + EventPropagation::Stop + }) +} + +enum TextInputState { + Content { + text: String, + offset: usize, + preedit_range: Option<(usize, usize)>, + }, + Focus(bool), + Placeholder(String), +} + +pub struct TextInput { + id: ViewId, + content: String, + offset: usize, + preedit_range: Option<(usize, usize)>, + editor: EditorData, + focus: bool, + text_node: Option, + text_layout: RwSignal>, + text_rect: Rect, + text_viewport: Rect, + layout_rect: Rect, + cursor_line: RwSignal, + placeholder: String, + placeholder_text_layout: Option, + cursor_pos: Point, + on_cursor_pos: Option>, + hide_cursor: RwSignal, + config: ReadSignal>, + style: Extractor, +} + +impl TextInput { + pub fn placeholder(self, placeholder: impl Fn() -> String + 'static) -> Self { + let id = self.id; + create_effect(move |_| { + let placeholder = placeholder(); + id.update_state(TextInputState::Placeholder(placeholder)); + }); + self + } + + pub fn on_cursor_pos(mut self, cursor_pos: impl Fn(Point) + 'static) -> Self { + self.on_cursor_pos = Some(Box::new(cursor_pos)); + self + } + + pub fn editor(&self) -> EditorData { + self.editor.clone() + } + + pub fn doc_signal(&self) -> DocSignal { + self.editor.doc_signal() + } + + pub fn doc(&self) -> Rc { + self.editor.doc() + } + + pub fn cursor(&self) -> RwSignal { + self.editor.cursor() + } + + fn set_text_layout(&mut self) { + let mut text_layout = TextLayout::new(); + let mut attrs = + Attrs::new().color(self.style.color().unwrap_or(Color::BLACK)); + if let Some(font_size) = self.style.font_size() { + attrs = attrs.font_size(font_size); + } + if let Some(font_style) = self.style.font_style() { + attrs = attrs.style(font_style); + } + let font_family = self.style.font_family().as_ref().map(|font_family| { + let family: Vec = + FamilyOwned::parse_list(font_family).collect(); + family + }); + if let Some(font_family) = font_family.as_ref() { + attrs = attrs.family(font_family); + } + if let Some(font_weight) = self.style.font_weight() { + attrs = attrs.weight(font_weight); + } + if let Some(line_height) = self.style.line_height() { + attrs = attrs.line_height(line_height); + } + text_layout.set_text( + if self.content.is_empty() { + " " + } else { + self.content.as_str() + }, + AttrsList::new(attrs.clone()), + None, + ); + self.text_layout.set(Some(text_layout)); + + let mut placeholder_text_layout = TextLayout::new(); + attrs = attrs.color( + self.style + .color() + .unwrap_or(Color::BLACK) + .multiply_alpha(0.5), + ); + placeholder_text_layout.set_text( + &self.placeholder, + AttrsList::new(attrs), + None, + ); + self.placeholder_text_layout = Some(placeholder_text_layout); + } + + fn hit_index(&self, _cx: &mut EventCx, point: Point) -> usize { + self.text_layout.with_untracked(|text_layout| { + if let Some(text_layout) = text_layout.as_ref() { + let padding_left = + match self.id.get_combined_style().get(PaddingLeft) { + PxPct::Px(v) => v, + PxPct::Pct(pct) => { + let layout = self.id.get_layout().unwrap_or_default(); + pct * layout.size.width as f64 + } + }; + let hit = + text_layout.hit_point(Point::new(point.x - padding_left, 0.0)); + hit.index.min(self.content.len()) + } else { + 0 + } + }) + } + + fn clamp_text_viewport(&mut self, text_viewport: Rect) { + let text_rect = self.text_rect; + let actual_size = text_rect.size(); + let width = text_rect.width(); + let height = text_rect.height(); + let child_size = self + .text_layout + .with_untracked(|text_layout| text_layout.as_ref().unwrap().size()); + + let mut text_viewport = text_viewport; + if width >= child_size.width { + text_viewport.x0 = 0.0; + } else if text_viewport.x0 > child_size.width - width { + text_viewport.x0 = child_size.width - width; + } else if text_viewport.x0 < 0.0 { + text_viewport.x0 = 0.0; + } + + if height >= child_size.height { + text_viewport.y0 = 0.0; + } else if text_viewport.y0 > child_size.height - height { + text_viewport.y0 = child_size.height - height; + } else if text_viewport.y0 < 0.0 { + text_viewport.y0 = 0.0; + } + + let text_viewport = text_viewport.with_size(actual_size); + if text_viewport != self.text_viewport { + self.text_viewport = text_viewport; + self.id.request_paint(); + } + } + + fn ensure_cursor_visible(&mut self) { + fn closest_on_axis(val: f64, min: f64, max: f64) -> f64 { + assert!(min <= max); + if val > min && val < max { + 0.0 + } else if val <= min { + val - min + } else { + val - max + } + } + + let rect = Rect::ZERO.with_origin(self.cursor_pos).inflate(10.0, 0.0); + // clamp the target region size to our own size. + // this means we will show the portion of the target region that + // includes the origin. + let target_size = Size::new( + rect.width().min(self.text_viewport.width()), + rect.height().min(self.text_viewport.height()), + ); + let rect = rect.with_size(target_size); + + let x0 = closest_on_axis( + rect.min_x(), + self.text_viewport.min_x(), + self.text_viewport.max_x(), + ); + let x1 = closest_on_axis( + rect.max_x(), + self.text_viewport.min_x(), + self.text_viewport.max_x(), + ); + let y0 = closest_on_axis( + rect.min_y(), + self.text_viewport.min_y(), + self.text_viewport.max_y(), + ); + let y1 = closest_on_axis( + rect.max_y(), + self.text_viewport.min_y(), + self.text_viewport.max_y(), + ); + + let delta_x = if x0.abs() > x1.abs() { x0 } else { x1 }; + let delta_y = if y0.abs() > y1.abs() { y0 } else { y1 }; + let new_origin = self.text_viewport.origin() + Vec2::new(delta_x, delta_y); + self.clamp_text_viewport(self.text_viewport.with_origin(new_origin)); + } +} + +impl View for TextInput { + fn id(&self) -> ViewId { + self.id + } + + fn update( + &mut self, + _cx: &mut floem::context::UpdateCx, + state: Box, + ) { + if let Ok(state) = state.downcast() { + match *state { + TextInputState::Content { + text, + offset, + preedit_range, + } => { + self.content = text; + self.offset = offset; + self.preedit_range = preedit_range; + self.text_layout.set(None); + } + TextInputState::Focus(focus) => { + self.focus = focus; + } + TextInputState::Placeholder(placeholder) => { + self.placeholder = placeholder; + self.placeholder_text_layout = None; + } + } + self.id.request_layout(); + } + } + + fn style_pass(&mut self, cx: &mut floem::context::StyleCx<'_>) { + if self.style.read(cx) { + self.set_text_layout(); + self.id.request_layout(); + } + } + + fn layout( + &mut self, + cx: &mut floem::context::LayoutCx, + ) -> floem::taffy::prelude::NodeId { + cx.layout_node(self.id, true, |_cx| { + if self + .text_layout + .with_untracked(|text_layout| text_layout.is_none()) + || self.placeholder_text_layout.is_none() + { + self.set_text_layout(); + } + + let text_layout = self.text_layout; + text_layout.with_untracked(|text_layout| { + let text_layout = text_layout.as_ref().unwrap(); + + let offset = self.cursor().get_untracked().offset(); + let cursor_point = text_layout.hit_position(offset).point; + if cursor_point != self.cursor_pos { + self.cursor_pos = cursor_point; + self.ensure_cursor_visible(); + } + + let size = text_layout.size(); + let height = size.height as f32; + + if self.text_node.is_none() { + self.text_node = Some(self.id.new_taffy_node()); + } + + let text_node = self.text_node.unwrap(); + + let style = Style::new().height(height).to_taffy_style(); + self.id.set_taffy_style(text_node, style); + }); + + vec![self.text_node.unwrap()] + }) + } + + fn compute_layout( + &mut self, + _cx: &mut floem::context::ComputeLayoutCx, + ) -> Option { + let layout = self.id.get_layout().unwrap_or_default(); + + let style = self.id.get_combined_style(); + let style = style.builtin(); + let padding_left = match style.padding_left() { + PxPct::Px(padding) => padding, + PxPct::Pct(pct) => pct * layout.size.width as f64, + }; + let padding_right = match style.padding_right() { + PxPct::Px(padding) => padding, + PxPct::Pct(pct) => pct * layout.size.width as f64, + }; + + let size = Size::new(layout.size.width as f64, layout.size.height as f64); + let mut text_rect = size.to_rect(); + text_rect.x0 += padding_left; + text_rect.x1 -= padding_right; + self.text_rect = text_rect; + + self.clamp_text_viewport(self.text_viewport); + + let text_node = self.text_node.unwrap(); + let location = self.id.taffy_layout(text_node).unwrap_or_default().location; + self.layout_rect = size + .to_rect() + .with_origin(Point::new(location.x as f64, location.y as f64)); + let offset = self.cursor().with_untracked(|c| c.offset()); + let cursor_line = self.text_layout.with_untracked(|text_layout| { + let hit_position = text_layout.as_ref().unwrap().hit_position(offset); + let point = Point::new(location.x as f64, location.y as f64) + - self.text_viewport.origin().to_vec2(); + let cursor_point = hit_position.point + point.to_vec2(); + + Line::new( + Point::new( + cursor_point.x, + cursor_point.y - hit_position.glyph_ascent, + ), + Point::new( + cursor_point.x, + cursor_point.y + hit_position.glyph_descent, + ), + ) + }); + self.cursor_line.set(cursor_line); + + None + } + + fn event_before_children( + &mut self, + cx: &mut floem::context::EventCx, + event: &floem::event::Event, + ) -> EventPropagation { + let text_offset = self.text_viewport.origin(); + let event = event.clone().offset((-text_offset.x, -text_offset.y)); + match event { + Event::PointerDown(pointer) => { + let offset = self.hit_index(cx, pointer.pos); + self.cursor().update(|cursor| { + cursor.set_insert(Selection::caret(offset)); + }); + if pointer.button.is_primary() && pointer.count == 2 { + let offset = self.hit_index(cx, pointer.pos); + let (start, end) = self + .doc() + .buffer + .with_untracked(|buffer| buffer.select_word(offset)); + self.cursor().update(|cursor| { + cursor.set_insert(Selection::region(start, end)); + }); + } else if pointer.button.is_primary() && pointer.count == 3 { + self.cursor().update(|cursor| { + cursor.set_insert(Selection::region(0, self.content.len())); + }); + } + cx.update_active(self.id); + } + Event::PointerMove(pointer) => { + if cx.is_active(self.id) { + let offset = self.hit_index(cx, pointer.pos); + self.cursor().update(|cursor| { + cursor.set_offset(offset, true, false); + }); + } + } + Event::PointerWheel(pointer_event) => { + let delta = pointer_event.delta; + let delta = if delta.x == 0.0 && delta.y != 0.0 { + Vec2::new(delta.y, delta.x) + } else { + delta + }; + self.clamp_text_viewport(self.text_viewport + delta); + return EventPropagation::Continue; + } + _ => {} + } + EventPropagation::Continue + } + + fn paint(&mut self, cx: &mut floem::context::PaintCx) { + cx.save(); + cx.clip(&self.text_rect.inflate(1.0, 0.0)); + let text_node = self.text_node.unwrap(); + let location = self.id.taffy_layout(text_node).unwrap_or_default().location; + let point = Point::new(location.x as f64, location.y as f64) + - self.text_viewport.origin().to_vec2(); + + self.text_layout.with_untracked(|text_layout| { + let text_layout = text_layout.as_ref().unwrap(); + let height = text_layout.size().height; + let config = self.config.get_untracked(); + + let cursor = self.cursor().get_untracked(); + + if let CursorMode::Insert(selection) = &cursor.mode { + for region in selection.regions() { + if !region.is_caret() { + let min = text_layout.hit_position(region.min()).point.x; + let max = text_layout.hit_position(region.max()).point.x; + cx.fill( + &Rect::ZERO + .with_size(Size::new(max - min, height)) + .with_origin(Point::new(min + point.x, point.y)), + config.color(LapceColor::EDITOR_SELECTION), + 0.0, + ); + } + } + } + + if !self.content.is_empty() { + cx.draw_text(text_layout, point); + } else if !self.placeholder.is_empty() { + cx.draw_text(self.placeholder_text_layout.as_ref().unwrap(), point); + } + + if let Some((start, end)) = self.preedit_range { + let start_position = text_layout.hit_position(start); + let start_point = start_position.point + + self.layout_rect.origin().to_vec2() + - self.text_viewport.origin().to_vec2(); + let end_position = text_layout.hit_position(end); + let end_point = end_position.point + + self.layout_rect.origin().to_vec2() + - self.text_viewport.origin().to_vec2(); + + let line = Line::new( + Point::new( + start_point.x, + start_point.y + start_position.glyph_descent, + ), + Point::new( + end_point.x, + end_point.y + end_position.glyph_descent, + ), + ); + cx.stroke( + &line, + config.color(LapceColor::EDITOR_FOREGROUND), + &Stroke::new(1.0), + ); + } + + if !self.hide_cursor.get_untracked() + && (self.focus || cx.is_focused(self.id)) + { + cx.clip(&self.text_rect.inflate(2.0, 2.0)); + + let hit_position = text_layout.hit_position(self.offset); + let cursor_point = hit_position.point + + self.layout_rect.origin().to_vec2() + - self.text_viewport.origin().to_vec2(); + + let line = Line::new( + Point::new( + cursor_point.x, + cursor_point.y - hit_position.glyph_ascent, + ), + Point::new( + cursor_point.x, + cursor_point.y + hit_position.glyph_descent, + ), + ); + + cx.stroke( + &line, + self.config.get_untracked().color(LapceColor::EDITOR_CARET), + &Stroke::new(2.0), + ); + } + + cx.restore(); + }); + } +} diff --git a/lapce-app/src/title.rs b/lapce-app/src/title.rs new file mode 100644 index 0000000..5933603 --- /dev/null +++ b/lapce-app/src/title.rs @@ -0,0 +1,533 @@ +use std::{rc::Rc, sync::Arc}; + +use floem::{ + View, + event::EventListener, + menu::{Menu, MenuItem}, + peniko::Color, + reactive::{ + Memo, ReadSignal, RwSignal, SignalGet, SignalUpdate, SignalWith, create_memo, + }, + style::{AlignItems, CursorStyle, JustifyContent}, + views::{Decorators, container, drag_window_area, empty, label, stack, svg}, +}; +use lapce_core::meta; +use lapce_rpc::proxy::ProxyStatus; + +use crate::{ + app::{clickable_icon, not_clickable_icon, tooltip_label, window_menu}, + command::{LapceCommand, LapceWorkbenchCommand, WindowCommand}, + config::{LapceConfig, color::LapceColor, icon::LapceIcons}, + listener::Listener, + main_split::MainSplitData, + update::ReleaseInfo, + window_tab::WindowTabData, + workspace::LapceWorkspace, +}; + +fn left( + workspace: Arc, + lapce_command: Listener, + workbench_command: Listener, + config: ReadSignal>, + proxy_status: RwSignal>, + num_window_tabs: Memo, +) -> impl View { + let is_local = workspace.kind.is_local(); + let is_macos = cfg!(target_os = "macos"); + stack(( + empty().style(move |s| { + let should_hide = if is_macos { + num_window_tabs.get() > 1 + } else { + true + }; + s.width(75.0).apply_if(should_hide, |s| s.hide()) + }), + container(svg(move || config.get().ui_svg(LapceIcons::LOGO)).style( + move |s| { + let config = config.get(); + s.size(16.0, 16.0) + .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + }, + )) + .style(move |s| s.margin_horiz(10.0).apply_if(is_macos, |s| s.hide())), + not_clickable_icon( + || LapceIcons::MENU, + || false, + || false, + || "Menu", + config, + ) + .popout_menu(move || window_menu(lapce_command, workbench_command)) + .style(move |s| { + s.margin_left(4.0) + .margin_right(6.0) + .apply_if(is_macos, |s| s.hide()) + }), + tooltip_label( + config, + container(svg(move || config.get().ui_svg(LapceIcons::REMOTE)).style( + move |s| { + let config = config.get(); + let size = (config.ui.icon_size() as f32 + 2.0).min(30.0); + s.size(size, size).color(if is_local { + config.color(LapceColor::LAPCE_ICON_ACTIVE) + } else { + match proxy_status.get() { + Some(_) => Color::WHITE, + None => config.color(LapceColor::LAPCE_ICON_ACTIVE), + } + }) + }, + )), + || "Connect to Remote", + ) + .popout_menu(move || { + #[allow(unused_mut)] + let mut menu = Menu::new("").entry( + MenuItem::new("Connect to SSH Host").action(move || { + workbench_command.send(LapceWorkbenchCommand::ConnectSshHost); + }), + ); + if !is_local + && proxy_status.get().is_some_and(|p| { + matches!(p, ProxyStatus::Connecting | ProxyStatus::Connected) + }) + { + menu = menu.entry(MenuItem::new("Disconnect remote").action( + move || { + workbench_command + .send(LapceWorkbenchCommand::DisconnectRemote); + }, + )); + } + #[cfg(windows)] + { + menu = menu.entry(MenuItem::new("Connect to WSL Host").action( + move || { + workbench_command + .send(LapceWorkbenchCommand::ConnectWslHost); + }, + )); + } + menu + }) + .style(move |s| { + let config = config.get(); + let color = if is_local { + Color::TRANSPARENT + } else { + match proxy_status.get() { + Some(ProxyStatus::Connected) => { + config.color(LapceColor::LAPCE_REMOTE_CONNECTED) + } + Some(ProxyStatus::Connecting) => { + config.color(LapceColor::LAPCE_REMOTE_CONNECTING) + } + Some(ProxyStatus::Disconnected) => { + config.color(LapceColor::LAPCE_REMOTE_DISCONNECTED) + } + None => Color::TRANSPARENT, + } + }; + s.height_pct(100.0) + .padding_horiz(10.0) + .items_center() + .background(color) + .hover(|s| { + s.cursor(CursorStyle::Pointer).background( + config.color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + }) + .active(|s| { + s.cursor(CursorStyle::Pointer).background( + config.color(LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND), + ) + }) + }), + drag_window_area(empty()) + .style(|s| s.height_pct(100.0).flex_basis(0.0).flex_grow(1.0)), + )) + .style(move |s| { + s.height_pct(100.0) + .flex_basis(0.0) + .flex_grow(1.0) + .items_center() + }) + .debug_name("Left Side of Top Bar") +} + +fn middle( + workspace: Arc, + main_split: MainSplitData, + workbench_command: Listener, + config: ReadSignal>, +) -> impl View { + let local_workspace = workspace.clone(); + let can_jump_backward = { + let main_split = main_split.clone(); + create_memo(move |_| main_split.can_jump_location_backward(true)) + }; + let can_jump_forward = + create_memo(move |_| main_split.can_jump_location_forward(true)); + + let jump_backward = move || { + clickable_icon( + || LapceIcons::LOCATION_BACKWARD, + move || { + workbench_command.send(LapceWorkbenchCommand::JumpLocationBackward); + }, + || false, + move || !can_jump_backward.get(), + || "Jump Backward", + config, + ) + .style(move |s| s.margin_horiz(6.0)) + }; + let jump_forward = move || { + clickable_icon( + || LapceIcons::LOCATION_FORWARD, + move || { + workbench_command.send(LapceWorkbenchCommand::JumpLocationForward); + }, + || false, + move || !can_jump_forward.get(), + || "Jump Forward", + config, + ) + .style(move |s| s.margin_right(6.0)) + }; + + let open_folder = move || { + not_clickable_icon( + || LapceIcons::PALETTE_MENU, + || false, + || false, + || "Open Folder / Recent Workspace", + config, + ) + .popout_menu(move || { + Menu::new("") + .entry(MenuItem::new("Open Folder").action(move || { + workbench_command.send(LapceWorkbenchCommand::OpenFolder); + })) + .entry(MenuItem::new("Open Recent Workspace").action(move || { + workbench_command.send(LapceWorkbenchCommand::PaletteWorkspace); + })) + }) + }; + + stack(( + stack(( + drag_window_area(empty()) + .style(|s| s.height_pct(100.0).flex_basis(0.0).flex_grow(1.0)), + jump_backward(), + jump_forward(), + )) + .style(|s| { + s.flex_basis(0) + .flex_grow(1.0) + .justify_content(Some(JustifyContent::FlexEnd)) + }), + container( + stack(( + svg(move || config.get().ui_svg(LapceIcons::SEARCH)).style( + move |s| { + let config = config.get(); + let icon_size = config.ui.icon_size() as f32; + s.size(icon_size, icon_size) + .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + }, + ), + label(move || { + if let Some(s) = local_workspace.display() { + s + } else { + "Open Folder".to_string() + } + }) + .style(|s| s.padding_left(10).padding_right(5).selectable(false)), + open_folder(), + )) + .style(|s| s.align_items(Some(AlignItems::Center))), + ) + .on_event_stop(EventListener::PointerDown, |_| {}) + .on_click_stop(move |_| { + if workspace.clone().path.is_some() { + workbench_command.send(LapceWorkbenchCommand::PaletteHelpAndFile); + } else { + workbench_command.send(LapceWorkbenchCommand::PaletteWorkspace); + } + }) + .style(move |s| { + let config = config.get(); + s.flex_basis(0) + .flex_grow(10.0) + .min_width(200.0) + .max_width(500.0) + .height(26.0) + .justify_content(Some(JustifyContent::Center)) + .align_items(Some(AlignItems::Center)) + .border(1.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_radius(6.0) + .background(config.color(LapceColor::EDITOR_BACKGROUND)) + }), + stack(( + clickable_icon( + || LapceIcons::START, + move || { + workbench_command.send(LapceWorkbenchCommand::PaletteRunAndDebug) + }, + || false, + || false, + || "Run and Debug", + config, + ) + .style(move |s| s.margin_horiz(6.0)), + drag_window_area(empty()) + .style(|s| s.height_pct(100.0).flex_basis(0.0).flex_grow(1.0)), + )) + .style(move |s| { + s.flex_basis(0) + .flex_grow(1.0) + .justify_content(Some(JustifyContent::FlexStart)) + }), + )) + .style(|s| { + s.flex_basis(0) + .flex_grow(2.0) + .align_items(Some(AlignItems::Center)) + .justify_content(Some(JustifyContent::Center)) + }) + .debug_name("Middle of Top Bar") +} + +fn right( + window_command: Listener, + workbench_command: Listener, + latest_release: ReadSignal>>, + update_in_progress: RwSignal, + num_window_tabs: Memo, + window_maximized: RwSignal, + config: ReadSignal>, +) -> impl View { + let latest_version = create_memo(move |_| { + let latest_release = latest_release.get(); + let latest_version = + latest_release.as_ref().as_ref().map(|r| r.version.clone()); + if latest_version.is_some() + && latest_version.as_deref() != Some(meta::VERSION) + { + latest_version + } else { + None + } + }); + + let has_update = move || latest_version.with(|v| v.is_some()); + + stack(( + drag_window_area(empty()) + .style(|s| s.height_pct(100.0).flex_basis(0.0).flex_grow(1.0)), + stack(( + not_clickable_icon( + || LapceIcons::SETTINGS, + || false, + || false, + || "Settings", + config, + ) + .popout_menu(move || { + Menu::new("") + .entry(MenuItem::new("Command Palette").action(move || { + workbench_command.send(LapceWorkbenchCommand::PaletteCommand) + })) + .separator() + .entry(MenuItem::new("Open Settings").action(move || { + workbench_command.send(LapceWorkbenchCommand::OpenSettings) + })) + .entry(MenuItem::new("Open Keyboard Shortcuts").action( + move || { + workbench_command + .send(LapceWorkbenchCommand::OpenKeyboardShortcuts) + }, + )) + .entry(MenuItem::new("Open Theme Color Settings").action( + move || { + workbench_command + .send(LapceWorkbenchCommand::OpenThemeColorSettings) + }, + )) + .separator() + .entry(if let Some(v) = latest_version.get_untracked() { + if update_in_progress.get_untracked() { + MenuItem::new(format!("Update in progress ({v})")) + .enabled(false) + } else { + MenuItem::new(format!("Restart to update ({v})")).action( + move || { + workbench_command + .send(LapceWorkbenchCommand::RestartToUpdate) + }, + ) + } + } else { + MenuItem::new("No update available").enabled(false) + }) + .separator() + .entry(MenuItem::new("About Lapce").action(move || { + workbench_command.send(LapceWorkbenchCommand::ShowAbout) + })) + }), + container(label(|| "1".to_string()).style(move |s| { + let config = config.get(); + s.font_size(10.0) + .color(config.color(LapceColor::EDITOR_BACKGROUND)) + .border_radius(100.0) + .margin_left(5.0) + .margin_top(10.0) + .background(config.color(LapceColor::EDITOR_CARET)) + })) + .style(move |s| { + let has_update = has_update(); + s.absolute() + .size_pct(100.0, 100.0) + .justify_end() + .items_end() + .pointer_events_none() + .apply_if(!has_update, |s| s.hide()) + }), + )) + .style(move |s| s.margin_horiz(6.0)), + window_controls_view( + window_command, + true, + num_window_tabs, + window_maximized, + config, + ), + )) + .style(|s| { + s.flex_basis(0) + .flex_grow(1.0) + .justify_content(Some(JustifyContent::FlexEnd)) + }) + .debug_name("Right of top bar") +} + +pub fn title(window_tab_data: Rc) -> impl View { + let workspace = window_tab_data.workspace.clone(); + let lapce_command = window_tab_data.common.lapce_command; + let workbench_command = window_tab_data.common.workbench_command; + let window_command = window_tab_data.common.window_common.window_command; + let latest_release = window_tab_data.common.window_common.latest_release; + let proxy_status = window_tab_data.common.proxy_status; + let num_window_tabs = window_tab_data.common.window_common.num_window_tabs; + let window_maximized = window_tab_data.common.window_common.window_maximized; + let title_height = window_tab_data.title_height; + let update_in_progress = window_tab_data.update_in_progress; + let config = window_tab_data.common.config; + stack(( + left( + workspace.clone(), + lapce_command, + workbench_command, + config, + proxy_status, + num_window_tabs, + ), + middle( + workspace, + window_tab_data.main_split.clone(), + workbench_command, + config, + ), + right( + window_command, + workbench_command, + latest_release, + update_in_progress, + num_window_tabs, + window_maximized, + config, + ), + )) + .on_resize(move |rect| { + let height = rect.height(); + if height != title_height.get_untracked() { + title_height.set(height); + } + }) + .style(move |s| { + let config = config.get(); + s.width_pct(100.0) + .height(37.0) + .items_center() + .background(config.color(LapceColor::PANEL_BACKGROUND)) + .border_bottom(1.0) + .border_color(config.color(LapceColor::LAPCE_BORDER)) + }) + .debug_name("Title / Top Bar") +} + +pub fn window_controls_view( + window_command: Listener, + is_title: bool, + num_window_tabs: Memo, + window_maximized: RwSignal, + config: ReadSignal>, +) -> impl View { + stack(( + clickable_icon( + || LapceIcons::WINDOW_MINIMIZE, + || { + floem::action::minimize_window(); + }, + || false, + || false, + || "Minimize", + config, + ) + .style(|s| s.margin_right(16.0).margin_left(10.0)), + clickable_icon( + move || { + if window_maximized.get() { + LapceIcons::WINDOW_RESTORE + } else { + LapceIcons::WINDOW_MAXIMIZE + } + }, + move || { + floem::action::set_window_maximized( + !window_maximized.get_untracked(), + ); + }, + || false, + || false, + || "Maximize", + config, + ) + .style(|s| s.margin_right(16.0)), + clickable_icon( + || LapceIcons::WINDOW_CLOSE, + move || { + window_command.send(WindowCommand::CloseWindow); + }, + || false, + || false, + || "Close Window", + config, + ) + .style(|s| s.margin_right(6.0)), + )) + .style(move |s| { + s.apply_if( + cfg!(target_os = "macos") + || !config.get_untracked().core.custom_titlebar + || (is_title && num_window_tabs.get() > 1), + |s| s.hide(), + ) + }) +} diff --git a/lapce-app/src/tracing.rs b/lapce-app/src/tracing.rs new file mode 100644 index 0000000..24db7f4 --- /dev/null +++ b/lapce-app/src/tracing.rs @@ -0,0 +1,4 @@ +// Re-export `tracing` crate under own name to not collide and as convenient import +pub use tracing::{ + self, Instrument, Level as TraceLevel, event as trace, instrument, +}; diff --git a/lapce-app/src/update.rs b/lapce-app/src/update.rs new file mode 100644 index 0000000..0924cc6 --- /dev/null +++ b/lapce-app/src/update.rs @@ -0,0 +1,233 @@ +use std::path::{Path, PathBuf}; + +use anyhow::{Result, anyhow}; +use lapce_core::{directory::Directory, meta}; +use serde::Deserialize; + +#[derive(Clone, Deserialize, Debug)] +pub struct ReleaseInfo { + pub tag_name: String, + pub target_commitish: String, + pub assets: Vec, + #[serde(skip)] + pub version: String, +} + +#[derive(Clone, Deserialize, Debug)] +pub struct ReleaseAsset { + pub name: String, + pub browser_download_url: String, +} + +pub fn get_latest_release() -> Result { + let url = match meta::RELEASE { + meta::ReleaseType::Debug => { + return Err(anyhow!("no release for debug")); + } + meta::ReleaseType::Nightly => { + "https://api.github.com/repos/lapce/lapce/releases/tags/nightly" + } + _ => "https://api.github.com/repos/lapce/lapce/releases/latest", + }; + + let resp = lapce_proxy::get_url(url, Some("Lapce"))?; + if !resp.status().is_success() { + return Err(anyhow!("get release info failed {}", resp.text()?)); + } + let mut release: ReleaseInfo = serde_json::from_str(&resp.text()?)?; + + release.version = match release.tag_name.as_str() { + "nightly" => format!( + "{}+Nightly.{}", + env!("CARGO_PKG_VERSION"), + &release.target_commitish[..7] + ), + _ => release + .tag_name + .strip_prefix('v') + .unwrap_or(&release.tag_name) + .to_owned(), + }; + + Ok(release) +} + +pub fn download_release(release: &ReleaseInfo) -> Result { + let dir = + Directory::updates_directory().ok_or_else(|| anyhow!("no directory"))?; + let name = match std::env::consts::OS { + "macos" => "Lapce-macos.dmg", + "linux" => match std::env::consts::ARCH { + "aarch64" => "lapce-linux-arm64.tar.gz", + "x86_64" => "lapce-linux-amd64.tar.gz", + _ => return Err(anyhow!("arch not supported")), + }, + #[cfg(feature = "portable")] + "windows" => "Lapce-windows-portable.zip", + #[cfg(not(feature = "portable"))] + "windows" => "Lapce-windows.msi", + _ => return Err(anyhow!("os not supported")), + }; + let file_path = dir.join(name); + + for asset in &release.assets { + if asset.name == name { + let mut resp = lapce_proxy::get_url(&asset.browser_download_url, None)?; + if !resp.status().is_success() { + return Err(anyhow!("download file error {}", resp.text()?)); + } + let mut out = std::fs::File::create(&file_path)?; + resp.copy_to(&mut out)?; + return Ok(file_path); + } + } + + Err(anyhow!("can't download release")) +} + +#[cfg(target_os = "macos")] +pub fn extract(src: &Path, process_path: &Path) -> Result { + let info = dmg::Attach::new(src).with()?; + let dest = process_path.parent().ok_or_else(|| anyhow!("no parent"))?; + let dest = if dest.file_name().and_then(|s| s.to_str()) == Some("MacOS") { + dest.parent().unwrap().parent().unwrap().parent().unwrap() + } else { + dest + }; + std::fs::remove_dir_all(dest.join("Lapce.app"))?; + fs_extra::copy_items( + &[info.mount_point.join("Lapce.app")], + dest, + &fs_extra::dir::CopyOptions { + overwrite: true, + skip_exist: false, + buffer_size: 64000, + copy_inside: true, + content_only: false, + depth: 0, + }, + )?; + Ok(dest.join("Lapce.app")) +} + +#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"))] +pub fn extract(src: &Path, process_path: &Path) -> Result { + let tar_gz = std::fs::File::open(src)?; + let tar = flate2::read::GzDecoder::new(tar_gz); + let mut archive = tar::Archive::new(tar); + let parent = src.parent().ok_or_else(|| anyhow::anyhow!("no parent"))?; + archive.unpack(parent)?; + std::fs::remove_file(process_path)?; + std::fs::copy(parent.join("Lapce").join("lapce"), process_path)?; + Ok(process_path.to_path_buf()) +} + +#[cfg(all(target_os = "windows", feature = "portable"))] +pub fn extract(src: &Path, process_path: &Path) -> Result { + let parent = src + .parent() + .ok_or_else(|| anyhow::anyhow!("src has no parent"))?; + let dst_parent = process_path + .parent() + .ok_or_else(|| anyhow::anyhow!("process_path has no parent"))?; + + { + let mut archive = zip::ZipArchive::new(std::fs::File::open(src)?)?; + archive.extract(parent)?; + } + + // TODO(dbuga): instead of replacing the exe, run the msi installer for non-portable + // TODO(dbuga): there's a very slight chance the user might end up with a backup file without a working .exe + std::fs::rename(process_path, dst_parent.join("lapce.exe.bak"))?; + std::fs::copy(parent.join("lapce.exe"), process_path)?; + + Ok(process_path.to_path_buf()) +} + +#[cfg(all(target_os = "windows", not(feature = "portable")))] +pub fn extract(src: &Path, _process_path: &Path) -> Result { + // We downloaded an uncompressed msi installer, nothing to extract. + // On the other hand, we need to run this msi so pass its path back out. + Ok(src.to_path_buf()) +} + +#[cfg(target_os = "macos")] +pub fn restart(path: &Path) -> Result<()> { + use std::os::unix::process::CommandExt; + let _ = std::process::Command::new("open") + .arg("-n") + .arg(path) + .arg("--args") + .arg("-n") + .exec(); + Ok(()) +} + +#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"))] +pub fn restart(path: &Path) -> Result<()> { + use std::os::unix::process::CommandExt; + let _ = std::process::Command::new(path).arg("-n").exec(); + Ok(()) +} + +#[cfg(all(target_os = "windows", feature = "portable"))] +pub fn restart(path: &Path) -> Result<()> { + use std::os::windows::process::CommandExt; + const DETACHED_PROCESS: u32 = 0x00000008; + let process_id = std::process::id(); + let path = path + .to_str() + .ok_or_else(|| anyhow!("can't get path to str"))?; + std::process::Command::new("cmd") + .raw_arg(format!( + r#"/C taskkill /PID {process_id} & start "" "{path}""# + )) + .creation_flags(DETACHED_PROCESS) + .spawn()?; + Ok(()) +} + +#[cfg(all(target_os = "windows", not(feature = "portable")))] +pub fn restart(path: &Path) -> Result<()> { + use std::os::windows::process::CommandExt; + const DETACHED_PROCESS: u32 = 0x00000008; + let process_id = std::process::id(); + let path = path + .to_str() + .ok_or_else(|| anyhow!("can't get path to str"))?; + + let lapce_exe = std::env::current_exe() + .map_err(|err| anyhow!("can't get path to exe").context(err))?; + let lapce_exe = lapce_exe + .to_str() + .ok_or_else(|| anyhow!("can't convert exe path to str"))?; + + std::process::Command::new("cmd") + .raw_arg(format!( + r#"/C taskkill /PID {process_id} & msiexec /i "{path}" /qb & start "" "{lapce_exe}""#, + )) + .creation_flags(DETACHED_PROCESS) + .spawn()?; + Ok(()) +} + +#[cfg(all(target_os = "windows", feature = "portable"))] +pub fn cleanup() { + // Clean up backup exe after an update + if let Ok(process_path) = std::env::current_exe() { + if let Some(dst_parent) = process_path.parent() { + if let Err(err) = std::fs::remove_file(dst_parent.join("lapce.exe.bak")) + { + tracing::error!("{:?}", err); + } + } + } +} + +#[cfg(any( + not(target_os = "windows"), + all(target_os = "windows", not(feature = "portable")) +))] +pub fn cleanup() { + // Nothing to do yet +} diff --git a/lapce-app/src/wave.rs b/lapce-app/src/wave.rs new file mode 100644 index 0000000..9382cd0 --- /dev/null +++ b/lapce-app/src/wave.rs @@ -0,0 +1,59 @@ +use floem::{ + Renderer, View, ViewId, + peniko::kurbo::{BezPath, Point, Size}, + style::TextColor, +}; + +pub fn wave_box() -> WaveBox { + WaveBox { id: ViewId::new() } +} + +pub struct WaveBox { + id: ViewId, +} + +impl View for WaveBox { + fn id(&self) -> ViewId { + self.id + } + + fn paint(&mut self, cx: &mut floem::context::PaintCx) { + if let Some(color) = self.id.get_combined_style().get(TextColor) { + let layout = self.id.get_layout().unwrap_or_default(); + let size = layout.size; + let size = Size::new(size.width as f64, size.height as f64); + let radius = 4.0; + + let origin = Point::new(0.0, size.height); + let mut path = BezPath::new(); + path.move_to(origin); + + let mut x = 0.0; + let mut direction = -1.0; + while x < size.width { + let point = origin + (x, 0.0); + let p1 = point + (radius * 1.5, -radius * direction); + let p2 = point + (radius * 3.0, 0.0); + path.quad_to(p1, p2); + x += radius * 3.0; + direction *= -1.0; + } + { + let origin = Point::new(0.0, 0.0); + path.line_to(origin + (x, 0.0)); + direction *= -1.0; + while x >= 0.0 { + x -= radius * 3.0; + let point = origin + (x, 0.0); + let p1 = point + (radius * 1.5, -radius * direction); + let p2 = point; + path.quad_to(p1, p2); + direction *= -1.0; + } + } + path.line_to(origin); + + cx.fill(&path, color, 0.0); + } + } +} diff --git a/lapce-app/src/web_link.rs b/lapce-app/src/web_link.rs new file mode 100644 index 0000000..96a54a9 --- /dev/null +++ b/lapce-app/src/web_link.rs @@ -0,0 +1,24 @@ +use floem::{ + View, + peniko::Color, + style::CursorStyle, + views::{Decorators, label}, +}; + +use crate::{command::InternalCommand, listener::Listener}; + +pub fn web_link( + text: impl Fn() -> String + 'static, + uri: impl Fn() -> String + 'static, + color: impl Fn() -> Color + 'static, + internal_command: Listener, +) -> impl View { + label(text) + .on_click_stop(move |_| { + internal_command.send(InternalCommand::OpenWebUri { uri: uri() }); + }) + .style(move |s| { + s.color(color()) + .hover(move |s| s.cursor(CursorStyle::Pointer)) + }) +} diff --git a/lapce-app/src/window.rs b/lapce-app/src/window.rs new file mode 100644 index 0000000..0eda897 --- /dev/null +++ b/lapce-app/src/window.rs @@ -0,0 +1,394 @@ +use std::{path::PathBuf, rc::Rc, sync::Arc}; + +use floem::{ + ViewId, + action::TimerToken, + peniko::kurbo::{Point, Size}, + reactive::{ + Memo, ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith, + use_context, + }, + window::WindowId, +}; +use serde::{Deserialize, Serialize}; + +use crate::{ + app::AppCommand, + command::{InternalCommand, WindowCommand}, + config::LapceConfig, + db::LapceDb, + keypress::EventRef, + listener::Listener, + update::ReleaseInfo, + window_tab::WindowTabData, + workspace::LapceWorkspace, +}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct TabsInfo { + pub active_tab: usize, + pub workspaces: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct WindowInfo { + pub size: Size, + pub pos: Point, + pub maximised: bool, + pub tabs: TabsInfo, +} + +#[derive(Clone)] +pub struct WindowCommonData { + pub window_command: Listener, + pub window_scale: RwSignal, + pub size: RwSignal, + pub num_window_tabs: Memo, + pub window_maximized: RwSignal, + pub window_tab_header_height: RwSignal, + pub latest_release: ReadSignal>>, + pub ime_allowed: RwSignal, + pub cursor_blink_timer: RwSignal, + // the value to be update by cursor blinking + pub hide_cursor: RwSignal, + pub app_view_id: RwSignal, + pub extra_plugin_paths: Arc>, +} + +/// `WindowData` is the application model for a top-level window. +/// +/// A top-level window can be independently moved around and +/// resized using your window manager. Normally Lapce has only one +/// top-level window, but new ones can be created using the "New Window" +/// command. +/// +/// Each window has its own collection of "window tabs" (again, there is +/// normally only one window tab), size, position etc. +#[derive(Clone)] +pub struct WindowData { + pub window_id: WindowId, + pub scope: Scope, + /// The set of tabs within the window. These tabs are high-level + /// constructs for workspaces, in particular they are not **editor tabs**. + pub window_tabs: RwSignal, Rc)>>, + pub num_window_tabs: Memo, + /// The index of the active window tab. + pub active: RwSignal, + pub app_command: Listener, + pub position: RwSignal, + pub root_view_id: RwSignal, + pub window_scale: RwSignal, + pub config: RwSignal>, + pub ime_enabled: RwSignal, + pub common: Rc, +} + +impl WindowData { + pub fn new( + window_id: WindowId, + app_view_id: RwSignal, + info: WindowInfo, + window_scale: RwSignal, + latest_release: ReadSignal>>, + extra_plugin_paths: Arc>, + app_command: Listener, + ) -> Self { + let cx = Scope::new(); + let config = + LapceConfig::load(&LapceWorkspace::default(), &[], &extra_plugin_paths); + let config = cx.create_rw_signal(Arc::new(config)); + let root_view_id = cx.create_rw_signal(ViewId::new()); + + let window_tabs = cx.create_rw_signal(im::Vector::new()); + let num_window_tabs = + cx.create_memo(move |_| window_tabs.with(|tabs| tabs.len())); + let active = info.tabs.active_tab; + let window_command = Listener::new_empty(cx); + let ime_allowed = cx.create_rw_signal(false); + let window_maximized = cx.create_rw_signal(false); + let size = cx.create_rw_signal(Size::ZERO); + let window_tab_header_height = cx.create_rw_signal(0.0); + let cursor_blink_timer = cx.create_rw_signal(TimerToken::INVALID); + let hide_cursor = cx.create_rw_signal(false); + + let common = Rc::new(WindowCommonData { + window_command, + window_scale, + size, + num_window_tabs, + window_maximized, + window_tab_header_height, + latest_release, + ime_allowed, + cursor_blink_timer, + hide_cursor, + app_view_id, + extra_plugin_paths, + }); + + for w in info.tabs.workspaces { + let window_tab = + Rc::new(WindowTabData::new(cx, Arc::new(w), common.clone())); + window_tabs.update(|window_tabs| { + window_tabs.push_back((cx.create_rw_signal(0), window_tab)); + }); + } + + if window_tabs.with_untracked(|window_tabs| window_tabs.is_empty()) { + let window_tab = Rc::new(WindowTabData::new( + cx, + Arc::new(LapceWorkspace::default()), + common.clone(), + )); + window_tabs.update(|window_tabs| { + window_tabs.push_back((cx.create_rw_signal(0), window_tab)); + }); + } + + let active = cx.create_rw_signal(active); + let position = cx.create_rw_signal(info.pos); + + let window_data = Self { + window_id, + scope: cx, + window_tabs, + num_window_tabs, + active, + position, + root_view_id, + window_scale, + app_command, + config, + ime_enabled: cx.create_rw_signal(false), + common, + }; + + { + let window_data = window_data.clone(); + window_data.common.window_command.listen(move |cmd| { + window_data.run_window_command(cmd); + }); + } + + { + cx.create_effect(move |_| { + let active = active.get(); + let tab = window_tabs + .with(|tabs| tabs.get(active).map(|(_, tab)| tab.clone())); + if let Some(tab) = tab { + tab.common + .internal_command + .send(InternalCommand::ResetBlinkCursor); + } + }) + } + + window_data + } + + pub fn reload_config(&self) { + let config = LapceConfig::load( + &LapceWorkspace::default(), + &[], + &self.common.extra_plugin_paths, + ); + self.config.set(Arc::new(config)); + let window_tabs = self.window_tabs.get_untracked(); + for (_, window_tab) in window_tabs { + window_tab.reload_config(); + } + } + + pub fn run_window_command(&self, cmd: WindowCommand) { + match cmd { + WindowCommand::SetWorkspace { workspace } => { + let db: Arc = use_context().unwrap(); + if let Err(err) = db.update_recent_workspace(&workspace) { + tracing::error!("{:?}", err); + } + + let active = self.active.get_untracked(); + self.window_tabs.with_untracked(|window_tabs| { + if !window_tabs.is_empty() { + let active = window_tabs.len().saturating_sub(1).min(active); + if let Err(err) = + db.insert_window_tab(window_tabs[active].1.clone()) + { + tracing::error!("{:?}", err); + } + } + }); + + let window_tab = Rc::new(WindowTabData::new( + self.scope, + Arc::new(workspace), + self.common.clone(), + )); + self.window_tabs.update(|window_tabs| { + if window_tabs.is_empty() { + window_tabs + .push_back((self.scope.create_rw_signal(0), window_tab)); + } else { + let active = window_tabs.len().saturating_sub(1).min(active); + let (_, old_window_tab) = window_tabs.set( + active, + (self.scope.create_rw_signal(0), window_tab), + ); + old_window_tab.proxy.shutdown(); + } + }) + } + WindowCommand::NewWorkspaceTab { workspace, end } => { + let db: Arc = use_context().unwrap(); + if let Err(err) = db.update_recent_workspace(&workspace) { + tracing::error!("{:?}", err); + } + + let window_tab = Rc::new(WindowTabData::new( + self.scope, + Arc::new(workspace), + self.common.clone(), + )); + let active = self.active.get_untracked(); + let active = self + .window_tabs + .try_update(|tabs| { + if end || tabs.is_empty() { + tabs.push_back(( + self.scope.create_rw_signal(0), + window_tab, + )); + tabs.len() - 1 + } else { + let index = tabs.len().min(active + 1); + tabs.insert( + index, + (self.scope.create_rw_signal(0), window_tab), + ); + index + } + }) + .unwrap(); + self.active.set(active); + } + WindowCommand::CloseWorkspaceTab { index } => { + let active = self.active.get_untracked(); + let index = index.unwrap_or(active); + self.window_tabs.update(|window_tabs| { + if window_tabs.len() < 2 { + return; + } + + if index < window_tabs.len() { + let (_, old_window_tab) = window_tabs.remove(index); + old_window_tab.proxy.shutdown(); + let db: Arc = use_context().unwrap(); + if let Err(err) = db.save_window_tab(old_window_tab) { + tracing::error!("{:?}", err); + } + } + }); + + let tabs_len = self.window_tabs.with_untracked(|tabs| tabs.len()); + + if active > index && active > 0 { + self.active.set(active - 1); + } else if active >= tabs_len.saturating_sub(1) { + self.active.set(tabs_len.saturating_sub(1)); + } + } + WindowCommand::NextWorkspaceTab => { + let active = self.active.get_untracked(); + let tabs_len = self.window_tabs.with_untracked(|tabs| tabs.len()); + if tabs_len > 1 { + let active = if active >= tabs_len - 1 { + 0 + } else { + active + 1 + }; + self.active.set(active); + } + } + WindowCommand::PreviousWorkspaceTab => { + let active = self.active.get_untracked(); + let tabs_len = self.window_tabs.with_untracked(|tabs| tabs.len()); + if tabs_len > 1 { + let active = if active == 0 { + tabs_len - 1 + } else { + active - 1 + }; + self.active.set(active); + } + } + WindowCommand::NewWindow => { + self.app_command + .send(AppCommand::NewWindow { folder: None }); + } + WindowCommand::CloseWindow => { + self.app_command + .send(AppCommand::CloseWindow(self.window_id)); + } + } + self.app_command.send(AppCommand::SaveApp); + } + + pub fn key_down<'a>(&self, event: impl Into> + Copy) -> bool { + let active = self.active.get_untracked(); + let window_tab = self.window_tabs.with_untracked(|window_tabs| { + window_tabs + .get(active) + .or_else(|| window_tabs.last()) + .cloned() + }); + if let Some((_, window_tab)) = window_tab { + window_tab.key_down(event) + } else { + false + } + } + + pub fn info(&self) -> WindowInfo { + let workspaces: Vec = self + .window_tabs + .get_untracked() + .iter() + .map(|(_, t)| (*t.workspace).clone()) + .collect(); + WindowInfo { + size: self.common.size.get_untracked(), + pos: self.position.get_untracked(), + maximised: false, + tabs: TabsInfo { + active_tab: self.active.get_untracked(), + workspaces, + }, + } + } + + pub fn active_window_tab(&self) -> Option> { + let window_tabs = self.window_tabs.get_untracked(); + let active = self + .active + .get_untracked() + .min(window_tabs.len().saturating_sub(1)); + window_tabs.get(active).map(|(_, tab)| tab.clone()) + } + + pub fn move_tab(&self, from_index: usize, to_index: usize) { + if from_index == to_index { + return; + } + + let to_index = if from_index < to_index { + to_index - 1 + } else { + to_index + }; + self.window_tabs.update(|tabs| { + let tab = tabs.remove(from_index); + tabs.insert(to_index, tab); + }); + self.active.set(to_index); + } +} diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs new file mode 100644 index 0000000..f21ead0 --- /dev/null +++ b/lapce-app/src/window_tab.rs @@ -0,0 +1,2989 @@ +use std::{ + collections::{BTreeMap, HashSet}, + env, + path::{Path, PathBuf}, + rc::Rc, + sync::{ + Arc, + mpsc::{Sender, channel}, + }, + time::Instant, +}; + +use alacritty_terminal::vte::ansi::Handler; +use floem::{ + ViewId, + action::{TimerToken, open_file, remove_overlay}, + ext_event::{create_ext_action, create_signal_from_channel}, + file::FileDialogOptions, + keyboard::Modifiers, + kurbo::Size, + peniko::kurbo::{Point, Rect, Vec2}, + prelude::SignalTrack, + reactive::{ + Memo, ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith, + WriteSignal, use_context, + }, + text::{Attrs, AttrsList, FamilyOwned, LineHeightValue, TextLayout}, + views::editor::core::buffer::rope_text::RopeText, +}; +use im::HashMap; +use indexmap::IndexMap; +use itertools::Itertools; +use lapce_core::{ + command::FocusCommand, cursor::CursorAffinity, directory::Directory, meta, + mode::Mode, register::Register, +}; +use lapce_rpc::{ + RpcError, + core::CoreNotification, + dap_types::{ConfigSource, RunDebugConfig}, + file::{Naming, PathObject}, + plugin::PluginId, + proxy::{ProxyResponse, ProxyRpcHandler, ProxyStatus}, + source_control::FileDiff, + terminal::TermId, +}; +use lsp_types::{ + CodeActionOrCommand, CodeLens, Diagnostic, ProgressParams, ProgressToken, + ShowMessageParams, +}; +use serde_json::Value; +use tracing::{Level, debug, error, event}; + +use crate::{ + about::AboutData, + alert::{AlertBoxData, AlertButton}, + code_action::{CodeActionData, CodeActionStatus}, + command::{ + CommandExecuted, CommandKind, InternalCommand, LapceCommand, + LapceWorkbenchCommand, WindowCommand, + }, + completion::{CompletionData, CompletionStatus}, + config::LapceConfig, + db::LapceDb, + debug::{DapData, LapceBreakpoint, RunDebugMode, RunDebugProcess}, + doc::DocContent, + editor::location::{EditorLocation, EditorPosition}, + editor_tab::EditorTabChild, + file_explorer::data::FileExplorerData, + find::Find, + global_search::GlobalSearchData, + hover::HoverData, + id::WindowTabId, + inline_completion::InlineCompletionData, + keypress::{EventRef, KeyPressData, KeyPressFocus, condition::Condition}, + listener::Listener, + lsp::path_from_url, + main_split::{MainSplitData, SplitData, SplitDirection, SplitMoveDirection}, + palette::{DEFAULT_RUN_TOML, PaletteData, PaletteStatus, kind::PaletteKind}, + panel::{ + call_hierarchy_view::{CallHierarchyData, CallHierarchyItemData}, + data::{PanelData, PanelSection, default_panel_order}, + kind::PanelKind, + position::PanelContainerPosition, + }, + plugin::PluginData, + proxy::{ProxyData, new_proxy}, + rename::RenameData, + source_control::SourceControlData, + terminal::{ + event::{TermEvent, TermNotification, terminal_update_process}, + panel::TerminalPanelData, + }, + tracing::*, + window::WindowCommonData, + workspace::{LapceWorkspace, LapceWorkspaceType, WorkspaceInfo}, +}; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Focus { + Workbench, + Palette, + CodeAction, + Rename, + AboutPopup, + Panel(PanelKind), +} + +#[derive(Clone)] +pub enum DragContent { + Panel(PanelKind), + EditorTab(EditorTabChild), +} + +impl DragContent { + pub fn is_panel(&self) -> bool { + matches!(self, DragContent::Panel(_)) + } +} + +#[derive(Clone)] +pub struct WorkProgress { + pub token: ProgressToken, + pub title: String, + pub message: Option, + pub percentage: Option, +} + +#[derive(Clone)] +pub struct CommonData { + pub workspace: Arc, + pub scope: Scope, + pub focus: RwSignal, + pub keypress: RwSignal, + pub completion: RwSignal, + pub inline_completion: RwSignal, + pub hover: HoverData, + pub register: RwSignal, + pub find: Find, + pub workbench_size: RwSignal, + pub window_origin: RwSignal, + pub internal_command: Listener, + pub lapce_command: Listener, + pub workbench_command: Listener, + pub term_tx: Sender<(TermId, TermEvent)>, + pub term_notification_tx: Sender, + pub proxy: ProxyRpcHandler, + pub view_id: RwSignal, + pub ui_line_height: Memo, + pub dragging: RwSignal>, + pub config: ReadSignal>, + pub proxy_status: RwSignal>, + pub mouse_hover_timer: RwSignal, + pub breakpoints: RwSignal>>, + // the current focused view which will receive keyboard events + pub keyboard_focus: RwSignal>, + pub window_common: Rc, +} + +impl std::fmt::Debug for CommonData { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("CommonData") + .field("workspace", &self.workspace) + .finish() + } +} + +#[derive(Clone)] +pub struct WindowTabData { + pub scope: Scope, + pub window_tab_id: WindowTabId, + pub workspace: Arc, + pub palette: PaletteData, + pub main_split: MainSplitData, + pub file_explorer: FileExplorerData, + pub panel: PanelData, + pub terminal: TerminalPanelData, + pub plugin: PluginData, + pub code_action: RwSignal, + pub code_lens: RwSignal>, + pub source_control: SourceControlData, + pub rename: RenameData, + pub global_search: GlobalSearchData, + pub call_hierarchy_data: CallHierarchyData, + pub about_data: AboutData, + pub alert_data: AlertBoxData, + pub layout_rect: RwSignal, + pub title_height: RwSignal, + pub status_height: RwSignal, + pub proxy: ProxyData, + pub set_config: WriteSignal>, + pub update_in_progress: RwSignal, + pub progresses: RwSignal>, + pub messages: RwSignal>, + pub common: Rc, +} + +impl std::fmt::Debug for WindowTabData { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("WindowTabData") + .field("window_tab_id", &self.window_tab_id) + .finish() + } +} + +impl KeyPressFocus for WindowTabData { + fn get_mode(&self) -> Mode { + Mode::Normal + } + + fn check_condition(&self, condition: Condition) -> bool { + match condition { + Condition::PanelFocus => { + matches!(self.common.focus.get_untracked(), Focus::Panel(_)) + } + Condition::SourceControlFocus => { + self.common.focus.get_untracked() + == Focus::Panel(PanelKind::SourceControl) + } + _ => false, + } + } + + fn run_command( + &self, + command: &LapceCommand, + _count: Option, + _mods: Modifiers, + ) -> CommandExecuted { + match &command.kind { + CommandKind::Workbench(cmd) => { + self.run_workbench_command(cmd.clone(), None); + } + CommandKind::Focus(cmd) => { + if self.common.focus.get_untracked() == Focus::Workbench { + match cmd { + FocusCommand::SplitClose => { + self.main_split.editor_tab_child_close_active(); + } + FocusCommand::SplitVertical => { + self.main_split.split_active(SplitDirection::Vertical); + } + FocusCommand::SplitHorizontal => { + self.main_split.split_active(SplitDirection::Horizontal); + } + FocusCommand::SplitRight => { + self.main_split + .split_move_active(SplitMoveDirection::Right); + } + FocusCommand::SplitLeft => { + self.main_split + .split_move_active(SplitMoveDirection::Left); + } + FocusCommand::SplitUp => { + self.main_split + .split_move_active(SplitMoveDirection::Up); + } + FocusCommand::SplitDown => { + self.main_split + .split_move_active(SplitMoveDirection::Down); + } + FocusCommand::SplitExchange => { + self.main_split.split_exchange_active(); + } + _ => { + return CommandExecuted::No; + } + } + } + } + _ => { + return CommandExecuted::No; + } + } + + CommandExecuted::Yes + } + + fn receive_char(&self, _c: &str) {} +} + +impl WindowTabData { + #[allow(clippy::too_many_arguments)] + pub fn new( + cx: Scope, + workspace: Arc, + window_common: Rc, + ) -> Self { + let cx = cx.create_child(); + let db: Arc = use_context().unwrap(); + + let disabled_volts = db.get_disabled_volts().unwrap_or_default(); + let workspace_disabled_volts = db + .get_workspace_disabled_volts(&workspace) + .unwrap_or_default(); + let mut all_disabled_volts = disabled_volts.clone(); + all_disabled_volts.extend(workspace_disabled_volts.clone()); + + let workspace_info = if workspace.path.is_some() { + db.get_workspace_info(&workspace).ok() + } else { + let mut info = db.get_workspace_info(&workspace).ok(); + if let Some(info) = info.as_mut() { + info.split.children.clear(); + } + info + }; + + let config = LapceConfig::load( + &workspace, + &all_disabled_volts, + &window_common.extra_plugin_paths, + ); + let lapce_command = Listener::new_empty(cx); + let workbench_command = Listener::new_empty(cx); + let internal_command = Listener::new_empty(cx); + let keypress = cx.create_rw_signal(KeyPressData::new(cx, &config)); + let proxy_status = cx.create_rw_signal(None); + + let (term_tx, term_rx) = channel(); + let (term_notification_tx, term_notification_rx) = channel(); + { + let term_notification_tx = term_notification_tx.clone(); + std::thread::Builder::new() + .name("terminal update process".to_owned()) + .spawn(move || { + terminal_update_process(term_rx, term_notification_tx); + }) + .unwrap(); + } + + let proxy = new_proxy( + workspace.clone(), + all_disabled_volts, + window_common.extra_plugin_paths.as_ref().clone(), + config.plugins.clone(), + term_tx.clone(), + ); + let (config, set_config) = cx.create_signal(Arc::new(config)); + + let focus = cx.create_rw_signal(Focus::Workbench); + let completion = cx.create_rw_signal(CompletionData::new(cx, config)); + let inline_completion = cx.create_rw_signal(InlineCompletionData::new(cx)); + let hover = HoverData::new(cx); + + let register = cx.create_rw_signal(Register::default()); + let view_id = cx.create_rw_signal(ViewId::new()); + let find = Find::new(cx); + + let ui_line_height = cx.create_memo(move |_| { + let config = config.get(); + let mut text_layout = TextLayout::new(); + + let family: Vec = + FamilyOwned::parse_list(&config.ui.font_family).collect(); + let attrs = Attrs::new() + .family(&family) + .font_size(config.ui.font_size() as f32) + .line_height(LineHeightValue::Normal(1.8)); + let attrs_list = AttrsList::new(attrs); + text_layout.set_text("W", attrs_list, None); + text_layout.size().height + }); + + let common = Rc::new(CommonData { + workspace: workspace.clone(), + scope: cx, + keypress, + focus, + completion, + inline_completion, + hover, + register, + find, + internal_command, + lapce_command, + workbench_command, + term_tx, + term_notification_tx, + proxy: proxy.proxy_rpc.clone(), + view_id, + ui_line_height, + dragging: cx.create_rw_signal(None), + workbench_size: cx.create_rw_signal(Size::ZERO), + config, + proxy_status, + mouse_hover_timer: cx.create_rw_signal(TimerToken::INVALID), + window_origin: cx.create_rw_signal(Point::ZERO), + breakpoints: cx.create_rw_signal(BTreeMap::new()), + keyboard_focus: cx.create_rw_signal(None), + window_common: window_common.clone(), + }); + + let main_split = MainSplitData::new(cx, common.clone()); + let code_action = + cx.create_rw_signal(CodeActionData::new(cx, common.clone())); + let source_control = + SourceControlData::new(cx, main_split.editors, common.clone()); + let file_explorer = + FileExplorerData::new(cx, main_split.editors, common.clone()); + + if let Some(info) = workspace_info.as_ref() { + let root_split = main_split.root_split; + info.split.to_data(main_split.clone(), None, root_split); + } else { + let root_split = main_split.root_split; + let root_split_data = { + let cx = cx.create_child(); + let root_split_data = SplitData { + scope: cx, + parent_split: None, + split_id: root_split, + children: Vec::new(), + direction: SplitDirection::Horizontal, + window_origin: Point::ZERO, + layout_rect: Rect::ZERO, + }; + cx.create_rw_signal(root_split_data) + }; + main_split.splits.update(|splits| { + splits.insert(root_split, root_split_data); + }); + } + + let palette = PaletteData::new( + cx, + workspace.clone(), + main_split.clone(), + keypress.read_only(), + source_control.clone(), + common.clone(), + ); + + let title_height = cx.create_rw_signal(0.0); + let status_height = cx.create_rw_signal(0.0); + let panel_available_size = cx.create_memo(move |_| { + let title_height = title_height.get(); + let status_height = status_height.get(); + let num_window_tabs = window_common.num_window_tabs.get(); + let window_size = window_common.size.get(); + Size::new( + window_size.width, + window_size.height + - title_height + - status_height + - if num_window_tabs > 1 { + window_common.window_tab_header_height.get() + } else { + 0.0 + }, + ) + }); + let panel = workspace_info + .as_ref() + .map(|i| { + let panel_order = db + .get_panel_orders() + .unwrap_or_else(|_| default_panel_order()); + PanelData { + panels: cx.create_rw_signal(panel_order), + styles: cx.create_rw_signal(i.panel.styles.clone()), + size: cx.create_rw_signal(i.panel.size.clone()), + available_size: panel_available_size, + sections: cx.create_rw_signal( + i.panel + .sections + .iter() + .map(|(key, value)| (*key, cx.create_rw_signal(*value))) + .collect(), + ), + common: common.clone(), + } + }) + .unwrap_or_else(|| { + let panel_order = db + .get_panel_orders() + .unwrap_or_else(|_| default_panel_order()); + PanelData::new( + cx, + panel_order, + panel_available_size, + im::HashMap::new(), + common.clone(), + ) + }); + + let terminal = TerminalPanelData::new( + workspace.clone(), + common.config.get_untracked().terminal.get_default_profile(), + common.clone(), + main_split.clone(), + ); + if let Some(workspace_info) = workspace_info.as_ref() { + terminal.debug.breakpoints.set( + workspace_info + .breakpoints + .clone() + .into_iter() + .map(|(path, breakpoints)| { + ( + path, + breakpoints + .into_iter() + .map(|b| (b.line, b)) + .collect::>(), + ) + }) + .collect(), + ); + } + + let rename = RenameData::new(cx, main_split.editors, common.clone()); + let global_search = GlobalSearchData::new(cx, main_split.clone()); + + let plugin = PluginData::new( + cx, + HashSet::from_iter(disabled_volts), + HashSet::from_iter(workspace_disabled_volts), + main_split.editors, + common.clone(), + proxy.core_rpc.clone(), + ); + + { + let notification = create_signal_from_channel(term_notification_rx); + let terminal = terminal.clone(); + cx.create_effect(move |_| { + notification.with(|notification| { + if let Some(notification) = notification.as_ref() { + match notification { + TermNotification::SetTitle { term_id, title } => { + terminal.set_title(term_id, title); + } + TermNotification::RequestPaint => { + view_id.get_untracked().request_paint(); + } + } + } + }); + }); + } + + let about_data = AboutData::new(cx, common.focus); + let alert_data = AlertBoxData::new(cx, common.clone()); + + let window_tab_data = Self { + scope: cx, + window_tab_id: WindowTabId::next(), + workspace, + palette, + main_split, + terminal, + panel, + file_explorer, + code_action, + code_lens: cx.create_rw_signal(None), + source_control, + plugin, + rename, + global_search, + call_hierarchy_data: CallHierarchyData { + root: cx.create_rw_signal(None), + common: common.clone(), + scroll_to_line: cx.create_rw_signal(None), + }, + about_data, + alert_data, + layout_rect: cx.create_rw_signal(Rect::ZERO), + title_height, + status_height, + proxy, + set_config, + update_in_progress: cx.create_rw_signal(false), + progresses: cx.create_rw_signal(IndexMap::new()), + messages: cx.create_rw_signal(Vec::new()), + common, + }; + + { + let focus = window_tab_data.common.focus; + let active_editor = window_tab_data.main_split.active_editor; + let rename_active = window_tab_data.rename.active; + let internal_command = window_tab_data.common.internal_command; + cx.create_effect(move |_| { + let focus = focus.get(); + active_editor.track(); + internal_command.send(InternalCommand::ResetBlinkCursor); + + if focus != Focus::Rename && rename_active.get_untracked() { + rename_active.set(false); + } + }); + } + + { + let window_tab_data = window_tab_data.clone(); + window_tab_data.common.lapce_command.listen(move |cmd| { + window_tab_data.run_lapce_command(cmd); + }); + } + + { + let window_tab_data = window_tab_data.clone(); + window_tab_data.common.workbench_command.listen(move |cmd| { + window_tab_data.run_workbench_command(cmd, None); + }); + } + + { + let window_tab_data = window_tab_data.clone(); + let internal_command = window_tab_data.common.internal_command; + internal_command.listen(move |cmd| { + window_tab_data.run_internal_command(cmd); + }); + } + + { + let window_tab_data = window_tab_data.clone(); + let notification = window_tab_data.proxy.notification; + cx.create_effect(move |_| { + notification.with(|rpc| { + if let Some(rpc) = rpc.as_ref() { + window_tab_data.handle_core_notification(rpc); + } + }); + }); + } + + window_tab_data + } + + pub fn reload_config(&self) { + let db: Arc = use_context().unwrap(); + + let disabled_volts = db.get_disabled_volts().unwrap_or_default(); + let workspace_disabled_volts = db + .get_workspace_disabled_volts(&self.workspace) + .unwrap_or_default(); + let mut all_disabled_volts = disabled_volts; + all_disabled_volts.extend(workspace_disabled_volts); + + let config = LapceConfig::load( + &self.workspace, + &all_disabled_volts, + &self.common.window_common.extra_plugin_paths, + ); + self.common.keypress.update(|keypress| { + keypress.update_keymaps(&config); + }); + + let mut change_plugins = Vec::new(); + for (key, configs) in self.common.config.get_untracked().plugins.iter() { + if config + .plugins + .get(key) + .map(|x| x != configs) + .unwrap_or_default() + { + change_plugins.push(key.clone()); + } + } + self.set_config.set(Arc::new(config.clone())); + if !change_plugins.is_empty() { + self.common + .proxy + .update_plugin_configs(config.plugins.clone()); + if config.core.auto_reload_plugin { + let mut plugin_metas: HashMap< + String, + lapce_rpc::plugin::VoltMetadata, + > = self + .plugin + .installed + .get_untracked() + .values() + .map(|x| { + let meta = x.meta.get_untracked(); + (meta.name.clone(), meta) + }) + .collect(); + for name in change_plugins { + if let Some(meta) = plugin_metas.remove(&name) { + self.common.proxy.reload_volt(meta); + } else { + tracing::error!("not found volt metadata of {}", name); + } + } + } + } + } + + pub fn run_lapce_command(&self, cmd: LapceCommand) { + match cmd.kind { + CommandKind::Workbench(command) => { + self.run_workbench_command(command, cmd.data); + } + CommandKind::Scroll(_) + | CommandKind::Focus(_) + | CommandKind::Edit(_) + | CommandKind::Move(_) => { + if self.palette.status.get_untracked() != PaletteStatus::Inactive { + self.palette.run_command(&cmd, None, Modifiers::empty()); + } else if let Some(editor_data) = + self.main_split.active_editor.get_untracked() + { + editor_data.run_command(&cmd, None, Modifiers::empty()); + } else { + // TODO: dispatch to current focused view? + } + } + CommandKind::MotionMode(_) => {} + CommandKind::MultiSelection(_) => {} + } + } + + pub fn run_workbench_command( + &self, + cmd: LapceWorkbenchCommand, + data: Option, + ) { + use LapceWorkbenchCommand::*; + match cmd { + // ==== Modal ==== + EnableModal => { + let internal_command = self.common.internal_command; + internal_command.send(InternalCommand::SetModal { modal: true }); + } + DisableModal => { + let internal_command = self.common.internal_command; + internal_command.send(InternalCommand::SetModal { modal: false }); + } + + // ==== Files / Folders ==== + OpenFolder => { + if !self.workspace.kind.is_remote() { + let window_command = self.common.window_common.window_command; + let mut options = FileDialogOptions::new().title("Choose a folder").select_directories(); + options = if let Some(parent) = self.workspace.path.as_ref().and_then(|x| x.parent()) { + options.force_starting_directory(parent) + } else { + options + }; + open_file(options, move |file| { + if let Some(mut file) = file { + let workspace = LapceWorkspace { + kind: LapceWorkspaceType::Local, + path: Some(if let Some(path) = file.path.pop() { + path + } else { + tracing::error!("No path"); + return; + }), + last_open: std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_secs(), + }; + window_command + .send(WindowCommand::SetWorkspace { workspace }); + } + }); + } + } + CloseFolder => { + if !self.workspace.kind.is_remote() { + let window_command = self.common.window_common.window_command; + let workspace = LapceWorkspace { + kind: LapceWorkspaceType::Local, + path: None, + last_open: 0, + }; + window_command.send(WindowCommand::SetWorkspace { workspace }); + } + } + OpenFile => { + if !self.workspace.kind.is_remote() { + let internal_command = self.common.internal_command; + let options = FileDialogOptions::new().title("Choose a file"); + open_file(options, move |file| { + if let Some(mut file) = file { + internal_command.send(InternalCommand::OpenFile { + path: if let Some(path) = file.path.pop() { + path + } else { + tracing::error!("No path"); + return; + }, + }) + } + }); + } + } + NewFile => { + self.main_split.new_file(); + } + RevealActiveFileInFileExplorer => { + if let Some(editor_data) = self.main_split.active_editor.get() { + let doc = editor_data.doc(); + let path = if let DocContent::File { path, .. } = + doc.content.get_untracked() + { + Some(path) + } else { + None + }; + let Some(path) = path else { return }; + let path = path.parent().unwrap_or(&path); + + open_uri(path); + } + } + + SaveAll => { + self.main_split.editors.with_editors_untracked(|editors| { + let mut paths = HashSet::new(); + for (_, editor_data) in editors.iter() { + let doc = editor_data.doc(); + let should_save = if let DocContent::File { path, .. } = + doc.content.get_untracked() + { + if paths.contains(&path) { + false + } else { + paths.insert(path.clone()); + + true + } + } else { + false + }; + + if should_save { + editor_data.save(true, || {}); + } + } + }); + } + + // ==== Configuration / Info Files and Folders ==== + OpenSettings => { + self.main_split.open_settings(); + } + OpenSettingsFile => { + if let Some(path) = LapceConfig::settings_file() { + self.main_split.jump_to_location( + EditorLocation { + path, + position: None, + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }, + None, + ); + } + } + OpenSettingsDirectory => { + if let Some(dir) = Directory::config_directory() { + open_uri(&dir); + } + } + OpenThemeColorSettings => { + self.main_split.open_theme_color_settings(); + } + OpenKeyboardShortcuts => { + self.main_split.open_keymap(); + } + OpenKeyboardShortcutsFile => { + if let Some(path) = LapceConfig::keymaps_file() { + self.main_split.jump_to_location( + EditorLocation { + path, + position: None, + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }, + None, + ); + } + } + OpenLogFile => { + if let Some(dir) = Directory::logs_directory() { + self.open_paths(&[PathObject::from_path( + dir.join(format!( + "lapce.{}.log", + chrono::prelude::Local::now().format("%Y-%m-%d") + )), + false, + )]) + } + } + OpenLogsDirectory => { + if let Some(dir) = Directory::logs_directory() { + open_uri(&dir); + } + } + OpenProxyDirectory => { + if let Some(dir) = Directory::proxy_directory() { + open_uri(&dir); + } + } + OpenThemesDirectory => { + if let Some(dir) = Directory::themes_directory() { + open_uri(&dir); + } + } + OpenPluginsDirectory => { + if let Some(dir) = Directory::plugins_directory() { + open_uri(&dir); + } + } + OpenGrammarsDirectory => { + if let Some(dir) = Directory::grammars_directory() { + open_uri(&dir); + } + } + OpenQueriesDirectory => { + if let Some(dir) = Directory::queries_directory() { + open_uri(&dir); + } + } + + InstallTheme => {} + ExportCurrentThemeSettings => { + self.main_split.export_theme(); + } + ToggleInlayHints => {} + + // ==== Window ==== + ReloadWindow => { + self.common.window_common.window_command.send( + WindowCommand::SetWorkspace { + workspace: (*self.workspace).clone(), + }, + ); + } + NewWindow => { + self.common + .window_common + .window_command + .send(WindowCommand::NewWindow); + } + CloseWindow => { + self.common + .window_common + .window_command + .send(WindowCommand::CloseWindow); + } + // ==== Window Tabs ==== + NewWindowTab => { + self.common.window_common.window_command.send( + WindowCommand::NewWorkspaceTab { + workspace: LapceWorkspace::default(), + end: false, + }, + ); + } + CloseWindowTab => { + self.common + .window_common + .window_command + .send(WindowCommand::CloseWorkspaceTab { index: None }); + } + NextWindowTab => { + self.common + .window_common + .window_command + .send(WindowCommand::NextWorkspaceTab); + } + PreviousWindowTab => { + self.common + .window_common + .window_command + .send(WindowCommand::PreviousWorkspaceTab); + } + + // ==== Editor Tabs ==== + NextEditorTab => { + if let Some(editor_tab_id) = + self.main_split.active_editor_tab.get_untracked() + { + self.main_split.editor_tabs.with_untracked(|editor_tabs| { + let Some(editor_tab) = editor_tabs.get(&editor_tab_id) + else { + return; + }; + + let new_index = editor_tab.with_untracked(|editor_tab| { + if editor_tab.children.is_empty() { + None + } else if editor_tab.active + == editor_tab.children.len() - 1 + { + Some(0) + } else { + Some(editor_tab.active + 1) + } + }); + + if let Some(new_index) = new_index { + editor_tab.update(|editor_tab| { + editor_tab.active = new_index; + }); + } + }); + } + } + PreviousEditorTab => { + if let Some(editor_tab_id) = + self.main_split.active_editor_tab.get_untracked() + { + self.main_split.editor_tabs.with_untracked(|editor_tabs| { + let Some(editor_tab) = editor_tabs.get(&editor_tab_id) + else { + return; + }; + + let new_index = editor_tab.with_untracked(|editor_tab| { + if editor_tab.children.is_empty() { + None + } else if editor_tab.active == 0 { + Some(editor_tab.children.len() - 1) + } else { + Some(editor_tab.active - 1) + } + }); + + if let Some(new_index) = new_index { + editor_tab.update(|editor_tab| { + editor_tab.active = new_index; + }); + } + }); + } + } + + // ==== Terminal ==== + NewTerminalTab => { + self.terminal.new_tab( + self.common + .config + .get_untracked() + .terminal + .get_default_profile(), + ); + if !self.panel.is_panel_visible(&PanelKind::Terminal) { + self.panel.show_panel(&PanelKind::Terminal); + } + self.common.focus.set(Focus::Panel(PanelKind::Terminal)); + } + CloseTerminalTab => { + self.terminal.close_tab(None); + if self + .terminal + .tab_info + .with_untracked(|info| info.tabs.is_empty()) + { + if self.panel.is_panel_visible(&PanelKind::Terminal) { + self.panel.hide_panel(&PanelKind::Terminal); + } + self.common.focus.set(Focus::Workbench); + } else { + if !self.panel.is_panel_visible(&PanelKind::Terminal) { + self.panel.show_panel(&PanelKind::Terminal); + } + self.common.focus.set(Focus::Panel(PanelKind::Terminal)); + } + } + NextTerminalTab => { + self.terminal.next_tab(); + if !self.panel.is_panel_visible(&PanelKind::Terminal) { + self.panel.show_panel(&PanelKind::Terminal); + } + self.common.focus.set(Focus::Panel(PanelKind::Terminal)); + } + PreviousTerminalTab => { + self.terminal.previous_tab(); + if !self.panel.is_panel_visible(&PanelKind::Terminal) { + self.panel.show_panel(&PanelKind::Terminal); + } + self.common.focus.set(Focus::Panel(PanelKind::Terminal)); + } + + // ==== Remote ==== + ConnectSshHost => { + self.palette.run(PaletteKind::SshHost); + } + #[cfg(windows)] + ConnectWslHost => { + self.palette.run(PaletteKind::WslHost); + } + DisconnectRemote => { + self.common.window_common.window_command.send( + WindowCommand::SetWorkspace { + workspace: LapceWorkspace { + kind: LapceWorkspaceType::Local, + path: None, + last_open: 0, + }, + }, + ); + } + + // ==== Palette Commands ==== + PaletteHelp => self.palette.run(PaletteKind::PaletteHelp), + PaletteHelpAndFile => self.palette.run(PaletteKind::HelpAndFile), + PaletteLine => { + self.palette.run(PaletteKind::Line); + } + Palette => { + self.palette.run(PaletteKind::File); + } + PaletteSymbol => { + self.palette.run(PaletteKind::DocumentSymbol); + } + PaletteWorkspaceSymbol => {} + PaletteCommand => { + self.palette.run(PaletteKind::Command); + } + PaletteWorkspace => { + self.palette.run(PaletteKind::Workspace); + } + PaletteRunAndDebug => { + self.palette.run(PaletteKind::RunAndDebug); + } + PaletteSCMReferences => { + self.palette.run(PaletteKind::SCMReferences); + } + ChangeColorTheme => { + self.palette.run(PaletteKind::ColorTheme); + } + ChangeIconTheme => { + self.palette.run(PaletteKind::IconTheme); + } + ChangeFileLanguage => { + self.palette.run(PaletteKind::Language); + } + ChangeFileLineEnding => { + self.palette.run(PaletteKind::LineEnding); + } + DiffFiles => self.palette.run(PaletteKind::DiffFiles), + + // ==== Running / Debugging ==== + RunAndDebugRestart => { + let active_term = self.terminal.debug.active_term.get_untracked(); + if let Some(is_debug) = active_term + .and_then(|term_id| self.terminal.restart_run_debug(term_id)) + { + self.panel.show_panel(&PanelKind::Terminal); + if is_debug { + self.panel.show_panel(&PanelKind::Debug); + } + } else { + self.palette.run(PaletteKind::RunAndDebug); + } + } + RunAndDebugStop => { + let active_term = self.terminal.debug.active_term.get_untracked(); + if let Some(term_id) = active_term { + self.terminal.stop_run_debug(term_id); + } + } + + // ==== UI ==== + ZoomIn => { + let mut scale = + self.common.window_common.window_scale.get_untracked(); + scale += 0.1; + if scale > 4.0 { + scale = 4.0 + } + self.common.window_common.window_scale.set(scale); + + LapceConfig::update_file( + "ui", + "scale", + toml_edit::Value::from(scale), + ); + } + ZoomOut => { + let mut scale = + self.common.window_common.window_scale.get_untracked(); + scale -= 0.1; + if scale < 0.1 { + scale = 0.1 + } + self.common.window_common.window_scale.set(scale); + + LapceConfig::update_file( + "ui", + "scale", + toml_edit::Value::from(scale), + ); + } + ZoomReset => { + self.common.window_common.window_scale.set(1.0); + + LapceConfig::update_file( + "ui", + "scale", + toml_edit::Value::from(1.0), + ); + } + + ToggleMaximizedPanel => { + if let Some(data) = data { + if let Ok(kind) = serde_json::from_value::(data) { + self.panel.toggle_maximize(&kind); + } + } else { + self.panel.toggle_active_maximize(); + } + } + HidePanel => { + if let Some(data) = data { + if let Ok(kind) = serde_json::from_value::(data) { + self.hide_panel(kind); + } + } + } + ShowPanel => { + if let Some(data) = data { + if let Ok(kind) = serde_json::from_value::(data) { + self.show_panel(kind); + } + } + } + TogglePanelFocus => { + if let Some(data) = data { + if let Ok(kind) = serde_json::from_value::(data) { + self.toggle_panel_focus(kind); + } + } + } + TogglePanelVisual => { + if let Some(data) = data { + if let Ok(kind) = serde_json::from_value::(data) { + self.toggle_panel_visual(kind); + } + } + } + TogglePanelLeftVisual => { + self.toggle_container_visual(&PanelContainerPosition::Left); + } + TogglePanelRightVisual => { + self.toggle_container_visual(&PanelContainerPosition::Right); + } + TogglePanelBottomVisual => { + self.toggle_container_visual(&PanelContainerPosition::Bottom); + } + ToggleTerminalFocus => { + self.toggle_panel_focus(PanelKind::Terminal); + } + ToggleSourceControlFocus => { + self.toggle_panel_focus(PanelKind::SourceControl); + } + TogglePluginFocus => { + self.toggle_panel_focus(PanelKind::Plugin); + } + ToggleFileExplorerFocus => { + self.toggle_panel_focus(PanelKind::FileExplorer); + } + ToggleProblemFocus => { + self.toggle_panel_focus(PanelKind::Problem); + } + ToggleSearchFocus => { + self.toggle_panel_focus(PanelKind::Search); + } + ToggleTerminalVisual => { + self.toggle_panel_visual(PanelKind::Terminal); + } + ToggleSourceControlVisual => { + self.toggle_panel_visual(PanelKind::SourceControl); + } + TogglePluginVisual => { + self.toggle_panel_visual(PanelKind::Plugin); + } + ToggleFileExplorerVisual => { + self.toggle_panel_visual(PanelKind::FileExplorer); + } + ToggleProblemVisual => { + self.toggle_panel_visual(PanelKind::Problem); + } + ToggleDebugVisual => { + self.toggle_panel_visual(PanelKind::Debug); + } + ToggleSearchVisual => { + self.toggle_panel_visual(PanelKind::Search); + } + FocusEditor => { + self.common.focus.set(Focus::Workbench); + } + FocusTerminal => { + self.common.focus.set(Focus::Panel(PanelKind::Terminal)); + } + OpenUIInspector => { + self.common.view_id.get_untracked().inspect(); + } + ShowEnvironment => { + self.main_split.show_env(); + } + + // ==== Source Control ==== + SourceControlInit => { + self.proxy.proxy_rpc.git_init(); + } + CheckoutReference => match data { + Some(reference) => { + if let Some(reference) = reference.as_str() { + self.proxy.proxy_rpc.git_checkout(reference.to_string()); + } + } + None => error!("No ref provided"), + }, + SourceControlCommit => { + self.source_control.commit(); + } + SourceControlCopyActiveFileRemoteUrl => {} + SourceControlDiscardActiveFileChanges => {} + SourceControlDiscardTargetFileChanges => { + if let Some(diff) = data + .and_then(|data| serde_json::from_value::(data).ok()) + { + match diff { + FileDiff::Added(path) => { + self.common.proxy.trash_path(path, Box::new(|_| {})); + } + FileDiff::Modified(path) | FileDiff::Deleted(path) => { + self.common.proxy.git_discard_files_changes(vec![path]); + } + FileDiff::Renamed(old_path, new_path) => { + self.common + .proxy + .git_discard_files_changes(vec![old_path]); + self.common.proxy.trash_path(new_path, Box::new(|_| {})); + } + } + } + } + SourceControlDiscardWorkspaceChanges => {} + + // ==== UI ==== + ShowAbout => { + self.about_data.open(); + } + + // ==== Updating ==== + RestartToUpdate => { + if let Some(release) = self + .common + .window_common + .latest_release + .get_untracked() + .as_ref() + { + let release = release.clone(); + let update_in_progress = self.update_in_progress; + if release.version != *meta::VERSION { + if let Ok(process_path) = env::current_exe() { + update_in_progress.set(true); + let send = create_ext_action( + self.common.scope, + move |_started| { + update_in_progress.set(false); + }, + ); + std::thread::Builder::new().name("RestartToUpdate".to_owned()).spawn(move || { + let do_update = || -> anyhow::Result<()> { + let src = + crate::update::download_release(&release)?; + + let path = + crate::update::extract(&src, &process_path)?; + + crate::update::restart(&path)?; + + Ok(()) + }; + + if let Err(err) = do_update() { + error!("Failed to update: {err}"); + } + + send(false); + }).unwrap(); + } + } + } + } + + // ==== Movement ==== + #[cfg(target_os = "macos")] + InstallToPATH => { + self.common.internal_command.send( + InternalCommand::ExecuteProcess { + program: String::from("osascript"), + arguments: vec![String::from("-e"), format!(r#"do shell script "ln -sf '{}' /usr/local/bin/lapce" with administrator privileges"#, std::env::args().next().unwrap())], + } + ) + } + #[cfg(target_os = "macos")] + UninstallFromPATH => { + self.common.internal_command.send( + InternalCommand::ExecuteProcess { + program: String::from("osascript"), + arguments: vec![String::from("-e"), String::from(r#"do shell script "rm /usr/local/bin/lapce" with administrator privileges"#)], + } + ) + } + JumpLocationForward => { + self.main_split.jump_location_forward(false); + } + JumpLocationBackward => { + self.main_split.jump_location_backward(false); + } + JumpLocationForwardLocal => { + self.main_split.jump_location_forward(true); + } + JumpLocationBackwardLocal => { + self.main_split.jump_location_backward(true); + } + NextError => { + self.main_split.next_error(); + } + PreviousError => {} + Quit => { + floem::quit_app(); + } + RevealInPanel => { + if let Some(editor_data) = + self.main_split.active_editor.get_untracked() + { + self.show_panel(PanelKind::FileExplorer); + self.panel + .section_open(PanelSection::FileExplorer).update(|x| { + *x = true; + }); + if let DocContent::File {path, ..} = editor_data.doc().content.get_untracked() { + self.file_explorer.reveal_in_file_tree(path); + } + } + } + SourceControlOpenActiveFileRemoteUrl => { + if let Some(editor_data) = + self.main_split.active_editor.get_untracked() + { + if let DocContent::File {path, ..} = editor_data.doc().content.get_untracked() { + let offset = editor_data.cursor().with_untracked(|c| c.offset()); + let line = editor_data.doc() + .buffer + .with_untracked(|buffer| buffer.line_of_offset(offset)); + self.common.proxy.git_get_remote_file_url( + path, + create_ext_action(self.scope, move |result| { + if let Ok(ProxyResponse::GitGetRemoteFileUrl { + file_url + }) = result + { + if let Err(err) = open::that(format!("{}#L{}", file_url, line)) { + error!("Failed to open file in github: {}", err); + } + } + }), + ); + + } + } + } + RevealInFileExplorer => { + if let Some(editor_data) = + self.main_split.active_editor.get_untracked() + { + if let DocContent::File {path, ..} = editor_data.doc().content.get_untracked() { + let path = path.parent().unwrap_or(&path); + if !path.exists() { + return; + } + if let Err(err) = open::that(path) { + error!( + "Failed to reveal file in system file explorer: {}", + err + ); + } + } + } + } + ShowCallHierarchy => { + if let Some(editor_data) = + self.main_split.active_editor.get_untracked() + { + editor_data.call_hierarchy(self.clone()); + } + } + FindReferences => { + if let Some(editor_data) = + self.main_split.active_editor.get_untracked() + { + editor_data.find_reference(self.clone()); + } + } + GoToImplementation => { + if let Some(editor_data) = + self.main_split.active_editor.get_untracked() + { + editor_data.go_to_implementation(self.clone()); + } + } + RunInTerminal => { + if let Some(editor_data) = + self.main_split.active_editor.get_untracked() + { + let name = editor_data.word_at_cursor(); + if !name.is_empty() { + let mut args_str = name.split(" "); + let program = args_str.next().map(|x| x.to_string()).unwrap(); + let args: Vec = args_str.map(|x| x.to_string()).collect(); + let args = if args.is_empty() { + None + } else { + Some(args) + }; + + let config = RunDebugConfig { + ty: None, + name, + program, + args, + cwd: None, + env: None, + prelaunch: None, + debug_command: None, + dap_id: Default::default(), + tracing_output: false, + config_source: ConfigSource::RunInTerminal, + }; + self.common + .internal_command + .send(InternalCommand::RunAndDebug { mode: RunDebugMode::Run, config }); + } + } + } + GoToLocation => { + if let Some(editor_data) = + self.main_split.active_editor.get_untracked() + { + let doc = editor_data.doc(); + let path = match if doc.loaded() { + doc.content.with_untracked(|c| c.path().cloned()) + } else { + None + } { + Some(path) => path, + None => return, + }; + let offset = editor_data.cursor().with_untracked(|c| c.offset()); + let internal_command = self.common.internal_command; + + internal_command.send(InternalCommand::MakeConfirmed); + internal_command.send(InternalCommand::GoToLocation { location: EditorLocation { + path, + position: Some(EditorPosition::Offset(offset)), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + } }); + } + } + AddRunDebugConfig => { + if let Some(editor_data) = + self.main_split.active_editor.get_untracked() + { + editor_data.receive_char(DEFAULT_RUN_TOML); + } + } + + } + } + + pub fn run_internal_command(&self, cmd: InternalCommand) { + let cx = self.scope; + match cmd { + InternalCommand::ReloadConfig => { + self.reload_config(); + } + InternalCommand::UpdateLogLevel { level } => { + // TODO: implement logging panel, runtime log level change + debug!("{level}"); + } + InternalCommand::MakeConfirmed => { + if let Some(editor) = self.main_split.active_editor.get_untracked() { + editor.confirmed.set(true); + } + } + InternalCommand::OpenFile { path } => { + self.main_split.jump_to_location( + EditorLocation { + path, + position: None, + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }, + None, + ); + } + InternalCommand::OpenAndConfirmedFile { path } => { + self.main_split.jump_to_location( + EditorLocation { + path, + position: None, + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }, + None, + ); + if let Some(editor) = self.main_split.active_editor.get_untracked() { + editor.confirmed.set(true); + } + } + InternalCommand::OpenFileInNewTab { path } => { + self.main_split.jump_to_location( + EditorLocation { + path, + position: None, + scroll_offset: None, + ignore_unconfirmed: true, + same_editor_tab: false, + }, + None, + ); + } + InternalCommand::OpenFileChanges { path } => { + self.main_split.open_file_changes(path); + } + InternalCommand::ReloadFileExplorer => { + self.file_explorer.reload(); + } + InternalCommand::TestPathCreation { new_path } => { + let naming = self.file_explorer.naming; + + let send = create_ext_action( + self.scope, + move |response: Result| match response { + Ok(_) => { + naming.update(Naming::set_ok); + } + Err(err) => { + naming.update(|naming| naming.set_err(err.message)); + } + }, + ); + + self.common.proxy.test_create_at_path(new_path, send); + } + InternalCommand::FinishRenamePath { + current_path, + new_path, + } => { + let send_current_path = current_path.clone(); + let send_new_path = new_path.clone(); + let file_explorer = self.file_explorer.clone(); + let editors = self.main_split.editors; + + let send = create_ext_action( + self.scope, + move |response: Result| match response { + Ok(response) => { + // Get the canonicalized new path from the proxy. + let new_path = + if let ProxyResponse::CreatePathResponse { path } = + response + { + path + } else { + send_new_path + }; + + // If the renamed item is a file, update any editors the file is open + // in to use the new path. + // If the renamed item is a directory, update any editors in which a + // file the renamed directory is an ancestor of is open to use the + // file's new path. + let renamed_editors_content: Vec<_> = editors + .with_editors_untracked(|editors| { + editors + .values() + .map(|editor| editor.doc().content) + .filter(|content| { + content.with_untracked(|content| { + match content { + DocContent::File { + path, + .. + } => path.starts_with( + &send_current_path, + ), + _ => false, + } + }) + }) + .collect() + }); + + for content in renamed_editors_content { + content.update(|content| { + if let DocContent::File { path, .. } = content { + if let Ok(suffix) = + path.strip_prefix(&send_current_path) + { + *path = new_path.join(suffix); + } + } + }); + } + + file_explorer.reload(); + file_explorer.naming.set(Naming::None); + } + Err(err) => { + file_explorer + .naming + .update(|naming| naming.set_err(err.message)); + } + }, + ); + + self.file_explorer.naming.update(Naming::set_pending); + self.common + .proxy + .rename_path(current_path.clone(), new_path, send); + } + InternalCommand::FinishNewNode { is_dir, path } => { + let file_explorer = self.file_explorer.clone(); + let internal_command = self.common.internal_command; + + let send = create_ext_action( + self.scope, + move |response: Result| { + match response { + Ok(response) => { + file_explorer.reload(); + file_explorer.naming.set(Naming::None); + + // Open a new file in the editor + if let ProxyResponse::CreatePathResponse { path } = + response + { + if !is_dir { + internal_command.send( + InternalCommand::OpenFile { path }, + ); + } + } + } + Err(err) => { + file_explorer + .naming + .update(|naming| naming.set_err(err.message)); + } + } + }, + ); + + self.file_explorer.naming.update(Naming::set_pending); + if is_dir { + self.common.proxy.create_directory(path, send); + } else { + self.common.proxy.create_file(path, send); + } + } + InternalCommand::FinishDuplicate { source, path } => { + let file_explorer = self.file_explorer.clone(); + + let send = create_ext_action( + self.scope, + move |response: Result<_, RpcError>| { + if let Err(err) = response { + file_explorer + .naming + .update(|naming| naming.set_err(err.message)); + } else { + file_explorer.reload(); + file_explorer.naming.set(Naming::None); + } + }, + ); + + self.file_explorer.naming.update(Naming::set_pending); + self.common.proxy.duplicate_path(source, path, send); + } + InternalCommand::GoToLocation { location } => { + self.main_split.go_to_location(location, None); + } + InternalCommand::JumpToLocation { location } => { + self.main_split.jump_to_location(location, None); + } + InternalCommand::PaletteReferences { references } => { + self.palette.references.set(references); + self.palette.run(PaletteKind::Reference); + } + InternalCommand::Split { + direction, + editor_tab_id, + } => { + self.main_split.split(direction, editor_tab_id); + } + InternalCommand::SplitMove { + direction, + editor_tab_id, + } => { + self.main_split.split_move(direction, editor_tab_id); + } + InternalCommand::SplitExchange { editor_tab_id } => { + self.main_split.split_exchange(editor_tab_id); + } + InternalCommand::EditorTabClose { editor_tab_id } => { + self.main_split.editor_tab_close(editor_tab_id); + } + InternalCommand::EditorTabChildClose { + editor_tab_id, + child, + } => { + self.main_split + .editor_tab_child_close(editor_tab_id, child, false); + } + InternalCommand::EditorTabCloseByKind { + editor_tab_id, + child, + kind, + } => { + self.main_split.editor_tab_child_close_by_kind( + editor_tab_id, + child, + kind, + ); + } + InternalCommand::ShowCodeActions { + offset, + mouse_click, + plugin_id, + code_actions, + } => { + let mut code_action = self.code_action.get_untracked(); + code_action.show(plugin_id, code_actions, offset, mouse_click); + self.code_action.set(code_action); + } + InternalCommand::RunCodeAction { plugin_id, action } => { + self.main_split.run_code_action(plugin_id, action); + } + InternalCommand::ApplyWorkspaceEdit { edit } => { + self.main_split.apply_workspace_edit(&edit); + } + InternalCommand::SaveJumpLocation { + path, + offset, + scroll_offset, + } => { + self.main_split + .save_jump_location(path, offset, scroll_offset); + } + InternalCommand::NewTerminal { profile } => { + self.terminal.new_tab(profile); + } + InternalCommand::SplitTerminal { term_id } => { + self.terminal.split(term_id); + } + InternalCommand::SplitTerminalNext { term_id } => { + self.terminal.split_next(term_id); + } + InternalCommand::SplitTerminalPrevious { term_id } => { + self.terminal.split_previous(term_id); + } + InternalCommand::SplitTerminalExchange { term_id } => { + self.terminal.split_exchange(term_id); + } + InternalCommand::RunAndDebug { mode, config } => { + self.run_and_debug(cx, &mode, &config); + } + InternalCommand::StartRename { + path, + placeholder, + position, + start, + } => { + self.rename.start(path, placeholder, start, position); + } + InternalCommand::Search { pattern } => { + self.main_split.set_find_pattern(pattern); + } + InternalCommand::FindEditorReceiveChar { s } => { + self.main_split.find_editor.receive_char(&s); + } + InternalCommand::ReplaceEditorReceiveChar { s } => { + self.main_split.replace_editor.receive_char(&s); + } + InternalCommand::FindEditorCommand { + command, + count, + mods, + } => { + self.main_split + .find_editor + .run_command(&command, count, mods); + } + InternalCommand::ReplaceEditorCommand { + command, + count, + mods, + } => { + self.main_split + .replace_editor + .run_command(&command, count, mods); + } + InternalCommand::FocusEditorTab { editor_tab_id } => { + self.main_split.active_editor_tab.set(Some(editor_tab_id)); + } + InternalCommand::SetColorTheme { name, save } => { + if save { + // The config file is watched + LapceConfig::update_file( + "core", + "color-theme", + toml_edit::Value::from(name), + ); + } else { + let mut new_config = self.common.config.get_untracked(); + Arc::make_mut(&mut new_config) + .set_color_theme(&self.workspace, &name); + self.set_config.set(new_config); + } + } + InternalCommand::SetIconTheme { name, save } => { + if save { + // The config file is watched + LapceConfig::update_file( + "core", + "icon-theme", + toml_edit::Value::from(name), + ); + } else { + let mut new_config = self.common.config.get_untracked(); + Arc::make_mut(&mut new_config) + .set_icon_theme(&self.workspace, &name); + self.set_config.set(new_config); + } + } + InternalCommand::SetModal { modal } => { + LapceConfig::update_file( + "core", + "modal", + toml_edit::Value::from(modal), + ); + } + InternalCommand::OpenWebUri { uri } => { + if !uri.is_empty() { + match open::that(&uri) { + Ok(_) => { + trace!(TraceLevel::TRACE, "opened web uri: {uri:?}"); + } + Err(e) => { + trace!( + TraceLevel::ERROR, + "failed to open web uri: {uri:?}, error: {e}" + ); + } + } + } + } + InternalCommand::ShowAlert { + title, + msg, + buttons, + } => { + self.show_alert(title, msg, buttons); + } + InternalCommand::HideAlert => { + self.alert_data.active.set(false); + } + InternalCommand::SaveScratchDoc { doc } => { + self.main_split.save_scratch_doc(doc); + } + InternalCommand::SaveScratchDoc2 { doc } => { + self.main_split.save_scratch_doc2(doc); + } + InternalCommand::UpdateProxyStatus { status } => { + self.common.proxy_status.set(Some(status)); + } + InternalCommand::DapFrameScopes { dap_id, frame_id } => { + self.terminal.dap_frame_scopes(dap_id, frame_id); + } + InternalCommand::OpenVoltView { volt_id } => { + self.main_split.open_volt_view(volt_id); + } + InternalCommand::ResetBlinkCursor => { + // All the editors share the blinking information and logic, so we can just reset + // one of them. + if let Some(e_data) = self.main_split.active_editor.get_untracked() { + e_data.editor.cursor_info.reset(); + } + } + InternalCommand::OpenDiffFiles { + left_path, + right_path, + } => self.main_split.open_diff_files(left_path, right_path), + InternalCommand::ExecuteProcess { program, arguments } => { + let mut cmd = match std::process::Command::new(program) + .args(arguments) + .spawn() + { + Ok(v) => v, + Err(e) => { + return event!(Level::ERROR, "Failed to spawn process: {e}"); + } + }; + + match cmd.wait() { + Ok(v) => event!(Level::TRACE, "Process exited with status {v}"), + Err(e) => { + event!(Level::ERROR, "Process exited with an error: {e}") + } + }; + } + InternalCommand::ClearTerminalBuffer { + view_id, + tab_index, + terminal_index, + } => { + let Some(tab) = self.terminal.tab_info.with_untracked(|x| { + x.tabs.iter().find_map(|(index, data)| { + if index.get_untracked() == tab_index { + Some(data.clone()) + } else { + None + } + }) + }) else { + error!("could not find terminal tab data: index={tab_index}"); + return; + }; + let Some(raw) = tab.terminals.with_untracked(|x| { + x.iter().find_map(|(index, data)| { + if index.get_untracked() == terminal_index { + Some(data.raw.get_untracked()) + } else { + None + } + }) + }) else { + error!("could not find terminal data: index={terminal_index}"); + return; + }; + raw.write().term.reset_state(); + view_id.request_paint(); + } + InternalCommand::StopTerminal { term_id } => { + self.terminal.stop_run_debug(term_id); + } + InternalCommand::RestartTerminal { term_id } => { + if let Some(is_debug) = self.terminal.restart_run_debug(term_id) { + self.panel.show_panel(&PanelKind::Terminal); + if is_debug { + self.panel.show_panel(&PanelKind::Debug); + } + } else { + self.palette.run(PaletteKind::RunAndDebug); + } + } + InternalCommand::CallHierarchyIncoming { item_id } => { + self.call_hierarchy_incoming(item_id); + } + } + } + + fn handle_core_notification(&self, rpc: &CoreNotification) { + let cx = self.scope; + match rpc { + CoreNotification::ProxyStatus { status } => { + self.common.proxy_status.set(Some(status.to_owned())); + } + CoreNotification::DiffInfo { diff } => { + self.source_control.branch.set(diff.head.clone()); + self.source_control + .branches + .set(diff.branches.iter().cloned().collect()); + self.source_control + .tags + .set(diff.tags.iter().cloned().collect()); + self.source_control.file_diffs.update(|file_diffs| { + *file_diffs = diff + .diffs + .iter() + .cloned() + .map(|diff| { + let checked = + file_diffs.get(diff.path()).is_none_or(|(_, c)| *c); + (diff.path().clone(), (diff, checked)) + }) + .collect(); + }); + + let docs = self.main_split.docs.get_untracked(); + for (_, doc) in docs { + doc.retrieve_head(); + } + } + CoreNotification::CompletionResponse { + request_id, + input, + resp, + plugin_id, + } => { + self.common.completion.update(|completion| { + completion.receive(*request_id, input, resp, *plugin_id); + }); + + let completion = self.common.completion.get_untracked(); + let editor_data = completion + .latest_editor_id + .and_then(|id| self.main_split.editors.editor_untracked(id)); + if let Some(editor_data) = editor_data { + let cursor_offset = + editor_data.cursor().with_untracked(|c| c.offset()); + completion + .update_document_completion(&editor_data, cursor_offset); + } + } + CoreNotification::PublishDiagnostics { diagnostics } => { + let path = path_from_url(&diagnostics.uri); + let diagnostics: im::Vector = diagnostics + .diagnostics + .clone() + .into_iter() + .sorted_by_key(|d| d.range.start) + .collect(); + + self.main_split + .get_diagnostic_data(&path) + .diagnostics + .set(diagnostics); + + // inform the document about the diagnostics + if let Some(doc) = self + .main_split + .docs + .with_untracked(|docs| docs.get(&path).cloned()) + { + doc.init_diagnostics(); + } + } + CoreNotification::ServerStatus { params } => { + if params.is_ok() { + // todo filter by language + self.main_split.docs.with_untracked(|x| { + for doc in x.values() { + doc.get_code_lens(); + doc.get_document_symbol(); + doc.get_semantic_styles(); + doc.get_folding_range(); + doc.get_inlay_hints(); + } + }); + } + } + CoreNotification::TerminalProcessStopped { term_id, exit_code } => { + debug!("TerminalProcessStopped {:?}, {:?}", term_id, exit_code); + if let Err(err) = self + .common + .term_tx + .send((*term_id, TermEvent::CloseTerminal)) + { + tracing::error!("{:?}", err); + } + self.terminal.terminal_stopped(term_id, *exit_code); + if self + .terminal + .tab_info + .with_untracked(|info| info.tabs.is_empty()) + { + if self.panel.is_panel_visible(&PanelKind::Terminal) { + self.panel.hide_panel(&PanelKind::Terminal); + } + self.common.focus.set(Focus::Workbench); + } + } + CoreNotification::TerminalLaunchFailed { term_id, error } => { + self.terminal.launch_failed(term_id, error); + } + CoreNotification::RunInTerminal { config } => { + self.run_in_terminal(cx, &RunDebugMode::Debug, config, true); + } + CoreNotification::TerminalProcessId { + term_id, + process_id, + } => { + self.terminal.set_process_id(term_id, *process_id); + } + CoreNotification::DapStopped { + dap_id, + stopped, + stack_frames, + variables, + } => { + self.show_panel(PanelKind::Debug); + self.terminal + .dap_stopped(dap_id, stopped, stack_frames, variables); + } + CoreNotification::OpenPaths { paths } => { + self.open_paths(paths); + } + CoreNotification::DapContinued { dap_id } => { + self.terminal.dap_continued(dap_id); + } + CoreNotification::DapBreakpointsResp { + path, breakpoints, .. + } => { + self.terminal.debug.breakpoints.update(|all_breakpoints| { + if let Some(current_breakpoints) = all_breakpoints.get_mut(path) + { + let mut line_changed = HashSet::new(); + let mut i = 0; + for (_, current_breakpoint) in current_breakpoints.iter_mut() + { + if !current_breakpoint.active { + continue; + } + if let Some(breakpoint) = breakpoints.get(i) { + current_breakpoint.id = breakpoint.id; + current_breakpoint.verified = breakpoint.verified; + current_breakpoint + .message + .clone_from(&breakpoint.message); + if let Some(new_line) = breakpoint.line { + if current_breakpoint.line + 1 != new_line { + line_changed.insert(current_breakpoint.line); + current_breakpoint.line = + new_line.saturating_sub(1); + } + } + } + i += 1; + } + for line in line_changed { + if let Some(changed) = current_breakpoints.remove(&line) + { + current_breakpoints.insert(changed.line, changed); + } + } + } + }); + } + CoreNotification::OpenFileChanged { path, content } => { + self.main_split.open_file_changed(path, content); + } + CoreNotification::VoltInstalled { volt, icon } => { + self.plugin.volt_installed(volt, icon); + } + CoreNotification::VoltRemoved { volt, .. } => { + self.plugin.volt_removed(volt); + } + CoreNotification::WorkDoneProgress { progress } => { + self.update_progress(progress); + } + CoreNotification::ShowMessage { title, message } => { + self.show_message(title, message); + } + CoreNotification::Log { + level, + message, + target, + } => { + use lapce_rpc::core::LogLevel; + use tracing_log::log::{Level, log}; + + let target = target.clone().unwrap_or(String::from("unknown")); + + match level { + LogLevel::Trace => { + log!(target: &target, Level::Trace, "{}", message); + } + LogLevel::Debug => { + log!(target: &target, Level::Debug, "{}", message); + } + LogLevel::Info => { + log!(target: &target, Level::Info, "{}", message); + } + LogLevel::Warn => { + log!(target: &target, Level::Warn, "{}", message); + } + LogLevel::Error => { + log!(target: &target, Level::Error, "{}", message); + } + } + } + CoreNotification::LogMessage { message, target } => { + use lsp_types::MessageType; + use tracing_log::log::{Level, log}; + match message.typ { + MessageType::ERROR => { + log!(target: target, Level::Error, "{}", message.message) + } + MessageType::WARNING => { + log!(target: target, Level::Warn, "{}", message.message) + } + MessageType::INFO => { + log!(target: target, Level::Info, "{}", message.message) + } + MessageType::DEBUG => { + log!(target: target, Level::Debug, "{}", message.message) + } + MessageType::LOG => { + log!(target: target, Level::Debug, "{}", message.message) + } + _ => {} + } + } + CoreNotification::WorkspaceFileChange => { + self.file_explorer.reload(); + } + _ => {} + } + } + + pub fn key_down<'a>(&self, event: impl Into> + Copy) -> bool { + if self.alert_data.active.get_untracked() { + return false; + } + let focus = self.common.focus.get_untracked(); + let keypress = self.common.keypress.get_untracked(); + let handle = match focus { + Focus::Workbench => self.main_split.key_down(event, &keypress), + Focus::Palette => Some(keypress.key_down(event, &self.palette)), + Focus::CodeAction => { + let code_action = self.code_action.get_untracked(); + Some(keypress.key_down(event, &code_action)) + } + Focus::Rename => Some(keypress.key_down(event, &self.rename)), + Focus::AboutPopup => Some(keypress.key_down(event, &self.about_data)), + Focus::Panel(PanelKind::Terminal) => { + self.terminal.key_down(event, &keypress) + } + Focus::Panel(PanelKind::Search) => { + Some(keypress.key_down(event, &self.global_search)) + } + Focus::Panel(PanelKind::Plugin) => { + Some(keypress.key_down(event, &self.plugin)) + } + Focus::Panel(PanelKind::SourceControl) => { + Some(keypress.key_down(event, &self.source_control)) + } + _ => None, + }; + + if let Some(handle) = &handle { + if handle.handled { + true + } else { + keypress + .handle_keymatch( + self, + handle.keymatch.clone(), + handle.keypress.clone(), + ) + .handled + } + } else { + keypress.key_down(event, self).handled + } + } + + pub fn workspace_info(&self) -> WorkspaceInfo { + let main_split_data = self + .main_split + .splits + .get_untracked() + .get(&self.main_split.root_split) + .cloned() + .unwrap(); + WorkspaceInfo { + split: main_split_data.get_untracked().split_info(self), + panel: self.panel.panel_info(), + breakpoints: self + .terminal + .debug + .breakpoints + .get_untracked() + .into_iter() + .map(|(path, breakpoints)| { + (path, breakpoints.into_values().collect::>()) + }) + .collect(), + } + } + + pub fn hover_origin(&self) -> Option { + if !self.common.hover.active.get_untracked() { + return None; + } + + let editor_id = self.common.hover.editor_id.get_untracked(); + let editor_data = self.main_split.editors.editor(editor_id)?; + + let (window_origin, viewport, editor) = ( + editor_data.window_origin(), + editor_data.viewport(), + &editor_data.editor, + ); + + // TODO(minor): affinity should be gotten from where the hover was started at. + let (point_above, point_below) = editor.points_of_offset( + self.common.hover.offset.get_untracked(), + CursorAffinity::Forward, + ); + + let window_origin = + window_origin.get() - self.common.window_origin.get().to_vec2(); + let viewport = viewport.get(); + let hover_size = self.common.hover.layout_rect.get().size(); + let tab_size = self.layout_rect.get().size(); + + let mut origin = window_origin + + Vec2::new( + point_below.x - viewport.x0, + (point_above.y - viewport.y0) - hover_size.height, + ); + if origin.y < 0.0 { + origin.y = window_origin.y + point_below.y - viewport.y0; + } + if origin.x + hover_size.width + 1.0 > tab_size.width { + origin.x = tab_size.width - hover_size.width - 1.0; + } + if origin.x <= 0.0 { + origin.x = 0.0; + } + + Some(origin) + } + + pub fn completion_origin(&self) -> Point { + let completion = self.common.completion.get(); + if completion.status == CompletionStatus::Inactive { + return Point::ZERO; + } + let config = self.common.config.get(); + let editor_data = + if let Some(editor) = self.main_split.active_editor.get_untracked() { + editor + } else { + return Point::ZERO; + }; + + let (window_origin, viewport, editor) = ( + editor_data.window_origin(), + editor_data.viewport(), + &editor_data.editor, + ); + + // TODO(minor): What affinity should we use for this? Probably just use the cursor's + // original affinity.. + let (point_above, point_below) = + editor.points_of_offset(completion.offset, CursorAffinity::Forward); + + let window_origin = + window_origin.get() - self.common.window_origin.get().to_vec2(); + let viewport = viewport.get(); + let completion_size = completion.layout_rect.size(); + let tab_size = self.layout_rect.get().size(); + + let mut origin = window_origin + + Vec2::new( + point_below.x + - viewport.x0 + - config.editor.line_height() as f64 + - 5.0, + point_below.y - viewport.y0, + ); + if origin.y + completion_size.height > tab_size.height { + origin.y = window_origin.y + (point_above.y - viewport.y0) + - completion_size.height; + } + if origin.x + completion_size.width + 1.0 > tab_size.width { + origin.x = tab_size.width - completion_size.width - 1.0; + } + if origin.x <= 0.0 { + origin.x = 0.0; + } + + origin + } + + pub fn code_action_origin(&self) -> Point { + let code_action = self.code_action.get(); + let config = self.common.config.get(); + if code_action.status.get_untracked() == CodeActionStatus::Inactive { + return Point::ZERO; + } + + let tab_size = self.layout_rect.get().size(); + let code_action_size = code_action.layout_rect.size(); + + let editor_data = + if let Some(editor) = self.main_split.active_editor.get_untracked() { + editor + } else { + return Point::ZERO; + }; + + let (window_origin, viewport, editor) = ( + editor_data.window_origin(), + editor_data.viewport(), + &editor_data.editor, + ); + + // TODO(minor): What affinity should we use for this? + let (_point_above, point_below) = + editor.points_of_offset(code_action.offset, CursorAffinity::Forward); + + let window_origin = + window_origin.get() - self.common.window_origin.get().to_vec2(); + let viewport = viewport.get(); + + let mut origin = window_origin + + Vec2::new( + if code_action.mouse_click { + 0.0 + } else { + point_below.x - viewport.x0 + }, + point_below.y - viewport.y0, + ); + + if origin.y + code_action_size.height > tab_size.height { + origin.y = origin.y + - config.editor.line_height() as f64 + - code_action_size.height; + } + if origin.x + code_action_size.width + 1.0 > tab_size.width { + origin.x = tab_size.width - code_action_size.width - 1.0; + } + if origin.x <= 0.0 { + origin.x = 0.0; + } + + origin + } + + pub fn rename_origin(&self) -> Point { + let config = self.common.config.get(); + if !self.rename.active.get() { + return Point::ZERO; + } + + let tab_size = self.layout_rect.get().size(); + let rename_size = self.rename.layout_rect.get().size(); + + let editor_data = + if let Some(editor) = self.main_split.active_editor.get_untracked() { + editor + } else { + return Point::ZERO; + }; + + let (window_origin, viewport, editor) = ( + editor_data.window_origin(), + editor_data.viewport(), + &editor_data.editor, + ); + + // TODO(minor): What affinity should we use for this? + let (_point_above, point_below) = editor.points_of_offset( + self.rename.start.get_untracked(), + CursorAffinity::Forward, + ); + + let window_origin = + window_origin.get() - self.common.window_origin.get().to_vec2(); + let viewport = viewport.get(); + + let mut origin = window_origin + + Vec2::new(point_below.x - viewport.x0, point_below.y - viewport.y0); + + if origin.y + rename_size.height > tab_size.height { + origin.y = + origin.y - config.editor.line_height() as f64 - rename_size.height; + } + if origin.x + rename_size.width + 1.0 > tab_size.width { + origin.x = tab_size.width - rename_size.width - 1.0; + } + if origin.x <= 0.0 { + origin.x = 0.0; + } + + origin + } + + /// Get the mode for the current editor or terminal + pub fn mode(&self) -> Mode { + if self.common.config.get().core.modal { + let mode = if self.common.focus.get() == Focus::Workbench { + self.main_split + .active_editor + .get() + .map(|editor| editor.cursor().with(|c| c.get_mode())) + } else { + None + }; + + mode.unwrap_or(Mode::Normal) + } else { + Mode::Insert + } + } + + pub fn toggle_panel_visual(&self, kind: PanelKind) { + if self.panel.is_panel_visible(&kind) { + self.hide_panel(kind); + } else { + self.show_panel(kind); + } + } + + /// Toggle a specific kind of panel. + fn toggle_panel_focus(&self, kind: PanelKind) { + let should_hide = match kind { + PanelKind::FileExplorer + | PanelKind::Plugin + | PanelKind::Problem + | PanelKind::Debug + | PanelKind::CallHierarchy + | PanelKind::DocumentSymbol + | PanelKind::References + | PanelKind::Implementation => { + // Some panels don't accept focus (yet). Fall back to visibility check + // in those cases. + self.panel.is_panel_visible(&kind) + } + PanelKind::Terminal | PanelKind::SourceControl | PanelKind::Search => { + self.is_panel_focused(kind) + } + }; + if should_hide { + self.hide_panel(kind); + } else { + self.show_panel(kind); + } + } + + /// Toggle a panel on one of the sides. + fn toggle_container_visual(&self, position: &PanelContainerPosition) { + let shown = !self.panel.is_container_shown(position, false); + self.panel.set_shown(&position.first(), shown); + self.panel.set_shown(&position.second(), shown); + + if shown { + if let Some((kind, _)) = self + .panel + .active_panel_at_position(&position.second(), false) + { + self.show_panel(kind); + } + + if let Some((kind, _)) = self + .panel + .active_panel_at_position(&position.first(), false) + { + self.show_panel(kind); + } + } else { + if let Some((kind, _)) = self + .panel + .active_panel_at_position(&position.second(), false) + { + self.hide_panel(kind); + } + + if let Some((kind, _)) = self + .panel + .active_panel_at_position(&position.first(), false) + { + self.hide_panel(kind); + } + } + } + + fn is_panel_focused(&self, kind: PanelKind) -> bool { + // Moving between e.g. Search and Problems doesn't affect focus, so we need to also check + // visibility. + self.common.focus.get_untracked() == Focus::Panel(kind) + && self.panel.is_panel_visible(&kind) + } + + fn hide_panel(&self, kind: PanelKind) { + self.panel.hide_panel(&kind); + self.common.focus.set(Focus::Workbench); + } + + pub fn show_panel(&self, kind: PanelKind) { + if kind == PanelKind::Terminal + && self + .terminal + .tab_info + .with_untracked(|info| info.tabs.is_empty()) + { + self.terminal.new_tab( + self.common + .config + .get_untracked() + .terminal + .get_default_profile(), + ); + } + self.panel.show_panel(&kind); + if kind == PanelKind::Search + && self.common.focus.get_untracked() == Focus::Workbench + { + let active_editor = self.main_split.active_editor.get_untracked(); + let word = active_editor.map(|editor| editor.word_at_cursor()); + if let Some(word) = word { + if !word.is_empty() { + self.global_search.set_pattern(word); + } + } + } + self.common.focus.set(Focus::Panel(kind)); + } + + fn run_and_debug( + &self, + cx: Scope, + mode: &RunDebugMode, + config: &RunDebugConfig, + ) { + debug!("{:?}", config); + match mode { + RunDebugMode::Run => { + self.run_in_terminal(cx, mode, config, false); + } + RunDebugMode::Debug => { + if config.prelaunch.is_some() { + self.run_in_terminal(cx, mode, config, false); + } else { + self.common.proxy.dap_start( + config.clone(), + self.terminal.debug.source_breakpoints(), + ) + }; + if !self.panel.is_panel_visible(&PanelKind::Debug) { + self.panel.show_panel(&PanelKind::Debug); + } + } + } + } + + fn run_in_terminal( + &self, + cx: Scope, + mode: &RunDebugMode, + config: &RunDebugConfig, + from_dap: bool, + ) { + // if not from dap, then run prelaunch first + let is_prelaunch = !from_dap; + let term_id = if let Some(terminal) = + self.terminal.get_stopped_run_debug_terminal(mode, config) + { + terminal.new_process(Some(RunDebugProcess { + mode: *mode, + config: config.clone(), + stopped: false, + created: Instant::now(), + is_prelaunch, + })); + + terminal.term_id + } else { + let new_terminal_tab = self.terminal.new_tab_run_debug( + Some(RunDebugProcess { + mode: *mode, + config: config.clone(), + stopped: false, + created: Instant::now(), + is_prelaunch, + }), + None, + ); + new_terminal_tab.active_terminal(false).unwrap().term_id + }; + self.common.focus.set(Focus::Panel(PanelKind::Terminal)); + self.terminal.focus_terminal(term_id); + + self.terminal.debug.active_term.set(Some(term_id)); + self.terminal.debug.daps.update(|daps| { + daps.insert( + config.dap_id, + DapData::new(cx, config.dap_id, term_id, self.common.clone()), + ); + }); + + if !self.panel.is_panel_visible(&PanelKind::Terminal) { + self.panel.show_panel(&PanelKind::Terminal); + } + } + + pub fn open_paths(&self, paths: &[PathObject]) { + let (folders, files): (Vec<&PathObject>, Vec<&PathObject>) = + paths.iter().partition(|p| p.is_dir); + + for folder in folders { + self.common.window_common.window_command.send( + WindowCommand::NewWorkspaceTab { + workspace: LapceWorkspace { + kind: self.workspace.kind.clone(), + path: Some(folder.path.clone()), + last_open: 0, + }, + end: false, + }, + ); + } + + for file in files { + let position = file.linecol.map(|pos| { + EditorPosition::Position(lsp_types::Position { + line: pos.line.saturating_sub(1) as u32, + character: pos.column.saturating_sub(1) as u32, + }) + }); + + self.common + .internal_command + .send(InternalCommand::GoToLocation { + location: EditorLocation { + path: file.path.clone(), + position, + scroll_offset: None, + // Create a new editor for the file, so we don't change any current unconfirmed + // editor + ignore_unconfirmed: true, + same_editor_tab: false, + }, + }); + } + } + + pub fn show_alert(&self, title: String, msg: String, buttons: Vec) { + self.alert_data.title.set(title); + self.alert_data.msg.set(msg); + self.alert_data.buttons.set(buttons); + self.alert_data.active.set(true); + } + + fn update_progress(&self, progress: &ProgressParams) { + let token = progress.token.clone(); + match &progress.value { + lsp_types::ProgressParamsValue::WorkDone(progress) => match progress { + lsp_types::WorkDoneProgress::Begin(progress) => { + let progress = WorkProgress { + token: token.clone(), + title: progress.title.clone(), + message: progress.message.clone(), + percentage: progress.percentage, + }; + self.progresses.update(|p| { + p.insert(token, progress); + }); + } + lsp_types::WorkDoneProgress::Report(report) => { + self.progresses.update(|p| { + if let Some(progress) = p.get_mut(&token) { + progress.message.clone_from(&report.message); + progress.percentage = report.percentage; + } + }) + } + lsp_types::WorkDoneProgress::End(_) => { + self.progresses.update(|p| { + p.swap_remove(&token); + }); + } + }, + } + } + + fn show_message(&self, title: &str, message: &ShowMessageParams) { + self.messages.update(|messages| { + messages.push((title.to_string(), message.clone())); + }); + } + + pub fn update_code_lens_id(&self, view_id: Option) { + if let Some(Some(old_id)) = self.code_lens.try_update(|x| { + let old = x.take(); + if let Some(id) = view_id { + let _ = x.insert(id); + } + old + }) { + remove_overlay(old_id); + } + } + + pub fn show_code_lens( + &self, + mouse_click: bool, + plugin_id: PluginId, + offset: usize, + lens: im::Vector, + ) { + self.common + .internal_command + .send(InternalCommand::ShowCodeActions { + offset, + mouse_click, + plugin_id, + code_actions: lens + .into_iter() + .filter_map(|lens| { + Some(CodeActionOrCommand::Command(lens.command?)) + }) + .collect(), + }); + } + + pub fn call_hierarchy_incoming(&self, item_id: ViewId) { + let Some(root) = self.call_hierarchy_data.root.get_untracked() else { + return; + }; + let Some(item) = CallHierarchyItemData::find_by_id(root, item_id) else { + return; + }; + let root_item = item; + let path: PathBuf = item.get_untracked().item.uri.to_file_path().unwrap(); + let scope = self.scope; + let send = + create_ext_action(scope, move |_rs: Result| { + match _rs { + Ok(ProxyResponse::CallHierarchyIncomingResponse { items }) => { + if let Some(items) = items { + let mut item_children = Vec::new(); + for x in items { + let item = Rc::new(x.from); + for range in x.from_ranges { + item_children.push(scope.create_rw_signal( + CallHierarchyItemData { + view_id: floem::ViewId::new(), + item: item.clone(), + from_range: range, + init: false, + open: scope.create_rw_signal(false), + children: + scope.create_rw_signal(Vec::new()), + }, + )) + } + } + root_item.update(|x| { + x.init = true; + x.children.update(|children| { + *children = item_children; + }) + }); + } + } + Err(err) => { + tracing::error!("{:?}", err); + } + Ok(_) => {} + } + }); + self.common.proxy.call_hierarchy_incoming( + path, + item.get_untracked().item.as_ref().clone(), + send, + ); + } +} + +/// Open path with the default application without blocking. +fn open_uri(path: &Path) { + match open::that(path) { + Ok(_) => { + debug!("opened active file: {path:?}"); + } + Err(e) => { + error!("failed to open active file: {path:?}, error: {e}"); + } + } +} diff --git a/lapce-app/src/workspace.rs b/lapce-app/src/workspace.rs new file mode 100644 index 0000000..7181ac0 --- /dev/null +++ b/lapce-app/src/workspace.rs @@ -0,0 +1,159 @@ +use std::{collections::HashMap, fmt::Display, path::PathBuf}; + +use serde::{Deserialize, Serialize}; + +use crate::{debug::LapceBreakpoint, main_split::SplitInfo, panel::data::PanelInfo}; + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)] +pub struct SshHost { + pub user: Option, + pub host: String, + pub port: Option, +} + +impl SshHost { + pub fn from_string(s: &str) -> Self { + let mut whole_splits = s.split(':'); + let splits = whole_splits + .next() + .unwrap() + .split('@') + .collect::>(); + let mut splits = splits.iter().rev(); + let host = splits.next().unwrap().to_string(); + let user = splits.next().map(|s| s.to_string()); + let port = whole_splits.next().and_then(|s| s.parse::().ok()); + Self { user, host, port } + } + + pub fn user_host(&self) -> String { + if let Some(user) = self.user.as_ref() { + format!("{user}@{}", self.host) + } else { + self.host.clone() + } + } +} + +impl Display for SshHost { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(user) = self.user.as_ref() { + write!(f, "{user}@")?; + } + write!(f, "{}", self.host)?; + if let Some(port) = self.port { + write!(f, ":{port}")?; + } + Ok(()) + } +} + +#[cfg(windows)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)] +pub struct WslHost { + pub host: String, +} + +#[cfg(windows)] +impl Display for WslHost { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.host)?; + Ok(()) + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub enum LapceWorkspaceType { + Local, + RemoteSSH(SshHost), + #[cfg(windows)] + RemoteWSL(WslHost), +} + +impl LapceWorkspaceType { + pub fn is_local(&self) -> bool { + matches!(self, LapceWorkspaceType::Local) + } + + pub fn is_remote(&self) -> bool { + use LapceWorkspaceType::*; + + #[cfg(not(windows))] + return matches!(self, RemoteSSH(_)); + + #[cfg(windows)] + return matches!(self, RemoteSSH(_) | RemoteWSL(_)); + } +} + +impl std::fmt::Display for LapceWorkspaceType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + LapceWorkspaceType::Local => f.write_str("Local"), + LapceWorkspaceType::RemoteSSH(remote) => { + write!(f, "ssh://{remote}") + } + #[cfg(windows)] + LapceWorkspaceType::RemoteWSL(remote) => { + write!(f, "{remote} (WSL)") + } + } + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct LapceWorkspace { + pub kind: LapceWorkspaceType, + pub path: Option, + pub last_open: u64, +} + +impl LapceWorkspace { + pub fn display(&self) -> Option { + let path = self.path.as_ref()?; + let path = path + .file_name() + .unwrap_or(path.as_os_str()) + .to_string_lossy() + .to_string(); + let remote = match &self.kind { + LapceWorkspaceType::Local => String::new(), + LapceWorkspaceType::RemoteSSH(remote) => { + format!(" [SSH: {}]", remote.host) + } + #[cfg(windows)] + LapceWorkspaceType::RemoteWSL(remote) => { + format!(" [WSL: {}]", remote.host) + } + }; + Some(format!("{path}{remote}")) + } +} + +impl Default for LapceWorkspace { + fn default() -> Self { + Self { + kind: LapceWorkspaceType::Local, + path: None, + last_open: 0, + } + } +} + +impl std::fmt::Display for LapceWorkspace { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}:{}", + self.kind, + self.path.as_ref().and_then(|p| p.to_str()).unwrap_or("") + ) + } +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct WorkspaceInfo { + pub split: SplitInfo, + pub panel: PanelInfo, + pub breakpoints: HashMap>, +} diff --git a/lapce-core/Cargo.toml b/lapce-core/Cargo.toml new file mode 100644 index 0000000..2182b7a --- /dev/null +++ b/lapce-core/Cargo.toml @@ -0,0 +1,43 @@ +[package] +name = "lapce-core" +license = { workspace = true } +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } + +[dependencies] +directories = { workspace = true } +itertools = { workspace = true } +once_cell = { workspace = true } +strum = { workspace = true } +strum_macros = { workspace = true } +thiserror = { workspace = true } +tracing = { workspace = true } +include_dir = { workspace = true } +regex = { workspace = true } + +lsp-types = { workspace = true } +lapce-xi-rope = { workspace = true } +lapce-rpc = { workspace = true } +floem-editor-core = { workspace = true } + +libloading = "0.8.1" +slotmap = "1.0" +arc-swap = "1.6.0" +tree-sitter = "0.22.6" +ahash = "0.8.11" +remain = "0.2" +hashbrown = { version = "0.14.5", features = ["raw"] } + + +[features] +default = [] +portable = [] +distribution = [] + +[build-dependencies] +anyhow = { workspace = true } + +[target.'cfg(not(target_os = "linux"))'.build-dependencies] +git2 = { workspace = true } diff --git a/lapce-core/build.rs b/lapce-core/build.rs new file mode 100644 index 0000000..d4a7d15 --- /dev/null +++ b/lapce-core/build.rs @@ -0,0 +1,114 @@ +use std::{env, fs, path::Path}; + +use anyhow::Result; + +#[derive(Debug)] +struct ReleaseInfo { + version: String, + branch: String, +} + +fn main() -> Result<()> { + println!("cargo:rerun-if-changed=build.rs"); + println!("cargo:rerun-if-changed=../.git/HEAD"); + println!("cargo:rerun-if-env-changed=CARGO_PKG_VERSION"); + println!("cargo:rerun-if-env-changed=CARGO_FEATURE_DISTRIBUTION"); + println!("cargo:rerun-if-env-changed=RELEASE_TAG_NAME"); + + let release_info = get_info()?; + + // Print info to terminal during compilation + println!("cargo::warning=Compiling meta: {release_info:?}"); + + let meta_file = Path::new(&env::var("OUT_DIR")?).join("meta.rs"); + + let ReleaseInfo { version, branch } = release_info; + + #[rustfmt::skip] + let meta = format!(r#" + pub const NAME: &str = "Lapce-{branch}"; + pub const VERSION: &str = "{version}"; + pub const RELEASE: ReleaseType = ReleaseType::{branch}; + "#); + + fs::write(meta_file, meta)?; + + Ok(()) +} + +fn get_info() -> Result { + // CARGO_PKG_* are always available, even in build scripts + let cargo_tag = env!("CARGO_PKG_VERSION"); + + // For any downstream that complains about us doing magic + if env::var("CARGO_FEATURE_DISTRIBUTION").is_ok() { + return Ok(ReleaseInfo { + version: cargo_tag.to_string(), + branch: String::from("Stable"), + }); + } + + let release_info = { + let release_tag = env::var("RELEASE_TAG_NAME").unwrap_or_default(); + + if release_tag.starts_with('v') { + ReleaseInfo { + version: cargo_tag.to_string(), + branch: "Stable".to_string(), + } + } else { + #[cfg(not(debug_assertions))] + let release = "Nightly"; + #[cfg(debug_assertions)] + let release = "Debug"; + + let tag = format!( + "{cargo_tag}+{release}.{}", + get_head().unwrap_or("unknown".to_string()) + ); + ReleaseInfo { + version: tag, + branch: release.to_string(), + } + } + }; + + Ok(release_info) +} + +#[cfg(not(target_os = "linux"))] +fn get_head() -> Option { + let repo = match git2::Repository::discover(format!( + "{}/..", + env::var("CARGO_MANIFEST_DIR").ok()? + )) { + Ok(v) => v, + Err(err) => { + println!("cargo::warning=Failed to obtain git repo: {err}"); + return None; + } + }; + let reference = match repo.head() { + Ok(v) => v, + Err(err) => { + println!("cargo::warning=Failed to obtain head: {err}"); + return None; + } + }; + let commit = reference.target(); + println!("cargo::warning=Commit found: {commit:?}"); + commit.map(|s| s.to_string().split_at(7).0.to_owned()) +} + +#[cfg(target_os = "linux")] +fn get_head() -> Option { + let cmd = std::process::Command::new("git") + .args(["show", "--pretty=format:%h", "--no-patch"]) + .output() + .ok()?; + + let commit = String::from_utf8_lossy(&cmd.stdout); + let commit = commit.trim(); + + Some(commit.to_string()) +} diff --git a/lapce-core/src/directory.rs b/lapce-core/src/directory.rs new file mode 100644 index 0000000..4284977 --- /dev/null +++ b/lapce-core/src/directory.rs @@ -0,0 +1,192 @@ +use std::path::PathBuf; + +use directories::{BaseDirs, ProjectDirs}; + +use crate::meta::NAME; + +pub struct Directory {} + +impl Directory { + pub fn home_dir() -> Option { + BaseDirs::new().map(|d| PathBuf::from(d.home_dir())) + } + + #[cfg(not(feature = "portable"))] + fn project_dirs() -> Option { + ProjectDirs::from("dev", "lapce", NAME) + } + + /// Return path adjacent to lapce executable when built as portable + #[cfg(feature = "portable")] + fn project_dirs() -> Option { + if let Ok(current_exe) = std::env::current_exe() { + if let Some(parent) = current_exe.parent() { + return ProjectDirs::from_path(parent.join("lapce-data")); + } + unreachable!("Couldn't obtain current process parent path"); + } + unreachable!("Couldn't obtain current process path"); + } + + // Get path of local data directory + // Local data directory differs from data directory + // on some platforms and is not transferred across + // machines + pub fn data_local_directory() -> Option { + match Self::project_dirs() { + Some(dir) => { + let dir = dir.data_local_dir(); + if !dir.exists() { + if let Err(err) = std::fs::create_dir_all(dir) { + tracing::error!("{:?}", err); + } + } + Some(dir.to_path_buf()) + } + None => None, + } + } + + /// Get the path to logs directory + /// Each log file is for individual application startup + pub fn logs_directory() -> Option { + if let Some(dir) = Self::data_local_directory() { + let dir = dir.join("logs"); + if !dir.exists() { + if let Err(err) = std::fs::create_dir(&dir) { + tracing::error!("{:?}", err); + } + } + Some(dir) + } else { + None + } + } + + /// Get the path to cache directory + pub fn cache_directory() -> Option { + if let Some(dir) = Self::data_local_directory() { + let dir = dir.join("cache"); + if !dir.exists() { + if let Err(err) = std::fs::create_dir(&dir) { + tracing::error!("{:?}", err); + } + } + Some(dir) + } else { + None + } + } + + /// Directory to store proxy executables used on local + /// host as well, as ones uploaded to remote host when + /// connecting + pub fn proxy_directory() -> Option { + if let Some(dir) = Self::data_local_directory() { + let dir = dir.join("proxy"); + if !dir.exists() { + if let Err(err) = std::fs::create_dir(&dir) { + tracing::error!("{:?}", err); + } + } + Some(dir) + } else { + None + } + } + /// Get the path to the themes folder + /// Themes are stored within as individual toml files + pub fn themes_directory() -> Option { + if let Some(dir) = Self::data_local_directory() { + let dir = dir.join("themes"); + if !dir.exists() { + if let Err(err) = std::fs::create_dir(&dir) { + tracing::error!("{:?}", err); + } + } + Some(dir) + } else { + None + } + } + // Get the path to plugins directory + // Each plugin has own directory that contains + // metadata file and plugin wasm + pub fn plugins_directory() -> Option { + if let Some(dir) = Self::data_local_directory() { + let dir = dir.join("plugins"); + if !dir.exists() { + if let Err(err) = std::fs::create_dir(&dir) { + tracing::error!("{:?}", err); + } + } + Some(dir) + } else { + None + } + } + + // Config directory contain only configuration files + pub fn config_directory() -> Option { + match Self::project_dirs() { + Some(dir) => { + let dir = dir.config_dir(); + if !dir.exists() { + if let Err(err) = std::fs::create_dir_all(dir) { + tracing::error!("{:?}", err); + } + } + Some(dir.to_path_buf()) + } + None => None, + } + } + + pub fn local_socket() -> Option { + Self::data_local_directory().map(|dir| dir.join("local.sock")) + } + + pub fn updates_directory() -> Option { + if let Some(dir) = Self::data_local_directory() { + let dir = dir.join("updates"); + if !dir.exists() { + if let Err(err) = std::fs::create_dir(&dir) { + tracing::error!("{:?}", err); + } + } + Some(dir) + } else { + None + } + } + + pub fn queries_directory() -> Option { + if let Some(dir) = Self::config_directory() { + let dir = dir.join("queries"); + if !dir.exists() { + if let Err(err) = std::fs::create_dir(&dir) { + tracing::error!("{:?}", err); + } + } + + Some(dir) + } else { + None + } + } + + pub fn grammars_directory() -> Option { + if let Some(dir) = Self::data_local_directory() { + let dir = dir.join("grammars"); + if !dir.exists() { + if let Err(err) = std::fs::create_dir(&dir) { + tracing::error!("{:?}", err); + } + } + + Some(dir) + } else { + None + } + } +} diff --git a/lapce-core/src/encoding.rs b/lapce-core/src/encoding.rs new file mode 100644 index 0000000..f67c107 --- /dev/null +++ b/lapce-core/src/encoding.rs @@ -0,0 +1,163 @@ +/// Convert a utf8 offset into a utf16 offset, if possible +/// `text` is what the offsets are into +pub fn offset_utf8_to_utf16( + char_indices: impl Iterator, + offset: usize, +) -> usize { + if offset == 0 { + return 0; + } + + let mut utf16_offset = 0; + let mut last_ich = None; + for (utf8_offset, ch) in char_indices { + last_ich = Some((utf8_offset, ch)); + + match utf8_offset.cmp(&offset) { + std::cmp::Ordering::Less => {} + // We found the right offset + std::cmp::Ordering::Equal => { + return utf16_offset; + } + // Implies that the offset was inside of a character + std::cmp::Ordering::Greater => return utf16_offset, + } + + utf16_offset += ch.len_utf16(); + } + + // TODO: We could use TrustedLen when that is stabilized and it is impl'd on + // the iterators we use + + // We did not find the offset. This means that it is either at the end + // or past the end. + let text_len = last_ich.map(|(i, c)| i + c.len_utf8()); + if text_len == Some(offset) { + // Since the utf16 offset was being incremented each time, by now it is equivalent to the length + // but in utf16 characters + return utf16_offset; + } + + utf16_offset +} + +pub fn offset_utf8_to_utf16_str(text: &str, offset: usize) -> usize { + offset_utf8_to_utf16(text.char_indices(), offset) +} + +/// Convert a utf16 offset into a utf8 offset, if possible +/// `char_indices` is an iterator over utf8 offsets and the characters +/// It is cloneable so that it can be iterated multiple times. Though it should be cheaply cloneable. +pub fn offset_utf16_to_utf8( + char_indices: impl Iterator, + offset: usize, +) -> usize { + if offset == 0 { + return 0; + } + + // We accumulate the utf16 char lens until we find the utf8 offset that matches it + // or, we find out that it went into the middle of sometext + // We also keep track of the last offset and char in order to calculate the length of the text + // if we the index was at the end of the string + let mut utf16_offset = 0; + let mut last_ich = None; + for (utf8_offset, ch) in char_indices { + last_ich = Some((utf8_offset, ch)); + + let ch_utf16_len = ch.len_utf16(); + + match utf16_offset.cmp(&offset) { + std::cmp::Ordering::Less => {} + // We found the right offset + std::cmp::Ordering::Equal => { + return utf8_offset; + } + // This implies that the offset was in the middle of a character as we skipped over it + std::cmp::Ordering::Greater => return utf8_offset, + } + + utf16_offset += ch_utf16_len; + } + + // We did not find the offset, this means that it was either at the end + // or past the end + // Since we've iterated over all the char indices, the utf16_offset is now the + // utf16 length + if let Some((last_utf8_offset, last_ch)) = last_ich { + last_utf8_offset + last_ch.len_utf8() + } else { + 0 + } +} + +pub fn offset_utf16_to_utf8_str(text: &str, offset: usize) -> usize { + offset_utf16_to_utf8(text.char_indices(), offset) +} + +#[cfg(test)] +mod tests { + // TODO: more tests with unicode characters + + use crate::encoding::{offset_utf8_to_utf16_str, offset_utf16_to_utf8_str}; + + #[test] + fn utf8_to_utf16() { + let text = "hello world"; + + assert_eq!(offset_utf8_to_utf16_str(text, 0), 0); + assert_eq!(offset_utf8_to_utf16_str("", 0), 0); + + assert_eq!(offset_utf8_to_utf16_str("", 1), 0); + + assert_eq!(offset_utf8_to_utf16_str("h", 0), 0); + assert_eq!(offset_utf8_to_utf16_str("h", 1), 1); + + assert_eq!(offset_utf8_to_utf16_str(text, text.len()), text.len()); + + assert_eq!( + offset_utf8_to_utf16_str(text, text.len() - 1), + text.len() - 1 + ); + + assert_eq!(offset_utf8_to_utf16_str(text, text.len() + 1), text.len()); + + assert_eq!(offset_utf8_to_utf16_str("×", 0), 0); + assert_eq!(offset_utf8_to_utf16_str("×", 1), 1); + assert_eq!(offset_utf8_to_utf16_str("×", 2), 1); + assert_eq!(offset_utf8_to_utf16_str("a×", 0), 0); + assert_eq!(offset_utf8_to_utf16_str("a×", 1), 1); + assert_eq!(offset_utf8_to_utf16_str("a×", 2), 2); + assert_eq!(offset_utf8_to_utf16_str("a×", 3), 2); + } + + #[test] + fn utf16_to_utf8() { + let text = "hello world"; + + assert_eq!(offset_utf16_to_utf8_str(text, 0), 0); + assert_eq!(offset_utf16_to_utf8_str("", 0), 0); + + assert_eq!(offset_utf16_to_utf8_str("", 1), 0); + + assert_eq!(offset_utf16_to_utf8_str("h", 0), 0); + assert_eq!(offset_utf16_to_utf8_str("h", 1), 1); + + assert_eq!(offset_utf16_to_utf8_str(text, text.len()), text.len()); + + assert_eq!( + offset_utf16_to_utf8_str(text, text.len() - 1), + text.len() - 1 + ); + + assert_eq!(offset_utf16_to_utf8_str(text, text.len() + 1), text.len()); + + assert_eq!(offset_utf16_to_utf8_str("×", 0), 0); + assert_eq!(offset_utf16_to_utf8_str("×", 1), 2); + assert_eq!(offset_utf16_to_utf8_str("a×", 0), 0); + assert_eq!(offset_utf16_to_utf8_str("a×", 1), 1); + assert_eq!(offset_utf16_to_utf8_str("a×", 2), 3); + assert_eq!(offset_utf16_to_utf8_str("×a", 1), 2); + assert_eq!(offset_utf16_to_utf8_str("×a", 2), 3); + } +} diff --git a/lapce-core/src/language.rs b/lapce-core/src/language.rs new file mode 100644 index 0000000..6d4356d --- /dev/null +++ b/lapce-core/src/language.rs @@ -0,0 +1,2075 @@ +use std::{ + collections::{HashMap, HashSet, hash_map::Entry}, + fmt::Write, + path::Path, + str::FromStr, +}; + +use lapce_rpc::style::{LineStyle, Style}; +use once_cell::sync::Lazy; +use regex::Regex; +use strum_macros::{AsRefStr, Display, EnumMessage, EnumString, IntoStaticStr}; +use tracing::{Level, event}; +use tree_sitter::{Point, TreeCursor}; + +use crate::{ + directory::Directory, + syntax::highlight::{HighlightConfiguration, HighlightIssue}, +}; + +#[remain::sorted] +pub enum Indent { + Space(u8), + Tab, +} + +impl Indent { + const fn tab() -> &'static str { + Indent::Tab.as_str() + } + + const fn space(count: u8) -> &'static str { + Indent::Space(count).as_str() + } + + const fn as_str(&self) -> &'static str { + match self { + Indent::Tab => "\u{0009}", + #[allow(clippy::wildcard_in_or_patterns)] + Indent::Space(v) => match v { + 2 => "\u{0020}\u{0020}", + 4 => "\u{0020}\u{0020}\u{0020}\u{0020}", + 8 | _ => { + "\u{0020}\u{0020}\u{0020}\u{0020}\u{0020}\u{0020}\u{0020}\u{0020}" + } + }, + } + } +} + +const DEFAULT_CODE_GLANCE_LIST: &[&str] = &["source_file"]; +const DEFAULT_CODE_GLANCE_IGNORE_LIST: &[&str] = &["source_file"]; + +#[macro_export] +macro_rules! comment_properties { + () => { + CommentProperties { + single_line_start: None, + single_line_end: None, + + multi_line_start: None, + multi_line_end: None, + multi_line_prefix: None, + } + }; + ($s:expr) => { + CommentProperties { + single_line_start: Some($s), + single_line_end: None, + + multi_line_start: None, + multi_line_end: None, + multi_line_prefix: None, + } + }; + ($s:expr, $e:expr) => { + CommentProperties { + single_line_start: Some($s), + single_line_end: Some($e), + + multi_line_start: None, + multi_line_end: None, + multi_line_prefix: None, + } + }; + ($sl_s:expr, $sl_e:expr, $ml_s:expr, $ml_e:expr) => { + CommentProperties { + single_line_start: Some($sl_s), + single_line_end: Some($sl_e), + + multi_line_start: Some($sl_s), + multi_line_end: None, + multi_line_prefix: Some($sl_e), + } + }; +} + +#[derive(Eq, PartialEq, Hash, Clone, Copy, Debug, PartialOrd, Ord, Default)] +pub struct SyntaxProperties { + /// An extra check to make sure that the array elements are in the correct order. + /// If this id does not match the enum value, a panic will happen with a debug assertion message. + id: LapceLanguage, + + /// All tokens that can be used for comments in language + comment: CommentProperties, + /// The indent unit. + /// " " for bash, " " for rust, for example. + indent: &'static str, + /// Filenames that belong to this language + /// `["Dockerfile"]` for Dockerfile, `[".editorconfig"]` for EditorConfig + files: &'static [&'static str], + /// File name extensions to determine the language. + /// `["py"]` for python, `["rs"]` for rust, for example. + extensions: &'static [&'static str], + /// Tree-sitter properties + tree_sitter: TreeSitterProperties, +} + +#[derive(Eq, PartialEq, Hash, Clone, Copy, Debug, PartialOrd, Ord, Default)] +struct TreeSitterProperties { + /// the grammar name that's in the grammars folder + grammar: Option<&'static str>, + /// the grammar fn name + grammar_fn: Option<&'static str>, + /// the query folder name + query: Option<&'static str>, + /// Preface: Originally this feature was called "Code Lens", which is not + /// an LSP "Code Lens". It is renamed to "Code Glance", below doc text is + /// left unchanged. + /// + /// Lists of tree-sitter node types that control how code lenses are built. + /// The first is a list of nodes that should be traversed and included in + /// the lens, along with their children. The second is a list of nodes that + /// should be excluded from the lens, though they will still be traversed. + /// See `walk_tree` for more details. + /// + /// The tree-sitter playground may be useful when creating these lists: + /// https://tree-sitter.github.io/tree-sitter/playground + /// + /// If unsure, use `DEFAULT_CODE_GLANCE_LIST` and + /// `DEFAULT_CODE_GLANCE_IGNORE_LIST`. + code_glance: (&'static [&'static str], &'static [&'static str]), + /// the tree-sitter tag names that can be put in sticky headers + sticky_headers: &'static [&'static str], +} + +impl TreeSitterProperties { + const DEFAULT: Self = Self { + grammar: None, + grammar_fn: None, + query: None, + code_glance: (DEFAULT_CODE_GLANCE_LIST, DEFAULT_CODE_GLANCE_IGNORE_LIST), + sticky_headers: &[], + }; +} + +#[derive(Eq, PartialEq, Hash, Clone, Copy, Debug, PartialOrd, Ord, Default)] +struct CommentProperties { + /// Single line comment token used when commenting out one line. + /// "#" for python, "//" for rust for example. + single_line_start: Option<&'static str>, + single_line_end: Option<&'static str>, + + /// Multi line comment token used when commenting a selection of lines. + /// "#" for python, "//" for rust for example. + multi_line_start: Option<&'static str>, + multi_line_end: Option<&'static str>, + multi_line_prefix: Option<&'static str>, +} + +/// NOTE: Keep the enum variants "fieldless" so they can cast to usize as array +/// indices into the LANGUAGES array. See method `LapceLanguage::properties`. +/// +/// Do not assign values to the variants because the number of variants and +/// number of elements in the LANGUAGES array change as different features +/// selected by the cargo build command. +#[derive( + Eq, + PartialEq, + Ord, + PartialOrd, + Hash, + Clone, + Copy, + Debug, + Display, + AsRefStr, + IntoStaticStr, + EnumString, + EnumMessage, + Default, +)] +#[strum(ascii_case_insensitive)] +#[remain::sorted] +pub enum LapceLanguage { + // Do not move + #[remain::unsorted] + #[default] + #[strum(message = "Plain Text")] + PlainText, + + #[strum(message = "Ada")] + Ada, + #[strum(message = "Adl")] + Adl, + #[strum(message = "Agda")] + Agda, + #[strum(message = "Astro")] + Astro, + #[strum(message = "Bash")] + Bash, + #[strum(message = "Bass")] + Bass, + #[strum(message = "Beancount")] + Beancount, + #[strum(message = "Bibtex")] + Bibtex, + #[strum(message = "Bitbake")] + Bitbake, + #[strum(message = "Blade")] + Blade, + #[strum(message = "C")] + C, + #[strum(message = "Clojure")] + Clojure, + #[strum(message = "CMake")] + Cmake, + #[strum(message = "Comment")] + Comment, + #[strum(message = "C++")] + Cpp, + #[strum(message = "C#")] + Csharp, + #[strum(message = "CSS")] + Css, + #[strum(message = "Cue")] + Cue, + #[strum(message = "D")] + D, + #[strum(message = "Dart")] + Dart, + #[strum(message = "Dhall")] + Dhall, + #[strum(message = "Diff")] + Diff, + #[strum(message = "Dockerfile")] + Dockerfile, + #[strum(message = "Dot")] + Dot, + #[strum(message = "Elixir")] + Elixir, + #[strum(message = "Elm")] + Elm, + #[strum(message = "Erlang")] + Erlang, + #[strum(message = "Fish Shell")] + Fish, + #[strum(message = "Fluent")] + Fluent, + #[strum(message = "Forth")] + Forth, + #[strum(message = "Fortran")] + Fortran, + #[strum(message = "F#")] + FSharp, + #[strum(message = "Gitattributes")] + Gitattributes, + #[strum(message = "Git (commit)")] + GitCommit, + #[strum(message = "Git (config)")] + GitConfig, + #[strum(message = "Git (rebase)")] + GitRebase, + #[strum(message = "Gleam")] + Gleam, + #[strum(message = "Glimmer")] + Glimmer, + #[strum(message = "GLSL")] + Glsl, + #[strum(message = "Gn")] + Gn, + #[strum(message = "Go")] + Go, + #[strum(message = "Go (go.mod)")] + GoMod, + #[strum(message = "Go (template)")] + GoTemplate, + #[strum(message = "Go (go.work)")] + GoWork, + #[strum(message = "GraphQL")] + GraphQl, + #[strum(message = "Groovy")] + Groovy, + #[strum(message = "Hare")] + Hare, + #[strum(message = "Haskell")] + Haskell, + #[strum(message = "Haxe")] + Haxe, + #[strum(message = "HCL")] + Hcl, + #[strum(message = "Hosts file (/etc/hosts)")] + Hosts, + #[strum(message = "HTML")] + Html, + #[strum(message = "INI")] + Ini, + #[strum(message = "Java")] + Java, + #[strum(message = "JavaScript")] + Javascript, + #[strum(message = "JSDoc")] + Jsdoc, + #[strum(message = "JSON")] + Json, + #[strum(message = "JSON5")] + Json5, + #[strum(message = "Jsonnet")] + Jsonnet, + #[strum(message = "JavaScript React")] + Jsx, + #[strum(message = "Julia")] + Julia, + #[strum(message = "Just")] + Just, + #[strum(message = "KDL")] + Kdl, + #[strum(message = "Kotlin")] + Kotlin, + #[strum(message = "Kotlin Build Script")] + KotlinBuildScript, + #[strum(message = "LaTeX")] + Latex, + #[strum(message = "Linker Script")] + Ld, + #[strum(message = "LLVM")] + Llvm, + #[strum(message = "LLVM MIR")] + LlvmMir, + #[strum(message = "Log")] + Log, + #[strum(message = "Lua")] + Lua, + #[strum(message = "Makefile")] + Make, + #[strum(message = "Markdown")] + Markdown, + #[strum(serialize = "markdown.inline")] + MarkdownInline, + #[strum(message = "Meson")] + Meson, + #[strum(message = "NASM")] + Nasm, + #[strum(message = "Nix")] + Nix, + #[strum(message = "Nu (nushell)")] + Nushell, + #[strum(message = "Ocaml")] + Ocaml, + #[strum(serialize = "ocaml.interface")] + OcamlInterface, + #[strum(message = "Odin")] + Odin, + #[strum(message = "OpenCL")] + OpenCl, + #[strum(message = "Pascal")] + Pascal, + #[strum(message = "Password file (/etc/passwd)")] + Passwd, + #[strum(message = "PEM (RFC 1422)")] + Pem, + #[strum(message = "PHP")] + Php, + #[strum(message = "PKL")] + Pkl, + #[strum(message = "PowerShell")] + PowerShell, + #[strum(message = "Prisma")] + Prisma, + #[strum(message = "Proto")] + ProtoBuf, + #[strum(message = "Python")] + Python, + #[strum(message = "QL")] + Ql, + #[strum(message = "R")] + R, + #[strum(message = "RCL")] + Rcl, + #[strum(message = "RegEx")] + Regex, + #[strum(message = "REGO")] + Rego, + #[strum(message = "RON (Rust Object Notation)")] + Ron, + #[strum(message = "Rst")] + Rst, + #[strum(message = "Ruby")] + Ruby, + #[strum(message = "Rust")] + Rust, + #[strum(message = "Scala")] + Scala, + #[strum(message = "Scheme")] + Scheme, + #[strum(message = "SCSS")] + Scss, + #[strum(message = "Shell Script (POSIX)")] + ShellScript, + #[strum(message = "Smithy")] + Smithy, + #[strum(message = "SQL")] + Sql, + #[strum(message = "SSH Config")] + SshClientConfig, + #[strum(message = "Strace")] + Strace, + #[strum(message = "Svelte")] + Svelte, + #[strum(message = "Sway")] + Sway, + #[strum(message = "Swift")] + Swift, + #[strum(message = "TCL")] + Tcl, + #[strum(message = "TOML")] + Toml, + #[strum(message = "Tsx")] + Tsx, + #[strum(message = "TypeScript")] + Typescript, + #[strum(message = "Typst")] + Typst, + #[strum(message = "Verilog")] + Verilog, + #[strum(message = "Vue")] + Vue, + #[strum(message = "WASM")] + Wasm, + #[strum(message = "WGSL")] + Wgsl, + #[strum(message = "WIT")] + Wit, + #[strum(message = "XML")] + Xml, + #[strum(message = "YAML")] + Yaml, + #[strum(message = "Zig")] + Zig, +} + +/// NOTE: Elements in the array must be in the same order as the enum variants of +/// `LapceLanguage` as they will be accessed using the enum variants as indices. +const LANGUAGES: &[SyntaxProperties] = &[ + // Undetected/unmatched fallback or just plain file + SyntaxProperties { + id: LapceLanguage::PlainText, + indent: Indent::tab(), + files: &[], + extensions: &["txt"], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + // Languages + SyntaxProperties { + id: LapceLanguage::Ada, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Adl, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Agda, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Astro, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Bash, + indent: Indent::space(2), + files: &[], + extensions: &["bash", "sh"], + comment: comment_properties!("#"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Bass, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Beancount, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Bibtex, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Bitbake, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Blade, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::C, + indent: Indent::space(4), + files: &[], + extensions: &["c", "h"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties { + grammar: None, + grammar_fn: None, + query: None, + code_glance: (DEFAULT_CODE_GLANCE_LIST, DEFAULT_CODE_GLANCE_IGNORE_LIST), + sticky_headers: &["function_definition", "struct_specifier"], + }, + }, + SyntaxProperties { + id: LapceLanguage::Clojure, + indent: Indent::space(2), + files: &[], + extensions: &[ + "clj", + "edn", // spellchecker:disable-line + "cljs", + "cljc", + "cljd", + "bb", + "clj_kondo", + ], + comment: comment_properties!(";"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Cmake, + indent: Indent::space(2), + files: &["cmakelists"], + extensions: &["cmake"], + comment: comment_properties!("#"), + tree_sitter: TreeSitterProperties { + grammar: None, + grammar_fn: None, + query: None, + code_glance: (DEFAULT_CODE_GLANCE_LIST, DEFAULT_CODE_GLANCE_IGNORE_LIST), + sticky_headers: &["function_definition"], + }, + }, + SyntaxProperties { + id: LapceLanguage::Comment, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Cpp, + indent: Indent::space(4), + files: &[], + extensions: &["cpp", "cxx", "cc", "c++", "hpp", "hxx", "hh", "h++"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties { + grammar: None, + grammar_fn: None, + query: None, + code_glance: (DEFAULT_CODE_GLANCE_LIST, DEFAULT_CODE_GLANCE_IGNORE_LIST), + sticky_headers: &[ + "function_definition", + "class_specifier", + "struct_specifier", + ], + }, + }, + SyntaxProperties { + id: LapceLanguage::Csharp, + indent: Indent::space(2), + files: &[], + extensions: &["cs", "csx"], + comment: comment_properties!("#"), + tree_sitter: TreeSitterProperties { + grammar: None, + grammar_fn: None, + query: None, + code_glance: (DEFAULT_CODE_GLANCE_LIST, DEFAULT_CODE_GLANCE_IGNORE_LIST), + sticky_headers: &[ + "interface_declaration", + "class_declaration", + "enum_declaration", + "struct_declaration", + "record_declaration", + "record_struct_declaration", + "namespace_declaration", + "constructor_declaration", + "destructor_declaration", + "method_declaration", + ], + }, + }, + SyntaxProperties { + id: LapceLanguage::Css, + indent: Indent::space(2), + files: &[], + extensions: &["css"], + comment: comment_properties!("/*", "*/"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Cue, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::D, + indent: Indent::space(4), + files: &[], + extensions: &["d", "di", "dlang"], + comment: CommentProperties { + single_line_start: Some("//"), + single_line_end: None, + multi_line_start: Some("/+"), + multi_line_prefix: None, + multi_line_end: Some("+/"), + }, + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Dart, + indent: Indent::space(2), + files: &[], + extensions: &["dart"], + comment: CommentProperties { + single_line_start: Some("//"), + single_line_end: None, + + multi_line_start: Some("/*"), + multi_line_prefix: None, + multi_line_end: Some("*/"), + }, + tree_sitter: TreeSitterProperties { + grammar: None, + grammar_fn: None, + query: None, + code_glance: ( + &["program", "class_definition"], + &[ + "program", + "import_or_export", + "comment", + "documentation_comment", + ], + ), + sticky_headers: &["class_definition"], + }, + }, + SyntaxProperties { + id: LapceLanguage::Dhall, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Diff, + indent: Indent::tab(), + files: &[], + extensions: &["diff", "patch"], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Dockerfile, + indent: Indent::space(2), + files: &["Dockerfile", "Containerfile"], + extensions: &["containerfile", "dockerfile"], + comment: comment_properties!("#"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Dot, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Elixir, + indent: Indent::space(2), + files: &[], + extensions: &["ex", "exs", "eex", "heex", "sface"], + comment: comment_properties!("#"), + tree_sitter: TreeSitterProperties { + grammar: None, + grammar_fn: None, + query: None, + code_glance: (DEFAULT_CODE_GLANCE_LIST, DEFAULT_CODE_GLANCE_IGNORE_LIST), + sticky_headers: &["do_block"], + }, + }, + SyntaxProperties { + id: LapceLanguage::Elm, + indent: Indent::space(4), + files: &[], + extensions: &["elm"], + comment: comment_properties!("#"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Erlang, + indent: Indent::space(4), + files: &[], + extensions: &["erl", "hrl"], + comment: comment_properties!("%"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::FSharp, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Fish, + indent: Indent::tab(), + files: &[], + extensions: &["fish"], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Fluent, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Forth, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Fortran, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Gitattributes, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::GitCommit, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::GitConfig, + indent: Indent::tab(), + files: &[".gitconfig", ".git/config"], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::GitRebase, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Gleam, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Glimmer, + indent: Indent::space(2), + files: &[], + extensions: &["hbs"], + comment: comment_properties!("{{!", "!}}"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Glsl, + indent: Indent::space(2), + files: &[], + // spellchecker:off + extensions: &[ + "glsl", "cs", "vs", "gs", "fs", "csh", "vsh", "gsh", "fsh", "cshader", + "vshader", "gshader", "fshader", "comp", "vert", "geom", "frag", "tesc", + "tese", "mesh", "task", "rgen", "rint", "rahit", "rchit", "rmiss", + "rcall", + ], + // spellchecker:on + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Gn, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Go, + indent: Indent::tab(), + files: &[], + extensions: &["go"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties { + grammar: None, + grammar_fn: None, + query: None, + code_glance: ( + &[ + "source_file", + "type_declaration", + "type_spec", + "interface_type", + "method_spec_list", + ], + &["source_file", "comment", "line_comment"], + ), + sticky_headers: &[], + }, + }, + SyntaxProperties { + id: LapceLanguage::GoMod, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::GoTemplate, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::GoWork, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::GraphQl, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Groovy, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Hare, + indent: Indent::space(8), + files: &[], + extensions: &["ha"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Haskell, + indent: Indent::space(2), + files: &[], + extensions: &["hs"], + comment: comment_properties!("--"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Haxe, + indent: Indent::space(2), + files: &[], + extensions: &["hx"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Hcl, + indent: Indent::space(2), + files: &[], + extensions: &["hcl", "tf"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Hosts, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Html, + indent: Indent::space(4), + files: &[], + extensions: &["html", "htm"], + comment: comment_properties!(""), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Ini, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Java, + indent: Indent::space(4), + files: &[], + extensions: &["java"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Javascript, + indent: Indent::space(2), + files: &[], + extensions: &["js", "cjs", "mjs"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties { + grammar: None, + grammar_fn: None, + query: None, + code_glance: (&["source_file", "program"], &["source_file"]), + sticky_headers: &[], + }, + }, + SyntaxProperties { + id: LapceLanguage::Jsdoc, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Json, + indent: Indent::space(4), + files: &[], + extensions: &["json", "har"], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Json5, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Jsonnet, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Jsx, + indent: Indent::space(2), + files: &[], + extensions: &["jsx"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties { + grammar: Some("javascript"), + grammar_fn: Some("javascript"), + query: Some("jsx"), + code_glance: (&["source_file", "program"], &["source_file"]), + sticky_headers: &[], + }, + }, + SyntaxProperties { + id: LapceLanguage::Julia, + indent: Indent::space(4), + files: &[], + extensions: &["julia", "jl"], + comment: CommentProperties { + single_line_start: Some("#"), + single_line_end: None, + multi_line_start: Some("#="), + multi_line_prefix: None, + multi_line_end: Some("=#"), + }, + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Just, + indent: Indent::tab(), + files: &["justfile", "Justfile", ".justfile", ".Justfile"], + extensions: &["just"], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Kdl, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Kotlin, + indent: Indent::space(2), + files: &[], + extensions: &["kt"], + comment: CommentProperties { + single_line_start: Some("//"), + single_line_end: None, + + multi_line_start: Some("/*"), + multi_line_prefix: None, + multi_line_end: Some("*/"), + }, + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::KotlinBuildScript, + indent: Indent::space(2), + files: &[], + extensions: &["kts"], + comment: CommentProperties { + single_line_start: Some("//"), + single_line_end: None, + + multi_line_start: Some("/*"), + multi_line_prefix: None, + multi_line_end: Some("*/"), + }, + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Latex, + indent: Indent::space(2), + files: &[], + extensions: &["tex"], + comment: comment_properties!("%"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Ld, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Llvm, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::LlvmMir, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Log, + indent: Indent::tab(), + files: &["log.txt"], + extensions: &["log"], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Lua, + indent: Indent::space(2), + files: &[], + extensions: &["lua"], + comment: comment_properties!("--"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Make, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Markdown, + indent: Indent::space(4), + files: &[], + extensions: &["md"], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::MarkdownInline, + indent: Indent::space(4), + // markdown inline is only used as an injection by the Markdown language + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties { + grammar: Some("markdown_inline"), + grammar_fn: Some("markdown_inline"), + query: Some("markdown.inline"), + code_glance: (DEFAULT_CODE_GLANCE_LIST, DEFAULT_CODE_GLANCE_IGNORE_LIST), + sticky_headers: &[], + }, + }, + SyntaxProperties { + id: LapceLanguage::Meson, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Nasm, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Nix, + indent: Indent::space(2), + files: &[], + extensions: &["nix"], + comment: CommentProperties { + single_line_start: Some("#"), + single_line_end: None, + + multi_line_start: Some("/*"), + multi_line_prefix: None, + multi_line_end: Some("*/"), + }, + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Nushell, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Ocaml, + indent: Indent::space(2), + files: &[], + extensions: &["ml"], + comment: CommentProperties { + single_line_start: Some("(*"), + single_line_end: Some("*)"), + + multi_line_start: Some("(*"), + multi_line_prefix: Some("*"), + multi_line_end: Some("*)"), + }, + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::OcamlInterface, + indent: Indent::space(2), + files: &[], + extensions: &["mli"], + comment: comment_properties!("(*"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Odin, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::OpenCl, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Pascal, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Passwd, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Pem, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Php, + indent: Indent::space(2), + files: &[], + extensions: &["php"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties { + grammar: None, + grammar_fn: None, + query: None, + code_glance: ( + &[ + "program", + "class_declaration", + "trait_declaration", + "interface_declaration", + "declaration_list", + "method_declaration", + "function_declaration", + ], + &[ + "program", + "php_tag", + "comment", + "namespace_definition", + "namespace_use_declaration", + "use_declaration", + "const_declaration", + "property_declaration", + "expression_statement", + ], + ), + sticky_headers: &[], + }, + }, + SyntaxProperties { + id: LapceLanguage::Pkl, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::PowerShell, + indent: Indent::space(4), + files: &[], + extensions: &["ps1", "psm1", "psd1", "ps1xml"], + comment: CommentProperties { + single_line_start: Some("#"), + single_line_end: None, + multi_line_start: Some("<#"), + multi_line_end: Some("#>"), + multi_line_prefix: None, + }, + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Prisma, + indent: Indent::space(4), + files: &[], + extensions: &["prisma"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::ProtoBuf, + indent: Indent::space(2), + files: &[], + extensions: &["proto"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Python, + indent: Indent::space(4), + files: &[], + extensions: &["py", "pyi", "pyc", "pyd", "pyw"], + comment: comment_properties!("#"), + tree_sitter: TreeSitterProperties { + grammar: None, + grammar_fn: None, + query: None, + code_glance: ( + &[ + "source_file", + "module", + "class_definition", + "class", + "identifier", + "decorated_definition", + "block", + ], + &["source_file", "import_statement", "import_from_statement"], + ), + sticky_headers: &[], + }, + }, + SyntaxProperties { + id: LapceLanguage::Ql, + indent: Indent::space(2), + files: &[], + extensions: &["ql"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::R, + indent: Indent::space(2), + files: &[], + extensions: &["r"], + comment: comment_properties!("#"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Rcl, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Regex, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Rego, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Ron, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Rst, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Ruby, + indent: Indent::space(2), + files: &[], + extensions: &["rb"], + comment: comment_properties!("#"), + tree_sitter: TreeSitterProperties { + grammar: None, + grammar_fn: None, + query: None, + code_glance: (DEFAULT_CODE_GLANCE_LIST, DEFAULT_CODE_GLANCE_IGNORE_LIST), + sticky_headers: &["module", "class", "method", "do_block"], + }, + }, + SyntaxProperties { + id: LapceLanguage::Rust, + indent: Indent::space(4), + files: &[], + extensions: &["rs"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties { + grammar: None, + grammar_fn: None, + query: None, + code_glance: ( + &["source_file", "impl_item", "trait_item", "declaration_list"], + &["source_file", "use_declaration", "line_comment"], + ), + sticky_headers: &[ + "struct_item", + "enum_item", + "function_item", + "impl_item", + ], + }, + }, + SyntaxProperties { + id: LapceLanguage::Scala, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Scheme, + indent: Indent::space(2), + files: &[], + extensions: &["scm", "ss"], + comment: comment_properties!(";"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Scss, + indent: Indent::space(2), + files: &[], + extensions: &["scss"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::ShellScript, + indent: Indent::space(2), + files: &[], + extensions: &["sh"], + comment: comment_properties!("#"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Smithy, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Sql, + indent: Indent::space(2), + files: &[], + extensions: &["sql"], + comment: comment_properties!("--"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::SshClientConfig, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Strace, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Svelte, + indent: Indent::space(2), + files: &[], + extensions: &["svelte"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Sway, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Swift, + indent: Indent::space(2), + files: &[], + extensions: &["swift"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Tcl, + indent: Indent::tab(), + files: &[], + extensions: &["tcl"], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Toml, + indent: Indent::space(2), + files: &["Cargo.lock"], + extensions: &["toml"], + comment: comment_properties!("#"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Tsx, + indent: Indent::space(4), + files: &[], + extensions: &["tsx"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties { + grammar: Some("tsx"), + grammar_fn: Some("tsx"), + query: Some("tsx"), + code_glance: (&["source_file", "program"], &["source_file"]), + sticky_headers: &[], + }, + }, + SyntaxProperties { + id: LapceLanguage::Typescript, + indent: Indent::space(4), + files: &[], + extensions: &["ts", "cts", "mts"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties { + grammar: Some("typescript"), + grammar_fn: Some("typescript"), + query: Some("typescript"), + code_glance: (&["source_file", "program"], &["source_file"]), + sticky_headers: &[], + }, + }, + SyntaxProperties { + id: LapceLanguage::Typst, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Verilog, + indent: Indent::tab(), + files: &[], + extensions: &[], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Vue, + indent: Indent::space(2), + files: &[], + extensions: &["vue"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Wasm, + indent: Indent::space(4), + files: &[], + extensions: &["wasm"], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Wgsl, + indent: Indent::space(4), + files: &[], + extensions: &["wgsl"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Wit, + indent: Indent::space(4), + files: &[], + extensions: &["wit"], + comment: comment_properties!(), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Xml, + indent: Indent::space(4), + files: &[], + extensions: &["xml", "csproj"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Yaml, + indent: Indent::space(2), + files: &[], + extensions: &["yml", "yaml"], + comment: comment_properties!("#"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, + SyntaxProperties { + id: LapceLanguage::Zig, + indent: Indent::space(4), + files: &[], + extensions: &["zig"], + comment: comment_properties!("//"), + tree_sitter: TreeSitterProperties::DEFAULT, + }, +]; + +impl LapceLanguage { + const HIGHLIGHTS_INJECTIONS_FILE_NAME: &'static str = "injections.scm"; + const HIGHLIGHTS_QUERIES_FILE_NAME: &'static str = "highlights.scm"; + + pub fn from_path(path: &Path) -> LapceLanguage { + Self::from_path_raw(path).unwrap_or(LapceLanguage::PlainText) + } + + pub fn from_path_raw(path: &Path) -> Option { + let filename = path.file_name().and_then(|s| s.to_str()); + let extension = path + .extension() + .and_then(|s| s.to_str().map(|s| s.to_lowercase())); + // NOTE: This is a linear search. It is assumed that this function + // isn't called in any tight loop. + for properties in LANGUAGES { + if properties.files.iter().any(|f| Some(*f) == filename) { + return Some(properties.id); + } + if properties + .extensions + .iter() + .any(|e| Some(*e) == extension.as_deref()) + { + return Some(properties.id); + } + } + + None + } + + pub fn from_name(name: &str) -> Option { + match LapceLanguage::from_str(name.to_lowercase().as_str()) { + Ok(v) => Some(v), + Err(e) => { + event!(Level::DEBUG, "failed parsing `{name}` LapceLanguage: {e}"); + None + } + } + } + + pub fn languages() -> Vec<&'static str> { + let mut langs = vec![]; + for l in LANGUAGES { + // Get only languages with display name to hide inline grammars + if let Some(lang) = strum::EnumMessage::get_message(&l.id) { + langs.push(lang) + } + } + langs + } + + // NOTE: Instead of using `&LANGUAGES[*self as usize]` directly, the + // `debug_assertion` gives better feedback should something has gone wrong + // badly. + fn properties(&self) -> &SyntaxProperties { + let i = *self as usize; + let l = &LANGUAGES[i]; + debug_assert!( + l.id == *self, + "LANGUAGES[{i}]: Setting::id mismatch: {:?} != {:?}", + l.id, + self + ); + l + } + + pub fn name(&self) -> &'static str { + strum::EnumMessage::get_message(self).unwrap_or(self.into()) + } + + pub fn sticky_header_tags(&self) -> &[&'static str] { + self.properties().tree_sitter.sticky_headers + } + + pub fn comment_token(&self) -> &'static str { + self.properties() + .comment + .single_line_start + .unwrap_or_default() + } + + pub fn indent_unit(&self) -> &str { + self.properties().indent + } + + fn get_grammar(&self) -> Option { + let grammar_name = self.grammar_name(); + let grammar_fn_name = self.grammar_fn_name(); + + if let Some(grammars_dir) = Directory::grammars_directory() { + match self::load_grammar(&grammar_name, &grammar_fn_name, &grammars_dir) + { + Ok(grammar) => { + return Some(grammar); + } + Err(err) => { + if self != &LapceLanguage::PlainText { + tracing::error!("{:?} {:?}", self, err); + } + } + } + }; + + None + } + + fn query_name(&self) -> String { + self.properties() + .tree_sitter + .query + .unwrap_or(self.properties().id.as_ref()) + .to_lowercase() + } + + fn grammar_name(&self) -> String { + self.properties() + .tree_sitter + .grammar + .unwrap_or(self.properties().id.as_ref()) + .to_lowercase() + } + + fn grammar_fn_name(&self) -> String { + self.properties() + .tree_sitter + .grammar_fn + .unwrap_or(self.properties().id.as_ref()) + .to_lowercase() + } + + fn get_grammar_query(&self) -> (String, String) { + let query_name = self.query_name(); + + // Try reading highlights from user config dir + if let Some(queries_dir) = Directory::queries_directory() { + return ( + read_grammar_query( + &queries_dir, + &query_name, + Self::HIGHLIGHTS_QUERIES_FILE_NAME, + ), + read_grammar_query( + &queries_dir, + &query_name, + Self::HIGHLIGHTS_INJECTIONS_FILE_NAME, + ), + ); + } + + ("".to_string(), "".to_string()) + } + + pub(crate) fn new_highlight_config( + &self, + ) -> Result { + let grammar = self.get_grammar().ok_or(HighlightIssue::NotAvailable)?; + let (query, injection) = self.get_grammar_query(); + + match HighlightConfiguration::new(grammar, &query, &injection, "") { + Ok(x) => Ok(x), + Err(x) => { + let str = format!( + "Encountered {x:?} while trying to construct HighlightConfiguration for {}", + self.name() + ); + event!(Level::ERROR, "{str}"); + Err(HighlightIssue::Error(str)) + } + } + } + + pub(crate) fn walk_tree( + &self, + cursor: &mut TreeCursor, + normal_lines: &mut HashSet, + ) { + let (list, ignore_list) = self.properties().tree_sitter.code_glance; + walk_tree(cursor, normal_lines, list, ignore_list); + } +} + +fn load_grammar( + grammar_name: &str, + grammar_fn_name: &str, + path: &Path, +) -> Result { + let mut library_path = path.join(format!("libtree-sitter-{grammar_name}")); + library_path.set_extension(std::env::consts::DLL_EXTENSION); + + if !library_path.exists() { + event!(Level::WARN, "Grammar not found at: {library_path:?}"); + + // Load backward compat libraries + library_path = path.join(format!("tree-sitter-{grammar_name}")); + library_path.set_extension(std::env::consts::DLL_EXTENSION); + + if !library_path.exists() { + event!(Level::WARN, "Grammar not found at: {library_path:?}"); + return Err(HighlightIssue::Error("grammar not found".to_string())); + } + } + + event!(Level::DEBUG, "Loading grammar from user grammar dir"); + let library = match unsafe { libloading::Library::new(&library_path) } { + Ok(v) => v, + Err(e) => { + let err = format!("Failed to load '{}': '{e}'", library_path.display()); + event!(Level::ERROR, err); + return Err(HighlightIssue::Error(err)); + } + }; + + let language_fn_name = + format!("tree_sitter_{}", grammar_fn_name.replace('-', "_")); + event!( + Level::DEBUG, + "Loading grammar with address: '{language_fn_name}'" + ); + let language = unsafe { + let language_fn: libloading::Symbol< + unsafe extern "C" fn() -> tree_sitter::Language, + > = match library.get(language_fn_name.as_bytes()) { + Ok(v) => v, + Err(e) => { + let err = format!("Failed to load '{language_fn_name}': '{e}'"); + event!(Level::ERROR, err); + if let Some(e) = library.close().err() { + event!(Level::ERROR, "Failed to drop loaded library: {e}"); + }; + return Err(HighlightIssue::Error(err)); + } + }; + language_fn() + }; + std::mem::forget(library); + + Ok(language) +} + +/// Walk an AST and determine which lines to include in the code glance. +/// +/// Node types listed in `list` will be walked, along with their children. All +/// nodes encountered will be included, unless they are listed in `ignore_list`. +fn walk_tree( + cursor: &mut TreeCursor, + normal_lines: &mut HashSet, + list: &[&str], + ignore_list: &[&str], +) { + let node = cursor.node(); + let start_pos = node.start_position(); + let end_pos = node.end_position(); + let kind = node.kind().trim(); + if !ignore_list.contains(&kind) && !kind.is_empty() { + normal_lines.insert(start_pos.row); + normal_lines.insert(end_pos.row); + } + + if list.contains(&kind) && cursor.goto_first_child() { + loop { + walk_tree(cursor, normal_lines, list, ignore_list); + if !cursor.goto_next_sibling() { + break; + } + } + cursor.goto_parent(); + } +} + +fn add_bracket_pos( + bracket_pos: &mut HashMap>, + start_pos: Point, + color: String, +) { + let line_style = LineStyle { + start: start_pos.column, + end: start_pos.column + 1, + style: Style { + fg_color: Some(color), + }, + }; + match bracket_pos.entry(start_pos.row) { + Entry::Vacant(v) => _ = v.insert(vec![line_style]), + Entry::Occupied(mut o) => o.get_mut().push(line_style), + } +} + +pub(crate) fn walk_tree_bracket_ast( + cursor: &mut TreeCursor, + level: &mut usize, + counter: &mut usize, + bracket_pos: &mut HashMap>, + palette: &Vec, +) { + if cursor.node().kind().ends_with('(') + || cursor.node().kind().ends_with('{') + || cursor.node().kind().ends_with('[') + { + let row = cursor.node().end_position().row; + let col = cursor.node().end_position().column - 1; + let start_pos = Point::new(row, col); + add_bracket_pos( + bracket_pos, + start_pos, + palette.get(*level % palette.len()).unwrap().clone(), + ); + *level += 1; + } else if cursor.node().kind().ends_with(')') + || cursor.node().kind().ends_with('}') + || cursor.node().kind().ends_with(']') + { + let (new_level, overflow) = (*level).overflowing_sub(1); + let row = cursor.node().end_position().row; + let col = cursor.node().end_position().column - 1; + let start_pos = Point::new(row, col); + if overflow { + add_bracket_pos(bracket_pos, start_pos, "bracket.unpaired".to_string()); + } else { + *level = new_level; + add_bracket_pos( + bracket_pos, + start_pos, + palette.get(*level % palette.len()).unwrap().clone(), + ); + } + } + *counter += 1; + if cursor.goto_first_child() { + loop { + walk_tree_bracket_ast(cursor, level, counter, bracket_pos, palette); + if !cursor.goto_next_sibling() { + break; + } + } + cursor.goto_parent(); + } +} + +fn read_grammar_query(queries_dir: &Path, name: &str, kind: &str) -> String { + static INHERITS_REGEX: Lazy = + Lazy::new(|| Regex::new(r";+\s*inherits\s*:?\s*([a-z_,()-]+)\s*").unwrap()); + + let file = queries_dir.join(name).join(kind); + let query = std::fs::read_to_string(&file).unwrap_or_else(|err| { + tracing::event!( + tracing::Level::WARN, + "Failed to read queries at: {file:?}, {err}" + ); + String::new() + }); + + INHERITS_REGEX + .replace_all(&query, |captures: ®ex::Captures| { + captures[1] + .split(',') + .fold(String::new(), |mut output, name| { + write!( + output, + "\n{}\n", + read_grammar_query(queries_dir, name, kind) + ) + .unwrap(); + output + }) + }) + .to_string() +} + +#[cfg(test)] +mod tests { + use std::path::PathBuf; + + use super::LapceLanguage; + + #[test] + fn test_language_from_path() { + let l = LapceLanguage::from_path(&PathBuf::new().join("test.rs")); + assert_eq!(l, LapceLanguage::Rust); + } +} diff --git a/lapce-core/src/lens.rs b/lapce-core/src/lens.rs new file mode 100644 index 0000000..348de5f --- /dev/null +++ b/lapce-core/src/lens.rs @@ -0,0 +1,388 @@ +use std::mem; + +use lapce_xi_rope::{ + Cursor, Delta, Interval, Metric, + interval::IntervalBounds, + tree::{DefaultMetric, Leaf, Node, NodeInfo, TreeBuilder}, +}; + +const MIN_LEAF: usize = 5; +const MAX_LEAF: usize = 10; + +pub type LensNode = Node; + +#[derive(Clone)] +pub struct Lens(LensNode); + +#[derive(Clone, Debug)] +pub struct LensInfo(usize); + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct LensData { + len: usize, + line_height: usize, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct LensLeaf { + len: usize, + data: Vec, + total_height: usize, +} + +pub struct LensIter<'a> { + cursor: Cursor<'a, LensInfo>, + end: usize, +} + +impl Lens { + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + pub fn line_of_height(&self, height: usize) -> usize { + let max_height = self.0.count::(self.0.len()); + if height >= max_height { + return self.0.len(); + } + self.0.count_base_units::(height) + } + + pub fn height_of_line(&self, line: usize) -> usize { + let line = self.0.len().min(line); + self.0.count::(line) + } + + pub fn iter(&self) -> LensIter<'_> { + LensIter { + cursor: Cursor::new(&self.0, 0), + end: self.len(), + } + } + + pub fn iter_chunks(&self, range: I) -> LensIter<'_> { + let Interval { start, end } = range.into_interval(self.len()); + + LensIter { + cursor: Cursor::new(&self.0, start), + end, + } + } + + pub fn apply_delta(&mut self, _delta: &Delta) {} +} + +impl NodeInfo for LensInfo { + type L = LensLeaf; + + fn accumulate(&mut self, other: &Self) { + self.0 += other.0; + } + + fn compute_info(l: &LensLeaf) -> LensInfo { + LensInfo(l.total_height) + } +} + +impl Leaf for LensLeaf { + fn len(&self) -> usize { + self.len + } + + fn is_ok_child(&self) -> bool { + self.data.len() >= MIN_LEAF + } + + fn push_maybe_split( + &mut self, + other: &LensLeaf, + iv: Interval, + ) -> Option { + let (iv_start, iv_end) = iv.start_end(); + let mut accum = 0; + let mut added_len = 0; + let mut added_height = 0; + for sec in &other.data { + if accum + sec.len < iv_start { + accum += sec.len; + continue; + } + + if accum + sec.len <= iv_end { + accum += sec.len; + self.data.push(LensData { + len: sec.len, + line_height: sec.line_height, + }); + added_len += sec.len; + added_height += sec.len * sec.line_height; + continue; + } + + let len = iv_end - (accum + sec.len); + self.data.push(LensData { + len, + line_height: sec.line_height, + }); + added_len += len; + added_height += sec.len * sec.line_height; + break; + } + self.len += added_len; + self.total_height += added_height; + + if self.data.len() <= MAX_LEAF { + None + } else { + let splitpoint = self.data.len() / 2; // number of spans + let new = self.data.split_off(splitpoint); + let new_len = new.iter().map(|d| d.len).sum(); + let new_height = new.iter().map(|d| d.len * d.line_height).sum(); + self.len -= new_len; + self.total_height -= new_height; + Some(LensLeaf { + len: new_len, + data: new, + total_height: new_height, + }) + } + } +} + +#[derive(Copy, Clone)] +pub struct LensMetric(()); + +impl Metric for LensMetric { + fn measure(info: &LensInfo, _len: usize) -> usize { + info.0 + } + + fn to_base_units(l: &LensLeaf, in_measured_units: usize) -> usize { + if in_measured_units > l.total_height { + l.len + } else if in_measured_units == 0 { + 0 + } else { + let mut line = 0; + let mut accum = 0; + for data in l.data.iter() { + let leaf_height = data.line_height * data.len; + let accum_height = accum + leaf_height; + if accum_height > in_measured_units { + return line + (in_measured_units - accum) / data.line_height; + } + accum = accum_height; + line += data.len; + } + line + } + } + + fn from_base_units(l: &LensLeaf, in_base_units: usize) -> usize { + let mut line = 0; + let mut accum = 0; + for data in l.data.iter() { + if in_base_units < line + data.len { + return accum + (in_base_units - line) * data.line_height; + } + accum += data.len * data.line_height; + line += data.len; + } + accum + } + + fn is_boundary(_l: &LensLeaf, _offset: usize) -> bool { + true + } + + fn prev(_l: &LensLeaf, offset: usize) -> Option { + if offset == 0 { None } else { Some(offset - 1) } + } + + fn next(l: &LensLeaf, offset: usize) -> Option { + if offset < l.len { + Some(offset + 1) + } else { + None + } + } + + fn can_fragment() -> bool { + false + } +} + +impl DefaultMetric for LensInfo { + type DefaultMetric = LensBaseMetric; +} + +#[derive(Copy, Clone)] +pub struct LensBaseMetric(()); + +impl Metric for LensBaseMetric { + fn measure(_: &LensInfo, len: usize) -> usize { + len + } + + fn to_base_units(_: &LensLeaf, in_measured_units: usize) -> usize { + in_measured_units + } + + fn from_base_units(_: &LensLeaf, in_base_units: usize) -> usize { + in_base_units + } + + fn is_boundary(l: &LensLeaf, offset: usize) -> bool { + LensMetric::is_boundary(l, offset) + } + + fn prev(l: &LensLeaf, offset: usize) -> Option { + LensMetric::prev(l, offset) + } + + fn next(l: &LensLeaf, offset: usize) -> Option { + LensMetric::next(l, offset) + } + + fn can_fragment() -> bool { + false + } +} + +pub struct LensBuilder { + b: TreeBuilder, + leaf: LensLeaf, +} + +impl Default for LensBuilder { + fn default() -> LensBuilder { + LensBuilder { + b: TreeBuilder::new(), + leaf: LensLeaf::default(), + } + } +} + +impl LensBuilder { + pub fn new() -> LensBuilder { + LensBuilder::default() + } + + pub fn add_section(&mut self, len: usize, line_height: usize) { + if self.leaf.data.len() == MAX_LEAF { + let leaf = mem::take(&mut self.leaf); + self.b.push(Node::from_leaf(leaf)); + } + self.leaf.len += len; + self.leaf.total_height += len * line_height; + self.leaf.data.push(LensData { len, line_height }); + } + + pub fn build(mut self) -> Lens { + self.b.push(Node::from_leaf(self.leaf)); + Lens(self.b.build()) + } +} + +impl Iterator for LensIter<'_> { + type Item = (usize, usize); + + fn next(&mut self) -> Option { + if self.cursor.pos() >= self.end { + return None; + } + if let Some((leaf, leaf_pos)) = self.cursor.get_leaf() { + if leaf.data.is_empty() { + return None; + } + let line = self.cursor.pos(); + self.cursor.next::(); + + let mut lines = 0; + for data in leaf.data.iter() { + if leaf_pos < data.len + lines { + return Some((line, data.line_height)); + } + lines += data.len; + } + return None; + } + None + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_lens_metric() { + let mut builder = LensBuilder::new(); + builder.add_section(10, 2); + builder.add_section(1, 25); + builder.add_section(20, 3); + let lens = builder.build(); + + assert_eq!(31, lens.len()); + assert_eq!(0, lens.height_of_line(0)); + assert_eq!(2, lens.height_of_line(1)); + assert_eq!(20, lens.height_of_line(10)); + assert_eq!(45, lens.height_of_line(11)); + assert_eq!(48, lens.height_of_line(12)); + assert_eq!(105, lens.height_of_line(31)); + assert_eq!(105, lens.height_of_line(32)); + assert_eq!(105, lens.height_of_line(62)); + + assert_eq!(0, lens.line_of_height(0)); + assert_eq!(0, lens.line_of_height(1)); + assert_eq!(1, lens.line_of_height(2)); + assert_eq!(1, lens.line_of_height(3)); + assert_eq!(2, lens.line_of_height(4)); + assert_eq!(2, lens.line_of_height(5)); + assert_eq!(3, lens.line_of_height(6)); + assert_eq!(10, lens.line_of_height(20)); + assert_eq!(10, lens.line_of_height(44)); + assert_eq!(11, lens.line_of_height(45)); + assert_eq!(11, lens.line_of_height(46)); + assert_eq!(31, lens.line_of_height(105)); + assert_eq!(31, lens.line_of_height(106)); + } + + #[test] + fn test_lens_iter() { + let mut builder = LensBuilder::new(); + builder.add_section(10, 2); + builder.add_section(1, 25); + builder.add_section(2, 3); + let lens = builder.build(); + + let mut iter = lens.iter(); + assert_eq!(Some((0, 2)), iter.next()); + assert_eq!(Some((1, 2)), iter.next()); + assert_eq!(Some((2, 2)), iter.next()); + for _ in 0..7 { + iter.next(); + } + assert_eq!(Some((10, 25)), iter.next()); + assert_eq!(Some((11, 3)), iter.next()); + assert_eq!(Some((12, 3)), iter.next()); + assert_eq!(None, iter.next()); + + let mut iter = lens.iter_chunks(9..12); + assert_eq!(Some((9, 2)), iter.next()); + assert_eq!(Some((10, 25)), iter.next()); + assert_eq!(Some((11, 3)), iter.next()); + assert_eq!(None, iter.next()); + + let mut iter = lens.iter_chunks(9..15); + assert_eq!(Some((9, 2)), iter.next()); + assert_eq!(Some((10, 25)), iter.next()); + assert_eq!(Some((11, 3)), iter.next()); + assert_eq!(Some((12, 3)), iter.next()); + assert_eq!(None, iter.next()); + } +} diff --git a/lapce-core/src/lib.rs b/lapce-core/src/lib.rs new file mode 100644 index 0000000..6c2f2c7 --- /dev/null +++ b/lapce-core/src/lib.rs @@ -0,0 +1,13 @@ +#![allow(clippy::manual_clamp)] + +pub mod directory; +pub mod encoding; +pub mod language; +pub mod lens; +pub mod meta; +pub mod rope_text_pos; +pub mod style; +pub mod syntax; +// This is primarily being re-exported to avoid changing every single usage +// in lapce-app. We should probably remove this at some point. +pub use floem_editor_core::*; diff --git a/lapce-core/src/meta.rs b/lapce-core/src/meta.rs new file mode 100644 index 0000000..1add227 --- /dev/null +++ b/lapce-core/src/meta.rs @@ -0,0 +1,8 @@ +#[derive(strum_macros::AsRefStr, PartialEq, Eq)] +pub enum ReleaseType { + Debug, + Stable, + Nightly, +} + +include!(concat!(env!("OUT_DIR"), "/meta.rs")); diff --git a/lapce-core/src/rope_text_pos.rs b/lapce-core/src/rope_text_pos.rs new file mode 100644 index 0000000..7b28305 --- /dev/null +++ b/lapce-core/src/rope_text_pos.rs @@ -0,0 +1,40 @@ +use floem_editor_core::buffer::rope_text::RopeText; +use lsp_types::Position; + +use crate::encoding::{offset_utf8_to_utf16, offset_utf16_to_utf8}; + +pub trait RopeTextPosition: RopeText { + /// Converts a UTF8 offset to a UTF16 LSP position + /// Returns None if it is not a valid UTF16 offset + fn offset_to_position(&self, offset: usize) -> Position { + let (line, col) = self.offset_to_line_col(offset); + let line_offset = self.offset_of_line(line); + + let utf16_col = + offset_utf8_to_utf16(self.char_indices_iter(line_offset..), col); + + Position { + line: line as u32, + character: utf16_col as u32, + } + } + + fn offset_of_position(&self, pos: &Position) -> usize { + let (line, column) = self.position_to_line_col(pos); + + self.offset_of_line_col(line, column) + } + + fn position_to_line_col(&self, pos: &Position) -> (usize, usize) { + let line = pos.line as usize; + let line_offset = self.offset_of_line(line); + + let column = offset_utf16_to_utf8( + self.char_indices_iter(line_offset..), + pos.character as usize, + ); + + (line, column) + } +} +impl RopeTextPosition for T {} diff --git a/lapce-core/src/style.rs b/lapce-core/src/style.rs new file mode 100644 index 0000000..775737e --- /dev/null +++ b/lapce-core/src/style.rs @@ -0,0 +1,75 @@ +use std::str; + +use lapce_rpc::style::{LineStyle, Style}; +use lapce_xi_rope::{LinesMetric, Rope, spans::Spans}; + +pub const SCOPES: &[&str] = &[ + "constant", + "type", + "type.builtin", + "property", + "comment", + "constructor", + "function", + "label", + "keyword", + "string", + "variable", + "variable.other.member", + "operator", + "attribute", + "escape", + "embedded", + "symbol", + "punctuation", + "punctuation.special", + "punctuation.delimiter", + "text", + "text.literal", + "text.title", + "text.uri", + "text.reference", + "string.escape", + "conceal", + "none", + "tag", + "markup.bold", + "markup.italic", + "markup.list", + "markup.quote", + "markup.heading", + "markup.link.url", + "markup.link.label", + "markup.link.text", +]; + +pub fn line_styles( + text: &Rope, + line: usize, + styles: &Spans