Skip to content

Commit

Permalink
Implement Document Formatting (#1732)
Browse files Browse the repository at this point in the history
* Implement Document Formatting

* Update changelog

* Remove unused parameters
  • Loading branch information
aslakhellesoy authored Sep 7, 2021
1 parent 190ba22 commit a839120
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 0 deletions.
4 changes: 4 additions & 0 deletions language-server/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Added

* Document Formatting
([#1732](https://github.com/cucumber/common/pull/1732)
[aslakhellesoy])

### Changed

### Deprecated
Expand Down
8 changes: 8 additions & 0 deletions language-server/javascript/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
TextDocumentPositionParams,
TextDocuments,
TextDocumentSyncKind,
TextEdit,
} from 'vscode-languageserver/node'

import { TextDocument } from 'vscode-languageserver-textdocument'
Expand All @@ -17,6 +18,7 @@ import {
getGherkinCompletionItems,
getGherkinDiagnostics,
getGherkinSemanticTokens,
getGherkinFormattingEdits,
semanticTokenModifiers,
semanticTokenTypes,
} from '@cucumber/language-service'
Expand Down Expand Up @@ -77,6 +79,7 @@ connection.onInitialize(async (params: InitializeParams) => {
},
}
: undefined,
documentFormattingProvider: true,
},
}
if (hasWorkspaceFolderCapability) {
Expand Down Expand Up @@ -164,6 +167,11 @@ connection.languages.semanticTokens.on((semanticTokenParams: SemanticTokensParam
return getGherkinSemanticTokens(gherkinSource, indexAndExpressions.expressions)
})

connection.onDocumentFormatting(async (params): Promise<TextEdit[]> => {
const gherkinSource = documents.get(params.textDocument.uri).getText()
return getGherkinFormattingEdits(gherkinSource)
})

documents.listen(connection)

connection.listen()
4 changes: 4 additions & 0 deletions language-service/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Added

* Document Formatting
([#1732](https://github.com/cucumber/common/pull/1732)
[aslakhellesoy])

### Changed

### Deprecated
Expand Down
1 change: 1 addition & 0 deletions language-service/javascript/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ and [Cucumber Monaco](../../monaco/javascript).

## Supported features

- [x] Formatting / pretty printing
- [x] Handle parse errors
- [x] Code completion
- [x] Steps
Expand Down
26 changes: 26 additions & 0 deletions language-service/javascript/src/getGherkinFormattingEdits.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { TextEdit } from "vscode-languageserver-types";
import { parseGherkinDocument } from './parseGherkinDocument'
import { pretty } from '@cucumber/gherkin-utils'

// https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#textDocument_formatting
export function getGherkinFormattingEdits(gherkinSource: string): TextEdit[] {
const { gherkinDocument } = parseGherkinDocument(gherkinSource)
const newText = pretty(gherkinDocument)
const lines = gherkinSource.split(/\r?\n/)
const line = lines.length - 1
const character = lines[line].length
const textEdit: TextEdit = {
newText,
range: {
start: {
line: 0,
character: 0
},
end: {
line,
character
}
}
}
return [textEdit]
}
1 change: 1 addition & 0 deletions language-service/javascript/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './getGherkinSemanticTokens'
export * from './getGherkinDiagnostics'
export * from './getGherkinCompletionItems'
export * from './getGherkinFormattingEdits'
30 changes: 30 additions & 0 deletions language-service/javascript/test/getGherkinFormattingEdits.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import assert from 'assert'
import { TextEdit } from 'vscode-languageserver-types'
import { getGherkinFormattingEdits } from '../src'

describe('getGherkinFormattingEdits', () => {
it('returns text edits that prettifies a Gherkin document', () => {
const gherkinSource = `Feature: Hello
Scenario: World
Given something`
const textEdits = getGherkinFormattingEdits(gherkinSource)
const expectedTextEdit: TextEdit = {
newText: `Feature: Hello
Scenario: World
Given something
`,
range: {
start: {
line: 0,
character: 0,
},
end: {
line: 2,
character: 15
}
}
}
assert.deepStrictEqual([expectedTextEdit], textEdits)
})
})
4 changes: 4 additions & 0 deletions monaco/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Added

* Document Formatting
([#1732](https://github.com/cucumber/common/pull/1732)
[aslakhellesoy])

### Changed

### Deprecated
Expand Down
11 changes: 11 additions & 0 deletions monaco/javascript/example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@
<title>Cucumber Monaco</title>
</head>
<body>
<h1>
Monaco Editor with Cucumber Plugin
</h1>
<p>
Things you can try:
</p>
<ul>
<li>⇧⌥F - Format Document</li>
<li>Modify the first step and see it underlined as undefined</li>
<li>Type a new step and see auto-complete suggestions</li>
</ul>
<script src="./main.bundle.js"></script>
</body>
</html>
2 changes: 2 additions & 0 deletions monaco/javascript/example/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ Feature: Hello
Scenario: Hi
Given I have 58 cukes in my belly
And this is an undefined step
| some | poorly |
| formatted | table |
`,
language: 'gherkin',
theme: 'vs-dark',
Expand Down
18 changes: 18 additions & 0 deletions monaco/javascript/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
getGherkinCompletionItems,
getGherkinDiagnostics,
getGherkinSemanticTokens,
getGherkinFormattingEdits,
semanticTokenModifiers,
semanticTokenTypes
} from '@cucumber/language-service'
Expand Down Expand Up @@ -85,4 +86,21 @@ export function configure(monaco: Monaco, index: Index | undefined, expressions:
}
}
})

// Document Formatting
monaco.languages.registerDocumentFormattingEditProvider('gherkin', {
provideDocumentFormattingEdits: function (model) {
const gherkinSource = model.getValue()
const textEdits = getGherkinFormattingEdits(gherkinSource)
return textEdits.map(textEdit => ({
range: {
startLineNumber: textEdit.range.start.line + 1,
startColumn: textEdit.range.start.character + 1,
endLineNumber: textEdit.range.end.line + 1,
endColumn: textEdit.range.end.character + 1,
},
text: textEdit.newText
}))
}
})
}

0 comments on commit a839120

Please sign in to comment.