Ensure correct coordinate ordering in selection file write (#4078)

## Description

Fix an issue where `write_selection_file` would create empty files when
selecting multiple lines. This occurred because the selection
coordinates were not properly ordered when writing to file.

## Problem

When selecting multiple lines from bottom to top , the resulting file
would be empty. This happened because:

1. Selection coordinates were used directly without proper ordering

2. `start()` and `end()` don't guarantee top-to-bottom, left-to-right
ordering

## Solution

Use `topLeft()` and `bottomRight()` methods to ensure correct coordinate
ordering when writing selection to file.


## Testing

Tested the following scenarios:

- Selecting multiple lines from top to bottom 

- Selecting multiple lines from bottom to top 


## Known Behavior

When selecting a single word, the entire line containing that word is
written to the file. This is consistent with the current terminal
behavior as noted in the [original
discussion](https://github.com/ghostty-org/ghostty/discussions/3594).

Fixes ghostty-org/ghostty#3594
This commit is contained in:
Mitchell Hashimoto
2024-12-30 10:51:38 -08:00
committed by GitHub
2 changed files with 17 additions and 2 deletions

View File

@ -4293,11 +4293,16 @@ fn writeScreenFile(
tmp_dir.deinit();
return;
};
// Use topLeft and bottomRight to ensure correct coordinate ordering
const tl = sel.topLeft(&self.io.terminal.screen);
const br = sel.bottomRight(&self.io.terminal.screen);
try self.io.terminal.screen.dumpString(
buf_writer.writer(),
.{
.tl = sel.start(),
.br = sel.end(),
.tl = tl,
.br = br,
.unwrap = true,
},
);

View File

@ -3413,6 +3413,16 @@ pub const Pin = struct {
direction: Direction,
limit: ?Pin,
) PageIterator {
if (build_config.slow_runtime_safety) {
if (limit) |l| {
// Check the order according to the iteration direction.
switch (direction) {
.right_down => assert(self.eql(l) or self.before(l)),
.left_up => assert(self.eql(l) or l.before(self)),
}
}
}
return .{
.row = self,
.limit = if (limit) |p| .{ .row = p } else .{ .none = {} },