Skip to content

Commit e5b8024

Browse files
committed
Add 'and' keyword autoformatting
1 parent c469828 commit e5b8024

File tree

4 files changed

+64
-26
lines changed

4 files changed

+64
-26
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
## Improvements:
44

5+
* Update autoformatting to replace sequential equivalent keywords with the `And` keyword
6+
57
## Bug fixes:
68

79
* Fix: Error message box when creating feature file with space in its name (#50)
810

9-
*Contributors of this release (in alphabetical order):* @gasparnagy
11+
*Contributors of this release (in alphabetical order):* @gasparnagy, @jdb0123
1012

1113
# v2024.7.204 - 2024-11-20
1214

Reqnroll.VisualStudio/Editor/Services/Formatting/GherkinDocumentFormatter.cs

Lines changed: 55 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,18 @@ public class GherkinDocumentFormatter
88
public void FormatGherkinDocument(DeveroomGherkinDocument gherkinDocument, DocumentLinesEditBuffer lines,
99
GherkinFormatSettings formatSettings)
1010
{
11-
if (gherkinDocument.Feature != null)
12-
{
13-
SetTagsAndLine(lines, gherkinDocument.Feature, string.Empty);
14-
SetLinesForChildren(lines, gherkinDocument.Feature.Children, formatSettings,
15-
formatSettings.FeatureChildrenIndentLevel);
16-
}
11+
if (gherkinDocument.Feature == null)
12+
return;
13+
14+
SetTagsAndLine(lines, gherkinDocument.Feature, string.Empty);
15+
SetLinesForChildren(lines, gherkinDocument.Feature.Children, formatSettings, formatSettings.FeatureChildrenIndentLevel);
1716
}
1817

1918
private void SetLinesForChildren(DocumentLinesEditBuffer lines, IEnumerable<IHasLocation> hasLocation,
2019
GherkinFormatSettings formatSettings, int indentLevel)
2120
{
21+
var dialectProvider = ReqnrollGherkinDialectProvider.Get(formatSettings.Language);
22+
2223
foreach (var featureChild in hasLocation)
2324
{
2425
SetTagsAndLine(lines, featureChild, GetIndent(formatSettings, indentLevel));
@@ -37,24 +38,55 @@ private void SetLinesForChildren(DocumentLinesEditBuffer lines, IEnumerable<IHas
3738
examplesBlockIndentLevel + formatSettings.ExamplesTableIndentLevelWithinExamplesBlock);
3839
}
3940

40-
if (featureChild is IHasSteps hasSteps)
41-
foreach (var step in hasSteps.Steps)
42-
{
43-
var stepIndentLevel = indentLevel + formatSettings.StepIndentLevelWithinStepContainer;
44-
if (step is DeveroomGherkinStep deveroomGherkinStep &&
45-
(deveroomGherkinStep.StepKeyword == StepKeyword.And ||
46-
deveroomGherkinStep.StepKeyword == StepKeyword.But))
47-
stepIndentLevel += formatSettings.AndStepIndentLevelWithinSteps;
48-
SetLine(lines, step, $"{GetIndent(formatSettings, stepIndentLevel)}{step.Keyword}{step.Text}");
49-
if (step.Argument is DataTable dataTable)
50-
FormatTable(lines, dataTable, formatSettings,
51-
stepIndentLevel + formatSettings.DataTableIndentLevelWithinStep);
52-
53-
if (step.Argument is DocString docString)
54-
FormatDocString(lines, docString, formatSettings,
55-
stepIndentLevel + formatSettings.DocStringIndentLevelWithinStep);
56-
}
41+
if (featureChild is IHasSteps hasSteps)
42+
FormatSteps(lines, formatSettings, indentLevel, hasSteps, dialectProvider);
43+
}
44+
}
45+
46+
private void FormatSteps(DocumentLinesEditBuffer lines, GherkinFormatSettings formatSettings, int indentLevel,
47+
IHasSteps hasSteps, GherkinDialectProvider dialectProvider)
48+
{
49+
var previousKeyword = "";
50+
51+
foreach (var step in hasSteps.Steps)
52+
{
53+
var stepIndentLevel = indentLevel + formatSettings.StepIndentLevelWithinStepContainer;
54+
55+
var newKeyword = step.Keyword;
56+
57+
if (step is DeveroomGherkinStep { StepKeyword: StepKeyword.And or StepKeyword.But })
58+
{
59+
stepIndentLevel += formatSettings.AndStepIndentLevelWithinSteps;
60+
}
61+
else
62+
{
63+
if (step.Keyword == previousKeyword)
64+
{
65+
var andKeyword = GetAndKeyword(dialectProvider);
66+
newKeyword = $"{andKeyword}";
67+
}
68+
else
69+
previousKeyword = step.Keyword;
70+
}
71+
72+
73+
SetLine(lines, step, $"{GetIndent(formatSettings, stepIndentLevel)}{newKeyword}{step.Text}");
74+
75+
switch (step.Argument)
76+
{
77+
case DataTable dataTable:
78+
FormatTable(lines, dataTable, formatSettings, stepIndentLevel + formatSettings.DataTableIndentLevelWithinStep);
79+
break;
80+
case DocString docString:
81+
FormatDocString(lines, docString, formatSettings, stepIndentLevel + formatSettings.DocStringIndentLevelWithinStep);
82+
break;
5783
}
84+
}
85+
}
86+
87+
private static string GetAndKeyword(GherkinDialectProvider dialectProvider)
88+
{
89+
return dialectProvider.DefaultDialect.AndStepKeywords.First(keyword => keyword != GherkinDialect.AsteriskKeyword);
5890
}
5991

6092
private void SetTagsAndLine(DocumentLinesEditBuffer lines, IHasLocation hasLocation, string indent)

Reqnroll.VisualStudio/Editor/Services/Formatting/GherkinFormatSettings.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public class GherkinFormatSettings
2323

2424
public string TableCellPadding => new(' ', Configuration.TableCellPaddingSize);
2525

26+
public string Language { get; set; } = "en-US";
2627

2728
public static GherkinFormatSettings Load(IEditorConfigOptionsProvider editorConfigOptionsProvider,
2829
IWpfTextView textView, DeveroomConfiguration configuration)
@@ -39,7 +40,8 @@ public static GherkinFormatSettings Load(IEditorConfigOptionsProvider editorConf
3940
var formatSettings = new GherkinFormatSettings
4041
{
4142
Indent = convertTabsToSpaces ? new string(' ', indentSize) : new string('\t', 1),
42-
Configuration = gherkinFormatConfiguration
43+
Configuration = gherkinFormatConfiguration,
44+
Language = configuration?.DefaultFeatureLanguage ?? "en-US"
4345
};
4446

4547
return formatSettings;

Reqnroll.VisualStudio/ProjectSystem/Configuration/ProjectScopeDeveroomConfigurationProvider.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,9 @@ private ConfigSource GetProjectConfigFilePath(string fileName)
116116
{
117117
var projectFolder = _projectScope.ProjectFolder;
118118
var fileSystem = _projectScope.IdeScope.FileSystem;
119-
var configFilePath = fileSystem.GetFilePathIfExists(Path.Combine(projectFolder, fileName));
119+
var assemblyPath = Path.GetDirectoryName(_projectScope.OutputAssemblyPath);
120+
121+
var configFilePath = fileSystem.GetFilePathIfExists(Path.Combine(assemblyPath ?? projectFolder, fileName));
120122

121123
if (fileName.Equals(SpecFlowAppConfigFileName)) configFilePath ??= GetAppConfigPathFromProject();
122124
if (configFilePath == null)

0 commit comments

Comments
 (0)