diff --git a/javascript/packages/language-server/src/formatting_service.ts b/javascript/packages/language-server/src/formatting_service.ts index 7948e4c5e..7cc95b6d2 100644 --- a/javascript/packages/language-server/src/formatting_service.ts +++ b/javascript/packages/language-server/src/formatting_service.ts @@ -382,10 +382,6 @@ export class FormattingService { }).join('\n') } - if (!formattedText.endsWith('\n')) { - formattedText += '\n' - } - if (formattedText === rangeText) { return [] } diff --git a/javascript/packages/language-server/test/formatting_service.test.ts b/javascript/packages/language-server/test/formatting_service.test.ts index 8975459e2..efd139ddc 100644 --- a/javascript/packages/language-server/test/formatting_service.test.ts +++ b/javascript/packages/language-server/test/formatting_service.test.ts @@ -200,6 +200,31 @@ describe('FormattingService', () => { expect(result[0].newText).toBe(expected) }) + + it('should add trailing newline to formatted document', async () => { + vi.mocked(settings.getDocumentSettings).mockResolvedValue({} as any) + + const input = '
test
' + const document = TextDocument.create('file:///test/file.erb', 'erb', 1, input) + vi.mocked(documents.get).mockReturnValue(document) + + const result = await formattingService.formatDocument(params) + + expect(result[0].newText).toBe('
test
\n') + expect(result[0].newText.endsWith('\n')).toBe(true) + }) + + it('should add trailing newline even when input already has content after last tag', async () => { + vi.mocked(settings.getDocumentSettings).mockResolvedValue({} as any) + + const input = '
test
extra' + const document = TextDocument.create('file:///test/file.erb', 'erb', 1, input) + vi.mocked(documents.get).mockReturnValue(document) + + const result = await formattingService.formatDocument(params) + + expect(result[0].newText.endsWith('\n')).toBe(true) + }) }) describe('formatDocumentIgnoreConfig', () => { @@ -354,6 +379,67 @@ describe('FormattingService', () => { expect(result[0].newText).toMatch(/^\s*test<\/span>/) } }) + + it('should NOT add trailing newline to range-formatted text', async () => { + vi.mocked(settings.getDocumentSettings).mockResolvedValue({} as any) + + const input = '
test
' + const document = TextDocument.create('file:///test/file.erb', 'erb', 1, input) + vi.mocked(documents.get).mockReturnValue(document) + + const range: Range = { + start: Position.create(0, 12), + end: Position.create(0, 12) + } + + const params = createRangeParams(range) + const result = await formattingService.formatRange(params) + + if (result.length > 0) { + expect(result[0].newText.endsWith('\n')).toBe(false) + } + }) + + it('should NOT add trailing newline when formatting a simple range (issue #1125)', async () => { + vi.mocked(settings.getDocumentSettings).mockResolvedValue({} as any) + + const input = '
content
' + const document = TextDocument.create('file:///test/file.erb', 'erb', 1, input) + vi.mocked(documents.get).mockReturnValue(document) + + const range: Range = { + start: Position.create(0, 5), + end: Position.create(0, 25) + } + + const params = createRangeParams(range) + const result = await formattingService.formatRange(params) + + if (result.length > 0) { + expect(result[0].newText.endsWith('\n')).toBe(false) + } + }) + + it('should preserve original trailing whitespace behavior in range formatting', async () => { + vi.mocked(settings.getDocumentSettings).mockResolvedValue({} as any) + + const input = '

Hello

' + const document = TextDocument.create('file:///test/file.erb', 'erb', 1, input) + vi.mocked(documents.get).mockReturnValue(document) + + const range: Range = { + start: Position.create(0, 0), + end: Position.create(0, 12) + } + + const params = createRangeParams(range) + const result = await formattingService.formatRange(params) + + if (result.length > 0) { + expect(result[0].newText).toBe('

Hello

') + expect(result[0].newText.endsWith('\n')).toBe(false) + } + }) }) describe('formatRangeIgnoreConfig', () => { @@ -412,7 +498,7 @@ describe('FormattingService', () => { '

\n' + ' some <%= formatted %> text, that needs <% needs %> <% to_be_formatted %>\n' + ' without being reset to the start of the line.\n' + - '

\n' + '

' ) }) })