Change:
Currently: What it should be: Row 4 is not considered a line, at least not according to the , so it shouldn't be numbered. (Atom issue ) Edit: You might also consider not showing the final line number unless the line is correctly terminated, or, displaying an icon as suggested in comment. However, this might "upset" certain users, so it should probably be configurable.
While I agree that files should have a new line at the end, wouldn't forcing this disallow saving files without the terminating new line character?
This has no effect on file saving, it's just about the display of line numbers.
So the line would still be there, just not the line number?
Yes, but it's not technically a "line", it's just an area that can receive focus for text entry.
what is your opinion?
IMHO not rendering the last line number would be confusing, both for users and extension authors, as the last line can be interacted with (e.g. an extension can create edits on it, asking for line count at the API level would return it). I really like the brief technical explanation from POSIX, but then if I understand correctly: Perhaps the intent of the issue is that the editor should never lead to a situation where a file is not terminated with a newline. In that case, I would treat the end of file newline in a similar way we treat the UTF8 BOM. The BOM is completely hidden in the model (cannot be interacted with or moved whatsoever) and when the workbench calls it comes. Perhaps the end of file newline can be implemented in a similar way. i.e. "It is not there until saving to disk".
I can agree that some users would need to adjust to the change, because they may not be used to it. However, I still feel that it is the correct interpretation, as a line is defined as a series of non-newline characters followed by a newline character, which means that "row" 4 is not a line as defined, but merely a UI affordance (an area that can be focused in order to enter new lines of text). A UI area that represents no backing content. No characters, including newlines, are represented. In my understanding, it's essentially not part of the file. That may be the same way that VIM handles it. If I enter "Test" into a new file, and save, it saves with a trailing newline: If you open the file, it displays , and not 2 lines. This may be an even better way of handling it, so you wouldn't even be able to navigate to the 4th row without hitting enter, which might make more sense and be easier for users to understand. I prefer this actually.
As this option is not configurable, there is no easy way to prevent 'No newline at end of file' warnings when using Git in merges (or just when reviewing commits).
hm:
This issue is more about the display (or lack thereof) of the final newline, and not its insertion. i.e. Don't render a numbered blank line at the end of files.
Agreed. This is how vim does it too.
Coming from Vim, I'm also searching for an option that will automatically save a at end of file, but not an "empty line". More history at
Moving this back to editor, neither I nor the issue creator agrees on the change of summary. I think this should be a setting that only has an impact on how the display behaves, not how the file is saved.
Any update here? If this is not going to be changed in core is anyone aware of an extension that can prevent display of the last line like does for Atom?
I tried adding the settings and but they don't suppress the display of the final line. They ensure the file as the correct final newline though. Coming from vim as well, would be nice to have a settings. I was deleting them until I got lint errors because I'm not used to seeing them.
This is an annoying issue for people used to the behavior of most Linux text editors. There should be an option to suppress last blank line display.
Just like vim does by default. Also it has a binary mode that prevents the final newline from being if the user wants to, for a single file.
Cursor can still move to a line without line number. Is this expected? ! If so please remove the verification-found label.
Yes, that is expected. (we must respect existing API and extensions can place a cursor there, make edits there, etc.).
This change doesn't affect Windows, correct? Verified with Ubuntu.
It does if you set to (it's by default on non-Linux OSs).
thanks! Verified on Windows too.
Why is it not default everywhere? I've been adding an extra newline to files all day long without realizing that VS Code changed when I upgraded to 1.32. It took me quite a while before I figured out that could put the cursor on a line with no line number.
I here to say I hated this "breaking" change. I spent a whole day frustrated looking for the correct setting to I'm used to. You shouldn't change something people expect unconsciously to be there without notice.
I agree with and on this one. Nothing against adding the option for people who want it but the default should be to keep consistent with the old behaviour. Now there are people searching for how to "fix" it and opening tickets like .
The code in the merged PR returns an empty line number when the line content is an empty string, instead of when it doesn't end with a . i.e. The line number technically shouldn't be displayed even when you start typing (only when you hit enter). Also, shouldn't this be by default on Mac as well? Finally, I think that (to make it less confusing for users used to the old behaviour), an optional display character to indicate that the previous line ends with a could be helpful. !

Discussion:
private _lineHeight: number; private _renderLineNumbers: RenderLineNumbersType; private _renderCustomLineNumbers: ((lineNumber: number) => string) | null; <ins> private _renderFinalNewline: boolean; </ins> private _lineNumbersLeft: number; private _lineNumbersWidth: number; private _lastCursorModelPosition: Position;

this._lineHeight = config.lineHeight; this._renderLineNumbers = config.viewInfo.renderLineNumbers; this._renderCustomLineNumbers = config.viewInfo.renderCustomLineNumbers; <ins> this._renderFinalNewline = config.viewInfo.renderFinalNewline; </ins> this._lineNumbersLeft = config.layoutInfo.lineNumbersLeft; this._lineNumbersWidth = config.layoutInfo.lineNumbersWidth; }

} let modelLineNumber = modelPosition.lineNumber; <ins> if (!this._renderFinalNewline) { const lineCount = this._context.model.getLineCount(); const lineContent = this._context.model.getLineContent(modelLineNumber); if (modelLineNumber === lineCount && lineContent === '') { return ''; } } </ins> if (this._renderCustomLineNumbers) { return this._renderCustomLineNumbers(modelLineNumber); }

'default': 'on', 'description': nls.localize('lineNumbers', "Controls the display of line numbers.") }, <ins> 'editor.renderFinalNewline': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.viewInfo.renderFinalNewline, 'description': nls.localize('renderFinalNewline', "Render last line number when the file ends with a newline.") }, </ins> 'editor.rulers': { 'type': 'array', 'items': {

&& a.ariaLabel === b.ariaLabel && a.renderLineNumbers === b.renderLineNumbers && a.renderCustomLineNumbers === b.renderCustomLineNumbers <ins> && a.renderFinalNewline === b.renderFinalNewline </ins> && a.selectOnLineNumbers === b.selectOnLineNumbers && a.glyphMargin === b.glyphMargin && a.revealHorizontalRightPadding === b.revealHorizontalRightPadding

ariaLabel: _string(opts.ariaLabel, defaults.ariaLabel), renderLineNumbers: renderLineNumbers, renderCustomLineNumbers: renderCustomLineNumbers, <ins> renderFinalNewline: _boolean(opts.renderFinalNewline, defaults.renderFinalNewline), </ins> selectOnLineNumbers: _boolean(opts.selectOnLineNumbers, defaults.selectOnLineNumbers), glyphMargin: _boolean(opts.glyphMargin, defaults.glyphMargin), revealHorizontalRightPadding: _clampedInt(opts.revealHorizontalRightPadding, defaults.revealHorizontalRightPadding, 0, 1000),

ariaLabel: (accessibilityIsOff ? nls.localize('accessibilityOffAriaLabel', "The editor is not accessible at this time. Press Alt+F1 for options.") : opts.viewInfo.ariaLabel), renderLineNumbers: opts.viewInfo.renderLineNumbers, renderCustomLineNumbers: opts.viewInfo.renderCustomLineNumbers, <ins> renderFinalNewline: opts.viewInfo.renderFinalNewline, </ins> selectOnLineNumbers: opts.viewInfo.selectOnLineNumbers, glyphMargin: opts.viewInfo.glyphMargin, revealHorizontalRightPadding: opts.viewInfo.revealHorizontalRightPadding,

ariaLabel: nls.localize('editorViewAccessibleLabel', "Editor content"), renderLineNumbers: RenderLineNumbersType.On, renderCustomLineNumbers: null, <ins> renderFinalNewline: (platform.isLinux ? false : true), </ins> selectOnLineNumbers: true, glyphMargin: true, revealHorizontalRightPadding: 30,

*/ lineNumbers?: 'on' | 'off' | 'relative' | 'interval' | ((lineNumber: number) => string); /** <ins> * Render last line number when the file ends with a newline. * Defaults to true on Windows/Mac and to false on Linux. */ renderFinalNewline?: boolean; /** </ins> * Should the corresponding line be selected when clicking on the line number? * Defaults to true. */

readonly ariaLabel: string; readonly renderLineNumbers: RenderLineNumbersType; readonly renderCustomLineNumbers: ((lineNumber: number) => string) | null; <ins> readonly renderFinalNewline: boolean; </ins> readonly selectOnLineNumbers: boolean; readonly glyphMargin: boolean; readonly revealHorizontalRightPadding: number;