Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: keep selection on formatting #372

Merged
merged 9 commits into from
Jan 30, 2025
17 changes: 10 additions & 7 deletions src/DocumentWatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
TextEditorOptions,
window,
workspace,
WorkspaceEdit,
} from 'vscode'
import {
InsertFinalNewline,
Expand Down Expand Up @@ -75,18 +76,20 @@ export default class DocumentWatcher {
const activeEditor = window.activeTextEditor
const activeDoc = activeEditor?.document
if (activeDoc && activeDoc === e.document && activeEditor) {
selections = activeEditor.selections
selections = [...activeEditor.selections]
}
const transformations = this.calculatePreSaveTransformations(
e.document,
e.reason,
)
e.waitUntil(transformations)
if (selections.length) {
const edits = await transformations
if (activeEditor && edits.length) {
activeEditor.selections = selections
}

const workspaceEdit = new WorkspaceEdit()
const textEdits = await transformations
workspaceEdit.set(e.document.uri, textEdits)
await workspace.applyEdit(workspaceEdit)

if (activeEditor && textEdits.length && selections.length) {
activeEditor.selections = selections
}
}),
)
Expand Down
40 changes: 32 additions & 8 deletions src/test/suite/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as assert from 'assert'
import * as os from 'os'
import { Position, window, workspace, WorkspaceEdit } from 'vscode'
import { Position, window, workspace, WorkspaceEdit, Uri } from 'vscode'
import { getFixturePath, getOptionsForFixture, wait } from '../testUtils'

import * as utils from 'vscode-test-utils'
Expand Down Expand Up @@ -284,22 +284,42 @@ suite('EditorConfig extension', function () {
`editor has insertSpaces: ${options.insertSpaces}`,
)
})

test('keep selection on format', async () => {
await withSetting('insert_final_newline', 'true', {
fileName: 'test-selection',
}).saveText('foobar')
assert(window.activeTextEditor, 'no active editor')

// Before saving, the selection is on line 0. This should remain unchanged.
assert.strictEqual(
SunsetTechuila marked this conversation as resolved.
Show resolved Hide resolved
window.activeTextEditor.selection.start.line,
0,
'editor selection start line changed',
)
assert.strictEqual(
window.activeTextEditor.selection.end.line,
0,
'editor selection end line changed',
)
SunsetTechuila marked this conversation as resolved.
Show resolved Hide resolved
})
})

function withSetting(
rule: string,
value: string,
options: {
contents?: string
fileName?: string
} = {},
) {
return {
async getText() {
return (await createDoc(options.contents)).getText()
return (await createDoc(options.contents, options.fileName)).getText()
},
saveText(text: string) {
return new Promise<string>(async resolve => {
const doc = await createDoc(options.contents)
const doc = await createDoc(options.contents, options.fileName)
workspace.onDidChangeTextDocument(doc.save)
workspace.onDidSaveTextDocument(savedDoc => {
assert.strictEqual(savedDoc.isDirty, false, 'dirty saved doc')
Expand All @@ -315,12 +335,16 @@ function withSetting(
})
},
}
async function createDoc(contents = '', name = 'test') {
const fixturePath = getFixturePath([rule, value, name])

async function createDoc(contents = '') {
const uri = await utils.createFile(
contents,
getFixturePath([rule, value, 'test']),
)
try {
await workspace.fs.delete(Uri.file(fixturePath))
} catch {
// ignore
}

const uri = await utils.createFile(contents, fixturePath)
const doc = await workspace.openTextDocument(uri)
await window.showTextDocument(doc)
await wait(50) // wait for EditorConfig to apply new settings
Expand Down