Skip to content

Commit ffe8674

Browse files
committed
Made a selection that ends on a new line end at the end of the previous line.
1 parent f1ec882 commit ffe8674

File tree

4 files changed

+100
-11
lines changed

4 files changed

+100
-11
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Changes
44

55
- 🐛 GitHub links now prevent markdown files from being rendered.
6+
- 🐛 Selections that end at the start of a new line are adjusted to end at the end of the previous line.
67

78
# 2.5.0 (2021-04-11)
89

src/commands/get-link-command.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { NoRemoteHeadError } from '../no-remote-head-error';
77
import { RepositoryFinder } from '../repository-finder';
88
import { STRINGS } from '../strings';
99
import { LinkType, Repository, RepositoryWithRemote, SelectedRange } from '../types';
10-
import { hasRemote, toSelectedRange } from '../utilities';
10+
import { getSelectedRange, hasRemote } from '../utilities';
1111

1212
/**
1313
* The command to get a URL from a file.
@@ -62,7 +62,7 @@ export class GetLinkCommand {
6262
// selection from the active editor, so we'll only include the selection
6363
// if the file we are generating the link for is in the active editor.
6464
if (resource.toString() === editor?.document.uri.toString()) {
65-
selection = toSelectedRange(editor.selection);
65+
selection = getSelectedRange(editor);
6666
log('Line selection: %o', selection);
6767
}
6868
}

src/utilities.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Position, Selection } from 'vscode';
1+
import { Position, Selection, TextEditor } from 'vscode';
22

33
import { Repository, RepositoryWithRemote, SelectedRange } from './types';
44

@@ -96,19 +96,31 @@ function hasMessage(err: unknown): err is { message: string } {
9696
}
9797

9898
/**
99-
* Converts a `Selection` to a `SelectedRange`.
99+
* Gets the `SelectedRange` from the editor's selection.
100100
*
101-
* @param selection The selection to convert.
101+
* @param editor The editor to get the selection from.
102102
* @returns The selected range.
103103
*/
104-
export function toSelectedRange(selection: Selection): SelectedRange {
104+
export function getSelectedRange(editor: TextEditor): SelectedRange {
105+
let start: Position;
106+
let end: Position;
107+
108+
start = editor.selection.start;
109+
end = editor.selection.end;
110+
111+
// If the selection ends at the start of a new line,
112+
// then change it to end at the end of the previous line.
113+
if (end.line > start.line && end.character === 0) {
114+
end = editor.document.lineAt(end.line - 1).range.end;
115+
}
116+
105117
// The line numbers are zero-based in the editor,
106118
// but we need them to be one-based for URLs.
107119
return {
108-
startLine: selection.start.line + 1,
109-
endLine: selection.end.line + 1,
110-
startColumn: selection.start.character + 1,
111-
endColumn: selection.end.character + 1
120+
startLine: start.line + 1,
121+
endLine: end.line + 1,
122+
startColumn: start.character + 1,
123+
endColumn: end.character + 1
112124
};
113125
}
114126

test/utilities.test.ts

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import assert = require('assert');
12
import { expect } from 'chai';
3+
import { commands, Position, Selection, TextEditor, window } from 'vscode';
24

3-
import { hasRemote, normalizeUrl } from '../src/utilities';
5+
import { getSelectedRange, hasRemote, normalizeUrl, toSelection } from '../src/utilities';
46

57
describe('utilities', () => {
68
describe('hasRemote', () => {
@@ -50,4 +52,78 @@ describe('utilities', () => {
5052
expect(normalizeUrl('ssh://example.com/')).to.equal('example.com');
5153
});
5254
});
55+
56+
describe('getSelectedRange', () => {
57+
let editor: TextEditor;
58+
59+
before(async () => {
60+
await commands.executeCommand('openEditors.newUntitledFile');
61+
62+
assert(window.activeTextEditor !== undefined);
63+
editor = window.activeTextEditor;
64+
65+
await editor.edit((b) => {
66+
b.insert(
67+
new Position(0, 0),
68+
['first line', 'second', 'third', 'fourth line', 'fifth'].join('\n')
69+
);
70+
});
71+
});
72+
73+
after(async () => {
74+
await commands.executeCommand('workbench.action.closeActiveEditor');
75+
});
76+
77+
it('should convert to one-based values.', () => {
78+
editor.selection = new Selection(new Position(1, 2), new Position(3, 4));
79+
80+
expect(getSelectedRange(editor)).to.deep.equal({
81+
startLine: 2,
82+
startColumn: 3,
83+
endLine: 4,
84+
endColumn: 5
85+
});
86+
});
87+
88+
it('should return correct value when selection is single point at the start of the line.', () => {
89+
editor.selection = new Selection(new Position(1, 0), new Position(1, 0));
90+
91+
expect(getSelectedRange(editor)).to.deep.equal({
92+
startLine: 2,
93+
startColumn: 1,
94+
endLine: 2,
95+
endColumn: 1
96+
});
97+
});
98+
99+
it('should return correct value when selection is a single line.', () => {
100+
editor.selection = new Selection(new Position(3, 2), new Position(3, 5));
101+
102+
expect(getSelectedRange(editor)).to.deep.equal({
103+
startLine: 4,
104+
startColumn: 3,
105+
endLine: 4,
106+
endColumn: 6
107+
});
108+
});
109+
110+
it('should exclude the last line if selection ends at the start of a new line.', () => {
111+
editor.selection = new Selection(new Position(2, 0), new Position(3, 0));
112+
113+
expect(getSelectedRange(editor)).to.deep.equal({
114+
startLine: 3,
115+
startColumn: 1,
116+
endLine: 3,
117+
endColumn: 6
118+
});
119+
});
120+
});
121+
122+
describe('toSelection', () => {
123+
it('should convert to zero-based values.', () => {
124+
expect(
125+
toSelection({ startLine: 10, startColumn: 20, endLine: 30, endColumn: 40 })
126+
).to.deep.equal(new Selection(new Position(9, 19), new Position(29, 39)));
127+
});
128+
});
53129
});

0 commit comments

Comments
 (0)