Skip to content

Commit

Permalink
feat(commands): add insertFinalNewLine
Browse files Browse the repository at this point in the history
  • Loading branch information
SunsetTechuila committed Feb 19, 2025
1 parent 8261885 commit 1942a30
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 0 deletions.
54 changes: 54 additions & 0 deletions src/vs/editor/common/commands/insertFinalNewLineCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import * as strings from '../../../base/common/strings.js';
import { EditOperation, ISingleEditOperation } from '../core/editOperation.js';
import { Position } from '../core/position.js';
import { Selection } from '../core/selection.js';
import { ICommand, ICursorStateComputerData, IEditOperationBuilder } from '../editorCommon.js';
import { ITextModel } from '../model.js';

export class InsertFinalNewLineCommand implements ICommand {

private readonly _selection: Selection;
private _selectionId: string | null;


constructor(selection: Selection) {
this._selection = selection;
this._selectionId = null;
}

public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void {
const op = insertFinalNewLine(model);
if (op) {
builder.addEditOperation(op.range, op.text);
}
this._selectionId = builder.trackSelection(this._selection);
}

public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection {
return helper.getTrackedSelection(this._selectionId!);
}
}

/**
* Generate edit operations for inserting a final new line if needed.
* Returns undefined if no edit is needed.
*/
export function insertFinalNewLine(model: ITextModel): ISingleEditOperation | undefined {
const lineCount = model.getLineCount();
const lastLine = model.getLineContent(lineCount);
const lastLineIsEmptyOrWhitespace = strings.lastNonWhitespaceIndex(lastLine) === -1;

if (!lineCount || lastLineIsEmptyOrWhitespace) {
return undefined;
}

return EditOperation.insert(
new Position(lineCount, model.getLineMaxColumn(lineCount)),
model.getEOL()
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { ICodeEditor } from '../../../browser/editorBrowser.js';
import { EditorAction, registerEditorAction, ServicesAccessor } from '../../../browser/editorExtensions.js';
import { InsertFinalNewLineCommand } from '../../../common/commands/insertFinalNewLineCommand.js';
import { EditorContextKeys } from '../../../common/editorContextKeys.js';
import * as nls from '../../../../nls.js';

export class InsertFinalNewLineAction extends EditorAction {

public static readonly ID = 'editor.action.insertFinalNewLine';

constructor() {
super({
id: InsertFinalNewLineAction.ID,
label: nls.localize2('insertFinalNewLine', "Insert Final New Line"),
precondition: EditorContextKeys.writable
});
}

public run(_accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
const selection = editor.getSelection();
if (selection === null) {
return;
}

const command = new InsertFinalNewLineCommand(selection);

editor.pushUndoStop();
editor.executeCommands(this.id, [command]);
editor.pushUndoStop();

if (args.reason === 'auto-save') {
// See https://github.com/editorconfig/editorconfig-vscode/issues/330
// It is very convenient for the editor config extension to invoke this action.
// So, if we get a reason:'auto-save' passed in, let's set cursor back to initial position after inserting final new line.
editor.setSelection(selection);
}
}
}

registerEditorAction(InsertFinalNewLineAction);
1 change: 1 addition & 0 deletions src/vs/editor/editor.all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import './contrib/hover/browser/hoverContribution.js';
import './contrib/indentation/browser/indentation.js';
import './contrib/inlayHints/browser/inlayHintsContribution.js';
import './contrib/inPlaceReplace/browser/inPlaceReplace.js';
import './contrib/insertFinalNewLine/browser/insertFinalNewLine.js';
import './contrib/lineSelection/browser/lineSelection.js';
import './contrib/linesOperations/browser/linesOperations.js';
import './contrib/linkedEditing/browser/linkedEditing.js';
Expand Down

0 comments on commit 1942a30

Please sign in to comment.