Skip to content

Commit 3781229

Browse files
committed
More WiP
1 parent 58c23ec commit 3781229

File tree

52 files changed

+1551
-349
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1551
-349
lines changed

code-description.md

Lines changed: 36 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ A tag set:
3737

3838
### Tag spans
3939

40-
A tag span is the text to which a tag applies. In an un-nested tag set, a tag span begins after the `}` of a version tag and ends with the `}` of the next tag. The `endif` tag has no tag span. For example:
40+
A tag span consists of the tag plus the text to which that tag applies. In an un-nested tag set, with the exception of an `endif` tag, a tag span begins with the `{` of the tag and ends with the `{` of the next tag. The `endif` tag has no related text, so it ends with the `}` of the tag. For example:
4141

4242
```
4343
This text does not belong to a tag span, {% ifversion some-version-name %}this is the ifversion tag span,
@@ -186,49 +186,39 @@ Having parsed the contents of the Markdown file, we now have the `currentTagSpan
186186

187187
#### Highlighting the relevant version tags
188188

189-
To highlight the relevant tags in the editor we iterate backwards through the `currentTagSpan` array, starting with the last element in the array:
189+
Highlighting is done in the `highlightVersionTags()` function.
190+
191+
First we define some colors to be used to highlight the tag sets. We'll highlight each set of tags in a different color, so we define and array of object, with each object having a pair of properties: the background color of the highlighting, and the color of the text. It's rare to have more than one level of nesting, so we'll usually only need two pairs of colors, but we define three just in case there is some double-nesting anywhere.
190192

191193
```
192-
for (let elementNumber = currentTagSpan.length - 1; elementNumber >= 0; elementNumber--) {
193-
... do stuff with currentTagSpan[elementNumber] ...
194-
}
194+
const colorPairs = [
195+
{ backgroundColor: 'darkred', color: 'white' },
196+
{ backgroundColor: 'darkblue', color: 'yellow' },
197+
{ backgroundColor: 'green', color: 'black' }
198+
];
195199
```
196200

197-
For each tag span element in the array we:
198-
- Look up the tag span ID (`currentTagSpan[elementNumber]`) in the `versionTags` array.
199-
- Get the tag set ID from the `tagSet` property of the element we find in the `versionTags` array, and assign it to `currentTagSetID`.
200-
- Find all the tags in the `versionTags` array that have the same tag set ID, and for each of these:
201-
- Get the start and end positions of the tag.
202-
- Add the start and end positions to an array of text ranges. We'll highlight these ranges in the editor.
201+
The tag set the cursor is directly within will use the first color pair. If this tag set is nested then the parent tag set will be highlighted using the second color pair, and so on. If there are additional levels of nesting in the Markdown we'll cycle back through the array of colors again.
203202

204-
We do the last three steps as follows:
203+
We then iterate backwards through the `currentTagSpan` array, starting with the last element in the array. This array contains one element for each level of nesting, starting with the most nested tag set the cursor is within, and ending with the un-nested ancestor tag span. So, in most cases, where versioning is un-nested, there will only be one element in this array. The value of each element in the `currentTagSpan` array is a tag ID.
205204

206-
```
207-
versionTags.filter(tag => tag.tagID === currentTagSetID).forEach(tag => {
208-
const range = new vscode.Range(
209-
tag.positionVersionTagStart,
210-
tag.positionVersionTagEnd
211-
);
212-
ranges.push(range);
213-
});
214-
```
205+
Now, within this iteration of the nesting level loop, we then use `vscode.window.createTextEditorDecorationType` to define the decoration we want to use for the tag set that this tag span belongs to. The definition consists of a pair of colors, which we pluck from the `colorPairs` array.
215206

216-
We can now use the `ranges` array to highlight the relevant tags.
207+
We add this definition to an array of decoration types that we declared at the start of the script. We'll use this later when we want to dispose of (i.e. remove) this type of decoration. We put it in an array so that we can dispose of all of the decoration types (i.e. the color pair for each nesting level) in a single operation.
217208

218-
```
219-
TODO: THIS CODE WON'T WORK BECAUSE, ON EACH LOOP, THE DECORATIONS APPLIED FOR THE PREVIOUS LEVEL WILL BE REMOVED:
220-
decoration.dispose(); // Remove any existing decorations.
209+
Then we create an array of `vscode.DecorationOptions` types. The only options we'll use are the positional range for each decoration (i.e. the start and end position of the tag we want to highlight). We'll fill up this array with details of all of the text ranges we want to highlight with this decoration type (i.e. all the tags that will have the same color highlighting).
221210

222-
// Create a new decoration type for highlighting the current version tags.
223-
decoration = vscode.window.createTextEditorDecorationType({
224-
backgroundColor: highlightBackgroundColor[elementNumber],
225-
color: highlightForegroundColor[elementNumber]
226-
});
211+
Still within the loop, for the tag span ID at this nesting level, we:
212+
- Get, from the `versionTags` array, the tag object for this tag span.
213+
- Get the ID of the tag set this tag belongs to.
214+
- Filter the `versionTags` array to get a subset array containing only those tag elements that have the same tag set ID as the one we just identified.
215+
- For each tag object in this filtered array, get the start and end positions as a vscode.Range, and push this into the decorations array for this nesting level (i.e. the tags with the same color of highlighting).
227216

228-
if (activeEditor) {
229-
activeEditor.setDecorations(decoration, ranges);
230-
}
231-
```
217+
Finally, within the nesting level loop, we use `activeEditor.setDecorations` to apply the specified decoration type to all of the ranges in the decorations array.
218+
219+
Then, if there's version nesting, we iterate through the loop again, applying another color to the tags in the parent tag set.
220+
221+
The .......... TODO: MENTION PRESSING ESC OR CHANGING THE CURSOR POSITION TO TRIGGER DISPOSING OF THE DECORATION TYPES. LINK TO REF FOR PACKAGE.JSON BELOW.
232222

233223
For more information about applying decorations to text in VS Code, see https://github.com/microsoft/vscode-extension-samples/blob/main/decorator-sample/USAGE.md.
234224

@@ -300,13 +290,16 @@ In this case the `versionDescription` array will contain:
300290

301291
Now the contents of `versioningString` will be: `ghec or ghes > 3.8 \nAND NOT ghes = 3.9 \nAND NOT ghes = 3.10`.
302292

293+
294+
295+
303296
## Reference
304297

305298
### Variables and constants in alphabetical order
306299

307300
The following variables and constants are used in the script. Except where marked, these are variables.
308301

309-
- **beforeCursor**: Boolean. This is set to true initially. We set it to false as soon as we get to the cursor position during the parsing phase. This allows us to quickly skip any more checking for the cursor position or assigning values related to the versioning message.
302+
- **cursorIsAfterTag **: Boolean. This is set to true initially. We set it to false as soon as we get to a tag that comes after the cursor positiion during the parsing phase. This allows us to stop assigning version text to the `versionDescription` array.
310303
- **currentTagSetID**: a number. This short-lived variable is just used to store the tag set ID of the tag we're currently processing when working out which tags to highlight.
311304
- **currentTagSpan[]**: an array of numbers. We store and retrieve values by using `nestingLevel` (i.e., `currentTagSpan[nestingLevel]`). The numbers identify the tag span (and possibly ancestor tag spans) in which the cursor is located. The last element in this array contains the ID of the tag span within which the cursor is directly located. Initially this array is empty, meaning the cursor is not within a tag span. Knowing the current tag span (and any ancestor spans), we can use the tag properties to find out which tag set(s) to highlight.
312305
- **cursorPosition**: (constant) a vscode.Position (i.e. a line number and the number of character on that line where the cursor currently sits).
@@ -357,7 +350,7 @@ We do the following for every tag we encounter during parsing.
357350

358351
Note: that `currentTagEnd` is actually the character after the closing bracket.
359352

360-
- Check whether the cursor position is after the end position of the tag. If it is we set `beforeCursor` to false.
353+
- Check whether the cursor position is before the beginning of the tag. If it is we set `cursorIsAfterTag` to false.
361354
- Create a new element in the `versionTags` array, containing these properties:
362355
- **tagID**: The unique ID (`tagCounter` number).
363356
- **tagSet**: The tag set ID (`tagSetID[nestingLevel]` number).
@@ -369,7 +362,7 @@ We do the following for every tag we encounter during parsing.
369362
When we find an `ifversion` tag we:
370363
- Increment `nestingLevel`. Initially this is -1, so this becomes 0 for an un-nested tag set and 1 for the first nesting level. This variable needs to survive from one tag processing to the next
371364
- Assign `tagCounter` to `tagSetID[nestingLevel]`. This is the ID of the tag set that this tag belongs to (always the same as the ifversion ID). This array needs to survive from one tag processing to the next.
372-
- If `beforeCursor` is true we:
365+
- If `cursorIsAfterTag` is true we:
373366
- Assign `tagCounter` to `currentTagSpan[nestingLevel]`. This array needs to survive from one tag processing to the next so that we can determine which tag span the cursor is currently within, and therefore which tags we need to highlight.
374367
- Get the version from the tag (e.g. "ghes"), using `match[1]` from the regular expression.
375368
- Assign the version to `versionDescription[nestingLevel]`.
@@ -378,7 +371,7 @@ When we find an `ifversion` tag we:
378371
#### `elsif`
379372

380373
When we find an `elsif` tag:
381-
- If `beforeCursor` is true we:
374+
- If `cursorIsAfterTag` is true we:
382375
- Assign `tagSetID[nestingLevel]` to `currentTagSpan[nestingLevel]`.
383376
- Get the version from the tag (e.g. "ghec").
384377
- Assign the version to `versionDescription[nestingLevel]`.
@@ -388,7 +381,7 @@ Note that we don't assign a value to `tagSetID[nestingLevel]` because this tag d
388381
#### `else`
389382

390383
When we find an `else` tag:
391-
- If `beforeCursor` is true we:
384+
- If `cursorIsAfterTag` is true we:
392385
- Assign `tagSetID[nestingLevel]` to `currentTagSpan[nestingLevel]`.
393386
- If `nestingLevel` is >0, we set `versionDescription[nestingLevel]` to " AND ".
394387
- Set `versionDescription[nestingLevel]` to `versionDescription[nestingLevel] + elsedVersions[nestingLevel]`.
@@ -397,7 +390,7 @@ As with `elsif` we again reuse the unmodified `tagSetID[nestingLevel]` value tha
397390
#### `endif`
398391

399392
When we find an `endif` tag:
400-
- If `beforeCursor` is true we:
393+
- If `cursorIsAfterTag` is true we:
401394
- Delete the last element in the `currentTagSpan`, `versionDescription` and `elsedVersions` arrays.
402395
- Decrement `nestingLevel`. At each `endif` we're stepping out of a level of nesting, or out of versioning altogether this is the `endif` for an un-nested tag set (in which case `nestingLevel` returns to -1).
403396
As with `elsif` we again reuse the unmodified `tagSetID[nestingLevel]` value that we set for the `ifversion` tag.
@@ -447,36 +440,13 @@ while (match = tagRegEx.exec(text)) {
447440

448441
The `while` loop will keep running until the regular expression fails to match anything in the text. Each time the regular expression matches something, it returns an array of strings (`match`). The first element in the array (`match[0]`) is the entire string that matched the regular expression. The second element in the array (`match[1]`) is the first capture group (the tag type - e.g. "ifversion"). The third element (`match[2]`) is the second capture group (the version - e.g. "fpt or ghec").
449442

450-
==================
443+
### The package.json file
451444

452-
TODO: TRY USING OUTLINE COLOR AROUND TAG SPANS:
445+
This file is located ....... it's used to ...........
453446

454-
To apply an outline around a range of text in the editor as a VS Code decoration, you can use the setDecorations method of the TextEditor object. Here's how you can do it:
455447

456-
First, define the decoration type:
457448

458-
const decorationType = vscode.window.createTextEditorDecorationType({
459-
borderWidth: '1px',
460-
borderStyle: 'solid',
461-
overviewRulerColor: 'blue',
462-
borderColor: 'darkblue',
463-
light: {
464-
borderColor: 'darkblue'
465-
},
466-
dark: {
467-
borderColor: 'lightblue'
468-
}
469-
});
470-
471-
Then, apply the decoration to a range:
472-
473-
const activeEditor = vscode.window.activeTextEditor;
474-
if (activeEditor) {
475-
const start = new vscode.Position(0, 0); // start position
476-
const end = new vscode.Position(0, 10); // end position
477-
const decoration = { range: new vscode.Range(start, end), hoverMessage: 'Test Decoration' };
478-
activeEditor.setDecorations(decorationType, [decoration]);
479-
}
449+
==================
480450

481451
================
482452

0 commit comments

Comments
 (0)