Skip to content

Commit 53bebc8

Browse files
author
Eric Amodio
committed
Initial commit -- very basic blame support
0 parents  commit 53bebc8

17 files changed

+456
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
out
2+
node_modules

.vscode/launch.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// A launch configuration that compiles the extension and then opens it inside a new window
2+
{
3+
"version": "0.1.0",
4+
"configurations": [
5+
{
6+
"name": "Launch Extension",
7+
"type": "extensionHost",
8+
"request": "launch",
9+
"runtimeExecutable": "${execPath}",
10+
"args": ["--extensionDevelopmentPath=${workspaceRoot}" ],
11+
"stopOnEntry": false,
12+
"sourceMaps": true,
13+
"outDir": "${workspaceRoot}/out/src",
14+
"preLaunchTask": "npm"
15+
},
16+
{
17+
"name": "Launch Tests",
18+
"type": "extensionHost",
19+
"request": "launch",
20+
"runtimeExecutable": "${execPath}",
21+
"args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test" ],
22+
"stopOnEntry": false,
23+
"sourceMaps": true,
24+
"outDir": "${workspaceRoot}/out/test",
25+
"preLaunchTask": "npm"
26+
}
27+
]
28+
}

.vscode/settings.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Place your settings in this file to overwrite default and user settings.
2+
{
3+
"files.exclude": {
4+
"out": false, // set this to true to hide the "out" folder with the compiled JS files
5+
"node_modules": false
6+
},
7+
"search.exclude": {
8+
"out": true, // set this to false to include "out" folder in search results
9+
"node_modules": true
10+
},
11+
"typescript.tsdk": "./node_modules/typescript/lib" // we want to use the TS server from our node_modules folder to control its version
12+
}

.vscode/tasks.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Available variables which can be used inside of strings.
2+
// ${workspaceRoot}: the root folder of the team
3+
// ${file}: the current opened file
4+
// ${fileBasename}: the current opened file's basename
5+
// ${fileDirname}: the current opened file's dirname
6+
// ${fileExtname}: the current opened file's extension
7+
// ${cwd}: the current working directory of the spawned process
8+
9+
// A task runner that calls a custom npm script that compiles the extension.
10+
{
11+
"version": "0.1.0",
12+
13+
// we want to run npm
14+
"command": "npm",
15+
16+
// the command is a shell script
17+
"isShellCommand": true,
18+
19+
// show the output window only if unrecognized errors occur.
20+
"showOutput": "silent",
21+
22+
// we run the custom script "compile" as defined in package.json
23+
"args": ["run", "compile", "--loglevel", "silent"],
24+
25+
// The tsc compiler is started in watching mode
26+
"isWatching": true,
27+
28+
// use the standard tsc in watch mode problem matcher to find compile problems in the output.
29+
"problemMatcher": "$tsc-watch"
30+
}

.vscodeignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.vscode/**
2+
typings/**
3+
out/test/**
4+
test/**
5+
src/**
6+
**/*.map
7+
.gitignore
8+
tsconfig.json
9+
vsc-extension-quickstart.md

LICENSE

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2016 Eric Amodio
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
22+

README.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# git-codelens README
2+
3+
This is the README for your extension "git-codelens". After writing up a brief description, we recommend including the following sections.
4+
5+
## Features
6+
7+
Describe specific features of your extension including screenshots of your extension in action. Image paths are relative to this README file.
8+
9+
For example if there is an image subfolder under your extension project workspace:
10+
11+
\!\[feature X\]\(images/feature-x.png\)
12+
13+
> Tip: Many popular extensions utilize animations. This is an excellent way to show off your extension! We recommend short, focused animations that are easy to follow.
14+
15+
## Requirements
16+
17+
If you have any requirements or dependencies, add a section describing those and how to install and configure them.
18+
19+
## Extension Settings
20+
21+
Include if your extension adds any VS Code settings through the `contributes.configuration` extension point.
22+
23+
For example:
24+
25+
This extension contributes the following settings:
26+
27+
* `myExtension.enable`: enable/disable this extension
28+
* `myExtension.thing`: set to `blah` to do something
29+
30+
## Known Issues
31+
32+
Calling out known issues can help limit users opening duplicate issues against your extension.
33+
34+
## Release Notes
35+
36+
Users appreciate release notes as you update your extension.
37+
38+
### 1.0.0
39+
40+
Initial release of ...
41+
42+
### 1.0.1
43+
44+
Fixed issue #.
45+
46+
### 1.1.0
47+
48+
Added features X, Y, and Z.
49+
50+
-----------------------------------------------------------------------------------------------------------
51+
52+
## Working with Markdown
53+
54+
**Note:** You can author your README using Visual Studio Code. Here are some useful editor keyboard shortcuts:
55+
56+
* Split the editor (`Cmd+\` on OSX or `Ctrl+\` on Windows and Linux)
57+
* Toggle preview (`Shift+CMD+V` on OSX or `Shift+Ctrl+V` on Windows and Linux)
58+
* Press `Ctrl+Space` (Windows, Linux) or `Cmd+Space` (OSX) to see a list of Markdown snippets
59+
60+
### For more information
61+
62+
* [Visual Studio Code's Markdown Support](http://code.visualstudio.com/docs/languages/markdown)
63+
* [Markdown Syntax Reference](https://help.github.com/articles/markdown-basics/)
64+
65+
**Enjoy!**

package.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"name": "git-codelens",
3+
"displayName": "Git CodeLens",
4+
"description": "Provides Git blame information in CodeLens",
5+
"version": "0.0.1",
6+
"author": "Eric Amodio",
7+
"publisher": "eamodio",
8+
"engines": {
9+
"vscode": "^1.3.0"
10+
},
11+
"categories": [
12+
"Other"
13+
],
14+
"activationEvents": [
15+
"*"
16+
],
17+
"keywords": [
18+
"git", "gitblame", "blame"
19+
],
20+
"main": "./out/src/extension",
21+
"contributes": {
22+
},
23+
"scripts": {
24+
"vscode:prepublish": "node ./node_modules/vscode/bin/compile",
25+
"compile": "node ./node_modules/vscode/bin/compile -watch -p ./",
26+
"postinstall": "node ./node_modules/vscode/bin/install && tsc"
27+
},
28+
"dependencies": {
29+
},
30+
"devDependencies": {
31+
"typescript": "^1.8.10",
32+
"vscode": "^0.11.15"
33+
}
34+
}

src/codeLensProvider.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
'use strict';
2+
import {CancellationToken, CodeLens, CodeLensProvider, commands, Range, SymbolInformation, SymbolKind, TextDocument, Uri} from 'vscode';
3+
import {IBlameLine, gitBlame} from './git';
4+
import * as moment from 'moment';
5+
6+
export class GitCodeLens extends CodeLens {
7+
constructor(public blame: Promise<IBlameLine[]>, public fileName: string, public blameRange: Range, range: Range) {
8+
super(range);
9+
10+
this.blame = blame;
11+
this.fileName = fileName;
12+
this.blameRange = blameRange;
13+
}
14+
}
15+
16+
export default class GitCodeLensProvider implements CodeLensProvider {
17+
constructor(public repoPath: string) { }
18+
19+
provideCodeLenses(document: TextDocument, token: CancellationToken): CodeLens[] | Thenable<CodeLens[]> {
20+
// TODO: Should I wait here?
21+
let blame = gitBlame(document.fileName);
22+
23+
return (commands.executeCommand('vscode.executeDocumentSymbolProvider', document.uri) as Promise<SymbolInformation[]>).then(symbols => {
24+
let lenses: CodeLens[] = [];
25+
symbols.forEach(sym => this._provideCodeLens(document, sym, blame, lenses));
26+
return lenses;
27+
});
28+
}
29+
30+
private _provideCodeLens(document: TextDocument, symbol: SymbolInformation, blame: Promise<IBlameLine[]>, lenses: CodeLens[]): void {
31+
switch (symbol.kind) {
32+
case SymbolKind.Module:
33+
case SymbolKind.Class:
34+
case SymbolKind.Interface:
35+
case SymbolKind.Method:
36+
case SymbolKind.Function:
37+
case SymbolKind.Constructor:
38+
case SymbolKind.Field:
39+
case SymbolKind.Property:
40+
break;
41+
default:
42+
return;
43+
}
44+
45+
var line = document.lineAt(symbol.location.range.start);
46+
// if (line.text.includes(symbol.name)) {
47+
// }
48+
49+
let lens = new GitCodeLens(blame, document.fileName, symbol.location.range, line.range);
50+
lenses.push(lens);
51+
}
52+
53+
resolveCodeLens(codeLens: CodeLens, token: CancellationToken): Thenable<CodeLens> {
54+
if (codeLens instanceof GitCodeLens) {
55+
return codeLens.blame.then(allLines => {
56+
let lines = allLines.slice(codeLens.blameRange.start.line, codeLens.blameRange.end.line + 1);
57+
let line = lines[0];
58+
if (lines.length > 1) {
59+
let sorted = lines.sort((a, b) => b.date.getTime() - a.date.getTime());
60+
line = sorted[0];
61+
}
62+
63+
codeLens.command = {
64+
title: `${line.author}, ${moment(line.date).fromNow()}`,
65+
command: 'git.viewFileHistory',
66+
arguments: [Uri.file(codeLens.fileName)]
67+
};
68+
return codeLens;
69+
});//.catch(ex => Promise.reject(ex)); // TODO: Figure out a better way to stop the codelens from appearing
70+
}
71+
}
72+
}

src/extension.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use strict';
2+
import {DocumentSelector, ExtensionContext, languages, workspace} from 'vscode';
3+
import GitCodeLensProvider from './codeLensProvider';
4+
import {gitRepoPath} from './git'
5+
6+
// this method is called when your extension is activated
7+
export function activate(context: ExtensionContext) {
8+
// Workspace not using a folder. No access to git repo.
9+
if (!workspace.rootPath) {
10+
return;
11+
}
12+
13+
gitRepoPath(workspace.rootPath).then(repoPath => {
14+
let selector: DocumentSelector = { scheme: 'file' };
15+
context.subscriptions.push(languages.registerCodeLensProvider(selector, new GitCodeLensProvider(repoPath)));
16+
}).catch(reason => console.warn(reason));
17+
}
18+
19+
// this method is called when your extension is deactivated
20+
export function deactivate() {
21+
}

0 commit comments

Comments
 (0)