flea-qml 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +511 -2
- package/THIRD-PARTY-NOTICES.md +29 -0
- package/demos/App.java +5 -0
- package/demos/Dockerfile +4 -0
- package/demos/Main.kt +3 -0
- package/demos/Program.cs +1 -0
- package/demos/README.md +12 -0
- package/demos/app.dart +3 -0
- package/demos/app.deb +0 -0
- package/demos/app.js +1 -0
- package/demos/backup.tar +0 -0
- package/demos/budget.xlsx +0 -0
- package/demos/build.sh +2 -0
- package/demos/bundle.zip +0 -0
- package/demos/clip.mp4 +0 -0
- package/demos/data.sqlite +0 -0
- package/demos/disk.iso +0 -0
- package/demos/engine.cpp +5 -0
- package/demos/firmware.bin +0 -0
- package/demos/flake.nix +4 -0
- package/demos/folder/inside.txt +1 -0
- package/demos/font.ttf +0 -0
- package/demos/index.html +5 -0
- package/demos/index.php +2 -0
- package/demos/init.lua +1 -0
- package/demos/letter.docx +0 -0
- package/demos/lib.rs +3 -0
- package/demos/main.c +6 -0
- package/demos/main.h +3 -0
- package/demos/math-and-diagrams.md +200 -0
- package/demos/notes.tar.gz +0 -0
- package/demos/notes.txt +3 -0
- package/demos/photo.png +0 -0
- package/demos/program +2 -0
- package/demos/report.pdf +32 -0
- package/demos/script.py +1 -0
- package/demos/server.go +7 -0
- package/demos/settings.json +4 -0
- package/demos/slides.pptx +0 -0
- package/demos/song.mp3 +0 -0
- package/demos/style.css +4 -0
- package/demos/tool.rb +1 -0
- package/demos/types.ts +2 -0
- package/docs/pele.md +23 -0
- package/docs/protocol.md +3420 -0
- package/docs/temml.md +63 -0
- package/index.js +107 -0
- package/package.json +34 -4
- package/src/archive.js +407 -0
- package/src/archiveops.js +728 -0
- package/src/backend.js +369 -0
- package/src/bulkrename.js +95 -0
- package/src/clip-host.js +76 -0
- package/src/clip.js +462 -0
- package/src/code.js +168 -0
- package/src/compare.js +74 -0
- package/src/create.js +128 -0
- package/src/dirsize.js +147 -0
- package/src/figure-svg.js +530 -0
- package/src/figure-thread.js +23 -0
- package/src/figure.js +132 -0
- package/src/find.js +55 -0
- package/src/flea.js +39 -0
- package/src/fsinfo.js +39 -0
- package/src/highlight.js +141 -0
- package/src/html.js +52 -0
- package/src/kinds.js +89 -0
- package/src/listing.js +130 -0
- package/src/markdown-html.js +317 -0
- package/src/mathml.js +186 -0
- package/src/menu.js +180 -0
- package/src/meta.js +135 -0
- package/src/office.js +810 -0
- package/src/order.js +100 -0
- package/src/peek.js +49 -0
- package/src/pele-wrapper.js +695 -0
- package/src/permissions.js +180 -0
- package/src/places.js +313 -0
- package/src/preview-language.js +10 -0
- package/src/terminal-server.js +95 -0
- package/src/terminal-shell.js +26 -0
- package/src/transfer.js +669 -0
- package/src/trash-record.js +41 -0
- package/src/trash.js +210 -0
- package/src/trashbrowse.js +327 -0
- package/src/uistate.js +393 -0
- package/src/uistore.js +168 -0
- package/src/vendor/LICENSES/Apache-2.0.txt +202 -0
- package/src/vendor/LICENSES/MIT-katex-2015.txt +27 -0
- package/src/vendor/LICENSES/MIT-katex.txt +21 -0
- package/src/vendor/LICENSES/MIT-mermaid.txt +21 -0
- package/src/vendor/LICENSES/MIT-pele.txt +40 -0
- package/src/vendor/LICENSES/MIT-perseus.txt +18 -0
- package/src/vendor/LICENSES/MIT-temml.txt +21 -0
- package/src/vendor/pele.js +145 -0
- package/src/vendor/temml.mjs +14708 -0
- package/src/watch.js +98 -0
- package/src/wayland/client.js +109 -0
- package/src/wayland/protocol.js +55 -0
- package/src/wayland/protocols/ext-data-control-v1.xml +276 -0
- package/src/wayland/protocols/wayland.xml +3248 -0
- package/src/wayland/protocols/wlr-data-control-unstable-v1.xml +278 -0
- package/src/wayland/resource-io.js +6 -0
- package/src/wayland/socket-discovery.js +26 -0
- package/src/wayland/transport-posix.js +120 -0
- package/src/wayland/transport-win32.js +11 -0
- package/src/wayland/transport.js +3 -0
- package/src/wayland/win32-resources.js +80 -0
- package/src/wayland/win32-wire.js +62 -0
- package/test/archive.test.js +80 -0
- package/test/bench-markdown-scroll.mjs +190 -0
- package/test/clip-host.test.js +113 -0
- package/test/code-preview.test.js +35 -0
- package/test/compare-ui-paths.test.js +24 -0
- package/test/compare.test.js +54 -0
- package/test/delete-trash.test.js +67 -0
- package/test/dirsize.test.js +138 -0
- package/test/file-ops.test.js +307 -0
- package/test/file-url.test.js +24 -0
- package/test/find-contents.test.js +161 -0
- package/test/find-input.test.js +66 -0
- package/test/fixtures/pele-parity.json +1006 -0
- package/test/highlight-launcher.test.js +35 -0
- package/test/html-preview.test.js +22 -0
- package/test/input.test.js +15 -0
- package/test/keymap.test.js +26 -0
- package/test/language-icons.test.js +36 -0
- package/test/launcher.test.js +51 -0
- package/test/manual-archive-here-ui.mjs +47 -0
- package/test/manual-code-scroll.mjs +28 -0
- package/test/manual-column-scroll.mjs +24 -0
- package/test/manual-compare-ui.mjs +20 -0
- package/test/manual-find-status.mjs +37 -0
- package/test/manual-folder-focus.mjs +63 -0
- package/test/manual-html-security.mjs +23 -0
- package/test/manual-html-ui.mjs +30 -0
- package/test/manual-syntax-preview.mjs +26 -0
- package/test/manual-terminal-lifecycle.mjs +42 -0
- package/test/manual-terminal-navigation.mjs +48 -0
- package/test/manual-terminal-ui.mjs +47 -0
- package/test/manual-trash-ui.mjs +86 -0
- package/test/markdown-diagrams.test.js +93 -0
- package/test/markdown-html.test.js +105 -0
- package/test/mathml.test.js +92 -0
- package/test/menu-transfer.test.js +57 -0
- package/test/office-preview.test.js +154 -0
- package/test/pele-parity.test.js +28 -0
- package/test/places.test.js +134 -0
- package/test/preview-keys.test.js +60 -0
- package/test/preview-language.test.js +22 -0
- package/test/status-filename.test.js +20 -0
- package/test/transfer-replace-merge.test.js +187 -0
- package/test/trash-address.test.js +23 -0
- package/test/trash-view.test.js +37 -0
- package/test/trashbrowse.test.js +135 -0
- package/ui/AboutFacts.qml +78 -0
- package/ui/ArchiveCards.qml +95 -0
- package/ui/ArchiveCompressDialog.qml +378 -0
- package/ui/ArchiveHereConfirm.qml +127 -0
- package/ui/ArchivePasswordDialog.qml +257 -0
- package/ui/Backend.qml +775 -0
- package/ui/BulkOldNames.qml +47 -0
- package/ui/BulkRenameDialog.qml +380 -0
- package/ui/CardFrame.qml +67 -0
- package/ui/CardScroll.qml +79 -0
- package/ui/CheckBox.qml +73 -0
- package/ui/ChromeBar.qml +360 -0
- package/ui/ChromeButton.qml +131 -0
- package/ui/ChromeModes.qml +43 -0
- package/ui/CodeLines.qml +256 -0
- package/ui/CodeRefusal.qml +52 -0
- package/ui/CollideConfirm.qml +147 -0
- package/ui/CollideHost.qml +167 -0
- package/ui/ColumnPane.qml +525 -0
- package/ui/ColumnRow.qml +380 -0
- package/ui/ColumnsArea.qml +594 -0
- package/ui/ColumnsLanding.qml +147 -0
- package/ui/CompareView.qml +321 -0
- package/ui/ContextMenu.qml +743 -0
- package/ui/ConvertDialog.qml +456 -0
- package/ui/CountedWorker.qml +7 -0
- package/ui/Crumb.qml +64 -0
- package/ui/CrumbDrop.qml +25 -0
- package/ui/CsvTable.qml +394 -0
- package/ui/CursorMark.qml +41 -0
- package/ui/DefaultClaim.qml +130 -0
- package/ui/DeviceLock.qml +47 -0
- package/ui/DeviceMounts.qml +540 -0
- package/ui/DialogButton.qml +150 -0
- package/ui/DialogField.qml +147 -0
- package/ui/DialogHeader.qml +31 -0
- package/ui/DialogScrim.qml +20 -0
- package/ui/DialogTitle.qml +37 -0
- package/ui/Divider.qml +9 -0
- package/ui/DropInto.qml +126 -0
- package/ui/DropTarget.qml +35 -0
- package/ui/DropboxMark.qml +60 -0
- package/ui/EmptyState.qml +150 -0
- package/ui/EscapeHint.qml +11 -0
- package/ui/FactsTable.qml +54 -0
- package/ui/FastScrollHandler.qml +476 -0
- package/ui/FatNamesConfirm.qml +157 -0
- package/ui/Favourites.qml +143 -0
- package/ui/FigureService.qml +120 -0
- package/ui/FileDrag.qml +267 -0
- package/ui/FilterStrip.qml +133 -0
- package/ui/FitMetrics.qml +22 -0
- package/ui/FlashDriveRows.qml +137 -0
- package/ui/FlashHost.qml +72 -0
- package/ui/FlashImageRow.qml +104 -0
- package/ui/FlashRunner.qml +119 -0
- package/ui/FlashStepRow.qml +172 -0
- package/ui/FlashStrip.qml +38 -0
- package/ui/FlashView.qml +397 -0
- package/ui/FleaMark.qml +88 -0
- package/ui/FlyoutFade.qml +23 -0
- package/ui/FontPane.qml +170 -0
- package/ui/Glass.qml +114 -0
- package/ui/GlassTagger.qml +59 -0
- package/ui/Glyph.qml +64 -0
- package/ui/GlyphSolid.qml +22 -0
- package/ui/GridArea.qml +664 -0
- package/ui/GridTile.qml +325 -0
- package/ui/GvfsBridge.qml +164 -0
- package/ui/Header.qml +433 -0
- package/ui/HoverTimers.qml +39 -0
- package/ui/HtmlClip.qml +30 -0
- package/ui/HtmlPane.qml +63 -0
- package/ui/HyprlandMark.qml +45 -0
- package/ui/Ipc.qml +1005 -0
- package/ui/IpcControls.qml +7 -0
- package/ui/IpcMenuState.qml +48 -0
- package/ui/IpcPreviewState.qml +185 -0
- package/ui/JumpPath.qml +51 -0
- package/ui/KeymapSheet.qml +561 -0
- package/ui/KeymapSheetResult.qml +89 -0
- package/ui/KindStack.qml +40 -0
- package/ui/LangMark.qml +51 -0
- package/ui/LangMarkLoader.qml +26 -0
- package/ui/List.qml +480 -0
- package/ui/LoadingState.qml +54 -0
- package/ui/LocalSend.qml +56 -0
- package/ui/LocalSendMark.qml +73 -0
- package/ui/MarkdownBlockView.qml +311 -0
- package/ui/MarkdownBlocks.qml +35 -0
- package/ui/MarkdownFigure.qml +254 -0
- package/ui/MarkdownImages.qml +72 -0
- package/ui/MarkdownList.qml +81 -0
- package/ui/MarkdownMathsText.qml +97 -0
- package/ui/MarkdownPane.qml +83 -0
- package/ui/MarkdownPictures.qml +41 -0
- package/ui/MarkdownQuote.qml +52 -0
- package/ui/MarkdownRemote.qml +82 -0
- package/ui/MarkdownSource.qml +155 -0
- package/ui/MarkdownTable.qml +222 -0
- package/ui/MarkdownTableScroll.qml +64 -0
- package/ui/MarkdownTableWheel.qml +126 -0
- package/ui/MarkdownText.qml +87 -0
- package/ui/MarkdownWorker.js +132 -0
- package/ui/MatchText.qml +99 -0
- package/ui/MediaSession.qml +38 -0
- package/ui/MediaSound.qml +26 -0
- package/ui/MediaStrip.qml +191 -0
- package/ui/MediaTrack.qml +36 -0
- package/ui/MediaVolume.qml +54 -0
- package/ui/MenuActionDialog.qml +396 -0
- package/ui/MenuEdgeFade.qml +24 -0
- package/ui/MenuHost.qml +227 -0
- package/ui/MenuRow.qml +351 -0
- package/ui/MountListing.qml +100 -0
- package/ui/NetworkDialog.qml +435 -0
- package/ui/NetworkForm.qml +426 -0
- package/ui/NetworkMounts.qml +913 -0
- package/ui/NetworkPlaces.qml +127 -0
- package/ui/OpenWithDialog.qml +613 -0
- package/ui/Opener.qml +95 -0
- package/ui/Pane.qml +1320 -0
- package/ui/PaneMenuActions.qml +527 -0
- package/ui/PanePath.qml +90 -0
- package/ui/PaneRail.qml +268 -0
- package/ui/PaneStates.qml +88 -0
- package/ui/PaneSwap.qml +339 -0
- package/ui/PaneWire.qml +601 -0
- package/ui/ParkedWait.qml +9 -0
- package/ui/PathEntry.qml +186 -0
- package/ui/PathJump.qml +400 -0
- package/ui/PdfViewer.qml +297 -0
- package/ui/PermissionsDialog.qml +658 -0
- package/ui/PermissionsHeadings.qml +31 -0
- package/ui/PhoneMounts.qml +67 -0
- package/ui/PickerAnswers.qml +75 -0
- package/ui/PickerBox.qml +26 -0
- package/ui/PickerChrome.qml +295 -0
- package/ui/PickerFilter.qml +97 -0
- package/ui/PickerGrid.qml +308 -0
- package/ui/PickerHeader.qml +28 -0
- package/ui/PickerLifecycle.qml +27 -0
- package/ui/PickerList.qml +218 -0
- package/ui/PickerListing.qml +149 -0
- package/ui/PickerPathBar.qml +127 -0
- package/ui/PickerPlaces.qml +189 -0
- package/ui/PickerRecent.qml +92 -0
- package/ui/PickerSave.qml +101 -0
- package/ui/PickerSelection.qml +155 -0
- package/ui/PickerWindow.qml +846 -0
- package/ui/PowerSectorsReader.qml +10 -0
- package/ui/PrebuildDriver.qml +146 -0
- package/ui/Preview.qml +1005 -0
- package/ui/PreviewAnimation.qml +24 -0
- package/ui/PreviewArchive.qml +91 -0
- package/ui/PreviewColumn.qml +553 -0
- package/ui/PreviewEdge.qml +63 -0
- package/ui/PreviewFacts.qml +30 -0
- package/ui/PreviewFactsLine.qml +34 -0
- package/ui/PreviewHtml.qml +233 -0
- package/ui/PreviewImage.qml +253 -0
- package/ui/PreviewImagePan.qml +13 -0
- package/ui/PreviewImageSharp.qml +32 -0
- package/ui/PreviewLines.qml +106 -0
- package/ui/PreviewMarkdown.qml +706 -0
- package/ui/PreviewMedia.qml +250 -0
- package/ui/PreviewPdf.qml +482 -0
- package/ui/PreviewScroll.qml +201 -0
- package/ui/PreviewSwap.qml +335 -0
- package/ui/PreviewText.qml +149 -0
- package/ui/ProtocolChip.qml +18 -0
- package/ui/QuickLookArchive.qml +41 -0
- package/ui/QuickLookBar.qml +103 -0
- package/ui/QuickLookPrepare.qml +355 -0
- package/ui/QuickLookSwap.qml +10 -0
- package/ui/QuickLookWarm.qml +65 -0
- package/ui/RailDrop.qml +155 -0
- package/ui/RailHeading.qml +19 -0
- package/ui/RailPlaces.qml +38 -0
- package/ui/RailTrashRow.qml +67 -0
- package/ui/RenameField.qml +353 -0
- package/ui/RendererRetry.qml +11 -0
- package/ui/ResizeHandle.qml +52 -0
- package/ui/Reveal.qml +54 -0
- package/ui/Row.qml +476 -0
- package/ui/RowDrag.qml +213 -0
- package/ui/RowDropTarget.qml +27 -0
- package/ui/RunCard.qml +286 -0
- package/ui/Scripts.qml +65 -0
- package/ui/SearchStrip.qml +232 -0
- package/ui/SelectionBand.qml +140 -0
- package/ui/SelectionPreview.qml +370 -0
- package/ui/SettingsFavourite.qml +122 -0
- package/ui/SettingsGroup.qml +96 -0
- package/ui/SettingsHint.qml +12 -0
- package/ui/SettingsMetrics.qml +29 -0
- package/ui/SettingsPane.qml +178 -0
- package/ui/SettingsPanel.qml +547 -0
- package/ui/SettingsRail.qml +128 -0
- package/ui/SettingsRow.qml +409 -0
- package/ui/SettingsRuler.qml +85 -0
- package/ui/SettingsSegment.qml +85 -0
- package/ui/ShareBrowser.qml +113 -0
- package/ui/ShareLink.qml +67 -0
- package/ui/ShelfPins.qml +101 -0
- package/ui/Sidebar.qml +728 -0
- package/ui/SidebarRow.qml +358 -0
- package/ui/Spinner.qml +60 -0
- package/ui/StableModel.qml +89 -0
- package/ui/StateMessage.qml +84 -0
- package/ui/StatusBar.qml +512 -0
- package/ui/StatusFileName.qml +27 -0
- package/ui/TabBar.qml +673 -0
- package/ui/TabDragGeometry.qml +60 -0
- package/ui/TagMenuMark.qml +52 -0
- package/ui/TagRailSection.qml +53 -0
- package/ui/TagSlot.qml +40 -0
- package/ui/TagState.qml +150 -0
- package/ui/TagSwatch.qml +28 -0
- package/ui/Taildrop.qml +86 -0
- package/ui/TailscaleMark.qml +50 -0
- package/ui/TerminalService.qml +69 -0
- package/ui/TerminalTab.qml +48 -0
- package/ui/TerminalTabs.qml +27 -0
- package/ui/Theme.qml +460 -0
- package/ui/ThemeColors.qml +43 -0
- package/ui/TransferCard.qml +239 -0
- package/ui/TrashConfirm.qml +129 -0
- package/ui/TrashDropHandler.qml +11 -0
- package/ui/TrashHost.qml +202 -0
- package/ui/TrashMonitor.qml +30 -0
- package/ui/TrashToolbar.qml +19 -0
- package/ui/TrashView.qml +492 -0
- package/ui/UnlockDialog.qml +450 -0
- package/ui/UnlockHost.qml +206 -0
- package/ui/UpdateCheck.qml +97 -0
- package/ui/UserDirs.qml +25 -0
- package/ui/ViewState.qml +565 -0
- package/ui/ViewportScrollBar.qml +195 -0
- package/ui/ViewportScrollBars.qml +25 -0
- package/ui/WebPreview.qml +33 -0
- package/ui/WebPreviewView.qml +26 -0
- package/ui/WindowBody.qml +829 -0
- package/ui/WindowDrag.qml +35 -0
- package/ui/boot/Commons/AudioNodes.qml +50 -0
- package/ui/boot/Commons/AudioNodesModel.js +96 -0
- package/ui/boot/Commons/Border.qml +243 -0
- package/ui/boot/Commons/BorderGeometry.js +373 -0
- package/ui/boot/Commons/Color.qml +258 -0
- package/ui/boot/Commons/I18n.qml +118 -0
- package/ui/boot/Commons/InputDevices.qml +112 -0
- package/ui/boot/Commons/InputMethodState.qml +38 -0
- package/ui/boot/Commons/IpcRegistry.qml +77 -0
- package/ui/boot/Commons/Numbers.js +19 -0
- package/ui/boot/Commons/Plural.js +91 -0
- package/ui/boot/Commons/ShellIpc.qml +12 -0
- package/ui/boot/Commons/Style.qml +561 -0
- package/ui/boot/Commons/Translations.qml +100 -0
- package/ui/boot/Commons/UntypedInput.qml +152 -0
- package/ui/boot/Commons/Util.qml +188 -0
- package/ui/boot/Commons/qmldir +13 -0
- package/ui/boot/LICENSE-omarchy +20 -0
- package/ui/boot/Ui/BackgroundMedia.qml +49 -0
- package/ui/boot/Ui/BarIconButton.qml +106 -0
- package/ui/boot/Ui/BarIconContent.qml +38 -0
- package/ui/boot/Ui/BarIndicator.qml +53 -0
- package/ui/boot/Ui/BarWidget.qml +50 -0
- package/ui/boot/Ui/BorderOverlay.qml +54 -0
- package/ui/boot/Ui/BorderSurface.qml +40 -0
- package/ui/boot/Ui/Button.qml +224 -0
- package/ui/boot/Ui/ButtonGroup.qml +131 -0
- package/ui/boot/Ui/ConfirmDialog.qml +134 -0
- package/ui/boot/Ui/CursorSurface.qml +42 -0
- package/ui/boot/Ui/Dropdown.qml +245 -0
- package/ui/boot/Ui/FilterInput.qml +26 -0
- package/ui/boot/Ui/IconContentBounds.qml +141 -0
- package/ui/boot/Ui/KeyboardPanel.qml +453 -0
- package/ui/boot/Ui/MultiSelect.qml +624 -0
- package/ui/boot/Ui/NumberField.qml +86 -0
- package/ui/boot/Ui/OpticalGlyph.qml +68 -0
- package/ui/boot/Ui/OverlayWindow.qml +102 -0
- package/ui/boot/Ui/Panel.qml +60 -0
- package/ui/boot/Ui/PanelActionButton.qml +105 -0
- package/ui/boot/Ui/PanelController.qml +16 -0
- package/ui/boot/Ui/PanelHero.qml +112 -0
- package/ui/boot/Ui/PanelKeyCatcher.qml +100 -0
- package/ui/boot/Ui/PanelSectionHeader.qml +31 -0
- package/ui/boot/Ui/PanelSeparator.qml +19 -0
- package/ui/boot/Ui/PanelSlider.qml +156 -0
- package/ui/boot/Ui/PanelToolTip.qml +50 -0
- package/ui/boot/Ui/PluginBarApi.qml +89 -0
- package/ui/boot/Ui/PointerMoveGate.qml +54 -0
- package/ui/boot/Ui/PopupCard.qml +181 -0
- package/ui/boot/Ui/ScreenMoveRemap.qml +43 -0
- package/ui/boot/Ui/SearchableDropdown.qml +354 -0
- package/ui/boot/Ui/SizedImage.qml +125 -0
- package/ui/boot/Ui/SpeedTestOverlay.qml +412 -0
- package/ui/boot/Ui/TextField.qml +58 -0
- package/ui/boot/Ui/Toggle.qml +118 -0
- package/ui/boot/Ui/ToggleSwitch.qml +115 -0
- package/ui/boot/Ui/WidgetButton.qml +172 -0
- package/ui/boot/Ui/qmldir +41 -0
- package/ui/boot/fleatab.qml +50 -0
- package/ui/boot/picker.qml +39 -0
- package/ui/boot/shell.qml +131 -0
- package/ui/boot/tabtearoff.qml +51 -0
- package/ui/js/Anchor.js +379 -0
- package/ui/js/AnchorHold.js +162 -0
- package/ui/js/Archive.js +157 -0
- package/ui/js/ArchiveCard.js +44 -0
- package/ui/js/ArchiveOps.js +44 -0
- package/ui/js/BackReturn.js +118 -0
- package/ui/js/BulkRename.js +100 -0
- package/ui/js/Buttons.js +54 -0
- package/ui/js/ChromeKeys.js +116 -0
- package/ui/js/ClipMarks.js +73 -0
- package/ui/js/ClipSelection.js +67 -0
- package/ui/js/Clipboard.js +179 -0
- package/ui/js/Cloud.js +97 -0
- package/ui/js/CodeRuns.js +72 -0
- package/ui/js/Collide.js +212 -0
- package/ui/js/ColumnFit.js +28 -0
- package/ui/js/ColumnMenu.js +111 -0
- package/ui/js/Columns.js +298 -0
- package/ui/js/ColumnsCarry.js +103 -0
- package/ui/js/Compare.js +74 -0
- package/ui/js/Contrast.js +157 -0
- package/ui/js/ControlReader.js +42 -0
- package/ui/js/Convert.js +52 -0
- package/ui/js/CopyAs.js +52 -0
- package/ui/js/Crumbs.js +178 -0
- package/ui/js/Csv.js +231 -0
- package/ui/js/Density.js +44 -0
- package/ui/js/Devices.js +440 -0
- package/ui/js/DirSizes.js +180 -0
- package/ui/js/Drag.js +360 -0
- package/ui/js/DragOut.js +166 -0
- package/ui/js/DropDev.js +52 -0
- package/ui/js/Dropbox.js +41 -0
- package/ui/js/Eject.js +217 -0
- package/ui/js/Errors.js +188 -0
- package/ui/js/ExtThumbs.js +115 -0
- package/ui/js/Facts.js +402 -0
- package/ui/js/FigureDate.js +14 -0
- package/ui/js/Filter.js +285 -0
- package/ui/js/Find.js +46 -0
- package/ui/js/Flash.js +184 -0
- package/ui/js/FlashCard.js +79 -0
- package/ui/js/FlashEndings.js +125 -0
- package/ui/js/FlashPane.js +116 -0
- package/ui/js/FleaBin.js +12 -0
- package/ui/js/Focus.js +504 -0
- package/ui/js/FolderSorts.js +108 -0
- package/ui/js/FolderViews.js +44 -0
- package/ui/js/Format.js +314 -0
- package/ui/js/Fuzzy.js +141 -0
- package/ui/js/GlassTag.js +72 -0
- package/ui/js/Grid.js +33 -0
- package/ui/js/GridGeometry.js +90 -0
- package/ui/js/GridNames.js +153 -0
- package/ui/js/GvfsBridge.js +200 -0
- package/ui/js/HostClipboard.js +29 -0
- package/ui/js/Icons.js +218 -0
- package/ui/js/Input.js +50 -0
- package/ui/js/Jump.js +200 -0
- package/ui/js/KeyName.js +64 -0
- package/ui/js/Keymap.js +401 -0
- package/ui/js/Kinds.js +164 -0
- package/ui/js/LICENSES/ISC-lucide.txt +43 -0
- package/ui/js/LangMarkPaths.js +47 -0
- package/ui/js/LangMarks.js +120 -0
- package/ui/js/Lists.js +11 -0
- package/ui/js/LocalSend.js +39 -0
- package/ui/js/LockedMenu.js +63 -0
- package/ui/js/MakeDefault.js +186 -0
- package/ui/js/MarkBox.js +7 -0
- package/ui/js/Markdown.js +119 -0
- package/ui/js/MarkdownLists.js +86 -0
- package/ui/js/MarkdownMaths.js +58 -0
- package/ui/js/MarkdownPictures.js +32 -0
- package/ui/js/MarkdownPrepared.js +139 -0
- package/ui/js/MarkdownTableFit.js +34 -0
- package/ui/js/Marks.js +148 -0
- package/ui/js/Marquee.js +96 -0
- package/ui/js/Match.js +93 -0
- package/ui/js/Material.js +109 -0
- package/ui/js/MdBlocks.js +437 -0
- package/ui/js/MdBreak.js +71 -0
- package/ui/js/MdChunks.js +70 -0
- package/ui/js/MdContainer.js +137 -0
- package/ui/js/MdDocument.js +337 -0
- package/ui/js/MdEmph.js +97 -0
- package/ui/js/MdEntity.js +108 -0
- package/ui/js/MdEntityTable.js +223 -0
- package/ui/js/MdEscape.js +59 -0
- package/ui/js/MdFront.js +37 -0
- package/ui/js/MdHold.js +32 -0
- package/ui/js/MdHtml.js +307 -0
- package/ui/js/MdHtmlBlock.js +290 -0
- package/ui/js/MdHtmlHeading.js +53 -0
- package/ui/js/MdHtmlImage.js +179 -0
- package/ui/js/MdInline.js +154 -0
- package/ui/js/MdItems.js +212 -0
- package/ui/js/MdLeaf.js +309 -0
- package/ui/js/MdLink.js +196 -0
- package/ui/js/MdMath.js +67 -0
- package/ui/js/MdParagraphs.js +138 -0
- package/ui/js/MdRefs.js +232 -0
- package/ui/js/MdResolve.js +226 -0
- package/ui/js/MdRun.js +300 -0
- package/ui/js/MdUrl.js +226 -0
- package/ui/js/Menu.js +514 -0
- package/ui/js/MenuContext.js +85 -0
- package/ui/js/MenuFit.js +13 -0
- package/ui/js/MenuRefresh.js +74 -0
- package/ui/js/MenuWheel.js +35 -0
- package/ui/js/Messages.js +186 -0
- package/ui/js/Motion.js +16 -0
- package/ui/js/Mounts.js +320 -0
- package/ui/js/MouseNav.js +13 -0
- package/ui/js/Nav.js +329 -0
- package/ui/js/NetFs.js +26 -0
- package/ui/js/OpenWith.js +83 -0
- package/ui/js/Ops.js +585 -0
- package/ui/js/Palette.js +33 -0
- package/ui/js/PathBar.js +260 -0
- package/ui/js/Permissions.js +179 -0
- package/ui/js/Phones.js +112 -0
- package/ui/js/Picker.js +353 -0
- package/ui/js/PlaceMenu.js +96 -0
- package/ui/js/Places.js +265 -0
- package/ui/js/PreviewAsk.js +21 -0
- package/ui/js/PreviewKeys.js +155 -0
- package/ui/js/PreviewSettle.js +29 -0
- package/ui/js/PreviewSwap.js +101 -0
- package/ui/js/PropertyFacts.js +144 -0
- package/ui/js/Protocols.js +296 -0
- package/ui/js/QuickLookKinds.js +27 -0
- package/ui/js/QuickLookRect.js +24 -0
- package/ui/js/RailDrop.js +51 -0
- package/ui/js/RailKeys.js +87 -0
- package/ui/js/RailMenu.js +133 -0
- package/ui/js/Recent.js +135 -0
- package/ui/js/RecentMode.js +156 -0
- package/ui/js/Reload.js +60 -0
- package/ui/js/Renderer.js +9 -0
- package/ui/js/RunFile.js +143 -0
- package/ui/js/Scripts.js +28 -0
- package/ui/js/Scroll.js +304 -0
- package/ui/js/ScrollOff.js +69 -0
- package/ui/js/Search.js +478 -0
- package/ui/js/Selection.js +97 -0
- package/ui/js/Settings.js +476 -0
- package/ui/js/SettingsAbout.js +97 -0
- package/ui/js/SettingsShelf.js +52 -0
- package/ui/js/SheetKeys.js +42 -0
- package/ui/js/SheetQuery.js +281 -0
- package/ui/js/ShelfPile.js +27 -0
- package/ui/js/SlowClick.js +53 -0
- package/ui/js/SlowOp.js +6 -0
- package/ui/js/Sort.js +134 -0
- package/ui/js/Startup.js +63 -0
- package/ui/js/StateWords.js +17 -0
- package/ui/js/Status.js +238 -0
- package/ui/js/Swap.js +166 -0
- package/ui/js/TabMove.js +39 -0
- package/ui/js/Tabs.js +751 -0
- package/ui/js/Tags.js +134 -0
- package/ui/js/Taildrop.js +128 -0
- package/ui/js/Tap.js +180 -0
- package/ui/js/TextSize.js +107 -0
- package/ui/js/Thumbs.js +158 -0
- package/ui/js/Transfer.js +172 -0
- package/ui/js/Trash.js +84 -0
- package/ui/js/TrashDates.js +47 -0
- package/ui/js/TrashDrop.js +64 -0
- package/ui/js/UiState.js +438 -0
- package/ui/js/Unlock.js +152 -0
- package/ui/js/Update.js +130 -0
- package/ui/js/UserDirs.js +56 -0
- package/ui/qmldir +230 -0
package/ui/js/Search.js
ADDED
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
.pragma library
|
|
2
|
+
.import "Input.js" as Input
|
|
3
|
+
.import "Format.js" as Format
|
|
4
|
+
|
|
5
|
+
// The status bar's two search lines, each filled by Format.fill.
|
|
6
|
+
var WORDS = {
|
|
7
|
+
// flea-qml: find reports matches only, so there is no scanned count to show.
|
|
8
|
+
searching: "%1 found · Searching",
|
|
9
|
+
landed: "%1 found in %2 s"
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Enter starts the subtree search; editing the real input alone does not run find.
|
|
13
|
+
var OFF = ""
|
|
14
|
+
var TYPING = "typing"
|
|
15
|
+
var RESULTS = "results"
|
|
16
|
+
|
|
17
|
+
// f opens the session with no rows touched; from Recent it leaves first, so the scope and rows are the real folder.
|
|
18
|
+
// flea-qml: `contents` (Ctrl+G) opens it as a content search; f and a tag place open a name search.
|
|
19
|
+
function start(root, contents) {
|
|
20
|
+
// A virtual collection has no single recursive filesystem scope. Never search
|
|
21
|
+
// the unrelated directory that was visible before opening Trash.
|
|
22
|
+
if (root.recentMode === "trash") {
|
|
23
|
+
root.message("Open a Trash folder to Find inside it; / filters this collection", false)
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
if (root.searchMode === RESULTS) {
|
|
27
|
+
root.searchMode = TYPING
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
if ((root.searchMode || "").length > 0) {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
// The cursor's file rides pendingSelect until Esc; mid-session landings skip it while the query stands.
|
|
34
|
+
var under = root.rowFor(root.cursorIndex)
|
|
35
|
+
root.pendingSelect = under && under.n ? root.join(root.path, under.n) : ""
|
|
36
|
+
var fromRecent = root.recentMode.length > 0
|
|
37
|
+
if (fromRecent) {
|
|
38
|
+
// The history rows keep their own base until the folder's rows, asked below, replace them.
|
|
39
|
+
root.searchBase = root.path
|
|
40
|
+
if (root.recentFrom.length > 0) {
|
|
41
|
+
root.path = root.recentFrom
|
|
42
|
+
}
|
|
43
|
+
root.recentMode = ""
|
|
44
|
+
root.recentFrom = ""
|
|
45
|
+
root.recentPaths = []
|
|
46
|
+
root.restoreRecentSort()
|
|
47
|
+
}
|
|
48
|
+
root.searchFrom = root.path
|
|
49
|
+
root.searchContents = contents === true
|
|
50
|
+
root.searchMode = TYPING
|
|
51
|
+
openScope(root)
|
|
52
|
+
// Recent's rows name paths under "/", so the folder's own rows are asked for now and Esc re-lists it.
|
|
53
|
+
if (fromRecent) {
|
|
54
|
+
sendQuery(root)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// The backend session for the pane's scope, with the drawn state of a fresh walk; f and a tag place both open through here.
|
|
59
|
+
function openScope(root) {
|
|
60
|
+
// Gens keep rising across sessions, so a closed session's late line never matches; the first answer parks on row 0.
|
|
61
|
+
root.searchOpenedGen = root.searchGen
|
|
62
|
+
if (root.swap) { root.swap.landedGen = 0; root.swap.answeredQuery = "" }
|
|
63
|
+
root.searchQuery = ""
|
|
64
|
+
root.searchSent = ""
|
|
65
|
+
// flea-qml: nothing runs until Enter, so a fresh strip is not searching yet.
|
|
66
|
+
root.searchRunning = false
|
|
67
|
+
root.searchCancelled = false
|
|
68
|
+
root.searchScanned = 0
|
|
69
|
+
root.backend.searchOpen(scopeRoot(root.path, root.home || "", root.searchStep), root.path, root.showHidden)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// flea-qml: Find's scopes, which Tab turns through in this order wherever the pane is: the folder
|
|
73
|
+
// itself, home, and the root of the folder's own filesystem.
|
|
74
|
+
var HERE = 0, HOME = 1, ROOT = 2
|
|
75
|
+
var SCOPE_COUNT = 3
|
|
76
|
+
var SCOPE_MARK = [".", "~", "/"]
|
|
77
|
+
|
|
78
|
+
// The root a path stands on, read off the path's own start, so every system answers alike:
|
|
79
|
+
// "/" for /home/a, "C:\" for C:\Users\a, and "\\server\share\" for a path under that share.
|
|
80
|
+
function rootOf(path) {
|
|
81
|
+
var m = /^(\\\\[^\\/]+[\\/][^\\/]+[\\/]?|[A-Za-z]:[\\/]?|[\\/])/.exec(String(path))
|
|
82
|
+
return m ? m[0] : "/"
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function scopeRoot(path, home, step) {
|
|
86
|
+
if (step === HOME && home) return home
|
|
87
|
+
if (step === ROOT) return rootOf(path)
|
|
88
|
+
return path
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Keystrokes send rising gens with old rows held and the cursor standing for the landing to keep.
|
|
92
|
+
// flea-qml: only Enter (and Tab over a query already run) sends one; searchSent is what it sent.
|
|
93
|
+
function sendQuery(root) {
|
|
94
|
+
root.searchSent = root.searchQuery
|
|
95
|
+
// flea-qml: the find runs from here until its terminal line lands.
|
|
96
|
+
root.searchRunning = root.searchQuery.length > 0
|
|
97
|
+
root.searchCancelled = false
|
|
98
|
+
root.searchGen += 1
|
|
99
|
+
root.searchKeyAt = Date.now()
|
|
100
|
+
root.searchFirstRowsAt = 0
|
|
101
|
+
root.searchSettledAt = 0
|
|
102
|
+
root.backend.searchQuery(root.searchQuery, root.searchGen, root.windowSize, root.sizeWish, root.searchContents === true)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// flea-qml: Ctrl+G. Outside Find it opens a content search; inside, it turns the search between
|
|
106
|
+
// names and contents. Either way nothing runs until Enter: from the results it goes back to the
|
|
107
|
+
// query line, as f does, so the next Enter runs the query in the new mode.
|
|
108
|
+
function contents(root) {
|
|
109
|
+
if ((root.searchMode || "").length === 0) {
|
|
110
|
+
start(root, true)
|
|
111
|
+
return
|
|
112
|
+
}
|
|
113
|
+
if (root.searchLeaving === true) return
|
|
114
|
+
root.searchContents = root.searchContents !== true
|
|
115
|
+
if (root.searchMode === RESULTS) root.searchMode = TYPING
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// flea-qml: typing only edits the query line; Enter runs the find.
|
|
119
|
+
function extend(root, character) {
|
|
120
|
+
root.searchQuery += character
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Backspace to empty sends "" and the folder rows come back, with the strip still open.
|
|
124
|
+
function shrink(root) {
|
|
125
|
+
if (root.searchQuery.length === 0) {
|
|
126
|
+
return
|
|
127
|
+
}
|
|
128
|
+
root.searchQuery = root.searchQuery.substring(0, root.searchQuery.length - 1)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// flea-qml: Enter runs the find every time, changed query or not, so the results are fresh; a press
|
|
132
|
+
// within ENTER_DEBOUNCE_MS of the last run is the same press repeated and runs nothing more.
|
|
133
|
+
var ENTER_DEBOUNCE_MS = 500
|
|
134
|
+
function commit(root) {
|
|
135
|
+
if ((root.searchQuery || "").length === 0) {
|
|
136
|
+
abort(root)
|
|
137
|
+
return
|
|
138
|
+
}
|
|
139
|
+
var now = Date.now()
|
|
140
|
+
if (now - (root.searchEnterAt || 0) >= ENTER_DEBOUNCE_MS) {
|
|
141
|
+
root.searchEnterAt = now
|
|
142
|
+
sendQuery(root)
|
|
143
|
+
}
|
|
144
|
+
root.searchMode = RESULTS
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// A leaving session takes no query from outside, so a caller that clears its own state first asks here.
|
|
148
|
+
function takesQuery(root) {
|
|
149
|
+
return root.searchLeaving !== true
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// A query set from outside the strip lands as results over the Home scope, from a fresh session, a standing one or a cancelled one; a leaving session takes none.
|
|
153
|
+
// Sample input: (pane, "tag:Red") with the pane browsing, in Recent, or typing or showing results at either scope.
|
|
154
|
+
function openQuery(root, query) {
|
|
155
|
+
if (!takesQuery(root)) {
|
|
156
|
+
return
|
|
157
|
+
}
|
|
158
|
+
if ((root.searchMode || "").length === 0) {
|
|
159
|
+
root.searchStep = HOME
|
|
160
|
+
start(root)
|
|
161
|
+
} else if (root.searchCancelled === true) {
|
|
162
|
+
// A cancelled walk answers nothing more, so the place opens a fresh Home session with the drawn state of a new walk.
|
|
163
|
+
root.searchStep = HOME
|
|
164
|
+
openScope(root)
|
|
165
|
+
} else if (root.searchStep !== HOME) {
|
|
166
|
+
// flea-qml: the place's query runs over home, whichever scope Tab had turned to.
|
|
167
|
+
root.searchStep = HOME
|
|
168
|
+
openScope(root)
|
|
169
|
+
}
|
|
170
|
+
root.searchQuery = query
|
|
171
|
+
sendQuery(root)
|
|
172
|
+
commit(root)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Tab flips the scope, opens the new scope at once and re-sends the standing query.
|
|
176
|
+
function rescope(root) {
|
|
177
|
+
root.searchStep = nextStep(root.searchStep, root.home || "")
|
|
178
|
+
var scope = scopeRoot(root.path, root.home || "", root.searchStep)
|
|
179
|
+
root.backend.searchOpen(scope, root.path, root.showHidden)
|
|
180
|
+
// flea-qml: a query already run reruns in the new scope; an unrun one waits for Enter.
|
|
181
|
+
if ((root.searchSent || "").length > 0 && (root.searchQuery || "").length > 0) {
|
|
182
|
+
sendQuery(root)
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// flea-qml: the command the empty query line stands for, after the scope it runs in.
|
|
187
|
+
// The space after -iname is the one a shell command line holds before its argument.
|
|
188
|
+
function placeholder(path, home, step, contents) {
|
|
189
|
+
// A content search names the text it looks for; the scope is the "in" after the field.
|
|
190
|
+
if (contents === true) return "grep -ri "
|
|
191
|
+
return "find " + SCOPE_MARK[step === HOME && !home ? HERE : step] + " -iname "
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// flea-qml: where Tab moves the scope next, the same everywhere; home is skipped when none is known.
|
|
195
|
+
function tabHint(path, home, step) {
|
|
196
|
+
return "tab: " + SCOPE_MARK[nextStep(step, home)]
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function nextStep(step, home) {
|
|
200
|
+
var next = (step + 1) % SCOPE_COUNT
|
|
201
|
+
return next === HOME && !home ? (next + 1) % SCOPE_COUNT : next
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// flea-qml: the manager's hidden setting changed under a standing Find: the scope reopens with it,
|
|
205
|
+
// and a query already run runs again, walking hidden folders now or pruning them.
|
|
206
|
+
function rehide(root) {
|
|
207
|
+
root.backend.searchOpen(scopeRoot(root.path, root.home || "", root.searchStep), root.path, root.showHidden)
|
|
208
|
+
if ((root.searchSent || "").length > 0 && (root.searchQuery || "").length > 0)
|
|
209
|
+
sendQuery(root)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// flea-qml: ✕ stops a running find and leaves at once, the two Escapes in one press.
|
|
213
|
+
function dismiss(root) {
|
|
214
|
+
if (root.searchRunning && root.backend) root.backend.searchCancel()
|
|
215
|
+
root.searchRunning = false
|
|
216
|
+
abort(root)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// The first Esc while the walk runs stops it and keeps the results on screen.
|
|
220
|
+
function cancel(root) {
|
|
221
|
+
if (root.backend) {
|
|
222
|
+
root.backend.searchCancel()
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Esc leaves at once when empty or landed, or re-lists the folder it came from otherwise.
|
|
227
|
+
function abort(root) {
|
|
228
|
+
// A second Esc lands nowhere: the first already closed the backend and owes the landing.
|
|
229
|
+
if (root.searchLeaving === true) {
|
|
230
|
+
return
|
|
231
|
+
}
|
|
232
|
+
// flea-qml: Esc has two meanings, decided only by whether a find runs: running, it stops the
|
|
233
|
+
// find and keeps what it found; not running, it closes Find. The query line plays no part.
|
|
234
|
+
if (root.searchRunning) {
|
|
235
|
+
cancel(root)
|
|
236
|
+
return
|
|
237
|
+
}
|
|
238
|
+
var back = (root.searchFrom || "").length > 0 ? root.searchFrom : root.path
|
|
239
|
+
if (!owesRelist(root)) {
|
|
240
|
+
closeSession(root)
|
|
241
|
+
root.pendingSelect = ""
|
|
242
|
+
return
|
|
243
|
+
}
|
|
244
|
+
// The backend closes at the request; the drawn state waits for the folder to land.
|
|
245
|
+
leaveWalk(root)
|
|
246
|
+
root.openWithoutHistory(back, { holdWalk: true, relist: true, keptQuery: root.filterQuery })
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Any gen this session sent may have drawn rows the folder does not own, so leaving it re-lists the folder.
|
|
250
|
+
function owesRelist(root) {
|
|
251
|
+
return (root.searchMode || "").length > 0 && root.searchGen > (root.searchOpenedGen || 0)
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// A live re-answer keeps the cursor's file when the new window still names it, else row 0.
|
|
255
|
+
function keptIndex(name, items, start) {
|
|
256
|
+
if (name === null || name === undefined) {
|
|
257
|
+
return start
|
|
258
|
+
}
|
|
259
|
+
for (var i = 0; i < items.length; i++) {
|
|
260
|
+
if (items[i].n === name) {
|
|
261
|
+
return start + i
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return start
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// A navigation drops the session without re-listing, so the next listing lands on clean state.
|
|
268
|
+
function leaveWalk(root) {
|
|
269
|
+
if ((root.searchMode || "").length === 0) {
|
|
270
|
+
return false
|
|
271
|
+
}
|
|
272
|
+
// One close per exit: tabs close the walk before the navigation closes it again.
|
|
273
|
+
if (root.searchLeaving === true) {
|
|
274
|
+
return true
|
|
275
|
+
}
|
|
276
|
+
// Results on screen keep their strip until the next listing lands; the backend closes now.
|
|
277
|
+
if (live(root)) {
|
|
278
|
+
if (root.backend) {
|
|
279
|
+
root.backend.searchClose()
|
|
280
|
+
}
|
|
281
|
+
root.searchLeaving = true
|
|
282
|
+
return true
|
|
283
|
+
}
|
|
284
|
+
return closeSession(root)
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Closing the session is one searchclose; a list closes it too, so a doubled close is silence.
|
|
288
|
+
function closeSession(root) {
|
|
289
|
+
if ((root.searchMode || "").length === 0) {
|
|
290
|
+
return false
|
|
291
|
+
}
|
|
292
|
+
if (root.backend) {
|
|
293
|
+
root.backend.searchClose()
|
|
294
|
+
}
|
|
295
|
+
root.searchMode = OFF
|
|
296
|
+
root.searchQuery = ""
|
|
297
|
+
root.searchRunning = false
|
|
298
|
+
root.searchCancelled = false
|
|
299
|
+
root.searchScanned = 0
|
|
300
|
+
root.searchFrom = ""
|
|
301
|
+
root.searchBase = ""
|
|
302
|
+
root.listingState = listingState(root, root.total)
|
|
303
|
+
root.stateMessage = ""
|
|
304
|
+
return true
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// A terminal line answers only the newest gen this session sent; older gens drop with anything gen-less.
|
|
308
|
+
function accepts(root, gen) {
|
|
309
|
+
return (root.searchMode || "").length > 0 && gen === root.searchGen && gen > (root.searchOpenedGen || 0)
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// An exit landing clears the drawn search state in the same turn its rows do; the backend already closed.
|
|
313
|
+
function closeLeaving(root) {
|
|
314
|
+
root.searchLeaving = false
|
|
315
|
+
root.searchMode = OFF
|
|
316
|
+
root.searchQuery = ""
|
|
317
|
+
root.searchRunning = false
|
|
318
|
+
root.searchCancelled = false
|
|
319
|
+
root.searchScanned = 0
|
|
320
|
+
root.searchFrom = ""
|
|
321
|
+
root.searchBase = ""
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// The answered counts land; the first window rides its own rows line, so nothing is asked for.
|
|
325
|
+
function searched(root, total, scanned, ms, cancelled, gen, walking) {
|
|
326
|
+
// Answers for a session closed at its exit's request never land.
|
|
327
|
+
if (root.searchLeaving === true) {
|
|
328
|
+
return
|
|
329
|
+
}
|
|
330
|
+
if (!accepts(root, gen)) {
|
|
331
|
+
return
|
|
332
|
+
}
|
|
333
|
+
root.searchRunning = walking === true
|
|
334
|
+
root.searchCancelled = cancelled
|
|
335
|
+
if (walking !== true) {
|
|
336
|
+
root.searchSettledAt = Date.now()
|
|
337
|
+
}
|
|
338
|
+
root.total = total
|
|
339
|
+
root.searchScanned = scanned
|
|
340
|
+
root.searchMs = ms
|
|
341
|
+
root.listingState = listingState(root, total)
|
|
342
|
+
root.listArea.restartSettle()
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Query-line keys: enter keeps, escape leaves, tab rescopes, printables extend; cursor motions run through Focus.
|
|
346
|
+
function typeKey(event, root) {
|
|
347
|
+
// Keys struck while the exit is out wait for the folder, the way any held listing holds them.
|
|
348
|
+
if (root.searchLeaving === true) {
|
|
349
|
+
return true
|
|
350
|
+
}
|
|
351
|
+
// Ctrl+V and Shift+Insert extend the query by the clipboard's first line, one generation (issue 287).
|
|
352
|
+
if (Input.isPasteKey(event))
|
|
353
|
+
return Input.pasteInto(root, function (text) { extend(root, text) })
|
|
354
|
+
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
|
|
355
|
+
commit(root)
|
|
356
|
+
return true
|
|
357
|
+
}
|
|
358
|
+
if (event.key === Qt.Key_Escape) {
|
|
359
|
+
abort(root)
|
|
360
|
+
return true
|
|
361
|
+
}
|
|
362
|
+
if (event.key === Qt.Key_Backspace) {
|
|
363
|
+
shrink(root)
|
|
364
|
+
return true
|
|
365
|
+
}
|
|
366
|
+
// Issue 30's control: tab flips the scope between the whole home directory and the one the pane
|
|
367
|
+
// is standing in. It is the only writer, and nothing resets it, so the flip holds for the window;
|
|
368
|
+
// ui/SearchStrip.qml draws "in <scope>" under the caret, so every search says which one it took.
|
|
369
|
+
if (event.key === Qt.Key_G && (event.modifiers & Qt.ControlModifier) && !(event.modifiers & (Qt.AltModifier | Qt.MetaModifier))) {
|
|
370
|
+
contents(root)
|
|
371
|
+
return true
|
|
372
|
+
}
|
|
373
|
+
if (event.key === Qt.Key_Tab || event.key === Qt.Key_Backtab) {
|
|
374
|
+
rescope(root)
|
|
375
|
+
return true
|
|
376
|
+
}
|
|
377
|
+
if (Input.isPrintable(event.text)) {
|
|
378
|
+
extend(root, event.text)
|
|
379
|
+
return true
|
|
380
|
+
}
|
|
381
|
+
return true
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// o on a result opens the directory that holds it and puts the cursor on the row, the design's reveal.
|
|
385
|
+
function reveal(root) {
|
|
386
|
+
var row = root.rowFor(root.cursorIndex)
|
|
387
|
+
if (!row) {
|
|
388
|
+
return
|
|
389
|
+
}
|
|
390
|
+
var full = root.join(baseOf(root), row.n)
|
|
391
|
+
var cut = full.lastIndexOf("/")
|
|
392
|
+
if (cut <= 0) {
|
|
393
|
+
return
|
|
394
|
+
}
|
|
395
|
+
root.recentMode = ""
|
|
396
|
+
root.recentFrom = ""
|
|
397
|
+
root.recentPaths = []
|
|
398
|
+
// Through the pane: importing RecentMode.js here would close a Nav import cycle.
|
|
399
|
+
root.restoreRecentSort()
|
|
400
|
+
root.pendingSelect = full
|
|
401
|
+
root.open(full.substring(0, cut))
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// Read-only stopwatch for the newest gen; per-keystroke latency is measured off it.
|
|
405
|
+
function stamps(root) {
|
|
406
|
+
return { gen: root.searchGen, keyAt: root.searchKeyAt || 0,
|
|
407
|
+
firstRowsAt: root.searchFirstRowsAt || 0, settledAt: root.searchSettledAt || 0 }
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// Rows on screen belong to a standing query: results in, folder out, whatever mode holds them.
|
|
411
|
+
function live(root) {
|
|
412
|
+
return (root.searchMode || "").length > 0 && (root.searchQuery || "").length > 0
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// What activating a row means right now. On a search result it takes
|
|
416
|
+
// you to the file instead of opening it; the canvas keeps enter on open and o on reveal, so it is
|
|
417
|
+
// only the pointer that asks this. ui/js/Tap.js is the one caller.
|
|
418
|
+
// flea-qml: a tap on a result only selects it, so the pointer browses results the way the arrows
|
|
419
|
+
// do and the search stays; two taps open, as anywhere else, and o or the menu reveals.
|
|
420
|
+
function activateAction(root) {
|
|
421
|
+
return "open"
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// A walk with no matches yet is still working, so the list area keeps the crawl rather than
|
|
425
|
+
// flashing the empty state at every directory that happens to hold nothing.
|
|
426
|
+
function listingState(root, total) {
|
|
427
|
+
if (total > 0) {
|
|
428
|
+
return "ready"
|
|
429
|
+
}
|
|
430
|
+
return root.searchRunning ? "loading" : "empty"
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// Strip note as whole templates: the count with its crawl while the walk runs, alone landed.
|
|
434
|
+
var NOTE = { walking: "%1 found · still scanning", landed: "%1 found" }
|
|
435
|
+
function note(total, running, empty) {
|
|
436
|
+
if (empty === true) {
|
|
437
|
+
return ""
|
|
438
|
+
}
|
|
439
|
+
if (running) {
|
|
440
|
+
return NOTE.walking.replace("%1", Format.count(total))
|
|
441
|
+
}
|
|
442
|
+
return NOTE.landed.replace("%1", Format.count(total))
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Empty-state caption for the query the shown answer is for; the function replacer keeps "$&" and "$$" in it literal.
|
|
446
|
+
function nothingMatches(answered) {
|
|
447
|
+
if (answered.length === 0) {
|
|
448
|
+
return ""
|
|
449
|
+
}
|
|
450
|
+
return "Nothing matches %1".replace("%1", function () { return answered })
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// Strip right edge as whole templates: walking esc stops the walk, any other esc leaves.
|
|
454
|
+
var WAY = { walking: "esc cancels, then returns", done: "esc returns" }
|
|
455
|
+
function wayOut(running, empty) {
|
|
456
|
+
if (running && empty !== true) {
|
|
457
|
+
return WAY.walking
|
|
458
|
+
}
|
|
459
|
+
return WAY.done
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// Row facilities join a row against the listing's base, the scope or the folder, never pane.path mid-session.
|
|
463
|
+
function baseOf(root) {
|
|
464
|
+
return (root.searchBase || "").length > 0 ? root.searchBase : root.path
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// The rule itself lives in Format.tilde, because the window chrome draws a path through the same one.
|
|
468
|
+
function scope(path, home) {
|
|
469
|
+
return Format.tilde(path, home)
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// The status bar's own left half while a search is up, the two lines the canvas draws.
|
|
473
|
+
function statusLine(running, total, scanned, ms) {
|
|
474
|
+
if (running) {
|
|
475
|
+
return Format.fill(WORDS.searching, Format.count(total), Format.count(scanned))
|
|
476
|
+
}
|
|
477
|
+
return Format.fill(WORDS.landed, Format.count(total), (ms / 1000).toFixed(1))
|
|
478
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
.pragma library
|
|
2
|
+
|
|
3
|
+
// A selection is a set of row indices over the current listing; a new list clears it, because an index
|
|
4
|
+
// into a directory that has changed means nothing. Task 8 declined ScriptModel plus ItemSelectionModel
|
|
5
|
+
// on measured memory (see AGENTS.md "The list model"), so this is a hand-rolled index set instead.
|
|
6
|
+
function create() {
|
|
7
|
+
var rows = {}
|
|
8
|
+
var n = 0
|
|
9
|
+
// True while the set is one row a plain tap or a landing anchor made, which a plain move carries along.
|
|
10
|
+
var lone = false
|
|
11
|
+
// True only for the row a navigation landed on, which Escape climbs past instead of unwinding.
|
|
12
|
+
var landed = false
|
|
13
|
+
// Shift adds to the gesture's starting marks; other mutators end it, and a cursor differing from shiftLast starts a new block.
|
|
14
|
+
var shiftBase = null
|
|
15
|
+
var shiftLast = -1
|
|
16
|
+
var shiftSeq = 0
|
|
17
|
+
|
|
18
|
+
function endShift() { shiftBase = null }
|
|
19
|
+
|
|
20
|
+
function has(i) {
|
|
21
|
+
return rows[i] === true
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function add(i) {
|
|
25
|
+
if (!has(i)) { rows[i] = true; n += 1 }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function remove(i) {
|
|
29
|
+
if (has(i)) { delete rows[i]; n -= 1 }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function dropLone() {
|
|
33
|
+
lone = false
|
|
34
|
+
landed = false
|
|
35
|
+
}
|
|
36
|
+
// v on its lone row keeps it and drops lone, so the next v toggles it off.
|
|
37
|
+
function promote(i) { if (lone && n === 1 && has(i)) { dropLone(); return true } return false }
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
has: has,
|
|
41
|
+
promote: promote,
|
|
42
|
+
count: function () { return n },
|
|
43
|
+
// A lone row follows a plain move; any deliberate mark drops that promise at once.
|
|
44
|
+
follows: function () { return lone && n === 1 },
|
|
45
|
+
// Only a navigation landing keeps the climb-through promise; a click's own only() drops it.
|
|
46
|
+
isLanded: function () { return landed === true && lone && n === 1 },
|
|
47
|
+
toggle: function (i) { dropLone(); endShift(); has(i) ? remove(i) : add(i) },
|
|
48
|
+
only: function (i, keep) {
|
|
49
|
+
rows = {}
|
|
50
|
+
n = 0
|
|
51
|
+
add(i)
|
|
52
|
+
lone = true
|
|
53
|
+
landed = keep === true
|
|
54
|
+
endShift()
|
|
55
|
+
},
|
|
56
|
+
extendTo: function (i, anchor) {
|
|
57
|
+
dropLone()
|
|
58
|
+
endShift()
|
|
59
|
+
var lo = Math.min(i, anchor)
|
|
60
|
+
var hi = Math.max(i, anchor)
|
|
61
|
+
rows = {}
|
|
62
|
+
n = 0
|
|
63
|
+
for (var r = lo; r <= hi; r++)
|
|
64
|
+
add(r)
|
|
65
|
+
},
|
|
66
|
+
all: function (total) {
|
|
67
|
+
dropLone()
|
|
68
|
+
endShift()
|
|
69
|
+
rows = {}
|
|
70
|
+
n = 0
|
|
71
|
+
for (var r = 0; r < total; r++)
|
|
72
|
+
add(r)
|
|
73
|
+
},
|
|
74
|
+
clear: function () { rows = {}; n = 0; dropLone(); endShift() },
|
|
75
|
+
// The gesture's own trio, the only calls that leave the base standing. The base is a snapshot
|
|
76
|
+
// taken once at gesture start, never per key, so the gesture's range may shrink without dropping it.
|
|
77
|
+
shiftBegin: function (base, last, seq) { shiftBase = base.slice(); shiftLast = last; shiftSeq = seq || 0 },
|
|
78
|
+
shiftMoved: function (last, seq) { shiftLast = last; shiftSeq = seq || 0 },
|
|
79
|
+
shiftState: function () { return shiftBase === null ? null : { base: shiftBase, last: shiftLast, seq: shiftSeq } },
|
|
80
|
+
shiftApply: function (range) {
|
|
81
|
+
dropLone()
|
|
82
|
+
rows = {}
|
|
83
|
+
n = 0
|
|
84
|
+
for (var i = 0; i < shiftBase.length; i++)
|
|
85
|
+
add(shiftBase[i])
|
|
86
|
+
for (var j = 0; j < range.length; j++)
|
|
87
|
+
add(range[j])
|
|
88
|
+
},
|
|
89
|
+
indices: function () {
|
|
90
|
+
var out = []
|
|
91
|
+
for (var k in rows)
|
|
92
|
+
out.push(Number(k))
|
|
93
|
+
out.sort(function (a, b) { return a - b })
|
|
94
|
+
return out
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|