Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 526fb22

Browse files
Handle block comments with text on the same line as <# #> (#2848)
* Handle block comments that have content on the same line as <##> * add more tests * handle \r\n better * support <# foo #> * include line ending in metadata
1 parent bb5dbb8 commit 526fb22

File tree

3 files changed

+321
-51
lines changed

3 files changed

+321
-51
lines changed

‎src/features/PowerShellNotebooks.ts‎

Lines changed: 143 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,24 @@ export class PowerShellNotebooksFeature extends LanguageClientConsumer {
6666
}
6767
}
6868

69+
interface IPowerShellNotebookCellMetadata {
70+
commentType: CommentType;
71+
openBlockCommentOnOwnLine?: boolean;
72+
closeBlockCommentOnOwnLine?: boolean;
73+
}
74+
75+
function CreateCell(cellKind: vscode.CellKind, source: string[], metadata: IPowerShellNotebookCellMetadata): vscode.NotebookCellData {
76+
return {
77+
cellKind,
78+
language: cellKind === vscode.CellKind.Markdown ? "markdown" : "powershell",
79+
outputs: [],
80+
source: source.join("\n"),
81+
metadata: {
82+
custom: metadata,
83+
},
84+
};
85+
}
86+
6987
class PowerShellNotebookContentProvider implements vscode.NotebookContentProvider {
7088
private _onDidChangeNotebook = new vscode.EventEmitter<vscode.NotebookDocumentEditEvent>();
7189
public onDidChangeNotebook: vscode.Event<vscode.NotebookDocumentEditEvent> = this._onDidChangeNotebook.event;
@@ -79,40 +97,72 @@ class PowerShellNotebookContentProvider implements vscode.NotebookContentProvide
7997
this.logger.writeDiagnostic(`Opening Notebook: ${uri.toString()}`);
8098

8199
const data = (await vscode.workspace.fs.readFile(actualUri)).toString();
82-
const lines = data.split(/\r\n|\r|\n/g);
100+
101+
let lines: string[];
102+
// store the line ending in the metadata of the document
103+
// so that we honor the line ending of the original file
104+
// on save.
105+
let lineEnding: string;
106+
if (data.indexOf('\r\n') !== -1) {
107+
lines = data.split(/\r\n/g);
108+
lineEnding = '\r\n';
109+
} else {
110+
lines = data.split(/\n/g);
111+
lineEnding = '\n';
112+
}
83113

84114
const notebookData: vscode.NotebookData = {
85115
languages: ["powershell"],
86116
cells: [],
87-
metadata: {}
117+
metadata: {
118+
custom: {
119+
lineEnding,
120+
}
121+
}
88122
};
89123

90124
let currentCellSource: string[] = [];
91125
let cellKind: vscode.CellKind | undefined;
92126
let insideBlockComment: boolean = false;
93127

128+
// This dictates whether the BlockComment cell was read in with content on the same
129+
// line as the opening <#. This is so we can preserve the format of the backing file on save.
130+
let openBlockCommentOnOwnLine: boolean = false;
131+
94132
// Iterate through all lines in a document (aka ps1 file) and group the lines
95133
// into cells (markdown or code) that will be rendered in Notebook mode.
96134
// tslint:disable-next-line: prefer-for-of
97135
for (let i = 0; i < lines.length; i++) {
98136
// Handle block comments
99137
if (insideBlockComment) {
100-
if (lines[i] === "#>") {
138+
if (lines[i].endsWith("#>")) {
139+
// Get the content of the current line without #>
140+
const currentLine = lines[i]
141+
.substring(0, lines[i].length - 2)
142+
.trimRight();
143+
144+
// This dictates whether the BlockComment cell was read in with content on the same
145+
// line as the closing #>. This is so we can preserve the format of the backing file
146+
// on save.
147+
let closeBlockCommentOnOwnLine: boolean = true;
148+
if (currentLine) {
149+
closeBlockCommentOnOwnLine = false;
150+
currentCellSource.push(currentLine);
151+
}
152+
101153
// We've reached the end of a block comment,
102154
// push a markdown cell.
103155
insideBlockComment = false;
104156

105-
notebookData.cells.push({
106-
cellKind: vscode.CellKind.Markdown,
107-
language: "markdown",
108-
outputs: [],
109-
source: currentCellSource.join("\n"),
110-
metadata: {
111-
custom: {
112-
commentType: CommentType.BlockComment
113-
}
157+
notebookData.cells.push(CreateCell(
158+
vscode.CellKind.Markdown,
159+
currentCellSource,
160+
{
161+
commentType: CommentType.BlockComment,
162+
openBlockCommentOnOwnLine,
163+
closeBlockCommentOnOwnLine
114164
}
115-
});
165+
));
116166

117167
currentCellSource = [];
118168
cellKind = null;
@@ -122,29 +172,65 @@ class PowerShellNotebookContentProvider implements vscode.NotebookContentProvide
122172
// If we're still in a block comment, push the line and continue.
123173
currentCellSource.push(lines[i]);
124174
continue;
125-
} else if (lines[i]==="<#") {
175+
} else if (lines[i].startsWith("<#")) {
126176
// If we found the start of a block comment,
127177
// insert what we saw leading up to this.
128178
// If cellKind is null/undefined, that means we
129179
// are starting the file with a BlockComment.
130180
if (cellKind) {
131-
notebookData.cells.push({
181+
notebookData.cells.push(CreateCell(
132182
cellKind,
133-
language: cellKind === vscode.CellKind.Markdown ? "markdown" : "powershell",
134-
outputs: [],
135-
source: currentCellSource.join("\n"),
136-
metadata: {
137-
custom: {
138-
commentType: cellKind === vscode.CellKind.Markdown ? CommentType.LineComment : CommentType.Disabled,
139-
}
183+
currentCellSource,
184+
{
185+
commentType: cellKind === vscode.CellKind.Markdown ? CommentType.LineComment : CommentType.Disabled,
140186
}
141-
});
187+
));
142188
}
143189

144-
// reset state because we're starting a new Markdown cell.
145-
currentCellSource = [];
190+
// We're starting a new Markdown cell.
146191
cellKind = vscode.CellKind.Markdown;
147192
insideBlockComment = true;
193+
194+
// Get the content of the current line without `<#`
195+
const currentLine = lines[i]
196+
.substring(2, lines[i].length)
197+
.trimLeft();
198+
199+
// If we have additional text on the line with the `<#`
200+
// We need to keep track of what comes after it.
201+
if (currentLine) {
202+
// If both the `<#` and the `#>` are on the same line
203+
// we want to push a markdown cell.
204+
if (currentLine.endsWith("#>")) {
205+
// Get the content of the current line without `#>`
206+
const newCurrentLine = currentLine
207+
.substring(0, currentLine.length - 2)
208+
.trimRight();
209+
210+
notebookData.cells.push(CreateCell(
211+
vscode.CellKind.Markdown,
212+
[ newCurrentLine ],
213+
{
214+
commentType: CommentType.BlockComment,
215+
openBlockCommentOnOwnLine: false,
216+
closeBlockCommentOnOwnLine: false,
217+
}
218+
));
219+
220+
// Reset
221+
currentCellSource = [];
222+
cellKind = null;
223+
insideBlockComment = false;
224+
continue;
225+
}
226+
227+
openBlockCommentOnOwnLine = false;
228+
currentCellSource = [ currentLine ];
229+
} else {
230+
openBlockCommentOnOwnLine = true;
231+
currentCellSource = [];
232+
}
233+
148234
continue;
149235
}
150236

@@ -158,17 +244,13 @@ class PowerShellNotebookContentProvider implements vscode.NotebookContentProvide
158244
} else {
159245
// If cellKind has a value, then we can add the cell we've just computed.
160246
if (cellKind) {
161-
notebookData.cells.push({
162-
cellKind: cellKind!,
163-
language: cellKind === vscode.CellKind.Markdown ? "markdown" : "powershell",
164-
outputs: [],
165-
source: currentCellSource.join("\n"),
166-
metadata: {
167-
custom: {
168-
commentType: cellKind === vscode.CellKind.Markdown ? CommentType.LineComment : CommentType.Disabled,
169-
}
247+
notebookData.cells.push(CreateCell(
248+
cellKind,
249+
currentCellSource,
250+
{
251+
commentType: cellKind === vscode.CellKind.Markdown ? CommentType.LineComment : CommentType.Disabled,
170252
}
171-
});
253+
));
172254
}
173255

174256
// set initial new cell state
@@ -182,17 +264,13 @@ class PowerShellNotebookContentProvider implements vscode.NotebookContentProvide
182264
// when there is only the _start_ of a block comment but not an _end_.)
183265
// add the appropriate cell.
184266
if (currentCellSource.length) {
185-
notebookData.cells.push({
186-
cellKind: cellKind!,
187-
language: cellKind === vscode.CellKind.Markdown ? "markdown" : "powershell",
188-
outputs: [],
189-
source: currentCellSource.join("\n"),
190-
metadata: {
191-
custom: {
192-
commentType: cellKind === vscode.CellKind.Markdown ? CommentType.LineComment : CommentType.Disabled,
193-
}
267+
notebookData.cells.push(CreateCell(
268+
cellKind!,
269+
currentCellSource,
270+
{
271+
commentType: cellKind === vscode.CellKind.Markdown ? CommentType.LineComment : CommentType.Disabled,
194272
}
195-
});
273+
));
196274
}
197275

198276
return notebookData;
@@ -228,23 +306,37 @@ class PowerShellNotebookContentProvider implements vscode.NotebookContentProvide
228306
const retArr: string[] = [];
229307
for (const cell of document.cells) {
230308
if (cell.cellKind === vscode.CellKind.Code) {
231-
retArr.push(...cell.document.getText().split(/\r|\n|\r\n/));
309+
retArr.push(...cell.document.getText().split(/\r\n|\n/));
232310
} else {
233311
// First honor the comment type of the cell if it already has one.
234312
// If not, use the user setting.
235313
const commentKind = cell.metadata.custom?.commentType || Settings.load().notebooks.saveMarkdownCellsAs;
236314

237315
if (commentKind === CommentType.BlockComment) {
238-
retArr.push("<#");
239-
retArr.push(...cell.document.getText().split(/\r|\n|\r\n/));
240-
retArr.push("#>");
316+
const openBlockCommentOnOwnLine: boolean = cell.metadata.custom?.openBlockCommentOnOwnLine;
317+
const closeBlockCommentOnOwnLine: boolean = cell.metadata.custom?.closeBlockCommentOnOwnLine;
318+
const text = cell.document.getText().split(/\r\n|\n/);
319+
if (openBlockCommentOnOwnLine) {
320+
retArr.push("<#");
321+
} else {
322+
text[0] = `<# ${text[0]}`;
323+
}
324+
325+
if (!closeBlockCommentOnOwnLine) {
326+
text[text.length - 1] += " #>";
327+
retArr.push(...text);
328+
} else {
329+
retArr.push(...text);
330+
retArr.push("#>");
331+
}
241332
} else {
242-
retArr.push(...cell.document.getText().split(/\r|\n|\r\n/).map((line) => `# ${line}`));
333+
retArr.push(...cell.document.getText().split(/\r\n|\n/).map((line) => `# ${line}`));
243334
}
244335
}
245336
}
246337

247-
await vscode.workspace.fs.writeFile(targetResource, new TextEncoder().encode(retArr.join("\n")));
338+
const eol = document.metadata.custom.lineEnding;
339+
await vscode.workspace.fs.writeFile(targetResource, new TextEncoder().encode(retArr.join(eol)));
248340
}
249341
}
250342

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /