Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions src/client/gui/lib/vm_details/terminal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,10 @@ class ResetTerminalFontIntent extends Intent {
const ResetTerminalFontIntent();
}

class SelectAllTerminalTextIntent extends Intent {
const SelectAllTerminalTextIntent();
}

class _VmTerminalState extends ConsumerState<VmTerminal> {
static const defaultFontSize = 13.0;
static const minFontSize = 2.5;
Expand Down Expand Up @@ -286,6 +290,16 @@ class _VmTerminalState extends ConsumerState<VmTerminal> {
);
},
),
ContextMenuButtonItem(
label: 'Select All',
onPressed: () {
ContextMenuController.removeAny();
Actions.maybeInvoke(
context,
const SelectAllTerminalTextIntent(),
);
},
),
];

final style = Theme.of(context).textButtonTheme.style?.copyWith(
Expand Down Expand Up @@ -405,6 +419,45 @@ class _VmTerminalState extends ConsumerState<VmTerminal> {
return null;
},
),
SelectAllTerminalTextIntent: CallbackAction<SelectAllTerminalTextIntent>(
onInvoke: (_) async {
// Select all text in the terminal buffer
final buffer = terminal.buffer;

// Check if there's any content to select
if (buffer.height == 0) return null;

// Find the last line with actual content
int lastContentLine = buffer.height - 1;
for (int i = buffer.height - 1; i >= 0; i--) {
final line = buffer.lines[i];
// Check if the line has any non-empty content
bool hasContent = false;
for (int j = 0; j < line.length; j++) {
if (line.getCodePoint(j) != 0 && line.getCodePoint(j) != 32) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if there is a nicer way to do this, but it seems LineBuffer is not trivially iterable and ' '.runes.first isn't much better than 32

// not null and not space
hasContent = true;
break;
}
}
if (hasContent) {
lastContentLine = i;
break;
}
}

// Create a selection from the first line to the last line with content
// Start from the first line, first column
final start = buffer.createAnchor(0, 0);
// End at the last content line, last column
final end =
buffer.createAnchor(buffer.viewWidth - 1, lastContentLine);

// Set the selection to cover all meaningful text
terminalController.setSelection(start, end);
return null;
},
),
};

return Actions(actions: terminalActions, child: scrollableTerminal);
Expand Down
Loading