Skip to content

Commit 0024204

Browse files
committed
feat(editor): implement triple-click line selection and drag expansion
- Add `isLineSelection` and `lineSelectionAnchor` to track line selection mode. - Handle mouse triple-click to select the entire line. - Update mouse move logic to expand selection by full lines when in line selection mode. - Reset line selection state on mouse up or focus loss.
1 parent 88f7c83 commit 0024204

2 files changed

Lines changed: 32 additions & 8 deletions

File tree

anycode-base/src/editor.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ export class AnycodeEditor {
4949
private autoScrollTimer: number | null = null;
5050
private isWordSelection: boolean = false;
5151
private wordSelectionAnchor: number = 0;
52+
private isLineSelection: boolean = false;
53+
private lineSelectionAnchor: number = 0;
5254

5355
private lastScrollTop = 0;
5456

@@ -314,7 +316,7 @@ export class AnycodeEditor {
314316

315317
private handleClick(e: MouseEvent): void {
316318
console.log("click", e);
317-
319+
318320
const oldCursor = this.code.getPosition(this.offset);
319321

320322
if (this.selection && this.selection.nonEmpty()) { return; }
@@ -371,6 +373,7 @@ export class AnycodeEditor {
371373
// console.log('handleMouseUp ', this.selection);
372374
this.isMouseSelecting = false;
373375
this.isWordSelection = false;
376+
this.isLineSelection = false;
374377

375378
if (this.autoScrollTimer) {
376379
cancelAnimationFrame(this.autoScrollTimer);
@@ -382,6 +385,7 @@ export class AnycodeEditor {
382385
// console.log('Editor lost focus');
383386
this.isMouseSelecting = false;
384387
this.isWordSelection = false;
388+
this.isLineSelection = false;
385389

386390
if (this.autoScrollTimer) {
387391
cancelAnimationFrame(this.autoScrollTimer);
@@ -413,10 +417,13 @@ export class AnycodeEditor {
413417

414418
if (e.detail === 3) { // triple click
415419
this.selectLine(pos.row);
420+
this.isLineSelection = true;
421+
this.lineSelectionAnchor = pos.row;
416422
return;
417423
}
418424

419425
this.isWordSelection = false;
426+
this.isLineSelection = false;
420427
const o = this.code.getOffset(pos.row, pos.col);
421428

422429
if (e.shiftKey && this.selection) {
@@ -486,6 +493,22 @@ export class AnycodeEditor {
486493
const start = this.code.getOffset(row, startCol);
487494
const end = this.code.getOffset(row, endCol);
488495

496+
this.selection = new Selection(start, end);
497+
this.offset = end;
498+
}
499+
} else if (this.isLineSelection) {
500+
const anchorRow = this.lineSelectionAnchor;
501+
502+
if (row < anchorRow) {
503+
// Selection moving up
504+
const start = this.code.getOffset(row, 0);
505+
const end = this.code.getOffset(anchorRow, this.code.lineLength(anchorRow));
506+
this.selection = new Selection(start, end);
507+
this.offset = start;
508+
} else {
509+
// Selection moving down or same line
510+
const start = this.code.getOffset(anchorRow, 0);
511+
const end = this.code.getOffset(row, this.code.lineLength(row));
489512
this.selection = new Selection(start, end);
490513
this.offset = end;
491514
}
@@ -579,6 +602,7 @@ export class AnycodeEditor {
579602

580603
if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === 'c') {
581604
if (hasDiagnosticSelection()) {
605+
console.log('hasDiagnosticSelection');
582606
return;
583607
}
584608
}

anycode/components/agent/AcpMessage.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ const ToolCallMessage: React.FC<{
2929
isExpanded: boolean;
3030
onToggle: () => void;
3131
}> = ({ message, toolResult, toolUpdate, isExpanded, onToggle }) => {
32-
const hasArguments = message.arguments &&
33-
JSON.stringify(message.arguments) !== '{}' &&
32+
const hasArguments = message.arguments &&
33+
JSON.stringify(message.arguments) !== '{}' &&
3434
JSON.stringify(message.arguments) !== '[]';
3535

3636
return (
@@ -40,7 +40,7 @@ const ToolCallMessage: React.FC<{
4040
<span className="acp-toggle-icon">{isExpanded ? '▼' : '▶'}</span>
4141
<div className="acp-tool-call-name">{message.name}</div>
4242
</div>
43-
43+
4444
{isExpanded && (
4545
<>
4646
{message.command && (
@@ -137,9 +137,9 @@ const ToolResultDetails: React.FC<{ result: any }> = ({ result }) => {
137137

138138
const contentText = Array.isArray(content)
139139
? content
140-
.map((item: any) => item?.content?.text)
141-
.filter((text: any) => typeof text === 'string' && text.length > 0)
142-
.join('')
140+
.map((item: any) => item?.content?.text)
141+
.filter((text: any) => typeof text === 'string' && text.length > 0)
142+
.join('')
143143
: undefined;
144144

145145
const normalizedContent = typeof contentText === 'string' ? contentText.trim() : undefined;
@@ -267,7 +267,7 @@ const ThoughtMessage: React.FC<{
267267
const isLong = message.content.length > 180;
268268
const shouldToggle = isLong;
269269
const expanded = shouldToggle ? isExpanded : true;
270-
const lines = message.content.split('\n');
270+
const lines = message.content.trim().split('\n');
271271
const previewLine = lines[0] || '';
272272
return (
273273
<div className="acp-message acp-message-thought">

0 commit comments

Comments
 (0)