@pierre/diffs 1.3.0-beta.1 → 1.3.0-beta.10
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/README.md +15 -15
- package/dist/components/CodeView.d.ts +103 -15
- package/dist/components/CodeView.d.ts.map +1 -1
- package/dist/components/CodeView.js +349 -50
- package/dist/components/CodeView.js.map +1 -1
- package/dist/components/File.d.ts +10 -7
- package/dist/components/File.d.ts.map +1 -1
- package/dist/components/File.js +99 -40
- package/dist/components/File.js.map +1 -1
- package/dist/components/FileDiff.d.ts +76 -36
- package/dist/components/FileDiff.d.ts.map +1 -1
- package/dist/components/FileDiff.js +364 -96
- package/dist/components/FileDiff.js.map +1 -1
- package/dist/components/FileStream.d.ts +0 -1
- package/dist/components/FileStream.d.ts.map +1 -1
- package/dist/components/FileStream.js +10 -7
- package/dist/components/FileStream.js.map +1 -1
- package/dist/components/UnresolvedFile.d.ts +3 -3
- package/dist/components/UnresolvedFile.d.ts.map +1 -1
- package/dist/components/UnresolvedFile.js +8 -6
- package/dist/components/UnresolvedFile.js.map +1 -1
- package/dist/components/VirtualizedFile.d.ts +8 -4
- package/dist/components/VirtualizedFile.d.ts.map +1 -1
- package/dist/components/VirtualizedFile.js +118 -44
- package/dist/components/VirtualizedFile.js.map +1 -1
- package/dist/components/VirtualizedFileDiff.d.ts +35 -9
- package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
- package/dist/components/VirtualizedFileDiff.js +367 -120
- package/dist/components/VirtualizedFileDiff.js.map +1 -1
- package/dist/components/Virtualizer.d.ts +4 -1
- package/dist/components/Virtualizer.d.ts.map +1 -1
- package/dist/components/Virtualizer.js +47 -29
- package/dist/components/Virtualizer.js.map +1 -1
- package/dist/components/VirtulizerDevelopment.d.ts.map +1 -1
- package/dist/components/web-components.d.ts.map +1 -1
- package/dist/components/web-components.js +2 -3
- package/dist/components/web-components.js.map +1 -1
- package/dist/constants.d.ts +5 -2
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +5 -2
- package/dist/constants.js.map +1 -1
- package/dist/editor/command.d.ts +3 -2
- package/dist/editor/command.d.ts.map +1 -1
- package/dist/editor/command.js +29 -6
- package/dist/editor/command.js.map +1 -1
- package/dist/editor/editStack.d.ts +7 -2
- package/dist/editor/editStack.d.ts.map +1 -1
- package/dist/editor/editStack.js +4 -4
- package/dist/editor/editStack.js.map +1 -1
- package/dist/editor/editor.d.ts +91 -8
- package/dist/editor/editor.d.ts.map +1 -1
- package/dist/editor/editor.js +1926 -704
- package/dist/editor/editor.js.map +1 -1
- package/dist/editor/editor2.js +6 -0
- package/dist/editor/editor2.js.map +1 -0
- package/dist/editor/index.d.ts +4 -2
- package/dist/editor/index.js +1 -2
- package/dist/editor/languages.d.ts +26 -0
- package/dist/editor/languages.d.ts.map +1 -0
- package/dist/editor/languages.js +363 -0
- package/dist/editor/languages.js.map +1 -0
- package/dist/editor/lineAnnotations.d.ts +2 -1
- package/dist/editor/lineAnnotations.d.ts.map +1 -1
- package/dist/editor/lineAnnotations.js +193 -13
- package/dist/editor/lineAnnotations.js.map +1 -1
- package/dist/editor/marker.d.ts +38 -0
- package/dist/editor/marker.d.ts.map +1 -0
- package/dist/editor/marker.js +245 -0
- package/dist/editor/marker.js.map +1 -0
- package/dist/editor/matchBrackets.d.ts +9 -0
- package/dist/editor/matchBrackets.d.ts.map +1 -0
- package/dist/editor/matchBrackets.js +138 -0
- package/dist/editor/matchBrackets.js.map +1 -0
- package/dist/editor/pieceTable.d.ts +15 -7
- package/dist/editor/pieceTable.d.ts.map +1 -1
- package/dist/editor/pieceTable.js +252 -171
- package/dist/editor/pieceTable.js.map +1 -1
- package/dist/editor/platform.d.ts +8 -1
- package/dist/editor/platform.d.ts.map +1 -1
- package/dist/editor/platform.js +18 -5
- package/dist/editor/platform.js.map +1 -1
- package/dist/editor/popover.d.ts +65 -0
- package/dist/editor/popover.d.ts.map +1 -0
- package/dist/editor/popover.js +187 -0
- package/dist/editor/popover.js.map +1 -0
- package/dist/editor/searchPanel.d.ts +17 -7
- package/dist/editor/searchPanel.d.ts.map +1 -1
- package/dist/editor/searchPanel.js +268 -169
- package/dist/editor/searchPanel.js.map +1 -1
- package/dist/editor/selection.d.ts +100 -15
- package/dist/editor/selection.d.ts.map +1 -1
- package/dist/editor/selection.js +862 -136
- package/dist/editor/selection.js.map +1 -1
- package/dist/editor/selectionAction.d.ts +46 -0
- package/dist/editor/selectionAction.d.ts.map +1 -0
- package/dist/editor/selectionAction.js +64 -0
- package/dist/editor/selectionAction.js.map +1 -0
- package/dist/editor/sprite.d.ts +8 -0
- package/dist/editor/sprite.d.ts.map +1 -0
- package/dist/editor/sprite.js +45 -0
- package/dist/editor/sprite.js.map +1 -0
- package/dist/editor/stateStorage.d.ts +15 -0
- package/dist/editor/stateStorage.d.ts.map +1 -0
- package/dist/editor/stateStorage.js +65 -0
- package/dist/editor/stateStorage.js.map +1 -0
- package/dist/editor/textDocument.d.ts +21 -83
- package/dist/editor/textDocument.d.ts.map +1 -1
- package/dist/editor/textDocument.js +117 -48
- package/dist/editor/textDocument.js.map +1 -1
- package/dist/editor/textMeasure.d.ts +31 -2
- package/dist/editor/textMeasure.d.ts.map +1 -1
- package/dist/editor/textMeasure.js +122 -21
- package/dist/editor/textMeasure.js.map +1 -1
- package/dist/editor/{tokenzier.d.ts → tokenizer.d.ts} +16 -12
- package/dist/editor/tokenizer.d.ts.map +1 -0
- package/dist/editor/tokenizer.js +513 -0
- package/dist/editor/tokenizer.js.map +1 -0
- package/dist/editor/utils.d.ts +6 -1
- package/dist/editor/utils.d.ts.map +1 -1
- package/dist/editor/utils.js +34 -3
- package/dist/editor/utils.js.map +1 -1
- package/dist/highlighter/languages/areLanguagesAttached.d.ts.map +1 -1
- package/dist/highlighter/languages/areLanguagesAttached.js +1 -2
- package/dist/highlighter/languages/areLanguagesAttached.js.map +1 -1
- package/dist/highlighter/languages/attachResolvedLanguages.d.ts +0 -2
- package/dist/highlighter/languages/attachResolvedLanguages.d.ts.map +1 -1
- package/dist/highlighter/languages/attachResolvedLanguages.js +1 -2
- package/dist/highlighter/languages/attachResolvedLanguages.js.map +1 -1
- package/dist/highlighter/languages/cleanUpResolvedLanguages.d.ts.map +1 -1
- package/dist/highlighter/languages/cleanUpResolvedLanguages.js +1 -2
- package/dist/highlighter/languages/cleanUpResolvedLanguages.js.map +1 -1
- package/dist/highlighter/languages/constants.d.ts +0 -1
- package/dist/highlighter/languages/constants.d.ts.map +1 -1
- package/dist/highlighter/languages/constants.js +1 -1
- package/dist/highlighter/languages/constants.js.map +1 -1
- package/dist/highlighter/languages/getResolvedLanguages.d.ts +0 -2
- package/dist/highlighter/languages/getResolvedLanguages.d.ts.map +1 -1
- package/dist/highlighter/languages/getResolvedLanguages.js +1 -2
- package/dist/highlighter/languages/getResolvedLanguages.js.map +1 -1
- package/dist/highlighter/languages/getResolvedOrResolveLanguage.d.ts +0 -2
- package/dist/highlighter/languages/getResolvedOrResolveLanguage.d.ts.map +1 -1
- package/dist/highlighter/languages/getResolvedOrResolveLanguage.js +1 -2
- package/dist/highlighter/languages/getResolvedOrResolveLanguage.js.map +1 -1
- package/dist/highlighter/languages/hasResolvedLanguages.d.ts.map +1 -1
- package/dist/highlighter/languages/hasResolvedLanguages.js +1 -2
- package/dist/highlighter/languages/hasResolvedLanguages.js.map +1 -1
- package/dist/highlighter/languages/registerCustomLanguage.d.ts +0 -1
- package/dist/highlighter/languages/registerCustomLanguage.d.ts.map +1 -1
- package/dist/highlighter/languages/registerCustomLanguage.js +1 -2
- package/dist/highlighter/languages/registerCustomLanguage.js.map +1 -1
- package/dist/highlighter/languages/resolveLanguage.d.ts +0 -2
- package/dist/highlighter/languages/resolveLanguage.d.ts.map +1 -1
- package/dist/highlighter/languages/resolveLanguage.js +4 -5
- package/dist/highlighter/languages/resolveLanguage.js.map +1 -1
- package/dist/highlighter/languages/resolveLanguages.d.ts +0 -2
- package/dist/highlighter/languages/resolveLanguages.d.ts.map +1 -1
- package/dist/highlighter/languages/resolveLanguages.js +1 -2
- package/dist/highlighter/languages/resolveLanguages.js.map +1 -1
- package/dist/highlighter/shared_highlighter.d.ts.map +1 -1
- package/dist/highlighter/shared_highlighter.js +6 -33
- package/dist/highlighter/shared_highlighter.js.map +1 -1
- package/dist/highlighter/themes/areThemesAttached.d.ts.map +1 -1
- package/dist/highlighter/themes/areThemesAttached.js +1 -2
- package/dist/highlighter/themes/areThemesAttached.js.map +1 -1
- package/dist/highlighter/themes/attachResolvedThemes.d.ts.map +1 -1
- package/dist/highlighter/themes/attachResolvedThemes.js +5 -5
- package/dist/highlighter/themes/attachResolvedThemes.js.map +1 -1
- package/dist/highlighter/themes/cleanUpResolvedThemes.d.ts.map +1 -1
- package/dist/highlighter/themes/cleanUpResolvedThemes.js +4 -4
- package/dist/highlighter/themes/cleanUpResolvedThemes.js.map +1 -1
- package/dist/highlighter/themes/constants.d.ts +1 -7
- package/dist/highlighter/themes/constants.d.ts.map +1 -1
- package/dist/highlighter/themes/constants.js +2 -5
- package/dist/highlighter/themes/constants.js.map +1 -1
- package/dist/highlighter/themes/getResolvedOrResolveTheme.d.ts.map +1 -1
- package/dist/highlighter/themes/getResolvedOrResolveTheme.js +3 -4
- package/dist/highlighter/themes/getResolvedOrResolveTheme.js.map +1 -1
- package/dist/highlighter/themes/getResolvedThemes.d.ts.map +1 -1
- package/dist/highlighter/themes/getResolvedThemes.js +3 -10
- package/dist/highlighter/themes/getResolvedThemes.js.map +1 -1
- package/dist/highlighter/themes/hasResolvedThemes.d.ts.map +1 -1
- package/dist/highlighter/themes/hasResolvedThemes.js +3 -5
- package/dist/highlighter/themes/hasResolvedThemes.js.map +1 -1
- package/dist/highlighter/themes/registerCustomCSSVariableTheme.d.ts.map +1 -1
- package/dist/highlighter/themes/registerCustomCSSVariableTheme.js +2 -3
- package/dist/highlighter/themes/registerCustomCSSVariableTheme.js.map +1 -1
- package/dist/highlighter/themes/registerCustomTheme.d.ts +5 -3
- package/dist/highlighter/themes/registerCustomTheme.d.ts.map +1 -1
- package/dist/highlighter/themes/registerCustomTheme.js +16 -7
- package/dist/highlighter/themes/registerCustomTheme.js.map +1 -1
- package/dist/highlighter/themes/resolveTheme.d.ts.map +1 -1
- package/dist/highlighter/themes/resolveTheme.js +7 -29
- package/dist/highlighter/themes/resolveTheme.js.map +1 -1
- package/dist/highlighter/themes/resolveThemes.d.ts.map +1 -1
- package/dist/highlighter/themes/resolveThemes.js +6 -14
- package/dist/highlighter/themes/resolveThemes.js.map +1 -1
- package/dist/highlighter/themes/themeResolution.d.ts +8 -0
- package/dist/highlighter/themes/themeResolution.d.ts.map +1 -0
- package/dist/highlighter/themes/themeResolution.js +21 -0
- package/dist/highlighter/themes/themeResolution.js.map +1 -0
- package/dist/highlighter/themes/themeResolver.d.ts +8 -0
- package/dist/highlighter/themes/themeResolver.d.ts.map +1 -0
- package/dist/highlighter/themes/themeResolver.js +7 -0
- package/dist/highlighter/themes/themeResolver.js.map +1 -0
- package/dist/index.d.ts +16 -14
- package/dist/index.js +13 -12
- package/dist/managers/InteractionManager.d.ts +7 -0
- package/dist/managers/InteractionManager.d.ts.map +1 -1
- package/dist/managers/InteractionManager.js +26 -5
- package/dist/managers/InteractionManager.js.map +1 -1
- package/dist/managers/ResizeManager.d.ts +10 -2
- package/dist/managers/ResizeManager.d.ts.map +1 -1
- package/dist/managers/ResizeManager.js +35 -15
- package/dist/managers/ResizeManager.js.map +1 -1
- package/dist/managers/ScrollSyncManager.d.ts.map +1 -1
- package/dist/managers/ScrollSyncManager.js +1 -1
- package/dist/managers/ScrollSyncManager.js.map +1 -1
- package/dist/managers/UniversalRenderingManager.d.ts +2 -1
- package/dist/managers/UniversalRenderingManager.d.ts.map +1 -1
- package/dist/managers/UniversalRenderingManager.js +8 -3
- package/dist/managers/UniversalRenderingManager.js.map +1 -1
- package/dist/node_modules/.pnpm/@types_hast@3.0.4/node_modules/@types/hast/index.d.ts +228 -0
- package/dist/node_modules/.pnpm/@types_hast@3.0.4/node_modules/@types/hast/index.d.ts.map +1 -0
- package/dist/node_modules/.pnpm/@types_unist@3.0.3/node_modules/@types/unist/index.d.ts +84 -0
- package/dist/node_modules/.pnpm/@types_unist@3.0.3/node_modules/@types/unist/index.d.ts.map +1 -0
- package/dist/react/CodeView.d.ts +26 -2
- package/dist/react/CodeView.d.ts.map +1 -1
- package/dist/react/CodeView.js +90 -30
- package/dist/react/CodeView.js.map +1 -1
- package/dist/react/EditContext.d.ts +15 -0
- package/dist/react/EditContext.d.ts.map +1 -0
- package/dist/react/EditContext.js +23 -0
- package/dist/react/EditContext.js.map +1 -0
- package/dist/react/File.d.ts +1 -0
- package/dist/react/File.d.ts.map +1 -1
- package/dist/react/File.js +4 -6
- package/dist/react/File.js.map +1 -1
- package/dist/react/FileDiff.d.ts +1 -0
- package/dist/react/FileDiff.d.ts.map +1 -1
- package/dist/react/FileDiff.js +4 -6
- package/dist/react/FileDiff.js.map +1 -1
- package/dist/react/MultiFileDiff.d.ts +4 -4
- package/dist/react/MultiFileDiff.d.ts.map +1 -1
- package/dist/react/MultiFileDiff.js +4 -6
- package/dist/react/MultiFileDiff.js.map +1 -1
- package/dist/react/PatchDiff.d.ts +1 -0
- package/dist/react/PatchDiff.d.ts.map +1 -1
- package/dist/react/PatchDiff.js +4 -6
- package/dist/react/PatchDiff.js.map +1 -1
- package/dist/react/UnresolvedFile.d.ts +2 -1
- package/dist/react/UnresolvedFile.d.ts.map +1 -1
- package/dist/react/UnresolvedFile.js +4 -6
- package/dist/react/UnresolvedFile.js.map +1 -1
- package/dist/react/Virtualizer.d.ts.map +1 -1
- package/dist/react/Virtualizer.js +2 -5
- package/dist/react/Virtualizer.js.map +1 -1
- package/dist/react/WorkerPoolContext.d.ts +0 -1
- package/dist/react/WorkerPoolContext.d.ts.map +1 -1
- package/dist/react/WorkerPoolContext.js +2 -5
- package/dist/react/WorkerPoolContext.js.map +1 -1
- package/dist/react/constants.d.ts.map +1 -1
- package/dist/react/constants.js +1 -1
- package/dist/react/constants.js.map +1 -1
- package/dist/react/index.d.ts +3 -3
- package/dist/react/index.js +2 -3
- package/dist/react/jsx.d.ts +0 -1
- package/dist/react/jsx.d.ts.map +1 -1
- package/dist/react/types.d.ts +2 -0
- package/dist/react/types.d.ts.map +1 -1
- package/dist/react/types.js +1 -0
- package/dist/react/utils/renderDiffChildren.d.ts +2 -0
- package/dist/react/utils/renderDiffChildren.d.ts.map +1 -1
- package/dist/react/utils/renderDiffChildren.js +18 -11
- package/dist/react/utils/renderDiffChildren.js.map +1 -1
- package/dist/react/utils/renderFileChildren.d.ts +2 -0
- package/dist/react/utils/renderFileChildren.d.ts.map +1 -1
- package/dist/react/utils/renderFileChildren.js +18 -11
- package/dist/react/utils/renderFileChildren.js.map +1 -1
- package/dist/react/utils/templateRender.d.ts.map +1 -1
- package/dist/react/utils/templateRender.js +1 -2
- package/dist/react/utils/templateRender.js.map +1 -1
- package/dist/react/utils/useFileDiffInstance.d.ts.map +1 -1
- package/dist/react/utils/useFileDiffInstance.js +15 -18
- package/dist/react/utils/useFileDiffInstance.js.map +1 -1
- package/dist/react/utils/useFileInstance.d.ts.map +1 -1
- package/dist/react/utils/useFileInstance.js +2 -3
- package/dist/react/utils/useFileInstance.js.map +1 -1
- package/dist/react/utils/useStableCallback.d.ts.map +1 -1
- package/dist/react/utils/useStableCallback.js +1 -2
- package/dist/react/utils/useStableCallback.js.map +1 -1
- package/dist/react/utils/useUnresolvedFileInstance.d.ts.map +1 -1
- package/dist/react/utils/useUnresolvedFileInstance.js +10 -11
- package/dist/react/utils/useUnresolvedFileInstance.js.map +1 -1
- package/dist/renderers/DiffHunksRenderer.d.ts +30 -4
- package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
- package/dist/renderers/DiffHunksRenderer.js +313 -45
- package/dist/renderers/DiffHunksRenderer.js.map +1 -1
- package/dist/renderers/FileRenderer.d.ts +7 -6
- package/dist/renderers/FileRenderer.d.ts.map +1 -1
- package/dist/renderers/FileRenderer.js +113 -56
- package/dist/renderers/FileRenderer.js.map +1 -1
- package/dist/renderers/UnresolvedFileHunksRenderer.d.ts +1 -2
- package/dist/renderers/UnresolvedFileHunksRenderer.d.ts.map +1 -1
- package/dist/renderers/UnresolvedFileHunksRenderer.js +1 -2
- package/dist/renderers/UnresolvedFileHunksRenderer.js.map +1 -1
- package/dist/shiki-stream/index.js +1 -2
- package/dist/shiki-stream/stream.d.ts +0 -1
- package/dist/shiki-stream/stream.d.ts.map +1 -1
- package/dist/shiki-stream/stream.js +1 -2
- package/dist/shiki-stream/stream.js.map +1 -1
- package/dist/shiki-stream/tokenizer.d.ts.map +1 -1
- package/dist/shiki-stream/tokenizer.js +1 -1
- package/dist/shiki-stream/tokenizer.js.map +1 -1
- package/dist/shiki-stream/types.d.ts +0 -1
- package/dist/shiki-stream/types.d.ts.map +1 -1
- package/dist/sprite.d.ts.map +1 -1
- package/dist/sprite.js +1 -1
- package/dist/ssr/FileDiffReact.d.ts.map +1 -1
- package/dist/ssr/FileDiffReact.js +4 -7
- package/dist/ssr/FileDiffReact.js.map +1 -1
- package/dist/ssr/index.d.ts +2 -2
- package/dist/ssr/index.js +1 -2
- package/dist/ssr/preloadDiffs.d.ts +12 -11
- package/dist/ssr/preloadDiffs.d.ts.map +1 -1
- package/dist/ssr/preloadDiffs.js +16 -9
- package/dist/ssr/preloadDiffs.js.map +1 -1
- package/dist/ssr/preloadFile.d.ts.map +1 -1
- package/dist/ssr/preloadFile.js +1 -2
- package/dist/ssr/preloadFile.js.map +1 -1
- package/dist/ssr/preloadPatchFile.d.ts.map +1 -1
- package/dist/ssr/preloadPatchFile.js +2 -3
- package/dist/ssr/preloadPatchFile.js.map +1 -1
- package/dist/ssr/renderHTML.d.ts +1 -1
- package/dist/ssr/renderHTML.d.ts.map +1 -1
- package/dist/ssr/renderHTML.js +1 -2
- package/dist/ssr/renderHTML.js.map +1 -1
- package/dist/string-import.d.ts +4 -0
- package/dist/string-import.d.ts.map +1 -1
- package/dist/style.js +3 -3
- package/dist/style.js.map +1 -1
- package/dist/types.d.ts +272 -31
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/applyLineTextWithNewline.d.ts +5 -0
- package/dist/utils/applyLineTextWithNewline.d.ts.map +1 -0
- package/dist/utils/applyLineTextWithNewline.js +11 -0
- package/dist/utils/applyLineTextWithNewline.js.map +1 -0
- package/dist/utils/areDiffLineAnnotationsEqual.d.ts.map +1 -1
- package/dist/utils/areDiffLineAnnotationsEqual.js +1 -1
- package/dist/utils/areDiffLineAnnotationsEqual.js.map +1 -1
- package/dist/utils/areDiffRenderOptionsEqual.d.ts.map +1 -1
- package/dist/utils/areDiffRenderOptionsEqual.js +1 -2
- package/dist/utils/areDiffRenderOptionsEqual.js.map +1 -1
- package/dist/utils/areDiffTargetsEqual.d.ts.map +1 -1
- package/dist/utils/areDiffTargetsEqual.js +1 -1
- package/dist/utils/areDiffTargetsEqual.js.map +1 -1
- package/dist/utils/areFileRenderOptionsEqual.d.ts.map +1 -1
- package/dist/utils/areFileRenderOptionsEqual.js +1 -2
- package/dist/utils/areFileRenderOptionsEqual.js.map +1 -1
- package/dist/utils/areFilesEqual.d.ts.map +1 -1
- package/dist/utils/areFilesEqual.js +1 -1
- package/dist/utils/areFilesEqual.js.map +1 -1
- package/dist/utils/areHunkDataEqual.d.ts.map +1 -1
- package/dist/utils/areHunkDataEqual.js +2 -2
- package/dist/utils/areHunkDataEqual.js.map +1 -1
- package/dist/utils/areLineAnnotationsEqual.d.ts.map +1 -1
- package/dist/utils/areLineAnnotationsEqual.js +1 -1
- package/dist/utils/areLineAnnotationsEqual.js.map +1 -1
- package/dist/utils/areManagedSnapshotsEqual.d.ts +2 -2
- package/dist/utils/areManagedSnapshotsEqual.d.ts.map +1 -1
- package/dist/utils/areManagedSnapshotsEqual.js +6 -1
- package/dist/utils/areManagedSnapshotsEqual.js.map +1 -1
- package/dist/utils/areMergeConflictActionsEqual.d.ts.map +1 -1
- package/dist/utils/areMergeConflictActionsEqual.js +1 -1
- package/dist/utils/areMergeConflictActionsEqual.js.map +1 -1
- package/dist/utils/areObjectsEqual.d.ts.map +1 -1
- package/dist/utils/areObjectsEqual.js +1 -1
- package/dist/utils/areObjectsEqual.js.map +1 -1
- package/dist/utils/areOptionsEqual.d.ts +0 -2
- package/dist/utils/areOptionsEqual.d.ts.map +1 -1
- package/dist/utils/areOptionsEqual.js +1 -2
- package/dist/utils/areOptionsEqual.js.map +1 -1
- package/dist/utils/arePrePropertiesEqual.d.ts.map +1 -1
- package/dist/utils/arePrePropertiesEqual.js +1 -1
- package/dist/utils/arePrePropertiesEqual.js.map +1 -1
- package/dist/utils/areRenderRangesEqual.d.ts.map +1 -1
- package/dist/utils/areRenderRangesEqual.js +1 -1
- package/dist/utils/areRenderRangesEqual.js.map +1 -1
- package/dist/utils/areSelectionPointsEqual.d.ts.map +1 -1
- package/dist/utils/areSelectionPointsEqual.js +1 -1
- package/dist/utils/areSelectionPointsEqual.js.map +1 -1
- package/dist/utils/areSelectionsEqual.d.ts.map +1 -1
- package/dist/utils/areSelectionsEqual.js +1 -1
- package/dist/utils/areSelectionsEqual.js.map +1 -1
- package/dist/utils/areThemesEqual.d.ts.map +1 -1
- package/dist/utils/areThemesEqual.js +1 -1
- package/dist/utils/areThemesEqual.js.map +1 -1
- package/dist/utils/areVirtualWindowSpecsEqual.d.ts.map +1 -1
- package/dist/utils/areVirtualWindowSpecsEqual.js +1 -1
- package/dist/utils/areVirtualWindowSpecsEqual.js.map +1 -1
- package/dist/utils/areWorkerStatsEqual.d.ts +0 -2
- package/dist/utils/areWorkerStatsEqual.d.ts.map +1 -1
- package/dist/utils/areWorkerStatsEqual.js +1 -1
- package/dist/utils/areWorkerStatsEqual.js.map +1 -1
- package/dist/utils/awaitWithTimeout.d.ts +5 -0
- package/dist/utils/awaitWithTimeout.d.ts.map +1 -0
- package/dist/utils/awaitWithTimeout.js +15 -0
- package/dist/utils/awaitWithTimeout.js.map +1 -0
- package/dist/utils/cleanLastNewline.d.ts.map +1 -1
- package/dist/utils/cleanLastNewline.js +1 -1
- package/dist/utils/cleanLastNewline.js.map +1 -1
- package/dist/utils/cloneFileDiffMetadata.d.ts +7 -0
- package/dist/utils/cloneFileDiffMetadata.d.ts.map +1 -0
- package/dist/utils/cloneFileDiffMetadata.js +16 -0
- package/dist/utils/cloneFileDiffMetadata.js.map +1 -0
- package/dist/utils/computeEstimatedDiffHeights.d.ts +3 -1
- package/dist/utils/computeEstimatedDiffHeights.d.ts.map +1 -1
- package/dist/utils/computeEstimatedDiffHeights.js +18 -23
- package/dist/utils/computeEstimatedDiffHeights.js.map +1 -1
- package/dist/utils/computeFileOffsets.d.ts +9 -1
- package/dist/utils/computeFileOffsets.d.ts.map +1 -1
- package/dist/utils/computeFileOffsets.js +20 -2
- package/dist/utils/computeFileOffsets.js.map +1 -1
- package/dist/utils/computeVirtualFileMetrics.d.ts.map +1 -1
- package/dist/utils/computeVirtualFileMetrics.js +1 -2
- package/dist/utils/computeVirtualFileMetrics.js.map +1 -1
- package/dist/utils/createAnnotationElement.d.ts +1 -1
- package/dist/utils/createAnnotationElement.d.ts.map +1 -1
- package/dist/utils/createAnnotationElement.js +1 -2
- package/dist/utils/createAnnotationElement.js.map +1 -1
- package/dist/utils/createAnnotationWrapperNode.d.ts.map +1 -1
- package/dist/utils/createAnnotationWrapperNode.js +1 -1
- package/dist/utils/createAnnotationWrapperNode.js.map +1 -1
- package/dist/utils/createCodeViewHeaderFooterHostElement.d.ts +5 -0
- package/dist/utils/createCodeViewHeaderFooterHostElement.d.ts.map +1 -0
- package/dist/utils/createCodeViewHeaderFooterHostElement.js +19 -0
- package/dist/utils/createCodeViewHeaderFooterHostElement.js.map +1 -0
- package/dist/utils/createContentColumn.d.ts +1 -1
- package/dist/utils/createContentColumn.d.ts.map +1 -1
- package/dist/utils/createContentColumn.js +1 -2
- package/dist/utils/createContentColumn.js.map +1 -1
- package/dist/utils/createEmptyRowBuffer.d.ts +1 -1
- package/dist/utils/createEmptyRowBuffer.d.ts.map +1 -1
- package/dist/utils/createEmptyRowBuffer.js +1 -2
- package/dist/utils/createEmptyRowBuffer.js.map +1 -1
- package/dist/utils/createFileHeaderElement.d.ts +1 -1
- package/dist/utils/createFileHeaderElement.d.ts.map +1 -1
- package/dist/utils/createFileHeaderElement.js +6 -3
- package/dist/utils/createFileHeaderElement.js.map +1 -1
- package/dist/utils/createGutterUtilityContentNode.d.ts.map +1 -1
- package/dist/utils/createGutterUtilityContentNode.js +1 -1
- package/dist/utils/createGutterUtilityContentNode.js.map +1 -1
- package/dist/utils/createGutterUtilityElement.d.ts +1 -1
- package/dist/utils/createGutterUtilityElement.d.ts.map +1 -1
- package/dist/utils/createGutterUtilityElement.js +1 -2
- package/dist/utils/createGutterUtilityElement.js.map +1 -1
- package/dist/utils/createNoNewlineElement.d.ts +1 -1
- package/dist/utils/createNoNewlineElement.d.ts.map +1 -1
- package/dist/utils/createNoNewlineElement.js +1 -2
- package/dist/utils/createNoNewlineElement.js.map +1 -1
- package/dist/utils/createPreElement.d.ts +1 -1
- package/dist/utils/createPreElement.d.ts.map +1 -1
- package/dist/utils/createPreElement.js +1 -3
- package/dist/utils/createPreElement.js.map +1 -1
- package/dist/utils/createRowNodes.d.ts.map +1 -1
- package/dist/utils/createRowNodes.js +1 -1
- package/dist/utils/createRowNodes.js.map +1 -1
- package/dist/utils/createSeparator.d.ts +1 -1
- package/dist/utils/createSeparator.d.ts.map +1 -1
- package/dist/utils/createSeparator.js +1 -2
- package/dist/utils/createSeparator.js.map +1 -1
- package/dist/utils/createSpanNodeFromToken.d.ts.map +1 -1
- package/dist/utils/createSpanNodeFromToken.js +1 -2
- package/dist/utils/createSpanNodeFromToken.js.map +1 -1
- package/dist/utils/createStyleElement.d.ts +1 -1
- package/dist/utils/createStyleElement.d.ts.map +1 -1
- package/dist/utils/createStyleElement.js +1 -2
- package/dist/utils/createStyleElement.js.map +1 -1
- package/dist/utils/createTransformerWithState.d.ts.map +1 -1
- package/dist/utils/createTransformerWithState.js +1 -2
- package/dist/utils/createTransformerWithState.js.map +1 -1
- package/dist/utils/createUnsafeCSSStyleNode.d.ts.map +1 -1
- package/dist/utils/createUnsafeCSSStyleNode.js +1 -2
- package/dist/utils/createUnsafeCSSStyleNode.js.map +1 -1
- package/dist/utils/createWindowFromScrollPosition.d.ts.map +1 -1
- package/dist/utils/createWindowFromScrollPosition.js +5 -5
- package/dist/utils/createWindowFromScrollPosition.js.map +1 -1
- package/dist/utils/cssWrappers.d.ts.map +1 -1
- package/dist/utils/cssWrappers.js +2 -3
- package/dist/utils/cssWrappers.js.map +1 -1
- package/dist/utils/detachString.d.ts.map +1 -1
- package/dist/utils/detachString.js +1 -1
- package/dist/utils/detachString.js.map +1 -1
- package/dist/utils/diffAcceptRejectHunk.d.ts.map +1 -1
- package/dist/utils/diffAcceptRejectHunk.js +1 -2
- package/dist/utils/diffAcceptRejectHunk.js.map +1 -1
- package/dist/utils/editSessionHunks.d.ts +84 -0
- package/dist/utils/editSessionHunks.d.ts.map +1 -0
- package/dist/utils/editSessionHunks.js +366 -0
- package/dist/utils/editSessionHunks.js.map +1 -0
- package/dist/utils/formatCSSVariablePrefix.d.ts.map +1 -1
- package/dist/utils/formatCSSVariablePrefix.js +1 -1
- package/dist/utils/formatCSSVariablePrefix.js.map +1 -1
- package/dist/utils/getDiffFileInput.d.ts +14 -0
- package/dist/utils/getDiffFileInput.d.ts.map +1 -0
- package/dist/utils/getDiffFileInput.js +24 -0
- package/dist/utils/getDiffFileInput.js.map +1 -0
- package/dist/utils/getDiffHunksRendererOptions.d.ts.map +1 -1
- package/dist/utils/getDiffHunksRendererOptions.js +2 -1
- package/dist/utils/getDiffHunksRendererOptions.js.map +1 -1
- package/dist/utils/getFileRendererOptions.d.ts.map +1 -1
- package/dist/utils/getFileRendererOptions.js +1 -1
- package/dist/utils/getFileRendererOptions.js.map +1 -1
- package/dist/utils/getFiletypeFromFileName.d.ts.map +1 -1
- package/dist/utils/getFiletypeFromFileName.js +3 -1
- package/dist/utils/getFiletypeFromFileName.js.map +1 -1
- package/dist/utils/getHighlighterOptions.d.ts.map +1 -1
- package/dist/utils/getHighlighterOptions.js +1 -2
- package/dist/utils/getHighlighterOptions.js.map +1 -1
- package/dist/utils/getHighlighterThemeStyles.d.ts.map +1 -1
- package/dist/utils/getHighlighterThemeStyles.js +17 -14
- package/dist/utils/getHighlighterThemeStyles.js.map +1 -1
- package/dist/utils/getHunkSeparatorSlotName.d.ts.map +1 -1
- package/dist/utils/getHunkSeparatorSlotName.js +1 -1
- package/dist/utils/getHunkSeparatorSlotName.js.map +1 -1
- package/dist/utils/getIconForType.d.ts.map +1 -1
- package/dist/utils/getIconForType.js +1 -1
- package/dist/utils/getIconForType.js.map +1 -1
- package/dist/utils/getLineAnnotationName.d.ts.map +1 -1
- package/dist/utils/getLineAnnotationName.js +1 -1
- package/dist/utils/getLineAnnotationName.js.map +1 -1
- package/dist/utils/getLineEndingType.d.ts.map +1 -1
- package/dist/utils/getLineEndingType.js +1 -1
- package/dist/utils/getLineEndingType.js.map +1 -1
- package/dist/utils/getLineNodes.d.ts +1 -1
- package/dist/utils/getLineNodes.d.ts.map +1 -1
- package/dist/utils/getLineNodes.js +1 -1
- package/dist/utils/getLineNodes.js.map +1 -1
- package/dist/utils/getMergeConflictActionSlotName.d.ts.map +1 -1
- package/dist/utils/getMergeConflictActionSlotName.js +1 -1
- package/dist/utils/getMergeConflictActionSlotName.js.map +1 -1
- package/dist/utils/getMergeConflictLineTypes.d.ts.map +1 -1
- package/dist/utils/getMergeConflictLineTypes.js +1 -2
- package/dist/utils/getMergeConflictLineTypes.js.map +1 -1
- package/dist/utils/getOrCreateCodeNode.d.ts.map +1 -1
- package/dist/utils/getOrCreateCodeNode.js +1 -1
- package/dist/utils/getOrCreateCodeNode.js.map +1 -1
- package/dist/utils/getSingularPatch.d.ts.map +1 -1
- package/dist/utils/getSingularPatch.js +1 -2
- package/dist/utils/getSingularPatch.js.map +1 -1
- package/dist/utils/getThemes.d.ts.map +1 -1
- package/dist/utils/getThemes.js +1 -2
- package/dist/utils/getThemes.js.map +1 -1
- package/dist/utils/getTotalLineCountFromHunks.d.ts.map +1 -1
- package/dist/utils/getTotalLineCountFromHunks.js +1 -1
- package/dist/utils/getTotalLineCountFromHunks.js.map +1 -1
- package/dist/utils/hast_utils.d.ts +1 -1
- package/dist/utils/hast_utils.d.ts.map +1 -1
- package/dist/utils/hast_utils.js +1 -1
- package/dist/utils/hast_utils.js.map +1 -1
- package/dist/utils/hostTheme.d.ts.map +1 -1
- package/dist/utils/hostTheme.js +1 -2
- package/dist/utils/hostTheme.js.map +1 -1
- package/dist/utils/hydratePartialDiff.d.ts +10 -0
- package/dist/utils/hydratePartialDiff.d.ts.map +1 -0
- package/dist/utils/hydratePartialDiff.js +140 -0
- package/dist/utils/hydratePartialDiff.js.map +1 -0
- package/dist/utils/includesFileAnnotations.d.ts +17 -0
- package/dist/utils/includesFileAnnotations.d.ts.map +1 -0
- package/dist/utils/includesFileAnnotations.js +19 -0
- package/dist/utils/includesFileAnnotations.js.map +1 -0
- package/dist/utils/isDefaultRenderRange.d.ts.map +1 -1
- package/dist/utils/isDefaultRenderRange.js +1 -1
- package/dist/utils/isDefaultRenderRange.js.map +1 -1
- package/dist/utils/isDiffPlainText.d.ts.map +1 -1
- package/dist/utils/isDiffPlainText.js +1 -2
- package/dist/utils/isDiffPlainText.js.map +1 -1
- package/dist/utils/isFilePlainText.d.ts.map +1 -1
- package/dist/utils/isFilePlainText.js +1 -2
- package/dist/utils/isFilePlainText.js.map +1 -1
- package/dist/utils/isStyleNode.d.ts.map +1 -1
- package/dist/utils/isStyleNode.js +1 -1
- package/dist/utils/isStyleNode.js.map +1 -1
- package/dist/utils/isWorkerContext.d.ts.map +1 -1
- package/dist/utils/isWorkerContext.js +1 -1
- package/dist/utils/isWorkerContext.js.map +1 -1
- package/dist/utils/iterateOverDiff.d.ts.map +1 -1
- package/dist/utils/iterateOverDiff.js +178 -214
- package/dist/utils/iterateOverDiff.js.map +1 -1
- package/dist/utils/normalizeDiffResolution.d.ts.map +1 -1
- package/dist/utils/normalizeDiffResolution.js +1 -1
- package/dist/utils/normalizeDiffResolution.js.map +1 -1
- package/dist/utils/parseDiffDecorations.d.ts.map +1 -1
- package/dist/utils/parseDiffDecorations.js +1 -2
- package/dist/utils/parseDiffDecorations.js.map +1 -1
- package/dist/utils/parseDiffFromFile.d.ts +1 -2
- package/dist/utils/parseDiffFromFile.d.ts.map +1 -1
- package/dist/utils/parseDiffFromFile.js +27 -7
- package/dist/utils/parseDiffFromFile.js.map +1 -1
- package/dist/utils/parseLineType.d.ts.map +1 -1
- package/dist/utils/parseLineType.js +1 -1
- package/dist/utils/parseLineType.js.map +1 -1
- package/dist/utils/parseMergeConflictDiffFromFile.d.ts.map +1 -1
- package/dist/utils/parseMergeConflictDiffFromFile.js +5 -5
- package/dist/utils/parseMergeConflictDiffFromFile.js.map +1 -1
- package/dist/utils/parsePatchFiles.d.ts.map +1 -1
- package/dist/utils/parsePatchFiles.js +101 -11
- package/dist/utils/parsePatchFiles.js.map +1 -1
- package/dist/utils/prefersReducedMotion.d.ts.map +1 -1
- package/dist/utils/prefersReducedMotion.js +1 -1
- package/dist/utils/prefersReducedMotion.js.map +1 -1
- package/dist/utils/prerenderHTMLIfNecessary.d.ts.map +1 -1
- package/dist/utils/prerenderHTMLIfNecessary.js +1 -1
- package/dist/utils/prerenderHTMLIfNecessary.js.map +1 -1
- package/dist/utils/processLine.d.ts +1 -1
- package/dist/utils/processLine.d.ts.map +1 -1
- package/dist/utils/processLine.js +1 -2
- package/dist/utils/processLine.js.map +1 -1
- package/dist/utils/realignChangeContent.d.ts +28 -0
- package/dist/utils/realignChangeContent.d.ts.map +1 -0
- package/dist/utils/realignChangeContent.js +142 -0
- package/dist/utils/realignChangeContent.js.map +1 -0
- package/dist/utils/renderDiffWithHighlighter.d.ts.map +1 -1
- package/dist/utils/renderDiffWithHighlighter.js +9 -8
- package/dist/utils/renderDiffWithHighlighter.js.map +1 -1
- package/dist/utils/renderFileWithHighlighter.d.ts.map +1 -1
- package/dist/utils/renderFileWithHighlighter.js +5 -4
- package/dist/utils/renderFileWithHighlighter.js.map +1 -1
- package/dist/utils/resolveConflict.d.ts.map +1 -1
- package/dist/utils/resolveConflict.js +1 -2
- package/dist/utils/resolveConflict.js.map +1 -1
- package/dist/utils/resolveRegion.d.ts.map +1 -1
- package/dist/utils/resolveRegion.js +1 -1
- package/dist/utils/resolveRegion.js.map +1 -1
- package/dist/utils/roundToDevicePixel.d.ts.map +1 -1
- package/dist/utils/roundToDevicePixel.js +1 -1
- package/dist/utils/roundToDevicePixel.js.map +1 -1
- package/dist/utils/scrollbarGutter.d.ts.map +1 -1
- package/dist/utils/scrollbarGutter.js +1 -2
- package/dist/utils/scrollbarGutter.js.map +1 -1
- package/dist/utils/setLanguageOverride.d.ts.map +1 -1
- package/dist/utils/setLanguageOverride.js +1 -1
- package/dist/utils/setLanguageOverride.js.map +1 -1
- package/dist/utils/setWrapperNodeProps.d.ts.map +1 -1
- package/dist/utils/setWrapperNodeProps.js +1 -2
- package/dist/utils/setWrapperNodeProps.js.map +1 -1
- package/dist/utils/shouldUseTokenTransformer.d.ts.map +1 -1
- package/dist/utils/shouldUseTokenTransformer.js +1 -1
- package/dist/utils/shouldUseTokenTransformer.js.map +1 -1
- package/dist/utils/splitFileContents.d.ts.map +1 -1
- package/dist/utils/splitFileContents.js +1 -2
- package/dist/utils/splitFileContents.js.map +1 -1
- package/dist/utils/trimPatchContext.d.ts.map +1 -1
- package/dist/utils/trimPatchContext.js +1 -2
- package/dist/utils/trimPatchContext.js.map +1 -1
- package/dist/utils/updateDiffHunks.d.ts +24 -0
- package/dist/utils/updateDiffHunks.d.ts.map +1 -0
- package/dist/utils/updateDiffHunks.js +235 -0
- package/dist/utils/updateDiffHunks.js.map +1 -0
- package/dist/utils/virtualDiffLayout.d.ts +62 -2
- package/dist/utils/virtualDiffLayout.d.ts.map +1 -1
- package/dist/utils/virtualDiffLayout.js +137 -3
- package/dist/utils/virtualDiffLayout.js.map +1 -1
- package/dist/utils/wrapTokenFragments.d.ts +1 -1
- package/dist/utils/wrapTokenFragments.d.ts.map +1 -1
- package/dist/utils/wrapTokenFragments.js +1 -2
- package/dist/utils/wrapTokenFragments.js.map +1 -1
- package/dist/worker/WorkerPoolManager.d.ts +7 -2
- package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
- package/dist/worker/WorkerPoolManager.js +88 -23
- package/dist/worker/WorkerPoolManager.js.map +1 -1
- package/dist/worker/getOrCreateWorkerPoolSingleton.d.ts.map +1 -1
- package/dist/worker/getOrCreateWorkerPoolSingleton.js +1 -2
- package/dist/worker/getOrCreateWorkerPoolSingleton.js.map +1 -1
- package/dist/worker/index.d.ts +2 -2
- package/dist/worker/index.js +1 -2
- package/dist/worker/types.d.ts +11 -1
- package/dist/worker/types.d.ts.map +1 -1
- package/dist/worker/wasm-B9ZqxnKj.js +8 -0
- package/dist/worker/wasm-B9ZqxnKj.js.map +1 -0
- package/dist/worker/worker-portable.js +3335 -6214
- package/dist/worker/worker-portable.js.map +1 -1
- package/dist/worker/worker.js +287 -309
- package/dist/worker/worker.js.map +1 -1
- package/package.json +29 -32
- package/dist/editor/css.d.ts +0 -6
- package/dist/editor/css.d.ts.map +0 -1
- package/dist/editor/css.js +0 -218
- package/dist/editor/css.js.map +0 -1
- package/dist/editor/quickEdit.d.ts +0 -29
- package/dist/editor/quickEdit.d.ts.map +0 -1
- package/dist/editor/quickEdit.js +0 -81
- package/dist/editor/quickEdit.js.map +0 -1
- package/dist/editor/tokenzier.d.ts.map +0 -1
- package/dist/editor/tokenzier.js +0 -348
- package/dist/editor/tokenzier.js.map +0 -1
- package/dist/react/EditorContext.d.ts +0 -16
- package/dist/react/EditorContext.d.ts.map +0 -1
- package/dist/react/EditorContext.js +0 -26
- package/dist/react/EditorContext.js.map +0 -1
- package/dist/worker/wasm-D4DU5jgR.js +0 -10
- package/dist/worker/wasm-D4DU5jgR.js.map +0 -1
package/dist/editor/selection.js
CHANGED
|
@@ -1,13 +1,33 @@
|
|
|
1
|
+
import { createSegmenter, endsWithLineBreak, getGraphemeSegmenter } from "./utils.js";
|
|
1
2
|
import { applyDocumentChangeToLineAnnotations } from "./lineAnnotations.js";
|
|
2
|
-
|
|
3
3
|
//#region src/editor/selection.ts
|
|
4
4
|
const DirectionBackward = -1;
|
|
5
5
|
const DirectionNone = 0;
|
|
6
6
|
const DirectionForward = 1;
|
|
7
|
+
const AUTO_SURROUND_CLOSE_CHARS = /* @__PURE__ */ new Map([
|
|
8
|
+
["'", "'"],
|
|
9
|
+
["\"", "\""],
|
|
10
|
+
["`", "`"],
|
|
11
|
+
["{", "}"],
|
|
12
|
+
["[", "]"],
|
|
13
|
+
["<", ">"],
|
|
14
|
+
["(", ")"]
|
|
15
|
+
]);
|
|
16
|
+
const AUTO_SURROUND_QUOTE_CHARS = /* @__PURE__ */ new Set([
|
|
17
|
+
"'",
|
|
18
|
+
"\"",
|
|
19
|
+
"`"
|
|
20
|
+
]);
|
|
21
|
+
const AUTO_SURROUND_BRACKET_CHARS = /* @__PURE__ */ new Set([
|
|
22
|
+
"{",
|
|
23
|
+
"[",
|
|
24
|
+
"(",
|
|
25
|
+
"<"
|
|
26
|
+
]);
|
|
7
27
|
/**
|
|
8
28
|
* Converts a selection from a web selection to an editor selection.
|
|
9
29
|
*/
|
|
10
|
-
function convertSelection(range, direction =
|
|
30
|
+
function convertSelection(range, direction = 0) {
|
|
11
31
|
const start = boundaryToPosition(range.startContainer, range.startOffset);
|
|
12
32
|
const end = boundaryToPosition(range.endContainer, range.endOffset);
|
|
13
33
|
if (start === null || end === null) return;
|
|
@@ -25,11 +45,13 @@ function resolveIndentEdits(textDocument, selection, tabSize, outdent) {
|
|
|
25
45
|
const { start, end } = selection;
|
|
26
46
|
const edits = [];
|
|
27
47
|
let newSelection = { ...selection };
|
|
48
|
+
const blockIndent = start.line !== end.line;
|
|
28
49
|
let endLine = end.line;
|
|
29
50
|
if (start.line < end.line && end.character === 0) endLine--;
|
|
30
51
|
for (let line = start.line; line <= endLine; line++) {
|
|
31
52
|
const lineText = textDocument.getLineText(line);
|
|
32
53
|
if (lineText === void 0) continue;
|
|
54
|
+
if (blockIndent && lineText.trim().length === 0) continue;
|
|
33
55
|
const indentUnit = lineText.startsWith(" ") ? " " : " ".repeat(tabSize);
|
|
34
56
|
let deleteLength = 0;
|
|
35
57
|
let newText = indentUnit;
|
|
@@ -76,32 +98,54 @@ function resolveIndentEdits(textDocument, selection, tabSize, outdent) {
|
|
|
76
98
|
/**
|
|
77
99
|
* Maps the cursor move to all selections.
|
|
78
100
|
*/
|
|
79
|
-
function mapCursorMove(textDocument, selections, shortcut) {
|
|
101
|
+
function mapCursorMove(textDocument, selections, shortcut, options = {}) {
|
|
80
102
|
const lineCount = textDocument.lineCount;
|
|
81
103
|
return selections.map((selection) => {
|
|
82
104
|
let { line, character } = shortcut === "up" || shortcut === "left" ? selection.start : selection.end;
|
|
83
105
|
if (shortcut === "textStart" || shortcut === "start" || shortcut === "end") {
|
|
106
|
+
const caret = getCaretPosition(selection);
|
|
107
|
+
line = caret.line;
|
|
108
|
+
character = caret.character;
|
|
109
|
+
const softLine = getSoftLineInfo(textDocument, line, character, options);
|
|
84
110
|
if (shortcut === "textStart") {
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
111
|
+
const softLineText = textDocument.getLineText(line).slice(softLine.start, softLine.end);
|
|
112
|
+
const indent = softLine.start + getLeadingSpaces(softLineText);
|
|
113
|
+
character = character === indent ? softLine.start : indent;
|
|
114
|
+
} else character = shortcut === "start" ? softLine.start : softLine.end;
|
|
115
|
+
} else if (shortcut === "up") {
|
|
116
|
+
const moved = moveBySoftLine(textDocument, line, character, -1, options);
|
|
117
|
+
if (moved !== void 0) {
|
|
118
|
+
line = moved.line;
|
|
119
|
+
character = moved.character;
|
|
120
|
+
} else if (line > 0) line = options.resolveRenderableLine == null ? line - 1 : options.resolveRenderableLine(line - 1, "up") ?? line;
|
|
121
|
+
} else if (shortcut === "down") {
|
|
122
|
+
const moved = moveBySoftLine(textDocument, line, character, 1, options);
|
|
123
|
+
if (moved !== void 0) {
|
|
124
|
+
line = moved.line;
|
|
125
|
+
character = moved.character;
|
|
126
|
+
} else {
|
|
127
|
+
const maxLine = Math.max(lineCount - 1, 0);
|
|
128
|
+
if (line < maxLine) line = options.resolveRenderableLine == null ? line + 1 : Math.min(options.resolveRenderableLine(line + 1, "down") ?? line, maxLine);
|
|
98
129
|
}
|
|
99
|
-
} else {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
130
|
+
} else if (isCollapsedSelection(selection)) {
|
|
131
|
+
const lineLength = textDocument.getLineLength(line);
|
|
132
|
+
character = Math.min(character, lineLength);
|
|
133
|
+
if (shortcut === "left") {
|
|
134
|
+
if (character > 0) character = stepCharacterByGrapheme(textDocument, line, character, false);
|
|
135
|
+
else if (line > 0) {
|
|
136
|
+
const targetLine = options.resolveRenderableLine == null ? line - 1 : options.resolveRenderableLine(line - 1, "up");
|
|
137
|
+
if (targetLine !== void 0) {
|
|
138
|
+
line = targetLine;
|
|
139
|
+
character = textDocument.getLineLength(line);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
} else if (character < lineLength) character = stepCharacterByGrapheme(textDocument, line, character, true);
|
|
143
|
+
else if (line < lineCount - 1) {
|
|
144
|
+
const targetLine = options.resolveRenderableLine == null ? line + 1 : options.resolveRenderableLine(line + 1, "down");
|
|
145
|
+
if (targetLine !== void 0) {
|
|
146
|
+
line = Math.min(targetLine, lineCount - 1);
|
|
147
|
+
character = 0;
|
|
148
|
+
}
|
|
105
149
|
}
|
|
106
150
|
}
|
|
107
151
|
const pos = {
|
|
@@ -111,33 +155,121 @@ function mapCursorMove(textDocument, selections, shortcut) {
|
|
|
111
155
|
return {
|
|
112
156
|
start: pos,
|
|
113
157
|
end: pos,
|
|
114
|
-
direction:
|
|
158
|
+
direction: 0
|
|
115
159
|
};
|
|
116
160
|
});
|
|
117
161
|
}
|
|
162
|
+
function moveBySoftLine(textDocument, line, character, direction, options) {
|
|
163
|
+
if (options.getSoftLineOffsets === void 0) return;
|
|
164
|
+
const current = getSoftLineInfo(textDocument, line, character, options);
|
|
165
|
+
const targetIndex = current.index + direction;
|
|
166
|
+
let targetLine = line;
|
|
167
|
+
let target;
|
|
168
|
+
if (targetIndex >= 0 && targetIndex < current.count) target = getSoftLineInfoAtIndex(textDocument, targetLine, targetIndex, options);
|
|
169
|
+
else {
|
|
170
|
+
const nextLine = line + direction;
|
|
171
|
+
if (nextLine < 0 || nextLine >= textDocument.lineCount) return {
|
|
172
|
+
line,
|
|
173
|
+
character
|
|
174
|
+
};
|
|
175
|
+
const resolvedLine = options.resolveRenderableLine == null ? nextLine : options.resolveRenderableLine(nextLine, direction < 0 ? "up" : "down");
|
|
176
|
+
if (resolvedLine === void 0) return {
|
|
177
|
+
line,
|
|
178
|
+
character
|
|
179
|
+
};
|
|
180
|
+
targetLine = Math.min(resolvedLine, textDocument.lineCount - 1);
|
|
181
|
+
const targetCount = getSoftLineCount(textDocument, targetLine, options);
|
|
182
|
+
target = getSoftLineInfoAtIndex(textDocument, targetLine, direction < 0 ? targetCount - 1 : 0, options);
|
|
183
|
+
}
|
|
184
|
+
const column = Math.max(0, character - current.start);
|
|
185
|
+
const targetCharacter = target.start + column;
|
|
186
|
+
const landedCharacter = target.index === target.count - 1 ? targetCharacter : Math.min(targetCharacter, target.end);
|
|
187
|
+
const targetLineText = textDocument.getLineText(targetLine);
|
|
188
|
+
return {
|
|
189
|
+
line: targetLine,
|
|
190
|
+
character: landedCharacter > targetLineText.length ? landedCharacter : snapCharacterToGraphemeBoundary(targetLineText, landedCharacter)
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
function snapCharacterToGraphemeBoundary(lineText, character) {
|
|
194
|
+
if (character <= 0 || character >= lineText.length) return character;
|
|
195
|
+
const segmenter = getGraphemeSegmenter();
|
|
196
|
+
if (segmenter !== void 0) {
|
|
197
|
+
for (const segment of segmenter.segment(lineText)) {
|
|
198
|
+
if (character <= segment.index) return character;
|
|
199
|
+
const segmentEnd = segment.index + segment.segment.length;
|
|
200
|
+
if (character < segmentEnd) return segmentEnd;
|
|
201
|
+
}
|
|
202
|
+
return character;
|
|
203
|
+
}
|
|
204
|
+
let segmentStart = 0;
|
|
205
|
+
for (const codePoint of lineText) {
|
|
206
|
+
if (character <= segmentStart) return character;
|
|
207
|
+
const segmentEnd = segmentStart + codePoint.length;
|
|
208
|
+
if (character < segmentEnd) return segmentEnd;
|
|
209
|
+
segmentStart = segmentEnd;
|
|
210
|
+
}
|
|
211
|
+
return character;
|
|
212
|
+
}
|
|
213
|
+
function getSoftLineInfo(textDocument, line, character, options) {
|
|
214
|
+
const lineLength = textDocument.getLineLength(line);
|
|
215
|
+
const offsets = options.getSoftLineOffsets?.(line);
|
|
216
|
+
if (offsets === void 0 || offsets.length < 2) return {
|
|
217
|
+
start: 0,
|
|
218
|
+
end: lineLength,
|
|
219
|
+
index: 0,
|
|
220
|
+
count: 1
|
|
221
|
+
};
|
|
222
|
+
for (let index = 0; index + 1 < offsets.length; index++) {
|
|
223
|
+
const softLine = getSoftLineInfoAtIndex(textDocument, line, index, options);
|
|
224
|
+
if (character >= softLine.start && character <= softLine.end) return softLine;
|
|
225
|
+
}
|
|
226
|
+
return getSoftLineInfoAtIndex(textDocument, line, character < (offsets[0] ?? 0) ? 0 : offsets.length - 2, options);
|
|
227
|
+
}
|
|
228
|
+
function getSoftLineCount(textDocument, line, options) {
|
|
229
|
+
const offsets = options.getSoftLineOffsets?.(line);
|
|
230
|
+
return offsets === void 0 || offsets.length < 2 ? 1 : offsets.length - 1;
|
|
231
|
+
}
|
|
232
|
+
function getSoftLineInfoAtIndex(textDocument, line, index, options) {
|
|
233
|
+
const lineLength = textDocument.getLineLength(line);
|
|
234
|
+
const offsets = options.getSoftLineOffsets?.(line);
|
|
235
|
+
if (offsets === void 0 || offsets.length < 2) return {
|
|
236
|
+
start: 0,
|
|
237
|
+
end: lineLength,
|
|
238
|
+
index: 0,
|
|
239
|
+
count: 1
|
|
240
|
+
};
|
|
241
|
+
const count = offsets.length - 1;
|
|
242
|
+
const boundedIndex = Math.max(0, Math.min(index, count - 1));
|
|
243
|
+
const start = Math.max(0, Math.min(lineLength, offsets[boundedIndex] ?? 0));
|
|
244
|
+
return {
|
|
245
|
+
start,
|
|
246
|
+
end: Math.max(start, Math.min(lineLength, offsets[boundedIndex + 1] ?? lineLength)),
|
|
247
|
+
index: boundedIndex,
|
|
248
|
+
count
|
|
249
|
+
};
|
|
250
|
+
}
|
|
118
251
|
/**
|
|
119
252
|
* Same as mapCursorMove, but with shift key pressed.
|
|
120
253
|
*/
|
|
121
|
-
function mapSelectionShift(textDocument, selections, shortcut) {
|
|
254
|
+
function mapSelectionShift(textDocument, selections, shortcut, options = {}) {
|
|
122
255
|
return selections.map((selection) => {
|
|
123
|
-
const
|
|
124
|
-
const focusPosition = textDocument.positionAt(focusOffset);
|
|
256
|
+
const focusPosition = selection.direction === -1 ? selection.start : selection.end;
|
|
125
257
|
const [movedFocusSelection] = mapCursorMove(textDocument, [{
|
|
126
258
|
start: focusPosition,
|
|
127
259
|
end: focusPosition,
|
|
128
|
-
direction:
|
|
129
|
-
}], shortcut);
|
|
130
|
-
return
|
|
260
|
+
direction: 0
|
|
261
|
+
}], shortcut, options);
|
|
262
|
+
return createSelectionFrom(selection, movedFocusSelection);
|
|
131
263
|
});
|
|
132
264
|
}
|
|
133
265
|
/**
|
|
134
266
|
* Applies a text change to the given text document
|
|
135
267
|
*/
|
|
136
|
-
function applyTextChangeToSelections(textDocument, selections, edit, lineAnnotations, tabSize = 2) {
|
|
268
|
+
function applyTextChangeToSelections(textDocument, selections, edit, lineAnnotations, tabSize = 2, undoBoundary = false) {
|
|
137
269
|
if (selections[selections.length - 1] === void 0) return { nextSelections: [] };
|
|
138
270
|
const selectionPositions = [];
|
|
139
271
|
for (const selection of selections) selectionPositions.push(selection.start, selection.end);
|
|
140
|
-
const selectionOffsets = textDocument.
|
|
272
|
+
const selectionOffsets = selectionPositions.map((position) => textDocument.offsetAt(position));
|
|
141
273
|
const primaryStartOffset = selectionOffsets[(selections.length - 1) * 2];
|
|
142
274
|
const primaryEndOffset = selectionOffsets[(selections.length - 1) * 2 + 1];
|
|
143
275
|
const ordered = [];
|
|
@@ -198,7 +330,7 @@ function applyTextChangeToSelections(textDocument, selections, edit, lineAnnotat
|
|
|
198
330
|
};
|
|
199
331
|
}
|
|
200
332
|
finalizeMergedGroup();
|
|
201
|
-
const change = textDocument.applyResolvedEdits(edits, true, selections);
|
|
333
|
+
const change = textDocument.applyResolvedEdits(edits, true, selections, void 0, undoBoundary);
|
|
202
334
|
const nextSelections = createSelectionsFromOffsetPairs(textDocument, nextSelectionOffsets.map((offsets) => {
|
|
203
335
|
if (offsets === void 0) throw new Error("Missing next selection offsets");
|
|
204
336
|
return offsets;
|
|
@@ -214,21 +346,45 @@ function applyTextChangeToSelections(textDocument, selections, edit, lineAnnotat
|
|
|
214
346
|
};
|
|
215
347
|
}
|
|
216
348
|
/**
|
|
217
|
-
*
|
|
349
|
+
* Returns the next anchor/focus offsets after replacing a selection range.
|
|
350
|
+
* When the inserted text still contains the original selection (auto-surround),
|
|
351
|
+
* the inner range is reselected to match VS Code/CodeMirror behavior.
|
|
352
|
+
*/
|
|
353
|
+
function getAutoSurroundPreservedOffset(originalText, newText) {
|
|
354
|
+
if (newText.length !== originalText.length + 2) return;
|
|
355
|
+
const closeChar = AUTO_SURROUND_CLOSE_CHARS.get(newText[0]);
|
|
356
|
+
if (closeChar === void 0 || newText[newText.length - 1] !== closeChar || newText.slice(1, -1) !== originalText) return;
|
|
357
|
+
return 1;
|
|
358
|
+
}
|
|
359
|
+
function getNextSelectionOffsetPairAfterReplace(textDocument, entry, offsetDelta, newText) {
|
|
360
|
+
const insertStart = entry.start + offsetDelta;
|
|
361
|
+
const insertEnd = insertStart + newText.length;
|
|
362
|
+
if (entry.end - entry.start > 0) {
|
|
363
|
+
const originalText = textDocument.getTextSlice(entry.start, entry.end);
|
|
364
|
+
const preservedOffset = getAutoSurroundPreservedOffset(originalText, newText) ?? newText.indexOf(originalText);
|
|
365
|
+
if (preservedOffset !== -1 && preservedOffset + originalText.length <= newText.length) {
|
|
366
|
+
const rangeStart = insertStart + preservedOffset;
|
|
367
|
+
return [rangeStart, rangeStart + originalText.length];
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
return [insertEnd, insertEnd];
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Applies text replacements to multiple selections. Texts pair by selection
|
|
374
|
+
* index unless they are explicitly marked as document ordered.
|
|
218
375
|
*/
|
|
219
|
-
function applyTextReplaceToSelections(textDocument, selections, texts, lineAnnotations) {
|
|
376
|
+
function applyTextReplaceToSelections(textDocument, selections, texts, lineAnnotations, undoBoundary = false, textOrder = "selection") {
|
|
220
377
|
if (selections.length !== texts.length) throw new Error("Selection text replacements must match the selection count");
|
|
221
378
|
const selectionPositions = [];
|
|
222
379
|
for (const selection of selections) selectionPositions.push(selection.start, selection.end);
|
|
223
|
-
const selectionOffsets = textDocument.
|
|
380
|
+
const selectionOffsets = selectionPositions.map((position) => textDocument.offsetAt(position));
|
|
224
381
|
const ordered = [];
|
|
225
382
|
let isAlreadyOrdered = true;
|
|
226
383
|
for (let index = 0; index < selections.length; index++) {
|
|
227
384
|
const entry = {
|
|
228
385
|
index,
|
|
229
386
|
start: selectionOffsets[index * 2],
|
|
230
|
-
end: selectionOffsets[index * 2 + 1]
|
|
231
|
-
text: texts[index]
|
|
387
|
+
end: selectionOffsets[index * 2 + 1]
|
|
232
388
|
};
|
|
233
389
|
const previous = ordered[ordered.length - 1];
|
|
234
390
|
if (previous !== void 0 && (entry.start < previous.start || entry.start === previous.start && entry.end < previous.end)) isAlreadyOrdered = false;
|
|
@@ -241,24 +397,68 @@ function applyTextReplaceToSelections(textDocument, selections, texts, lineAnnot
|
|
|
241
397
|
if (endOrder !== 0) return endOrder;
|
|
242
398
|
return a.index - b.index;
|
|
243
399
|
});
|
|
244
|
-
const
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
400
|
+
const allDeletes = texts.every((text) => text === "");
|
|
401
|
+
let edits;
|
|
402
|
+
const nextSelectionOffsetPairs = Array.from({ length: selections.length });
|
|
403
|
+
if (allDeletes) {
|
|
404
|
+
edits = [];
|
|
405
|
+
let hasEffect = false;
|
|
406
|
+
for (const entry of ordered) {
|
|
407
|
+
nextSelectionOffsetPairs[entry.index] = [entry.end, entry.end];
|
|
408
|
+
if (entry.start >= entry.end) continue;
|
|
409
|
+
hasEffect = true;
|
|
410
|
+
const last = edits[edits.length - 1];
|
|
411
|
+
if (last !== void 0 && entry.start < last.end) edits[edits.length - 1] = {
|
|
412
|
+
start: last.start,
|
|
413
|
+
end: Math.max(last.end, entry.end),
|
|
414
|
+
text: ""
|
|
415
|
+
};
|
|
416
|
+
else edits.push({
|
|
417
|
+
start: entry.start,
|
|
418
|
+
end: entry.end,
|
|
419
|
+
text: ""
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
if (!hasEffect) return { nextSelections: selections };
|
|
423
|
+
for (const entry of ordered) {
|
|
424
|
+
const caret = entry.end;
|
|
425
|
+
let delta = 0;
|
|
426
|
+
let next = caret;
|
|
427
|
+
for (const edit of edits) {
|
|
428
|
+
if (caret <= edit.start) break;
|
|
429
|
+
if (caret >= edit.end) {
|
|
430
|
+
delta -= edit.end - edit.start;
|
|
431
|
+
continue;
|
|
432
|
+
}
|
|
433
|
+
next = edit.start + delta;
|
|
434
|
+
break;
|
|
435
|
+
}
|
|
436
|
+
if (next === caret) next += delta;
|
|
437
|
+
nextSelectionOffsetPairs[entry.index] = [next, next];
|
|
438
|
+
}
|
|
439
|
+
} else {
|
|
440
|
+
edits = [];
|
|
441
|
+
let offsetDelta = 0;
|
|
442
|
+
let previousEditEnd = -1;
|
|
443
|
+
for (let index = 0; index < ordered.length; index++) {
|
|
444
|
+
const entry = ordered[index];
|
|
445
|
+
if (entry.start < previousEditEnd) throw new Error("Overlapping multi-selection edits are not supported");
|
|
446
|
+
previousEditEnd = entry.end;
|
|
447
|
+
const newText = expandSingleNewlineInsert(textDocument, texts[textOrder === "document" ? index : entry.index], entry.start);
|
|
448
|
+
edits.push({
|
|
449
|
+
start: entry.start,
|
|
450
|
+
end: entry.end,
|
|
451
|
+
text: newText
|
|
452
|
+
});
|
|
453
|
+
nextSelectionOffsetPairs[entry.index] = getNextSelectionOffsetPairAfterReplace(textDocument, entry, offsetDelta, newText);
|
|
454
|
+
offsetDelta += newText.length - (entry.end - entry.start);
|
|
455
|
+
}
|
|
259
456
|
}
|
|
260
|
-
const change = textDocument.applyResolvedEdits(edits, true, selections);
|
|
261
|
-
const nextSelections = createSelectionsFromOffsetPairs(textDocument,
|
|
457
|
+
const change = textDocument.applyResolvedEdits(edits, true, selections, void 0, undoBoundary);
|
|
458
|
+
const nextSelections = createSelectionsFromOffsetPairs(textDocument, nextSelectionOffsetPairs.map((offsets) => {
|
|
459
|
+
if (offsets === void 0) throw new Error("Missing next selection offsets");
|
|
460
|
+
return offsets;
|
|
461
|
+
}));
|
|
262
462
|
textDocument.setLastUndoSelectionsAfter(nextSelections);
|
|
263
463
|
if (change !== void 0 && lineAnnotations !== void 0) {
|
|
264
464
|
const nextLineAnnotations = applyDocumentChangeToLineAnnotations(change, lineAnnotations);
|
|
@@ -269,12 +469,32 @@ function applyTextReplaceToSelections(textDocument, selections, texts, lineAnnot
|
|
|
269
469
|
change
|
|
270
470
|
};
|
|
271
471
|
}
|
|
472
|
+
function shouldAutoSurroundChar(autoSurround, char) {
|
|
473
|
+
if (autoSurround === "never") return false;
|
|
474
|
+
if (autoSurround === "brackets") return AUTO_SURROUND_BRACKET_CHARS.has(char);
|
|
475
|
+
if (autoSurround === "quotes") return AUTO_SURROUND_QUOTE_CHARS.has(char);
|
|
476
|
+
return true;
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Returns per-selection replacement text when typing a surround character over
|
|
480
|
+
* non-collapsed selections, matching VS Code auto-surround behavior.
|
|
481
|
+
*/
|
|
482
|
+
function getAutoSurroundReplacementTexts(textDocument, selections, char, autoSurround) {
|
|
483
|
+
if (char.length !== 1 || selections.length === 0) return;
|
|
484
|
+
const closeChar = AUTO_SURROUND_CLOSE_CHARS.get(char);
|
|
485
|
+
if (closeChar === void 0 || !shouldAutoSurroundChar(autoSurround, char)) return;
|
|
486
|
+
const replacements = [];
|
|
487
|
+
for (const selection of selections) {
|
|
488
|
+
if (isCollapsedSelection(selection)) return;
|
|
489
|
+
replacements.push(char + textDocument.getText(selection) + closeChar);
|
|
490
|
+
}
|
|
491
|
+
return replacements;
|
|
492
|
+
}
|
|
272
493
|
/**
|
|
273
494
|
* Swaps the two characters adjacent to a collapsed selection, matching browser
|
|
274
495
|
* insertTranspose (Ctrl+T) behavior.
|
|
275
496
|
*/
|
|
276
497
|
function applyTransposeToSelections(textDocument, selections, lineAnnotations) {
|
|
277
|
-
const text = textDocument.getText();
|
|
278
498
|
const edits = [];
|
|
279
499
|
const nextOffsetPairs = [];
|
|
280
500
|
for (const selection of selections) {
|
|
@@ -285,36 +505,48 @@ function applyTransposeToSelections(textDocument, selections, lineAnnotations) {
|
|
|
285
505
|
}
|
|
286
506
|
const { line, character } = selection.start;
|
|
287
507
|
const offset = anchor;
|
|
288
|
-
const
|
|
508
|
+
const lineText = textDocument.getLineText(line);
|
|
509
|
+
const lineLength = lineText.length;
|
|
510
|
+
const lineStart = offset - character;
|
|
511
|
+
const graphemeStarts = getLineGraphemeStarts(lineText);
|
|
289
512
|
let edit;
|
|
290
513
|
if (character > 0 && character < lineLength) {
|
|
514
|
+
const before = findClusterBreak(lineText, character, false, graphemeStarts);
|
|
515
|
+
const after = findClusterBreak(lineText, character, true, graphemeStarts);
|
|
291
516
|
edit = {
|
|
292
|
-
start:
|
|
293
|
-
end:
|
|
294
|
-
text:
|
|
517
|
+
start: lineStart + before,
|
|
518
|
+
end: lineStart + after,
|
|
519
|
+
text: lineText.slice(character, after) + lineText.slice(before, character)
|
|
295
520
|
};
|
|
296
|
-
nextOffsetPairs.push([
|
|
297
|
-
} else if (character === lineLength &&
|
|
521
|
+
nextOffsetPairs.push([lineStart + after, lineStart + after]);
|
|
522
|
+
} else if (character === lineLength && graphemeStarts.length >= 2) {
|
|
523
|
+
const lastStart = graphemeStarts[graphemeStarts.length - 1];
|
|
524
|
+
const secondLastStart = graphemeStarts[graphemeStarts.length - 2];
|
|
298
525
|
edit = {
|
|
299
|
-
start:
|
|
526
|
+
start: lineStart + secondLastStart,
|
|
300
527
|
end: offset,
|
|
301
|
-
text:
|
|
528
|
+
text: lineText.slice(lastStart, lineLength) + lineText.slice(secondLastStart, lastStart)
|
|
302
529
|
};
|
|
303
530
|
nextOffsetPairs.push([offset, offset]);
|
|
304
531
|
} else if (character === 0 && line > 0 && lineLength > 0) {
|
|
305
532
|
const prevLine = line - 1;
|
|
306
|
-
const
|
|
533
|
+
const prevLineText = textDocument.getLineText(prevLine);
|
|
534
|
+
const prevLength = prevLineText.length;
|
|
307
535
|
const prevEnd = textDocument.offsetAt({
|
|
308
536
|
line: prevLine,
|
|
309
537
|
character: prevLength
|
|
310
538
|
});
|
|
311
|
-
const
|
|
539
|
+
const prevGraphemeStart = prevLength > 0 ? findClusterBreak(prevLineText, prevLength, false, getLineGraphemeStarts(prevLineText)) : prevLength;
|
|
540
|
+
const firstEnd = findClusterBreak(lineText, 0, true, graphemeStarts);
|
|
541
|
+
const prevStart = prevEnd - (prevLength - prevGraphemeStart);
|
|
542
|
+
const newText = lineText.slice(0, firstEnd) + textDocument.getTextSlice(prevEnd, offset) + prevLineText.slice(prevGraphemeStart, prevLength);
|
|
312
543
|
edit = {
|
|
313
544
|
start: prevStart,
|
|
314
|
-
end: offset +
|
|
315
|
-
text:
|
|
545
|
+
end: offset + firstEnd,
|
|
546
|
+
text: newText
|
|
316
547
|
};
|
|
317
|
-
|
|
548
|
+
const caret = prevStart + newText.length;
|
|
549
|
+
nextOffsetPairs.push([caret, caret]);
|
|
318
550
|
} else {
|
|
319
551
|
nextOffsetPairs.push([anchor, focus]);
|
|
320
552
|
continue;
|
|
@@ -347,10 +579,139 @@ function applyDeleteHardLineForwardToSelections(textDocument, selections, lineAn
|
|
|
347
579
|
return {
|
|
348
580
|
start: range.start,
|
|
349
581
|
end: range.end,
|
|
350
|
-
direction:
|
|
582
|
+
direction: 0
|
|
583
|
+
};
|
|
584
|
+
});
|
|
585
|
+
return applyTextReplaceToSelections(textDocument, deleteSelections, deleteSelections.map(() => ""), lineAnnotations);
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Deletes from each selection back to the start of its soft (visual) line.
|
|
589
|
+
* Non-collapsed selections delete their selected text instead.
|
|
590
|
+
*/
|
|
591
|
+
function applyDeleteSoftLineBackwardToSelections(textDocument, selections, getSoftLineStart, lineAnnotations) {
|
|
592
|
+
const deleteSelections = selections.map((selection) => {
|
|
593
|
+
if (!isCollapsedSelection(selection)) return {
|
|
594
|
+
start: selection.start,
|
|
595
|
+
end: selection.end,
|
|
596
|
+
direction: 0
|
|
597
|
+
};
|
|
598
|
+
const caret = getCaretPosition(selection);
|
|
599
|
+
const { line, character } = caret;
|
|
600
|
+
const softLineStart = getSoftLineStart?.(line, character) ?? 0;
|
|
601
|
+
if (character > softLineStart) return {
|
|
602
|
+
start: {
|
|
603
|
+
line,
|
|
604
|
+
character: softLineStart
|
|
605
|
+
},
|
|
606
|
+
end: {
|
|
607
|
+
line,
|
|
608
|
+
character
|
|
609
|
+
},
|
|
610
|
+
direction: 0
|
|
611
|
+
};
|
|
612
|
+
if (line === 0) return {
|
|
613
|
+
start: caret,
|
|
614
|
+
end: caret,
|
|
615
|
+
direction: 0
|
|
616
|
+
};
|
|
617
|
+
const prevLineLength = textDocument.getLineLength(line - 1);
|
|
618
|
+
return {
|
|
619
|
+
start: {
|
|
620
|
+
line: line - 1,
|
|
621
|
+
character: prevLineLength
|
|
622
|
+
},
|
|
623
|
+
end: {
|
|
624
|
+
line,
|
|
625
|
+
character: 0
|
|
626
|
+
},
|
|
627
|
+
direction: 0
|
|
628
|
+
};
|
|
629
|
+
});
|
|
630
|
+
return applyTextReplaceToSelections(textDocument, deleteSelections, deleteSelections.map(() => ""), lineAnnotations);
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Deletes the word or separator group immediately before each selection.
|
|
634
|
+
* Non-collapsed selections delete their selected text instead.
|
|
635
|
+
*/
|
|
636
|
+
function applyDeleteWordBackwardToSelections(textDocument, selections, lineAnnotations) {
|
|
637
|
+
const deleteSelections = selections.map((selection) => {
|
|
638
|
+
const [start, end] = resolveDeleteWordBackwardRange(textDocument, selection);
|
|
639
|
+
return {
|
|
640
|
+
start,
|
|
641
|
+
end,
|
|
642
|
+
direction: 0
|
|
643
|
+
};
|
|
644
|
+
});
|
|
645
|
+
return applyTextReplaceToSelections(textDocument, deleteSelections, deleteSelections.map(() => ""), lineAnnotations);
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* Resolves the document range deleted by Backspace or Delete at a collapsed
|
|
649
|
+
* caret. Non-collapsed selections delete their selected text instead.
|
|
650
|
+
*/
|
|
651
|
+
function resolveDeleteCharacterRange(textDocument, selection, forward) {
|
|
652
|
+
if (!isCollapsedSelection(selection)) return [selection.start, selection.end];
|
|
653
|
+
const caret = getCaretPosition(selection);
|
|
654
|
+
let { line, character } = caret;
|
|
655
|
+
const lineLength = textDocument.getLineLength(line);
|
|
656
|
+
const lineCount = textDocument.lineCount;
|
|
657
|
+
character = Math.min(character, lineLength);
|
|
658
|
+
if (forward) {
|
|
659
|
+
if (character < lineLength) return [{
|
|
660
|
+
line,
|
|
661
|
+
character
|
|
662
|
+
}, {
|
|
663
|
+
line,
|
|
664
|
+
character: stepCharacterByGrapheme(textDocument, line, character, true)
|
|
665
|
+
}];
|
|
666
|
+
if (line < lineCount - 1) return [{
|
|
667
|
+
line,
|
|
668
|
+
character: lineLength
|
|
669
|
+
}, {
|
|
670
|
+
line: line + 1,
|
|
671
|
+
character: 0
|
|
672
|
+
}];
|
|
673
|
+
return [caret, caret];
|
|
674
|
+
}
|
|
675
|
+
if (character > 0) return [{
|
|
676
|
+
line,
|
|
677
|
+
character: stepCharacterByGrapheme(textDocument, line, character, false)
|
|
678
|
+
}, {
|
|
679
|
+
line,
|
|
680
|
+
character
|
|
681
|
+
}];
|
|
682
|
+
if (line > 0) {
|
|
683
|
+
const prevLineLength = textDocument.getLineLength(line - 1);
|
|
684
|
+
return [{
|
|
685
|
+
line: line - 1,
|
|
686
|
+
character: prevLineLength
|
|
687
|
+
}, {
|
|
688
|
+
line,
|
|
689
|
+
character: 0
|
|
690
|
+
}];
|
|
691
|
+
}
|
|
692
|
+
return [caret, caret];
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* Deletes one grapheme (or selected text) at each selection.
|
|
696
|
+
*/
|
|
697
|
+
function applyDeleteCharacterToSelections(textDocument, selections, forward, lineAnnotations, tabSize = 2) {
|
|
698
|
+
const deleteSelections = selections.map((selection) => {
|
|
699
|
+
let [start, end] = resolveDeleteCharacterRange(textDocument, selection, forward);
|
|
700
|
+
if (!forward && isCollapsedSelection(selection)) {
|
|
701
|
+
const normalized = normalizeLeadingIndentForChange(textDocument, {
|
|
702
|
+
start: textDocument.offsetAt(start),
|
|
703
|
+
end: textDocument.offsetAt(end),
|
|
704
|
+
text: ""
|
|
705
|
+
}, tabSize);
|
|
706
|
+
start = textDocument.positionAt(normalized.start);
|
|
707
|
+
end = textDocument.positionAt(normalized.end);
|
|
708
|
+
}
|
|
709
|
+
return {
|
|
710
|
+
start,
|
|
711
|
+
end,
|
|
712
|
+
direction: 0
|
|
351
713
|
};
|
|
352
714
|
});
|
|
353
|
-
if (!deleteSelections.some((selection) => comparePosition(selection.start, selection.end) !== 0)) return { nextSelections: selections };
|
|
354
715
|
return applyTextReplaceToSelections(textDocument, deleteSelections, deleteSelections.map(() => ""), lineAnnotations);
|
|
355
716
|
}
|
|
356
717
|
/**
|
|
@@ -364,13 +725,13 @@ function isCollapsedSelection(selection) {
|
|
|
364
725
|
*/
|
|
365
726
|
function getCaretPosition(selection) {
|
|
366
727
|
const { start, end, direction } = selection;
|
|
367
|
-
return direction ===
|
|
728
|
+
return direction === -1 ? start : end;
|
|
368
729
|
}
|
|
369
730
|
/**
|
|
370
731
|
* Checks if a line is editable.
|
|
371
732
|
*/
|
|
372
733
|
function isLineEditable(lineType) {
|
|
373
|
-
return lineType === "context" || lineType === "
|
|
734
|
+
return lineType === "context" || lineType === "context-expanded" || lineType === "change-addition";
|
|
374
735
|
}
|
|
375
736
|
/**
|
|
376
737
|
* Checks whether selections `a` and `b` intersect.
|
|
@@ -394,7 +755,7 @@ function comparePosition(a, b) {
|
|
|
394
755
|
* Creates a selection from anchor and focus offsets.
|
|
395
756
|
*/
|
|
396
757
|
function createSelectionFromAnchorAndFocusOffsets(textDocument, anchorOffset, focusOffset) {
|
|
397
|
-
const direction = anchorOffset === focusOffset ?
|
|
758
|
+
const direction = anchorOffset === focusOffset ? 0 : anchorOffset < focusOffset ? 1 : -1;
|
|
398
759
|
const start = Math.min(anchorOffset, focusOffset);
|
|
399
760
|
const end = Math.max(anchorOffset, focusOffset);
|
|
400
761
|
return {
|
|
@@ -404,10 +765,44 @@ function createSelectionFromAnchorAndFocusOffsets(textDocument, anchorOffset, fo
|
|
|
404
765
|
};
|
|
405
766
|
}
|
|
406
767
|
/**
|
|
768
|
+
* Maps a single offset from the pre-edit document into the post-edit document.
|
|
769
|
+
* `edits` are resolved edits in pre-edit offsets, sorted ascending and
|
|
770
|
+
* non-overlapping. An offset at or after an edit's start shifts to the end of
|
|
771
|
+
* that edit's replacement (right gravity), so text inserted at the caret pushes
|
|
772
|
+
* the caret past it; an offset strictly before an edit is only shifted by the
|
|
773
|
+
* net length change of the edits that precede it.
|
|
774
|
+
*/
|
|
775
|
+
function remapOffsetThroughEdits(offset, edits) {
|
|
776
|
+
let delta = 0;
|
|
777
|
+
for (const edit of edits) {
|
|
778
|
+
if (offset < edit.start) break;
|
|
779
|
+
if (offset >= edit.end) delta += edit.text.length - (edit.end - edit.start);
|
|
780
|
+
else return edit.start + delta + edit.text.length;
|
|
781
|
+
}
|
|
782
|
+
return offset + delta;
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Re-anchors selections after a batch of text edits has been applied, so the
|
|
786
|
+
* caret keeps pointing at the same logical location in the changed buffer.
|
|
787
|
+
*
|
|
788
|
+
* `selectionOffsets` (one `[start, end]` pair per selection) and `edits` are
|
|
789
|
+
* measured in the PRE-edit document; the returned selections are built from
|
|
790
|
+
* `textDocument`, which must already reflect the applied edits. Selection
|
|
791
|
+
* direction is preserved by remapping each edge and re-deriving anchor/focus.
|
|
792
|
+
*/
|
|
793
|
+
function remapSelectionsAfterEdits(textDocument, selections, selectionOffsets, edits) {
|
|
794
|
+
return selections.map((selection, index) => {
|
|
795
|
+
const [startOffset, endOffset] = selectionOffsets[index];
|
|
796
|
+
const nextStart = remapOffsetThroughEdits(startOffset, edits);
|
|
797
|
+
const nextEnd = remapOffsetThroughEdits(endOffset, edits);
|
|
798
|
+
return createSelectionFromAnchorAndFocusOffsets(textDocument, selection.direction === -1 ? nextEnd : nextStart, selection.direction === -1 ? nextStart : nextEnd);
|
|
799
|
+
});
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
407
802
|
* Creates a selection from a anchor and focus selection.
|
|
408
803
|
*/
|
|
409
804
|
function createSelectionFrom(anchorSelection, focusSelection) {
|
|
410
|
-
const anchor = anchorSelection.direction ===
|
|
805
|
+
const anchor = anchorSelection.direction === -1 ? anchorSelection.end : anchorSelection.start;
|
|
411
806
|
const currentStartOrder = comparePosition(anchor, focusSelection.start);
|
|
412
807
|
const currentEndOrder = comparePosition(anchor, focusSelection.end);
|
|
413
808
|
let focus = focusSelection.end;
|
|
@@ -418,7 +813,7 @@ function createSelectionFrom(anchorSelection, focusSelection) {
|
|
|
418
813
|
return {
|
|
419
814
|
start: anchorVsFocus <= 0 ? anchor : focus,
|
|
420
815
|
end: anchorVsFocus <= 0 ? focus : anchor,
|
|
421
|
-
direction: anchorVsFocus === 0 ?
|
|
816
|
+
direction: anchorVsFocus === 0 ? 0 : anchorVsFocus < 0 ? 1 : -1
|
|
422
817
|
};
|
|
423
818
|
}
|
|
424
819
|
/**
|
|
@@ -431,22 +826,22 @@ function extendSelection(original, target) {
|
|
|
431
826
|
if (leftExtended && !rightExtended) return {
|
|
432
827
|
start: target.start,
|
|
433
828
|
end: original.end,
|
|
434
|
-
direction:
|
|
829
|
+
direction: -1
|
|
435
830
|
};
|
|
436
831
|
if (rightExtended && !leftExtended) return {
|
|
437
832
|
start: original.start,
|
|
438
833
|
end: target.end,
|
|
439
|
-
direction:
|
|
834
|
+
direction: 1
|
|
440
835
|
};
|
|
441
|
-
if (original.direction ===
|
|
836
|
+
if (original.direction === -1) return {
|
|
442
837
|
start: target.start,
|
|
443
838
|
end: original.end,
|
|
444
|
-
direction: comparePosition(target.start, original.end) === 0 ?
|
|
839
|
+
direction: comparePosition(target.start, original.end) === 0 ? 0 : -1
|
|
445
840
|
};
|
|
446
841
|
return {
|
|
447
842
|
start: original.start,
|
|
448
843
|
end: target.end,
|
|
449
|
-
direction: comparePosition(original.start, target.end) === 0 ?
|
|
844
|
+
direction: comparePosition(original.start, target.end) === 0 ? 0 : 1
|
|
450
845
|
};
|
|
451
846
|
}
|
|
452
847
|
/**
|
|
@@ -462,30 +857,91 @@ function extendSelections(selections, target) {
|
|
|
462
857
|
*/
|
|
463
858
|
function mergeOverlappingSelections(selections) {
|
|
464
859
|
if (selections.length <= 1) return selections;
|
|
465
|
-
const
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
860
|
+
const ordered = selections.map((selection, index) => ({
|
|
861
|
+
index,
|
|
862
|
+
selection
|
|
863
|
+
})).sort((a, b) => {
|
|
864
|
+
const startOrder = comparePosition(a.selection.start, b.selection.start);
|
|
865
|
+
if (startOrder !== 0) return startOrder;
|
|
866
|
+
const endOrder = comparePosition(a.selection.end, b.selection.end);
|
|
867
|
+
return endOrder !== 0 ? endOrder : a.index - b.index;
|
|
868
|
+
});
|
|
869
|
+
const merged = [];
|
|
870
|
+
let current = ordered[0];
|
|
871
|
+
for (const entry of ordered.slice(1)) {
|
|
872
|
+
if (selectionIntersects(current.selection, entry.selection)) {
|
|
873
|
+
const latest = entry.index > current.index ? entry : current;
|
|
874
|
+
const start = comparePosition(entry.selection.start, current.selection.start) < 0 ? entry.selection.start : current.selection.start;
|
|
875
|
+
const end = comparePosition(entry.selection.end, current.selection.end) > 0 ? entry.selection.end : current.selection.end;
|
|
876
|
+
let direction = latest.selection.direction;
|
|
877
|
+
if (direction === 0 && comparePosition(start, end) !== 0) direction = comparePosition(latest.selection.start, start) === 0 ? -1 : 1;
|
|
878
|
+
current = {
|
|
879
|
+
index: latest.index,
|
|
880
|
+
selection: {
|
|
881
|
+
direction,
|
|
882
|
+
end,
|
|
883
|
+
start
|
|
884
|
+
}
|
|
885
|
+
};
|
|
886
|
+
continue;
|
|
478
887
|
}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
888
|
+
merged.push(current);
|
|
889
|
+
current = entry;
|
|
890
|
+
}
|
|
891
|
+
merged.push(current);
|
|
892
|
+
return merged.sort((a, b) => a.index - b.index).map(({ selection }) => selection);
|
|
893
|
+
}
|
|
894
|
+
/**
|
|
895
|
+
* Converts selections into merged line blocks for line-based commands.
|
|
896
|
+
*/
|
|
897
|
+
function getSelectedLineBlocks(selections) {
|
|
898
|
+
const blocks = selections.map((selection) => {
|
|
899
|
+
let endLine = selection.end.line;
|
|
900
|
+
if (selection.end.character === 0 && comparePosition(selection.start, selection.end) !== 0) endLine--;
|
|
901
|
+
return {
|
|
902
|
+
startLine: selection.start.line,
|
|
903
|
+
endLine: Math.max(selection.start.line, endLine)
|
|
904
|
+
};
|
|
905
|
+
}).sort((a, b) => {
|
|
906
|
+
const startOrder = a.startLine - b.startLine;
|
|
907
|
+
return startOrder !== 0 ? startOrder : a.endLine - b.endLine;
|
|
908
|
+
});
|
|
909
|
+
const merged = [];
|
|
910
|
+
for (const block of blocks) {
|
|
911
|
+
const previous = merged.at(-1);
|
|
912
|
+
if (previous !== void 0 && block.startLine <= previous.endLine + 1) previous.endLine = Math.max(previous.endLine, block.endLine);
|
|
913
|
+
else merged.push({ ...block });
|
|
487
914
|
}
|
|
488
|
-
return
|
|
915
|
+
return merged;
|
|
916
|
+
}
|
|
917
|
+
/**
|
|
918
|
+
* Moves a selection's line positions after its lines are shifted, clamping to
|
|
919
|
+
* the target document bounds.
|
|
920
|
+
*/
|
|
921
|
+
function shiftSelectionLines(selection, direction, lineCount, getLineLength) {
|
|
922
|
+
const shiftPosition = (position) => {
|
|
923
|
+
const line = position.line + direction;
|
|
924
|
+
if (line >= lineCount) {
|
|
925
|
+
const lastLine = Math.max(0, lineCount - 1);
|
|
926
|
+
return {
|
|
927
|
+
line: lastLine,
|
|
928
|
+
character: getLineLength(lastLine)
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
if (line < 0) return {
|
|
932
|
+
line: 0,
|
|
933
|
+
character: 0
|
|
934
|
+
};
|
|
935
|
+
return {
|
|
936
|
+
line,
|
|
937
|
+
character: position.character
|
|
938
|
+
};
|
|
939
|
+
};
|
|
940
|
+
return {
|
|
941
|
+
start: shiftPosition(selection.start),
|
|
942
|
+
end: shiftPosition(selection.end),
|
|
943
|
+
direction: selection.direction
|
|
944
|
+
};
|
|
489
945
|
}
|
|
490
946
|
/**
|
|
491
947
|
* Finds the next matching word and updates the selections.
|
|
@@ -517,38 +973,193 @@ function getDocumentFullSelection(textDocument) {
|
|
|
517
973
|
},
|
|
518
974
|
end: {
|
|
519
975
|
line: lastLine,
|
|
520
|
-
character: textDocument.
|
|
976
|
+
character: textDocument.getLineLength(lastLine)
|
|
521
977
|
},
|
|
522
|
-
direction:
|
|
978
|
+
direction: 1
|
|
523
979
|
};
|
|
524
980
|
}
|
|
525
981
|
/**
|
|
526
982
|
* Get the boundary selection of the document.
|
|
527
983
|
*/
|
|
528
|
-
function getDocumentBoundarySelection(textDocument, atEnd) {
|
|
529
|
-
|
|
984
|
+
function getDocumentBoundarySelection(textDocument, atEnd, trimmedEndNewLine) {
|
|
985
|
+
let line = 0;
|
|
986
|
+
if (atEnd) {
|
|
987
|
+
const lastLine = textDocument.lineCount - 1;
|
|
988
|
+
line = trimmedEndNewLine === true && lastLine > 0 && textDocument.getLineLength(lastLine) === 0 ? lastLine - 1 : lastLine;
|
|
989
|
+
}
|
|
990
|
+
const character = atEnd ? textDocument.getLineLength(line) : 0;
|
|
530
991
|
const start = {
|
|
531
992
|
line,
|
|
532
|
-
character
|
|
993
|
+
character
|
|
533
994
|
};
|
|
534
995
|
return {
|
|
535
996
|
start,
|
|
536
997
|
end: start,
|
|
537
|
-
direction:
|
|
998
|
+
direction: 1
|
|
999
|
+
};
|
|
1000
|
+
}
|
|
1001
|
+
/** Resolves the document offset range one selection contributes to a copy. */
|
|
1002
|
+
function resolveClipboardRegion(textDocument, selection) {
|
|
1003
|
+
if (isCollapsedSelection(selection)) {
|
|
1004
|
+
const line = selection.start.line;
|
|
1005
|
+
return {
|
|
1006
|
+
start: textDocument.offsetAt({
|
|
1007
|
+
line,
|
|
1008
|
+
character: 0
|
|
1009
|
+
}),
|
|
1010
|
+
end: line < textDocument.lineCount - 1 ? textDocument.offsetAt({
|
|
1011
|
+
line: line + 1,
|
|
1012
|
+
character: 0
|
|
1013
|
+
}) : textDocument.offsetAt({
|
|
1014
|
+
line,
|
|
1015
|
+
character: textDocument.getLineLength(line)
|
|
1016
|
+
})
|
|
1017
|
+
};
|
|
1018
|
+
}
|
|
1019
|
+
const start = textDocument.offsetAt(selection.start);
|
|
1020
|
+
const end = textDocument.offsetAt(selection.end);
|
|
1021
|
+
return start <= end ? {
|
|
1022
|
+
start,
|
|
1023
|
+
end
|
|
1024
|
+
} : {
|
|
1025
|
+
start: end,
|
|
1026
|
+
end: start
|
|
538
1027
|
};
|
|
539
1028
|
}
|
|
540
1029
|
/**
|
|
541
|
-
*
|
|
1030
|
+
* Resolves the document offset range each selection contributes to the
|
|
1031
|
+
* clipboard, ordered by position. A collapsed selection contributes its whole
|
|
1032
|
+
* logical line including the trailing line break; the final line has no
|
|
1033
|
+
* trailing break to include. A ranged selection contributes the selected text.
|
|
1034
|
+
*/
|
|
1035
|
+
function resolveClipboardRegions(textDocument, selections) {
|
|
1036
|
+
return selections.map((selection) => resolveClipboardRegion(textDocument, selection)).sort((a, b) => {
|
|
1037
|
+
const startOrder = a.start - b.start;
|
|
1038
|
+
return startOrder !== 0 ? startOrder : a.end - b.end;
|
|
1039
|
+
});
|
|
1040
|
+
}
|
|
1041
|
+
/**
|
|
1042
|
+
* Gets the text contributed by each selection in document order, preserving
|
|
1043
|
+
* the pairing needed to paste the values into another set of selections.
|
|
1044
|
+
*/
|
|
1045
|
+
function getSelectionClipboardTexts(textDocument, selections) {
|
|
1046
|
+
return resolveClipboardRegions(textDocument, selections).map(({ start, end }) => textDocument.getTextSlice(start, end));
|
|
1047
|
+
}
|
|
1048
|
+
/**
|
|
1049
|
+
* Get the clipboard text of the selections for the given text document. Used by
|
|
1050
|
+
* both copy and cut so the two stay in sync. Overlapping regions (e.g. several
|
|
1051
|
+
* carets on one line) are merged so the same text is never emitted twice, and a
|
|
1052
|
+
* line-ending separator is inserted only between regions that aren't already
|
|
1053
|
+
* contiguous in the document.
|
|
542
1054
|
*/
|
|
543
1055
|
function getSelectionText(textDocument, selections) {
|
|
544
|
-
|
|
545
|
-
|
|
1056
|
+
const regions = resolveClipboardRegions(textDocument, selections);
|
|
1057
|
+
const eol = textDocument.eol;
|
|
1058
|
+
let result = "";
|
|
1059
|
+
let prevEnd = -1;
|
|
1060
|
+
for (const region of regions) {
|
|
1061
|
+
if (region.end <= region.start) continue;
|
|
1062
|
+
if (region.start <= prevEnd) {
|
|
1063
|
+
if (region.end > prevEnd) {
|
|
1064
|
+
result += textDocument.getTextSlice(prevEnd, region.end);
|
|
1065
|
+
prevEnd = region.end;
|
|
1066
|
+
}
|
|
1067
|
+
continue;
|
|
1068
|
+
}
|
|
1069
|
+
if (result.length > 0 && !endsWithLineBreak(result)) result += eol;
|
|
1070
|
+
result += textDocument.getTextSlice(region.start, region.end);
|
|
1071
|
+
prevEnd = region.end;
|
|
1072
|
+
}
|
|
1073
|
+
return result;
|
|
1074
|
+
}
|
|
1075
|
+
function resolveSelectionCutEdit(textDocument, selection) {
|
|
1076
|
+
if (isCollapsedSelection(selection)) return resolveCollapsedSelectionCutEdit(textDocument, selection);
|
|
1077
|
+
const [start, end] = comparePosition(selection.start, selection.end) <= 0 ? [selection.start, selection.end] : [selection.end, selection.start];
|
|
1078
|
+
return {
|
|
1079
|
+
start: textDocument.offsetAt(start),
|
|
1080
|
+
end: textDocument.offsetAt(end),
|
|
1081
|
+
text: ""
|
|
1082
|
+
};
|
|
1083
|
+
}
|
|
1084
|
+
function resolveCollapsedSelectionCutEdit(textDocument, selection) {
|
|
1085
|
+
const line = selection.start.line;
|
|
1086
|
+
const lineStart = textDocument.offsetAt({
|
|
1087
|
+
line,
|
|
1088
|
+
character: 0
|
|
1089
|
+
});
|
|
1090
|
+
const lineEnd = textDocument.offsetAt({
|
|
1091
|
+
line,
|
|
1092
|
+
character: textDocument.getLineLength(line)
|
|
1093
|
+
});
|
|
1094
|
+
if (line < textDocument.lineCount - 1) return {
|
|
1095
|
+
start: lineStart,
|
|
1096
|
+
end: textDocument.offsetAt({
|
|
1097
|
+
line: line + 1,
|
|
1098
|
+
character: 0
|
|
1099
|
+
}),
|
|
1100
|
+
text: ""
|
|
1101
|
+
};
|
|
1102
|
+
if (line > 0) return {
|
|
1103
|
+
start: textDocument.offsetAt({
|
|
1104
|
+
line: line - 1,
|
|
1105
|
+
character: textDocument.getLineLength(line - 1)
|
|
1106
|
+
}),
|
|
1107
|
+
end: lineEnd,
|
|
1108
|
+
text: ""
|
|
1109
|
+
};
|
|
1110
|
+
return {
|
|
1111
|
+
start: lineStart,
|
|
1112
|
+
end: lineEnd,
|
|
1113
|
+
text: ""
|
|
1114
|
+
};
|
|
1115
|
+
}
|
|
1116
|
+
function mergeCutEdits(orderedCuts) {
|
|
1117
|
+
const edits = [];
|
|
1118
|
+
for (const { edit } of orderedCuts) {
|
|
1119
|
+
if (edit.start >= edit.end) continue;
|
|
1120
|
+
const last = edits.at(-1);
|
|
1121
|
+
if (last !== void 0 && edit.start <= last.end) edits[edits.length - 1] = {
|
|
1122
|
+
start: last.start,
|
|
1123
|
+
end: Math.max(last.end, edit.end),
|
|
1124
|
+
text: ""
|
|
1125
|
+
};
|
|
1126
|
+
else edits.push(edit);
|
|
1127
|
+
}
|
|
1128
|
+
return edits;
|
|
1129
|
+
}
|
|
1130
|
+
function mapCutSelectionOffsets(orderedCuts, edits) {
|
|
1131
|
+
const nextOffsets = Array.from({ length: orderedCuts.length });
|
|
1132
|
+
let editIndex = 0;
|
|
1133
|
+
let offsetDelta = 0;
|
|
1134
|
+
for (const cut of orderedCuts) {
|
|
1135
|
+
while (editIndex < edits.length && cut.edit.start > edits[editIndex].end) {
|
|
1136
|
+
const edit = edits[editIndex];
|
|
1137
|
+
offsetDelta -= edit.end - edit.start;
|
|
1138
|
+
editIndex++;
|
|
1139
|
+
}
|
|
1140
|
+
const edit = edits[editIndex];
|
|
1141
|
+
if (edit !== void 0 && cut.edit.start >= edit.start && cut.edit.start <= edit.end) nextOffsets[cut.index] = edit.start + offsetDelta;
|
|
1142
|
+
else nextOffsets[cut.index] = cut.edit.start + offsetDelta;
|
|
1143
|
+
}
|
|
1144
|
+
return nextOffsets;
|
|
1145
|
+
}
|
|
1146
|
+
function resolveSelectionCut(textDocument, selections) {
|
|
1147
|
+
const orderedCuts = [...selections.map((selection, index) => ({
|
|
1148
|
+
index,
|
|
1149
|
+
edit: resolveSelectionCutEdit(textDocument, selection)
|
|
1150
|
+
}))].sort((a, b) => {
|
|
1151
|
+
const startOrder = a.edit.start - b.edit.start;
|
|
546
1152
|
if (startOrder !== 0) return startOrder;
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
1153
|
+
const endOrder = a.edit.end - b.edit.end;
|
|
1154
|
+
if (endOrder !== 0) return endOrder;
|
|
1155
|
+
return a.index - b.index;
|
|
1156
|
+
});
|
|
1157
|
+
const edits = mergeCutEdits(orderedCuts);
|
|
1158
|
+
return {
|
|
1159
|
+
text: getSelectionText(textDocument, selections),
|
|
1160
|
+
edits,
|
|
1161
|
+
nextSelectionOffsets: mapCutSelectionOffsets(orderedCuts, edits)
|
|
1162
|
+
};
|
|
552
1163
|
}
|
|
553
1164
|
/**
|
|
554
1165
|
* Get the anchor node and offset for a selection.
|
|
@@ -600,23 +1211,132 @@ function expandCollapsedSelectionToWord(textDocument, selection) {
|
|
|
600
1211
|
line,
|
|
601
1212
|
character: span.end
|
|
602
1213
|
},
|
|
603
|
-
direction:
|
|
1214
|
+
direction: 1
|
|
604
1215
|
};
|
|
605
1216
|
}
|
|
606
1217
|
function expandCollapsedLineWord(lineText, character) {
|
|
607
|
-
const segmenter =
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
1218
|
+
const segmenter = createSegmenter({ granularity: "word" });
|
|
1219
|
+
if (segmenter !== void 0) {
|
|
1220
|
+
for (const seg of segmenter.segment(lineText)) {
|
|
1221
|
+
if (seg.isWordLike !== true) continue;
|
|
1222
|
+
const lo = seg.index;
|
|
1223
|
+
const hi = lo + seg.segment.length;
|
|
1224
|
+
if (character >= lo && character <= hi) return {
|
|
1225
|
+
start: lo,
|
|
1226
|
+
end: hi
|
|
1227
|
+
};
|
|
1228
|
+
}
|
|
1229
|
+
return;
|
|
1230
|
+
}
|
|
1231
|
+
const wordRe = /[\p{Alphabetic}\p{Number}_]+/gu;
|
|
1232
|
+
let match;
|
|
1233
|
+
while ((match = wordRe.exec(lineText)) !== null) {
|
|
1234
|
+
const lo = match.index;
|
|
1235
|
+
const hi = lo + match[0].length;
|
|
612
1236
|
if (character >= lo && character <= hi) return {
|
|
613
1237
|
start: lo,
|
|
614
1238
|
end: hi
|
|
615
1239
|
};
|
|
616
1240
|
}
|
|
617
1241
|
}
|
|
1242
|
+
function resolveDeleteWordBackwardRange(textDocument, selection) {
|
|
1243
|
+
if (!isCollapsedSelection(selection)) return [selection.start, selection.end];
|
|
1244
|
+
const caret = getCaretPosition(selection);
|
|
1245
|
+
const { line, character: head } = caret;
|
|
1246
|
+
if (head === 0) {
|
|
1247
|
+
if (line === 0) return [caret, caret];
|
|
1248
|
+
const prevLineLength = textDocument.getLineLength(line - 1);
|
|
1249
|
+
return [{
|
|
1250
|
+
line: line - 1,
|
|
1251
|
+
character: prevLineLength
|
|
1252
|
+
}, {
|
|
1253
|
+
line,
|
|
1254
|
+
character: 0
|
|
1255
|
+
}];
|
|
1256
|
+
}
|
|
1257
|
+
const lineText = textDocument.getLineText(line);
|
|
1258
|
+
const graphemeStarts = getLineGraphemeStarts(lineText);
|
|
1259
|
+
let pos = head;
|
|
1260
|
+
let match;
|
|
1261
|
+
while (pos > 0) {
|
|
1262
|
+
const prev = findClusterBreak(lineText, pos, false, graphemeStarts);
|
|
1263
|
+
const nextChar = lineText.slice(prev, pos);
|
|
1264
|
+
const nextMatch = !/\S/.test(nextChar) ? 0 : /\p{Alphabetic}|\p{Number}|_/u.test(nextChar) ? 1 : 2;
|
|
1265
|
+
if (match !== void 0 && nextMatch !== match) break;
|
|
1266
|
+
if (nextMatch !== 0 || pos !== head) match = nextMatch;
|
|
1267
|
+
pos = prev;
|
|
1268
|
+
}
|
|
1269
|
+
return [{
|
|
1270
|
+
line,
|
|
1271
|
+
character: pos
|
|
1272
|
+
}, {
|
|
1273
|
+
line,
|
|
1274
|
+
character: head
|
|
1275
|
+
}];
|
|
1276
|
+
}
|
|
1277
|
+
function findClusterBreak(text, pos, forward, graphemeStarts) {
|
|
1278
|
+
if (forward) {
|
|
1279
|
+
for (const start of graphemeStarts) if (start > pos) return start;
|
|
1280
|
+
return text.length;
|
|
1281
|
+
}
|
|
1282
|
+
for (let i = graphemeStarts.length - 1; i >= 0; i--) {
|
|
1283
|
+
const start = graphemeStarts[i];
|
|
1284
|
+
if (start < pos) return start;
|
|
1285
|
+
}
|
|
1286
|
+
return 0;
|
|
1287
|
+
}
|
|
1288
|
+
function getLineGraphemeStarts(lineText) {
|
|
1289
|
+
const graphemeStarts = [0];
|
|
1290
|
+
const segmenter = getGraphemeSegmenter();
|
|
1291
|
+
if (segmenter !== void 0) {
|
|
1292
|
+
for (const segment of segmenter.segment(lineText)) if (segment.index > 0) graphemeStarts.push(segment.index);
|
|
1293
|
+
return graphemeStarts;
|
|
1294
|
+
}
|
|
1295
|
+
let index = 0;
|
|
1296
|
+
for (const codePoint of lineText) {
|
|
1297
|
+
if (index > 0) graphemeStarts.push(index);
|
|
1298
|
+
index += codePoint.length;
|
|
1299
|
+
}
|
|
1300
|
+
return graphemeStarts;
|
|
1301
|
+
}
|
|
1302
|
+
function stepCharacterByGrapheme(textDocument, line, character, forward) {
|
|
1303
|
+
const lineLength = textDocument.getLineLength(line);
|
|
1304
|
+
if (forward) {
|
|
1305
|
+
if (character >= lineLength) return lineLength;
|
|
1306
|
+
const lineStart = textDocument.offsetAt({
|
|
1307
|
+
line,
|
|
1308
|
+
character: 0
|
|
1309
|
+
});
|
|
1310
|
+
const suffix = textDocument.getTextSlice(lineStart + character, lineStart + lineLength);
|
|
1311
|
+
const segmenter = getGraphemeSegmenter();
|
|
1312
|
+
if (segmenter !== void 0) {
|
|
1313
|
+
for (const segment of segmenter.segment(suffix)) return character + segment.segment.length;
|
|
1314
|
+
return lineLength;
|
|
1315
|
+
}
|
|
1316
|
+
for (const codePoint of suffix) return character + codePoint.length;
|
|
1317
|
+
return lineLength;
|
|
1318
|
+
}
|
|
1319
|
+
if (character <= 0) return 0;
|
|
1320
|
+
const lineStart = textDocument.offsetAt({
|
|
1321
|
+
line,
|
|
1322
|
+
character: 0
|
|
1323
|
+
});
|
|
1324
|
+
const prefix = textDocument.getTextSlice(lineStart, lineStart + character);
|
|
1325
|
+
let prevStart = 0;
|
|
1326
|
+
const segmenter = getGraphemeSegmenter();
|
|
1327
|
+
if (segmenter !== void 0) {
|
|
1328
|
+
for (const segment of segmenter.segment(prefix)) prevStart = segment.index;
|
|
1329
|
+
return prevStart;
|
|
1330
|
+
}
|
|
1331
|
+
let index = 0;
|
|
1332
|
+
for (const codePoint of prefix) {
|
|
1333
|
+
prevStart = index;
|
|
1334
|
+
index += codePoint.length;
|
|
1335
|
+
}
|
|
1336
|
+
return prevStart;
|
|
1337
|
+
}
|
|
618
1338
|
function getSelectionAnchorAndFocusOffsets(textDocument, selection) {
|
|
619
|
-
const isBackward = selection.direction ===
|
|
1339
|
+
const isBackward = selection.direction === -1;
|
|
620
1340
|
return [textDocument.offsetAt(isBackward ? selection.end : selection.start), textDocument.offsetAt(getCaretPosition(selection))];
|
|
621
1341
|
}
|
|
622
1342
|
function resolveDeleteHardLineForwardRange(textDocument, selection) {
|
|
@@ -658,7 +1378,7 @@ function resolveDeleteHardLineForwardRange(textDocument, selection) {
|
|
|
658
1378
|
};
|
|
659
1379
|
}
|
|
660
1380
|
function expandSingleNewlineInsert(textDocument, insertText, insertStartOffset) {
|
|
661
|
-
if (insertText !== "\n" && insertText !== "\r\n") return insertText;
|
|
1381
|
+
if (insertText !== "\n" && insertText !== "\r" && insertText !== "\r\n") return insertText;
|
|
662
1382
|
const line = textDocument.positionAt(insertStartOffset).line;
|
|
663
1383
|
const lineText = textDocument.getLineText(line);
|
|
664
1384
|
const indentLen = getLeadingSpaces(lineText);
|
|
@@ -678,7 +1398,7 @@ function createSelectionsFromOffsetPairs(textDocument, offsetPairs) {
|
|
|
678
1398
|
for (const [anchorOffset, focusOffset] of offsetPairs) normalizedOffsets.push(Math.min(anchorOffset, focusOffset), Math.max(anchorOffset, focusOffset));
|
|
679
1399
|
const positions = textDocument.positionsAt(normalizedOffsets);
|
|
680
1400
|
return offsetPairs.map(([anchorOffset, focusOffset], index) => {
|
|
681
|
-
const direction = anchorOffset === focusOffset ?
|
|
1401
|
+
const direction = anchorOffset === focusOffset ? 0 : anchorOffset < focusOffset ? 1 : -1;
|
|
682
1402
|
return {
|
|
683
1403
|
start: positions[index * 2],
|
|
684
1404
|
end: positions[index * 2 + 1],
|
|
@@ -834,10 +1554,10 @@ function isInside(token, node) {
|
|
|
834
1554
|
}
|
|
835
1555
|
function offsetBefore(line, node) {
|
|
836
1556
|
if (node.parentElement === line) {
|
|
837
|
-
let offset
|
|
1557
|
+
let offset = 0;
|
|
838
1558
|
const index = Array.prototype.indexOf.call(line.childNodes, node);
|
|
839
|
-
for (let i = 0; i < index; i++) offset
|
|
840
|
-
return offset
|
|
1559
|
+
for (let i = 0; i < index; i++) offset = getLineChildEnd(line.childNodes[i]);
|
|
1560
|
+
return offset;
|
|
841
1561
|
}
|
|
842
1562
|
for (const token of collectTokens(line)) if (isInside(token, node)) return getCharacterIndex(token) + (node.nodeType === 3 ? textLengthBefore(token, node) : 0);
|
|
843
1563
|
let offset = 0;
|
|
@@ -867,10 +1587,10 @@ function getLineChildEnd(child, textOffsetInChild) {
|
|
|
867
1587
|
if (parent === null) return 0;
|
|
868
1588
|
const token = findTokenSpan(parent);
|
|
869
1589
|
if (token === null) return 0;
|
|
870
|
-
const base
|
|
871
|
-
if (base
|
|
1590
|
+
const base = getCharacterIndex(token);
|
|
1591
|
+
if (base === void 0) return 0;
|
|
872
1592
|
const length = textOffsetInChild === void 0 ? getTextOffset(child.textContent, child.textContent?.length ?? 0) : getTextOffset(child.textContent, textOffsetInChild);
|
|
873
|
-
return base
|
|
1593
|
+
return base + textLengthBefore(token, child) + length;
|
|
874
1594
|
}
|
|
875
1595
|
if (child.nodeType !== 1) return 0;
|
|
876
1596
|
const el = child;
|
|
@@ -882,19 +1602,25 @@ function getLineChildEnd(child, textOffsetInChild) {
|
|
|
882
1602
|
return end;
|
|
883
1603
|
}
|
|
884
1604
|
function getLineIndex(el) {
|
|
885
|
-
const { line } = el.dataset;
|
|
886
|
-
if (line !== void 0
|
|
1605
|
+
const { line, lineType } = el.dataset;
|
|
1606
|
+
if (line !== void 0 && lineType !== "change-deletion") {
|
|
1607
|
+
const lineNumber = parseInt(line, 10);
|
|
1608
|
+
if (!Number.isNaN(lineNumber)) return lineNumber - 1;
|
|
1609
|
+
}
|
|
887
1610
|
}
|
|
888
1611
|
function getCharacterIndex(el) {
|
|
889
1612
|
const { char } = el.dataset;
|
|
890
|
-
|
|
1613
|
+
if (char !== void 0) {
|
|
1614
|
+
const charIndex = parseInt(char, 10);
|
|
1615
|
+
if (!Number.isNaN(charIndex)) return charIndex;
|
|
1616
|
+
}
|
|
891
1617
|
}
|
|
892
1618
|
function getTextOffset(text, offset) {
|
|
893
1619
|
const value = text ?? "";
|
|
894
1620
|
const lineBreakIndex = value.search(/[\r\n]/);
|
|
895
1621
|
return Math.min(offset, lineBreakIndex === -1 ? value.length : lineBreakIndex);
|
|
896
1622
|
}
|
|
897
|
-
|
|
898
1623
|
//#endregion
|
|
899
|
-
export { DirectionBackward, DirectionForward, DirectionNone, applyDeleteHardLineForwardToSelections, applyTextChangeToSelections, applyTextReplaceToSelections, applyTransposeToSelections, comparePosition, convertSelection, createSelectionFrom, createSelectionFromAnchorAndFocusOffsets, expandCollapsedSelectionToWord, extendSelection, extendSelections, findNexMatch, getCaretPosition, getDocumentBoundarySelection, getDocumentFullSelection, getSelectionAnchor, getSelectionText, isCollapsedSelection, isLineEditable, mapCursorMove, mapSelectionShift, mergeOverlappingSelections, resolveIndentEdits, selectionIntersects };
|
|
1624
|
+
export { DirectionBackward, DirectionForward, DirectionNone, applyDeleteCharacterToSelections, applyDeleteHardLineForwardToSelections, applyDeleteSoftLineBackwardToSelections, applyDeleteWordBackwardToSelections, applyTextChangeToSelections, applyTextReplaceToSelections, applyTransposeToSelections, comparePosition, convertSelection, createSelectionFrom, createSelectionFromAnchorAndFocusOffsets, expandCollapsedSelectionToWord, extendSelection, extendSelections, findNexMatch, getAutoSurroundReplacementTexts, getCaretPosition, getDocumentBoundarySelection, getDocumentFullSelection, getSelectedLineBlocks, getSelectionAnchor, getSelectionClipboardTexts, getSelectionText, isCollapsedSelection, isLineEditable, mapCursorMove, mapSelectionShift, mergeOverlappingSelections, remapSelectionsAfterEdits, resolveDeleteCharacterRange, resolveIndentEdits, resolveSelectionCut, selectionIntersects, shiftSelectionLines };
|
|
1625
|
+
|
|
900
1626
|
//# sourceMappingURL=selection.js.map
|