Adding code snippets
This commit is contained in:
Родитель
d668aa681a
Коммит
a669422c2f
|
@ -1,3 +1,8 @@
|
||||||
|
## v0.0.38 (11/06/2020)
|
||||||
|
|
||||||
|
- Introduced support for inserting code snippets
|
||||||
|
- Added arrow icons to the previous/next navigation links
|
||||||
|
|
||||||
## v0.0.37 (11/04/2020)
|
## v0.0.37 (11/04/2020)
|
||||||
|
|
||||||
- Added `Previous`, `Next` and `Finish` commands to the bottom of the comment UI, in order to make it easier to navigate a tour.
|
- Added `Previous`, `Next` and `Finish` commands to the bottom of the comment UI, in order to make it easier to navigate a tour.
|
||||||
|
|
|
@ -133,6 +133,10 @@ In order to make it simpler to call common commands, CodeTour will prompt you wi
|
||||||
|
|
||||||
- `Start tour...` - Allows you to specify the title or another tour in the workspace, that when clicked, will automatically start that tour.
|
- `Start tour...` - Allows you to specify the title or another tour in the workspace, that when clicked, will automatically start that tour.
|
||||||
|
|
||||||
|
#### Code Blocks
|
||||||
|
|
||||||
|
If you add a markdown code block to a step's body content, then the CodeTour player will render an `Insert Code` link below it, which allows the viewer to automatically insert the code snippet into the current file, at the line that the step is associated with. This can make it easy to use CodeTour for creating interactive tutorials or samples.
|
||||||
|
|
||||||
### Versioning Tours
|
### Versioning Tours
|
||||||
|
|
||||||
When you record a tour, you'll be asked which git "ref" to associate it with. This allows you to define how resilient you want the tour to be, as changes are made to the respective codebase.
|
When you record a tour, you'll be asked which git "ref" to associate it with. This allows you to define how resilient you want the tour to be, as changes are made to the respective codebase.
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"displayName": "CodeTour",
|
"displayName": "CodeTour",
|
||||||
"description": "VS Code extension that allows you to record and playback guided tours of codebases, directly within the editor",
|
"description": "VS Code extension that allows you to record and playback guided tours of codebases, directly within the editor",
|
||||||
"publisher": "vsls-contrib",
|
"publisher": "vsls-contrib",
|
||||||
"version": "0.0.37",
|
"version": "0.0.38",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/vsls-contrib/codetour"
|
"url": "https://github.com/vsls-contrib/codetour"
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { when } from "mobx";
|
||||||
import * as vscode from "vscode";
|
import * as vscode from "vscode";
|
||||||
import { EXTENSION_NAME } from "../constants";
|
import { EXTENSION_NAME } from "../constants";
|
||||||
import { focusPlayer } from "../player";
|
import { focusPlayer } from "../player";
|
||||||
|
import { saveTour } from "../recorder/commands";
|
||||||
import { CodeTour, store } from "../store";
|
import { CodeTour, store } from "../store";
|
||||||
import {
|
import {
|
||||||
endCurrentCodeTour,
|
endCurrentCodeTour,
|
||||||
|
@ -85,6 +86,21 @@ export function registerPlayerCommands() {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
vscode.commands.registerCommand(
|
||||||
|
`${EXTENSION_NAME}.insertCodeSnippet`,
|
||||||
|
async (codeBlock: string) => {
|
||||||
|
const codeSnippet = decodeURIComponent(codeBlock);
|
||||||
|
const snippet = new vscode.SnippetString(codeSnippet);
|
||||||
|
vscode.window.activeTextEditor?.insertSnippet(snippet);
|
||||||
|
|
||||||
|
const lineAdjustment = codeSnippet.split("\n").length - 1;
|
||||||
|
if (lineAdjustment > 0) {
|
||||||
|
store.activeTour!.tour.steps[store.activeTour!.step].line! += lineAdjustment;
|
||||||
|
saveTour(store.activeTour!.tour);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
vscode.commands.registerCommand(
|
vscode.commands.registerCommand(
|
||||||
`${EXTENSION_NAME}.startTour`,
|
`${EXTENSION_NAME}.startTour`,
|
||||||
async (
|
async (
|
||||||
|
|
|
@ -28,6 +28,7 @@ let id = 0;
|
||||||
const SHELL_SCRIPT_PATTERN = /^>>\s+(?<script>.*)$/gm;
|
const SHELL_SCRIPT_PATTERN = /^>>\s+(?<script>.*)$/gm;
|
||||||
const COMMAND_PATTERN = /(?<commandPrefix>\(command:[\w+\.]+\?)(?<params>\[[^\]]+\])/gm;
|
const COMMAND_PATTERN = /(?<commandPrefix>\(command:[\w+\.]+\?)(?<params>\[[^\]]+\])/gm;
|
||||||
const TOUR_REFERENCE_PATTERN = /(?:\[(?<linkTitle>[^\]]+)\])?\[(?=\s*[^\]\s])(?<tourTitle>[^\]#]+)?(?:#(?<stepNumber>\d+))?\](?!\()/gm;
|
const TOUR_REFERENCE_PATTERN = /(?:\[(?<linkTitle>[^\]]+)\])?\[(?=\s*[^\]\s])(?<tourTitle>[^\]#]+)?(?:#(?<stepNumber>\d+))?\](?!\()/gm;
|
||||||
|
const CODE_FENCE_PATTERN = /```\w+\n([^`]+)\n```/gm;
|
||||||
|
|
||||||
export class CodeTourComment implements Comment {
|
export class CodeTourComment implements Comment {
|
||||||
public id: string = (++id).toString();
|
public id: string = (++id).toString();
|
||||||
|
@ -86,6 +87,13 @@ export class CodeTourComment implements Comment {
|
||||||
|
|
||||||
return _;
|
return _;
|
||||||
}
|
}
|
||||||
|
).replace(
|
||||||
|
CODE_FENCE_PATTERN,
|
||||||
|
(_, codeBlock) => {
|
||||||
|
const params = encodeURIComponent(JSON.stringify([codeBlock]));
|
||||||
|
return `${_}
|
||||||
|
↪ [Insert Code](command:codetour.insertCodeSnippet?${params} "Insert Code")`;
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,13 +205,13 @@ async function renderCurrentStep() {
|
||||||
|
|
||||||
if (hasPreviousStep) {
|
if (hasPreviousStep) {
|
||||||
const stepLabel = getStepLabel(currentTour, currentStep - 1, false);
|
const stepLabel = getStepLabel(currentTour, currentStep - 1, false);
|
||||||
content += `[Previous (${stepLabel})](command:codetour.previousTourStep "Navigate to previous step")`;
|
content += `← [Previous (${stepLabel})](command:codetour.previousTourStep "Navigate to previous step")`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const prefix = hasPreviousStep ? " | " : "";
|
const prefix = hasPreviousStep ? " | " : "";
|
||||||
if (hasNextStep) {
|
if (hasNextStep) {
|
||||||
const stepLabel = getStepLabel(currentTour, currentStep + 1, false);
|
const stepLabel = getStepLabel(currentTour, currentStep + 1, false);
|
||||||
content += `${prefix}[Next (${stepLabel})](command:codetour.nextTourStep "Navigate to next step")`;
|
content += `${prefix}[Next (${stepLabel})](command:codetour.nextTourStep "Navigate to next step") →`;
|
||||||
} else if (isFinalStep) {
|
} else if (isFinalStep) {
|
||||||
content += `${prefix}[Finish Tour](command:codetour.endTour "Finish the tour")`;
|
content += `${prefix}[Finish Tour](command:codetour.endTour "Finish the tour")`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,18 @@ import {
|
||||||
import { CodeTourNode, CodeTourStepNode } from "../tree/nodes";
|
import { CodeTourNode, CodeTourStepNode } from "../tree/nodes";
|
||||||
import { getActiveWorkspacePath, getRelativePath } from "../utils";
|
import { getActiveWorkspacePath, getRelativePath } from "../utils";
|
||||||
|
|
||||||
|
export async function saveTour(tour: CodeTour) {
|
||||||
|
const uri = vscode.Uri.parse(tour.id);
|
||||||
|
const newTour = {
|
||||||
|
...tour
|
||||||
|
};
|
||||||
|
delete newTour.id;
|
||||||
|
const tourContent = JSON.stringify(newTour, null, 2);
|
||||||
|
|
||||||
|
const bytes = new TextEncoder().encode(tourContent);
|
||||||
|
return vscode.workspace.fs.writeFile(uri, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
export function registerRecorderCommands() {
|
export function registerRecorderCommands() {
|
||||||
function getTourFileUri(workspaceRoot: vscode.Uri, title: string) {
|
function getTourFileUri(workspaceRoot: vscode.Uri, title: string) {
|
||||||
const file = title
|
const file = title
|
||||||
|
@ -460,18 +472,6 @@ export function registerRecorderCommands() {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
async function saveTour(tour: CodeTour) {
|
|
||||||
const uri = vscode.Uri.parse(tour.id);
|
|
||||||
const newTour = {
|
|
||||||
...tour
|
|
||||||
};
|
|
||||||
delete newTour.id;
|
|
||||||
const tourContent = JSON.stringify(newTour, null, 2);
|
|
||||||
|
|
||||||
const bytes = new TextEncoder().encode(tourContent);
|
|
||||||
return vscode.workspace.fs.writeFile(uri, bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function updateTourProperty(tour: CodeTour, property: string) {
|
async function updateTourProperty(tour: CodeTour, property: string) {
|
||||||
const propertyValue = await vscode.window.showInputBox({
|
const propertyValue = await vscode.window.showInputBox({
|
||||||
prompt: `Enter the ${property} for this tour`,
|
prompt: `Enter the ${property} for this tour`,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче