-
Notifications
You must be signed in to change notification settings - Fork 5
单击块选中和多文本选中后点击手柄进行多块选中 #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
14743768433
wants to merge
25
commits into
Ariestar:main
from
14743768433:codex/wip-selection-20260213-094042
Closed
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
a69dbf1
feat: enlarge drag handle default size for better visibility
14743768433 6fab21c
feat: 增加块选中的背景光晕
14743768433 354d61d
fix: use correct CSS variable for drop highlight color
14743768433 0fb9a34
feat: use text color for handle by default
14743768433 34b0a57
feat: add text selection to block selection conversion
14743768433 9f106b9
fix: clear editor text selection when converting to block selection
14743768433 8103e78
fix: hide vertical link line for text-selection-based block selection
14743768433 cce3c28
fix: properly hide link line when committing smart block selection
14743768433 a78ee79
fix: keep handle in normal state for smart block selection
14743768433 556a824
feat: hide handles for non-anchor blocks in smart selection
14743768433 5689603
fix: prevent handle hover effects during block selection
14743768433 96533ce
fix: hide other handles when committing single-click range selection
14743768433 1132939
fix: commit selection on quick mouse click and keep handle normal
14743768433 a91a223
fix: clear stale drag highlight after multi-node move
14743768433 b8c34b3
feat: improve range-selection drag flow and diagnostics
14743768433 68732ce
feat: keep single-block selected after drag drop
14743768433 69d67d7
feat: allow smart text-selection drag with persistent block selection
14743768433 e4e9187
wip: refine smart text-selection drag and selection visuals
14743768433 b42c167
fix: smart text-selection drag now correctly highlights all selected …
14743768433 646d52e
fix: allow native HTML5 drag after smart text selection
14743768433 4d1673a
fix: stabilize smart range selection and preserve drag workflows
14743768433 9dddaf5
fix: keep committed block selection stable after view updates
14743768433 e4c90ec
fix: allow clearing block selection by clicking selected area
14743768433 56f3067
fix: harden range selection restore and snapshot lifecycle
14743768433 d5246a0
chore: remove debug logs from drag interaction flow
14743768433 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,132 @@ | ||
| import type { EditorView } from '@codemirror/view'; | ||
| import type { LineRange } from '../../../types'; | ||
| import { | ||
| mergeLineRanges, | ||
| resolveBlockAlignedLineRange, | ||
| resolveBlockBoundaryAtLine, | ||
| } from '../../interaction/RangeSelectionLogic'; | ||
|
|
||
| export type EditorTextSelection = { | ||
| from: number; | ||
| to: number; | ||
| fromLine: number; | ||
| toLine: number; | ||
| }; | ||
|
|
||
| /** | ||
| * Bridge between CodeMirror editor selection and block-based selection. | ||
| * Reads the editor's native text selection and converts it to line ranges | ||
| * that can be used for block-aligned multi-line selection. | ||
| */ | ||
| export class EditorSelectionBridge { | ||
| constructor(private readonly view: EditorView) {} | ||
|
|
||
| /** | ||
| * Get the current text selection in the editor. | ||
| * @returns Selection info if there's a valid non-empty selection, null otherwise | ||
| */ | ||
| getTextSelection(): EditorTextSelection | null { | ||
| return this.getTextSelections()[0] ?? null; | ||
| } | ||
|
|
||
| /** | ||
| * Get all non-empty text selections in the editor. | ||
| * Supports multi-range selections (e.g. multiple carets/ranges). | ||
| */ | ||
| getTextSelections(): EditorTextSelection[] { | ||
| const doc = this.view.state.doc; | ||
| const ranges = this.view.state.selection.ranges; | ||
| const selections: EditorTextSelection[] = []; | ||
|
|
||
| for (const range of ranges) { | ||
| if (range.empty) continue; | ||
| const fromLine = doc.lineAt(range.from).number; | ||
| const toLine = doc.lineAt(range.to).number; | ||
| selections.push({ | ||
| from: range.from, | ||
| to: range.to, | ||
| fromLine, | ||
| toLine, | ||
| }); | ||
| } | ||
| return selections; | ||
| } | ||
|
|
||
| /** | ||
| * Check if a line number is within the current editor selection. | ||
| */ | ||
| isLineInSelection(lineNumber: number): boolean { | ||
| const selections = this.getTextSelections(); | ||
| if (selections.length === 0) return false; | ||
| return selections.some((selection) => ( | ||
| lineNumber >= selection.fromLine && lineNumber <= selection.toLine | ||
| )); | ||
| } | ||
|
|
||
| /** | ||
| * Convert the current editor selection to block-aligned line ranges. | ||
| * This ensures that partial selections are expanded to include complete blocks. | ||
| * @returns Block-aligned line ranges, or null if no valid selection | ||
| */ | ||
| resolveBlockAlignedSelection(): LineRange[] | null { | ||
| const selections = this.getTextSelections(); | ||
| if (selections.length === 0) return null; | ||
|
|
||
| const state = this.view.state; | ||
| const docLines = state.doc.lines; | ||
| const ranges: LineRange[] = []; | ||
|
|
||
| for (const selection of selections) { | ||
| // Get the block boundaries at the selection start and end | ||
| const startBoundary = resolveBlockBoundaryAtLine(state, selection.fromLine); | ||
| const endBoundary = resolveBlockBoundaryAtLine(state, selection.toLine); | ||
|
|
||
| // Resolve to block-aligned range | ||
| const aligned = resolveBlockAlignedLineRange( | ||
| state, | ||
| startBoundary.startLineNumber, | ||
| startBoundary.endLineNumber, | ||
| endBoundary.startLineNumber, | ||
| endBoundary.endLineNumber | ||
| ); | ||
| ranges.push({ | ||
| startLineNumber: aligned.startLineNumber, | ||
| endLineNumber: aligned.endLineNumber, | ||
| }); | ||
| } | ||
| return mergeLineRanges(docLines, ranges); | ||
| } | ||
|
|
||
| /** | ||
| * Check if a line number intersects with the editor selection. | ||
| * If it does, return the block-aligned selection ranges. | ||
| * @param lineNumber The line number to check (1-indexed) | ||
| * @returns Block-aligned ranges if the line intersects, null otherwise | ||
| */ | ||
| getBlockAlignedRangeIfIntersecting(lineNumber: number): LineRange[] | null { | ||
| return this.getBlockAlignedRangeIfRangeIntersecting(lineNumber, lineNumber); | ||
| } | ||
|
|
||
| /** | ||
| * Check if a line range intersects with the editor selection. | ||
| * If it does, return the block-aligned selection ranges. | ||
| * @param startLineNumber Inclusive start line number (1-indexed) | ||
| * @param endLineNumber Inclusive end line number (1-indexed) | ||
| */ | ||
| getBlockAlignedRangeIfRangeIntersecting(startLineNumber: number, endLineNumber: number): LineRange[] | null { | ||
| const selections = this.getTextSelections(); | ||
| if (selections.length === 0) return null; | ||
|
|
||
| const safeStart = Math.min(startLineNumber, endLineNumber); | ||
| const safeEnd = Math.max(startLineNumber, endLineNumber); | ||
|
|
||
| // Trigger only when clicked range intersects at least one text selection range. | ||
| const intersects = selections.some((selection) => ( | ||
| safeEnd >= selection.fromLine && safeStart <= selection.toLine | ||
| )); | ||
| if (!intersects) return null; | ||
|
|
||
| // Return the block-aligned selection | ||
| return this.resolveBlockAlignedSelection(); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个文件里硬编码了一个个人本地开发路径。这会导致其他开发者的构建失败,并且可能会泄露个人信息。建议使用环境变量来配置此路径,或者在提交前移除此更改。