Skip to content

Commit f300b22

Browse files
committed
Fix bugs that exceed boundaries when selecting text. (Issue: #88)
1 parent 6ed2944 commit f300b22

File tree

3 files changed

+56
-14
lines changed

3 files changed

+56
-14
lines changed

example/lib/main.dart

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:async';
2-
2+
import 'package:flutter/gestures.dart';
33
import 'package:flutter/material.dart';
4+
import 'package:flutter/services.dart';
45
import 'package:xterm/flutter.dart';
56
import 'package:xterm/xterm.dart';
67

@@ -96,9 +97,19 @@ class _MyHomePageState extends State<MyHomePage> {
9697
Widget build(BuildContext context) {
9798
return Scaffold(
9899
body: SafeArea(
99-
child: TerminalView(
100-
terminal: terminal,
101-
style: TerminalStyle(fontFamily: ['Cascadia Mono']),
100+
child: Listener(
101+
onPointerDown: (e) {
102+
if (e.kind == PointerDeviceKind.mouse && e.buttons == kSecondaryMouseButton) {
103+
final text = terminal.selectedText;
104+
terminal.clearSelection();
105+
terminal.refresh();
106+
Clipboard.setData(ClipboardData(text: text));
107+
}
108+
},
109+
child: TerminalView(
110+
terminal: terminal,
111+
style: TerminalStyle(fontFamily: ['Cascadia Mono']),
112+
),
102113
),
103114
),
104115
);

lib/terminal/terminal.dart

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ class Terminal
501501
}
502502

503503
void selectWordOrRow(Position position) {
504-
if (position.y > buffer.lines.length) {
504+
if (position.y >= buffer.lines.length) {
505505
return;
506506
}
507507

@@ -558,25 +558,23 @@ class Terminal
558558
}
559559

560560
final builder = StringBuffer();
561+
final yStart = max(_selection.start!.y, 0);
562+
final yEnd = min(_selection.end!.y, buffer.height - 1);
561563

562-
for (var row = _selection.start!.y; row <= _selection.end!.y; row++) {
563-
if (row >= buffer.height) {
564-
break;
565-
}
566-
564+
for (var row = yStart; row <= yEnd; row++) {
567565
final line = buffer.lines[row];
568566

569567
var xStart = 0;
570568
var xEnd = viewWidth - 1;
571569

572-
if (row == _selection.start!.y) {
573-
xStart = _selection.start!.x;
570+
if (row == yStart) {
571+
xStart = max(_selection.start!.x, 0);
574572
} else if (!line.isWrapped) {
575573
builder.write("\n");
576574
}
577575

578-
if (row == _selection.end!.y) {
579-
xEnd = _selection.end!.x;
576+
if (row == yEnd) {
577+
xEnd = min(_selection.end!.x, terminalWidth);
580578
}
581579

582580
for (var col = xStart; col <= xEnd; col++) {
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import 'dart:math' show max;
2+
import 'package:flutter_test/flutter_test.dart';
3+
import 'package:xterm/mouse/position.dart';
4+
import 'package:xterm/xterm.dart';
5+
6+
7+
void main() async {
8+
9+
group("Terminal selection test", () {
10+
11+
const text = ""
12+
"Hello World!\r\n"
13+
"This is beautiful plugin!";
14+
final linesLength = text.split('\n').length;
15+
final maxLengthInLine = text.split('\n').fold<int>(0, (pre, e) => max(pre, e.length));
16+
17+
test("Select in normal range", () {
18+
final terminal = Terminal(maxLines: 100);
19+
terminal.write(text);
20+
terminal.selection!.init(Position(0, 0));
21+
terminal.selection!.update(Position(maxLengthInLine, linesLength));
22+
expect(terminal.getSelectedText(), text.replaceAll('\r', '') + "\n");
23+
});
24+
25+
test("Select beyond the boundary", () {
26+
final terminal = Terminal(maxLines: 100);
27+
terminal.write(text);
28+
terminal.selection!.init(Position(-3, -7));
29+
terminal.selection!.update(Position(maxLengthInLine + 8, linesLength));
30+
expect(terminal.getSelectedText(), text.replaceAll('\r', '') + "\n");
31+
});
32+
});
33+
}

0 commit comments

Comments
 (0)