Adding support for step titles

This commit is contained in:
Jonathan Carter 2020-03-15 20:47:19 -07:00
Родитель 731c8a59e2
Коммит 072d2128f0
11 изменённых файлов: 111 добавлений и 39 удалений

10
.vscode/tours/statusbar.json поставляемый
Просмотреть файл

@ -5,22 +5,22 @@
{
"file": "src/extension.ts",
"line": 36,
"description": "The status bar provider is registered upon extension activiation"
"description": "### Activation\nThe status bar provider is registered upon extension activiation"
},
{
"file": "src/status.ts",
"line": 35,
"description": "If the currently opened workspace has any code tours, then we register the `Start Code Tour` status bar item."
"description": "### Registration\nIf the currently opened workspace has any code tours, then we register the `Start Code Tour` status bar item."
},
{
"file": "src/status.ts",
"line": 40,
"description": "Using MobX, we wait for the user to start and/or navigate a code tour."
"description": "### Waiting for user\nUsing MobX, we wait for the user to start and/or navigate a code tour."
},
{
"file": "src/status.ts",
"line": 47,
"description": "When a tour is activate and/or navigated, we update the status bar item to indicate the current step and title."
"description": "### Updating\nWhen a tour is activate and/or navigated, we update the status bar item to indicate the current step and title."
}
]
}
}

Просмотреть файл

@ -1,3 +1,9 @@
## v0.0.10 (03/16/2020)
- Introduced support for step titles, which provide a friendly display name in the `CodeTour` tree
- Added an extension API, so that other VS Code extensions (e.g. [GistPad](https://aka.ms/gistpad)) can manage code tours
- Added the `CodeTour: Edit Tour` command, that allows you to edit the tour you're currently playing.
## v0.0.9 (03/15/2020)
- Added the ability to record a text selection as part of a step

Просмотреть файл

@ -6,14 +6,14 @@ CodeTour is a Visual Studio Code extension, which allows you to record and playb
## Starting a tour
In order to start a tour, simply open up a codebase that has one or more tours. If this is the first time you've ever opened this codebase, then you'll be presented with a toast notification asking if you'd like to take a tour of it.
In order to start a tour, simply open up a codebase that has one or more tours. If this is the first time you've ever opened this codebase, you'll be presented with a toast notification asking if you'd like to take a tour of it.
<img width="400px" src="https://user-images.githubusercontent.com/116461/76691619-d0ada080-6609-11ea-81bf-c1f022dbff43.png" />
Otherwise, you can manually start a tour via any of the following methods:
1. Clicking the `> Start CodeTour` button in the [status bar](#status-bar)
2. Selecting oa tour (or specific step) in the [`CodeTours` view](#tree-view) in the `Explorer` activity tab
2. Selecting a tour (or specific step) in the [`CodeTour` view](#tree-view) in the `Explorer` activity tab
<img width="250px" src="https://user-images.githubusercontent.com/116461/76164362-8610bd80-610b-11ea-9621-4ba2d47a8a52.png" />
@ -44,15 +44,15 @@ If you navigate away from the current step and need to resume, you can do that v
At any time, you can end the current code tour by means of one of the following actions:
- Click the `x` button in the current step comment
- Click the `x` button next to the active tour in the `CodeTours` tree
- Click the stop button (the red square) in the current step comment
- Click the stop button next to the active tour in the `CodeTour` tree
- Running the `CodeTour: End Tour` command in the command palette
## Authoring tours
If you'd like to create a code tour for your codebase, you can simply click the `+` button in the `CodeTours` tree view and/or run the `CodeTour: Record Tour` command. This will start the "tour recorder", which allows you to begin opening files, clicking the "comment bar" for the line you want to annotate, and then adding the respective description (including markdown!). Add as many steps as you want, and then when done, click the save icon in the comment UI to write the tour to the currently opened workspace.
While you're recording, the `CodeTours` [tree view](#tree-view) will display the currently recorded tour, and it's current set of steps. You can tell which tour is being recorded because it will have a microphone icon to the left of its name.
While you're recording, the `CodeTour` [tree view](#tree-view) will display the currently recorded tour, and it's current set of steps. You can tell which tour is being recorded because it will have a microphone icon to the left of its name.
<img width="800px" src="https://user-images.githubusercontent.com/116461/76165260-c6c00500-6112-11ea-9cda-0a6cb9b72e8f.gif" />
@ -60,15 +60,19 @@ If you need to edit or delete a step while recording, click the `...` menu next
<img width="500px" src="https://user-images.githubusercontent.com/116461/76168548-1f50cb80-612e-11ea-9aca-8598b9e1c730.png" />
### Editing a tour
### Step titles
If you want to edit an existing tour, simply right-click the tour in the `CodeTour` tree and select `Edit Tour`. Alternatively, you can edit a tour you're actively viewing by clicking the pencil icon in the current step's comment bar.
By default, the `CodeTour` tree displays each tour step using the following display name format: `#<stepNumber> - <filePath>`. However, if you'd like to give the step a more friendly name, you can edit the step's description and add a markdown heading to the top of it, using whichever heading level you prefer (e.g. `#`, `##`, etc.). For example, if you add a step whose description starts with `### Activation, the step and tree view would look like the following:
At any time, you can right-click a tour in the `CodeTour` tree and change it's title/description, by selecting the `Change Title` or `Change Description` menu items. Additinoally, you can delete a tour by right-clicking it in the `CodeTour` tree and seelcting `Delete Tour`.
<img width="500px" src="https://user-images.githubusercontent.com/116461/76721235-91ac4780-66fc-11ea-80bf-f6de8bf4b02e.png" />
### Selection
While you can any heading leve for the step title, we'd recommend using `###` or "lower" (e.g. `####`), since that provides a nice look within the step's comment UI.
By default, each step is associated with the line of code you create the comment on. However, if you want to call out a specific span of code as part of the step, simply highlight the code before you add the step, and the selection will be captured as part of the step.
> If you'd like to add step titles to a tour, but don't want to add markdown headings to their descriptions, you can manually set the `title` property for each step in the tour's underlying `JSON` file (which can be found in the `.vscode/tours` directory). See [tour schema](#tour-schema) for more detials.
### Recording text selection
By default, each step is associated with the line of code you created the comment on (i.e. the line you clicked the `+` on the comment bar for). However, if you want to call out a specific span of code as part of the step, simply highlight the code before you add the step (clicking the `Add Tour to Step` button), and the selection will be captured as part of the step.
<img width="800px" src="https://user-images.githubusercontent.com/116461/76705627-b96cc280-669e-11ea-982a-d754c4f001aa.gif" />
@ -77,10 +81,10 @@ By default, each step is associated with the line of code you create the comment
While you're recording a tour, each new step that you add will be appended to the end of the tour. However, you can move existing steps up and down in the order by performing one of the following actions:
- Hover over the step in the `CodeTour` tree and click the up/down arrow icon
- Right-click the step i the `CodeTour` tree and select the `Move Up` or `Move Down` menu items
- Right-click the step in the `CodeTour` tree and select the `Move Up` or `Move Down` menu items
- Click the `...` menu in the step comment UI and select `Move Up` or `Move Down`
If you want to add a new step in the middle of a tour, simply navigate to the step that you want to insert a new step after, and then create the new step.
Additionally, if you want to add a new step in the middle of a tour, simply navigate to the step that you want to insert a new step after, and then create the new step.
### Deleting steps
@ -89,6 +93,12 @@ If you no longer need a specific step in a tour, you can delete it by means of o
- Right-clicking the step in the `CodeTour` tree and selecting `Delete Step`
- Navigating to the step in the replay/comment UI, selecting the `...` menu next to the comment description and selecting `Delete Step`
### Editing a tour
If you want to edit an existing tour, simply right-click the tour in the `CodeTour` tree and select `Edit Tour`. Alternatively, you can edit a tour you're actively viewing by clicking the pencil icon in the current step's comment bar, or running the `CodeTour: Edit Tour` command.
At any time, you can right-click a tour in the `CodeTour` tree and change it's title, description or git ref, by selecting the `Change Title`, `Change Description` or `Change Git Ref` menu items. Additionally, you can delete a tour by right-clicking it in the `CodeTour` tree and seelcting `Delete Tour`.
### 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.
@ -101,7 +111,7 @@ You can choose to associate with the tour with the following ref types:
- `Current Branch` - The tour is restricted to the current branch. This can have the same resiliency challenges as `None`, but, it allows you to maintain a special branch for your tours that can be versioned seperately. If the end-user has the associated branch checked out, then the tour will enable them to make edits to files as its taken. Otherwise, the tour will replay with read-only files.
- `Current Commit` - The tour is restricted to the current commit, and therefore, will never get out of sync. If the end-user's `HEAD` points at the specified commit, then the tour will enable them to make edits to files as its taken. Otherwise, the tour will replay with read-only files.
- Tags - The tour is restricted to the selected tag, and therefore, will never get out of sync. The repo's entire list of tags will be displayed, which allows you to easily select one.
At any time, you can edit the tour's ref by right-clicking it in the `CodeTour` tree and selecting `Change Git Ref`. This let's you "rebase" a tour to a tag/commit as you change/update your code and/or codebase.
### Tour Files
@ -117,12 +127,14 @@ Behind the scenes, the tour will be written as a JSON file to the `.vscode/tours
Within the tour file, you need to specify the following required properties:
- `title` - The display name of the tour, which will be shown in the `Code Tours` tree view, quick pick, etc.
- `description` - An optional description for the tour
- `title` - The display name of the tour, which will be shown in the `CodeTour` tree view, quick pick, etc.
- `description` - An optional description for the tour, which will be shown as the tooltip for the tour in the `CodeTour` tree view
- `ref` - An optional "git ref" (branch/tag/commit) that this tour applies to. See [versioning tours](#versioning-tours) for more details.
- `steps` - An array of tour steps
- `file` - The file path (relative to the workspace root) that this step is associated with
- `uri` - An absolute URI that this step is associated with. Note that `uri` and `file` are mutually exclusive, so only set one per step
- `line` - The 1-based line number that this step is associated with
- `title` - An optional title, which will be displayed as the step name in the `CodeTour` tree view.
- `description` - The text which explains the current file/line number, and can include plain text and markdown syntax
For an example, refer to the `.vscode/tour.json` file of this repository.
@ -155,9 +167,11 @@ In addition to the `CodeTour` tree view and the status bar item, the Code Tour e
- `CodeTour: Refresh Tours` - Refreshes the `Code Tours` view, which can be handy if you'd created/modified/deleted tour files on disk.
- `CodeTour: End Tour` - Ends the currently active tour.
- `CodeTour: Edit Tour` - Puts the currently active tour into edit more. This command is only visible while you're actively playing a tour, that you're not already editing.
-
- `CodeTour: Resume Current Tour` - Resumse the current tour by navigating to the file/line number that's associated with the current step.
- `CodeTour: End Tour` - Ends the currently active tour. This command is only visible while you're actively recording/playing a tour.
-
- `CodeTour: Resume Current Tour` - Resumse the current tour by navigating to the file/line number that's associated with the current step. This command is only visible while you're actively recording/playing a tour.
## Keybindings

Просмотреть файл

@ -3,7 +3,7 @@
"displayName": "CodeTour",
"description": "VS Code extension that allows you to record and playback guided tours of codebases, directly within the editor",
"publisher": "vsls-contrib",
"version": "0.0.9",
"version": "0.0.10",
"repository": {
"type": "git",
"url": "https://github.com/vsls-contrib/codetour"
@ -62,6 +62,7 @@
{
"command": "codetour.editTour",
"title": "Edit Tour",
"category": "CodeTour",
"icon": "$(edit)"
},
{
@ -71,7 +72,7 @@
{
"command": "codetour.endTour",
"title": "End Tour",
"category": "Code Tour",
"category": "CodeTour",
"icon": "$(debug-stop)"
},
{
@ -123,6 +124,10 @@
],
"menus": {
"commandPalette": [
{
"command": "codetour.editTour",
"when": "codetour:inTour && !codetour:recording"
},
{
"command": "codetour.endTour",
"when": "codetour:inTour"
@ -159,10 +164,6 @@
"command": "codetour.deleteTourStep",
"when": "false"
},
{
"command": "codetour.editTour",
"when": "false"
},
{
"command": "codetour.editTourStep",
"when": "false"

Просмотреть файл

@ -12,6 +12,10 @@
"type": "string",
"description": "Specifies an optional description for the code tour."
},
"ref": {
"type": "string",
"description": "Indicates the git ref (branch/commit/tag) that this tour associate with."
},
"steps": {
"type": "array",
"description": "Specifies the list of steps that are included in the code tour.",
@ -32,6 +36,10 @@
"type": "number",
"description": "Specifies the line number that is associated with the current step."
},
"title": {
"type": "string",
"description": "Specifies an optional title for the step"
},
"description": {
"type": "string",
"description": "Specifies the description of the current step."

Просмотреть файл

@ -13,7 +13,7 @@ import { discoverTours } from "./store/provider";
import { CodeTourNode, CodeTourStepNode } from "./tree/nodes";
import { runInAction, comparer } from "mobx";
import { api, RefType } from "./git";
import * as path from "path";
interface CodeTourQuickPickItem extends vscode.QuickPickItem {
tour: CodeTour;
}
@ -151,8 +151,15 @@ export function registerCommands() {
const thread = store.activeTour!.thread;
const stepNumber = store.activeTour!.step;
const file = store.activeTour!.workspaceRoot
? path.relative(
store.activeTour!.workspaceRoot.toString(),
thread!.uri.toString()
)
: vscode.workspace.asRelativePath(thread!.uri);
const step = {
file: vscode.workspace.asRelativePath(thread!.uri),
file,
line: thread!.range.start.line + 1,
description: reply.text
};
@ -231,7 +238,11 @@ export function registerCommands() {
} else if (store.activeTour) {
// We need to re-start the tour so that the associated
// comment controller is put into edit mode
startCodeTour(store.activeTour!.tour, store.activeTour!.step);
startCodeTour(
store.activeTour!.tour,
store.activeTour!.step,
store.activeTour.workspaceRoot
);
}
}
);

Просмотреть файл

@ -6,6 +6,7 @@ import { store } from "./store";
import { discoverTours } from "./store/provider";
import { registerTreeProvider } from "./tree";
import { initializeGitApi } from "./git";
import { startCodeTour, endCurrentCodeTour } from "./store/actions";
async function promptForTour(
workspaceRoot: string,
@ -39,4 +40,9 @@ export async function activate(context: vscode.ExtensionContext) {
initializeGitApi();
}
return {
startTour: startCodeTour,
endCurrentTour: endCurrentCodeTour
};
}

Просмотреть файл

@ -85,9 +85,12 @@ async function renderCurrentStep() {
label += ` (${currentTour.title})`;
}
const workspaceRoot = workspace.workspaceFolders
const workspaceRoot = store.activeTour!.workspaceRoot
? store.activeTour!.workspaceRoot
: workspace.workspaceFolders
? workspace.workspaceFolders[0].uri.toString()
: "";
let uri = step.uri
? Uri.parse(step.uri)
: Uri.parse(`${workspaceRoot}/${step.file}`);
@ -141,7 +144,11 @@ async function renderCurrentStep() {
showDocument(uri, range, selection);
}
export function startCodeTour(tour: CodeTour, stepNumber?: number) {
export function startCodeTour(
tour: CodeTour,
stepNumber?: number,
workspaceRoot?: Uri
) {
if (controller) {
controller.dispose();
}
@ -164,6 +171,7 @@ export function startCodeTour(tour: CodeTour, stepNumber?: number) {
store.activeTour = {
tour,
step: stepNumber ? stepNumber : tour.steps.length ? 0 : -1,
workspaceRoot,
thread: null
};

Просмотреть файл

@ -1,5 +1,5 @@
import { observable } from "mobx";
import { CommentThread } from "vscode";
import { CommentThread, Uri } from "vscode";
export const PENDING_TOUR_ID = "@@RECORDING";
@ -32,6 +32,10 @@ export interface ActiveTour {
// When recording, a tour can be active, without
// having created an actual comment yet.
thread: CommentThread | null | undefined;
// In order to resolve relative file
// paths, we need to know the workspace root
workspaceRoot?: Uri;
}
export interface Store {

Просмотреть файл

@ -27,7 +27,10 @@ class CodeTourTreeProvider implements TreeDataProvider<TreeItem>, Disposable {
? [
store.activeTour.tour.title,
store.activeTour.tour.description,
store.activeTour.tour.steps.map(step => step.description)
store.activeTour.tour.steps.map(step => [
step.title,
step.description
])
]
: null
],

Просмотреть файл

@ -51,8 +51,21 @@ export class CodeTourNode extends TreeItem {
}
}
function getStepLabel(tour: CodeTour, step: number) {
return tour.steps[step].uri ? tour.steps[step].uri! : tour.steps[step].file!;
const HEADING_PATTERN = /^#+\s*(.*)/;
function getStepLabel(tour: CodeTour, stepNumber: number) {
const step = tour.steps[stepNumber];
const prefix = `#${stepNumber + 1} - `;
let label;
if (step.title) {
label = step.title;
} else if (HEADING_PATTERN.test(step.description.trim())) {
label = step.description.trim().match(HEADING_PATTERN)![1];
} else {
label = step.uri ? step.uri! : step.file!;
}
return `${prefix}${label}`;
}
export class CodeTourStepNode extends TreeItem {
@ -67,8 +80,6 @@ export class CodeTourStepNode extends TreeItem {
arguments: [tour, stepNumber]
};
this.description = step.description;
this.resourceUri = step.uri
? Uri.parse(step.uri)!
: Uri.parse(