Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
094a469d
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
094a469d
编写于
4月 03, 2018
作者:
M
Matt Bierner
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Working on adding comment api
上级
b4195abe
变更
65
隐藏空白更改
内联
并排
Showing
65 changed file
with
2031 addition
and
29 deletion
+2031
-29
extensions/git-extended/.vscode/launch.json
extensions/git-extended/.vscode/launch.json
+18
-0
extensions/git-extended/.vscode/tasks.json
extensions/git-extended/.vscode/tasks.json
+9
-0
extensions/git-extended/.vscodeignore
extensions/git-extended/.vscodeignore
+2
-0
extensions/git-extended/README.md
extensions/git-extended/README.md
+5
-0
extensions/git-extended/images/npm_icon.png
extensions/git-extended/images/npm_icon.png
+0
-0
extensions/git-extended/package.json
extensions/git-extended/package.json
+119
-0
extensions/git-extended/package.nls.json
extensions/git-extended/package.nls.json
+11
-0
extensions/git-extended/resources/icons/checked_checkbox.png
extensions/git-extended/resources/icons/checked_checkbox.png
+0
-0
extensions/git-extended/resources/icons/dark/check.svg
extensions/git-extended/resources/icons/dark/check.svg
+1
-0
extensions/git-extended/resources/icons/dark/clean.svg
extensions/git-extended/resources/icons/dark/clean.svg
+1
-0
extensions/git-extended/resources/icons/dark/git.svg
extensions/git-extended/resources/icons/dark/git.svg
+1
-0
extensions/git-extended/resources/icons/dark/open-change.svg
extensions/git-extended/resources/icons/dark/open-change.svg
+1
-0
extensions/git-extended/resources/icons/dark/open-file.svg
extensions/git-extended/resources/icons/dark/open-file.svg
+1
-0
extensions/git-extended/resources/icons/dark/refresh.svg
extensions/git-extended/resources/icons/dark/refresh.svg
+1
-0
extensions/git-extended/resources/icons/dark/stage.svg
extensions/git-extended/resources/icons/dark/stage.svg
+1
-0
extensions/git-extended/resources/icons/dark/status-added.svg
...nsions/git-extended/resources/icons/dark/status-added.svg
+6
-0
extensions/git-extended/resources/icons/dark/status-conflict.svg
...ons/git-extended/resources/icons/dark/status-conflict.svg
+6
-0
extensions/git-extended/resources/icons/dark/status-copied.svg
...sions/git-extended/resources/icons/dark/status-copied.svg
+6
-0
extensions/git-extended/resources/icons/dark/status-deleted.svg
...ions/git-extended/resources/icons/dark/status-deleted.svg
+6
-0
extensions/git-extended/resources/icons/dark/status-ignored.svg
...ions/git-extended/resources/icons/dark/status-ignored.svg
+6
-0
extensions/git-extended/resources/icons/dark/status-modified.svg
...ons/git-extended/resources/icons/dark/status-modified.svg
+6
-0
extensions/git-extended/resources/icons/dark/status-renamed.svg
...ions/git-extended/resources/icons/dark/status-renamed.svg
+6
-0
extensions/git-extended/resources/icons/dark/status-untracked.svg
...ns/git-extended/resources/icons/dark/status-untracked.svg
+6
-0
extensions/git-extended/resources/icons/dark/unstage.svg
extensions/git-extended/resources/icons/dark/unstage.svg
+1
-0
extensions/git-extended/resources/icons/light/check.svg
extensions/git-extended/resources/icons/light/check.svg
+1
-0
extensions/git-extended/resources/icons/light/clean.svg
extensions/git-extended/resources/icons/light/clean.svg
+1
-0
extensions/git-extended/resources/icons/light/git.svg
extensions/git-extended/resources/icons/light/git.svg
+1
-0
extensions/git-extended/resources/icons/light/open-change.svg
...nsions/git-extended/resources/icons/light/open-change.svg
+1
-0
extensions/git-extended/resources/icons/light/open-file.svg
extensions/git-extended/resources/icons/light/open-file.svg
+3
-0
extensions/git-extended/resources/icons/light/refresh.svg
extensions/git-extended/resources/icons/light/refresh.svg
+1
-0
extensions/git-extended/resources/icons/light/stage.svg
extensions/git-extended/resources/icons/light/stage.svg
+1
-0
extensions/git-extended/resources/icons/light/status-added.svg
...sions/git-extended/resources/icons/light/status-added.svg
+6
-0
extensions/git-extended/resources/icons/light/status-conflict.svg
...ns/git-extended/resources/icons/light/status-conflict.svg
+6
-0
extensions/git-extended/resources/icons/light/status-copied.svg
...ions/git-extended/resources/icons/light/status-copied.svg
+6
-0
extensions/git-extended/resources/icons/light/status-deleted.svg
...ons/git-extended/resources/icons/light/status-deleted.svg
+6
-0
extensions/git-extended/resources/icons/light/status-ignored.svg
...ons/git-extended/resources/icons/light/status-ignored.svg
+6
-0
extensions/git-extended/resources/icons/light/status-modified.svg
...ns/git-extended/resources/icons/light/status-modified.svg
+6
-0
extensions/git-extended/resources/icons/light/status-renamed.svg
...ons/git-extended/resources/icons/light/status-renamed.svg
+6
-0
extensions/git-extended/resources/icons/light/status-untracked.svg
...s/git-extended/resources/icons/light/status-untracked.svg
+6
-0
extensions/git-extended/resources/icons/light/unstage.svg
extensions/git-extended/resources/icons/light/unstage.svg
+1
-0
extensions/git-extended/resources/icons/unchecked_checkbox.png
...sions/git-extended/resources/icons/unchecked_checkbox.png
+0
-0
extensions/git-extended/src/commitsProvider.ts
extensions/git-extended/src/commitsProvider.ts
+219
-0
extensions/git-extended/src/common/diff.ts
extensions/git-extended/src/common/diff.ts
+155
-0
extensions/git-extended/src/common/file.ts
extensions/git-extended/src/common/file.ts
+107
-0
extensions/git-extended/src/common/log.ts
extensions/git-extended/src/common/log.ts
+77
-0
extensions/git-extended/src/common/models/comment.ts
extensions/git-extended/src/common/models/comment.ts
+29
-0
extensions/git-extended/src/common/models/commit.ts
extensions/git-extended/src/common/models/commit.ts
+3
-0
extensions/git-extended/src/common/models/file.ts
extensions/git-extended/src/common/models/file.ts
+49
-0
extensions/git-extended/src/common/models/remote.ts
extensions/git-extended/src/common/models/remote.ts
+21
-0
extensions/git-extended/src/common/models/repository.ts
extensions/git-extended/src/common/models/repository.ts
+19
-0
extensions/git-extended/src/common/remote.ts
extensions/git-extended/src/common/remote.ts
+47
-0
extensions/git-extended/src/extension.ts
extensions/git-extended/src/extension.ts
+20
-0
extensions/git-extended/src/prProvider.ts
extensions/git-extended/src/prProvider.ts
+242
-0
extensions/git-extended/src/typings/ref.d.ts
extensions/git-extended/src/typings/ref.d.ts
+7
-0
extensions/git-extended/tsconfig.json
extensions/git-extended/tsconfig.json
+18
-0
extensions/git-extended/yarn.lock
extensions/git-extended/yarn.lock
+482
-0
src/vs/editor/common/modes.ts
src/vs/editor/common/modes.ts
+16
-0
src/vs/editor/contrib/review/review.ts
src/vs/editor/contrib/review/review.ts
+35
-28
src/vs/monaco.d.ts
src/vs/monaco.d.ts
+14
-0
src/vs/vscode.proposed.d.ts
src/vs/vscode.proposed.d.ts
+22
-0
src/vs/workbench/api/electron-browser/extensionHost.contribution.ts
...kbench/api/electron-browser/extensionHost.contribution.ts
+1
-0
src/vs/workbench/api/electron-browser/mainThreadComments.ts
src/vs/workbench/api/electron-browser/mainThreadComments.ts
+77
-0
src/vs/workbench/api/node/extHost.api.impl.ts
src/vs/workbench/api/node/extHost.api.impl.ts
+5
-0
src/vs/workbench/api/node/extHost.protocol.ts
src/vs/workbench/api/node/extHost.protocol.ts
+12
-1
src/vs/workbench/api/node/extHostComments.ts
src/vs/workbench/api/node/extHostComments.ts
+76
-0
未找到文件。
extensions/git-extended/.vscode/launch.json
0 → 100644
浏览文件 @
094a469d
{
"version"
:
"0.2.0"
,
"configurations"
:
[
{
"name"
:
"Launch Extension"
,
"type"
:
"extensionHost"
,
"request"
:
"launch"
,
"runtimeExecutable"
:
"${execPath}"
,
"args"
:
[
"--extensionDevelopmentPath=${workspaceFolder}"
],
"stopOnEntry"
:
false
,
"sourceMaps"
:
true
,
"outFiles"
:
[
"${workspaceFolder}/client/out/**/*.js"
],
"preLaunchTask"
:
"npm"
}
]
}
\ No newline at end of file
extensions/git-extended/.vscode/tasks.json
0 → 100644
浏览文件 @
094a469d
{
"version"
:
"0.1.0"
,
"command"
:
"npm"
,
"isShellCommand"
:
true
,
"showOutput"
:
"silent"
,
"args"
:
[
"run"
,
"compile"
],
"isBackground"
:
true
,
"problemMatcher"
:
"$tsc-watch"
}
\ No newline at end of file
extensions/git-extended/.vscodeignore
0 → 100644
浏览文件 @
094a469d
src/**
tsconfig.json
\ No newline at end of file
extensions/git-extended/README.md
0 → 100644
浏览文件 @
094a469d
# Git Extended
## Notices
Uses code from github desktop: https://github.com/desktop/desktop
\ No newline at end of file
extensions/git-extended/images/npm_icon.png
0 → 100644
浏览文件 @
094a469d
3.2 KB
extensions/git-extended/package.json
0 → 100644
浏览文件 @
094a469d
{
"name"
:
"git-extended"
,
"displayName"
:
"Git Extended"
,
"description"
:
"Git Extended"
,
"enableProposedApi"
:
true
,
"version"
:
"0.0.1"
,
"publisher"
:
"rebornix"
,
"engines"
:
{
"vscode"
:
"^1.13.0"
},
"categories"
:
[
"Other"
],
"activationEvents"
:
[
"onView:commits"
,
"onView:stash"
,
"onView:pr"
],
"main"
:
"./out/extension"
,
"contributes"
:
{
"views"
:
{
"explorer"
:
[
{
"id"
:
"pr"
,
"name"
:
"Pull Requests"
}
]
},
"commands"
:
[
{
"command"
:
"commits.revertCommit"
,
"title"
:
"Revert"
,
"icon"
:
{
"dark"
:
"resources/icons/dark/clean.svg"
,
"light"
:
"resources/icons/light/clean.svg"
}
},
{
"command"
:
"commits.refresh"
,
"title"
:
"Refresh"
,
"icon"
:
{
"dark"
:
"resources/icons/dark/refresh.svg"
,
"light"
:
"resources/icons/light/refresh.svg"
}
},
{
"command"
:
"pr.refreshList"
,
"title"
:
"Refresh"
,
"icon"
:
{
"dark"
:
"resources/icons/dark/refresh.svg"
,
"light"
:
"resources/icons/light/refresh.svg"
}
},
{
"command"
:
"stash.apply"
,
"title"
:
"Apply Stash"
},
{
"command"
:
"stash.delete"
,
"title"
:
"Delete Stash"
},
{
"command"
:
"stash.pop"
,
"title"
:
"Pop Stash"
},
{
"command"
:
"stash.stash"
,
"title"
:
"Stash"
,
"icon"
:
{
"dark"
:
"resources/icons/dark/stage.svg"
,
"light"
:
"resources/icons/light/stage.svg"
}
}
],
"menus"
:
{
"view/title"
:
[
{
"command"
:
"commits.refresh"
,
"when"
:
"view == commits"
,
"group"
:
"navigation"
},
{
"command"
:
"stash.stash"
,
"when"
:
"view == stash"
,
"group"
:
"navigation"
}
],
"view/item/context"
:
[
{
"command"
:
"stash.apply"
,
"when"
:
"view == stash"
},
{
"command"
:
"stash.pop"
,
"when"
:
"view == stash"
},
{
"command"
:
"stash.delete"
,
"when"
:
"view == stash"
}
]
}
},
"scripts"
:
{
"vscode:prepublish"
:
"tsc -p ./"
,
"compile"
:
"tsc -watch -p ./"
},
"devDependencies"
:
{
"typescript"
:
"^2.1.4"
,
"@types/node"
:
"*"
},
"dependencies"
:
{
"dugite"
:
"^1.28.0"
,
"tmp"
:
"^0.0.31"
,
"octokat"
:
"^0.8.0"
,
"request"
:
"^2.81.0"
,
"lodash"
:
"4.17.5"
}
}
extensions/git-extended/package.nls.json
0 → 100644
浏览文件 @
094a469d
{
"description"
:
"Extension to add task support for npm scripts."
,
"displayName"
:
"Npm support for VSCode"
,
"config.npm.autoDetect"
:
"Controls whether auto detection of npm scripts is on or off. Default is on."
,
"config.npm.runSilent"
:
"Run npm commands with the `--silent` option."
,
"config.npm.packageManager"
:
"The package manager used to run scripts."
,
"config.npm.exclude"
:
"Configure glob patterns for folders that should be excluded from automatic script detection."
,
"npm.parseError"
:
"Npm task detection: failed to parse the file {0}"
,
"taskdef.script"
:
"The npm script to customize."
,
"taskdef.path"
:
"The path to the folder of the package.json file that provides the script. Can be ommitted."
}
extensions/git-extended/resources/icons/checked_checkbox.png
0 → 100644
浏览文件 @
094a469d
1.3 KB
extensions/git-extended/resources/icons/dark/check.svg
0 → 100644
浏览文件 @
094a469d
<svg
xmlns=
"http://www.w3.org/2000/svg"
width=
"16"
height=
"16"
viewBox=
"-2 -2 16 16"
enable-background=
"new -2 -2 16 16"
><polygon
fill=
"#C5C5C5"
points=
"9,0 4.5,9 3,6 0,6 3,12 6,12 12,0"
/></svg>
\ No newline at end of file
extensions/git-extended/resources/icons/dark/clean.svg
0 → 100644
浏览文件 @
094a469d
<svg
xmlns=
"http://www.w3.org/2000/svg"
width=
"16"
height=
"16"
viewBox=
"-0.994 0 16 16"
enable-background=
"new -0.994 0 16 16"
><path
fill=
"#C5C5C5"
d=
"M13 6c0 1.461-.636 2.846-1.746 3.797l-5.584 4.951-1.324-1.496 5.595-4.962c.678-.582 1.061-1.413 1.061-2.29 0-1.654-1.345-3-2.997-3-.71 0-1.399.253-1.938.713l-1.521 1.287h2.448l-1.998 2h-3.996v-4l1.998-2v2.692l1.775-1.504c.899-.766 2.047-1.188 3.232-1.188 2.754 0 4.995 2.243 4.995 5z"
/></svg>
\ No newline at end of file
extensions/git-extended/resources/icons/dark/git.svg
0 → 100644
浏览文件 @
094a469d
<svg
xmlns=
"http://www.w3.org/2000/svg"
width=
"32"
height=
"32"
><path
d=
"M27.459 14.902l-10.439-10.439c-.296-.294-.672-.452-1.089-.452-.417 0-.793.157-1.089.452l-2.248 2.247 2.549 2.549c.249-.112.522-.177.813-.177 1.106 0 2.002.896 2.002 2.002 0 .291-.064.565-.176.814l2.311 2.336c.25-.111.633-.234.923-.234 1.106 0 2 .911 2 2.016s-.894 1.969-2 1.969c-1.105-.001-2.016-.751-2.016-1.985 0-.28.016-.462.119-.704l-2.373-2.374-.023.007v6.274c.747.295 1.277 1.026 1.277 1.875 0 1.105-.878 2.016-1.984 2.016-1.104 0-2.031-.926-2.031-2.031 0-.846.535-1.564 1.28-1.857l.001-6.25c-.762-.282-1.309-1.009-1.309-1.871 0-.28.059-.546.162-.788l-2.555-2.557-7.115 7.114c-.599.601-.601 1.576.001 2.178l10.44 10.518c.296.295.671.45 1.089.45.415 0 .796-.159 1.089-.45l10.391-10.471c.601-.599.599-1.576 0-2.177z"
fill=
"#fff"
/></svg>
\ No newline at end of file
extensions/git-extended/resources/icons/dark/open-change.svg
0 → 100644
浏览文件 @
094a469d
<svg
xmlns=
"http://www.w3.org/2000/svg"
width=
"16"
height=
"16"
><path
fill=
"#C5C5C5"
d=
"M15 4v6h-2.276c.113-.318.187-.653.226-1h1.05v-5h-2v-2h-4v2.051c-.347.038-.681.112-1 .225v-3.276h5l3 3zm-7 8.949v1.051h-6v-7h2.276c.126-.354.28-.693.485-1h-3.761v9h8v-2.051c-.166.02-.329.051-.5.051l-.5-.051z"
/><path
fill=
"#75BEFF"
d=
"M12 8.5c0-1.933-1.567-3.5-3.5-3.5s-3.5 1.567-3.5 3.5 1.567 3.5 3.5 3.5c.711 0 1.369-.215 1.922-.578l3.578 3.578 1-1-3.578-3.578c.363-.553.578-1.211.578-1.922zm-3.5 2.5c-1.381 0-2.5-1.119-2.5-2.5s1.119-2.5 2.5-2.5 2.5 1.119 2.5 2.5-1.119 2.5-2.5 2.5z"
/></svg>
\ No newline at end of file
extensions/git-extended/resources/icons/dark/open-file.svg
0 → 100644
浏览文件 @
094a469d
<svg
xmlns=
"http://www.w3.org/2000/svg"
width=
"16"
height=
"16"
><polygon
fill=
"#C5C5C5"
points=
"10,2 7.414,2 8.414,3 9,3 9,3.586 9,4 9,4.414 9,6 12,6 12,13 4,13 4,8 3,8 3,14 13,14 13,5"
/><polygon
fill=
"#75BEFF"
points=
"5,1 3,1 5,3 1,3 1,5 5,5 3,7 5,7 8,4"
/></svg>
\ No newline at end of file
extensions/git-extended/resources/icons/dark/refresh.svg
0 → 100644
浏览文件 @
094a469d
<svg
xmlns=
"http://www.w3.org/2000/svg"
width=
"16"
height=
"16"
><path
d=
"M13.451 5.609l-.579-.939-1.068.812-.076.094c-.335.415-.927 1.341-1.124 2.876l-.021.165.033.163.071.345c0 1.654-1.346 3-3 3-.795 0-1.545-.311-2.107-.868-.563-.567-.873-1.317-.873-2.111 0-1.431 1.007-2.632 2.351-2.929v2.926s2.528-2.087 2.984-2.461h.012l3.061-2.582-4.919-4.1h-1.137v2.404c-3.429.318-6.121 3.211-6.121 6.721 0 1.809.707 3.508 1.986 4.782 1.277 1.282 2.976 1.988 4.784 1.988 3.722 0 6.75-3.028 6.75-6.75 0-1.245-.349-2.468-1.007-3.536z"
fill=
"#2D2D30"
/><path
d=
"M12.6 6.134l-.094.071c-.269.333-.746 1.096-.91 2.375.057.277.092.495.092.545 0 2.206-1.794 4-4 4-1.098 0-2.093-.445-2.817-1.164-.718-.724-1.163-1.718-1.163-2.815 0-2.206 1.794-4 4-4l.351.025v1.85s1.626-1.342 1.631-1.339l1.869-1.577-3.5-2.917v2.218l-.371-.03c-3.176 0-5.75 2.574-5.75 5.75 0 1.593.648 3.034 1.695 4.076 1.042 1.046 2.482 1.694 4.076 1.694 3.176 0 5.75-2.574 5.75-5.75-.001-1.106-.318-2.135-.859-3.012z"
fill=
"#C5C5C5"
/></svg>
\ No newline at end of file
extensions/git-extended/resources/icons/dark/stage.svg
0 → 100644
浏览文件 @
094a469d
<svg
width=
"16"
height=
"16"
xmlns=
"http://www.w3.org/2000/svg"
><title>
Layer 1
</title><rect
height=
"11"
width=
"3"
y=
"3"
x=
"7"
fill=
"#C5C5C5"
/><rect
height=
"3"
width=
"11"
y=
"7"
x=
"3"
fill=
"#C5C5C5"
/></svg>
\ No newline at end of file
extensions/git-extended/resources/icons/dark/status-added.svg
0 → 100644
浏览文件 @
094a469d
<svg
width=
"14px"
height=
"14px"
viewBox=
"0 0 100 100"
xmlns=
"http://www.w3.org/2000/svg"
>
<rect
fill=
"#3c8746"
x=
"0"
y=
"0"
width=
"100"
height=
"100"
rx=
"35"
ry=
"35"
/>
<text
x=
"50"
y=
"75"
font-size=
"75"
text-anchor=
"middle"
style=
"font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Inconsolata", "Courier New", monospace, "Droid Sans Fallback";"
fill=
"white"
>
A
</text>
</svg>
\ No newline at end of file
extensions/git-extended/resources/icons/dark/status-conflict.svg
0 → 100644
浏览文件 @
094a469d
<svg
width=
"14px"
height=
"14px"
viewBox=
"0 0 100 100"
xmlns=
"http://www.w3.org/2000/svg"
>
<rect
fill=
"#7F4E7E"
x=
"0"
y=
"0"
width=
"100"
height=
"100"
rx=
"35"
ry=
"35"
/>
<text
x=
"50"
y=
"75"
font-size=
"75"
text-anchor=
"middle"
style=
"font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Inconsolata", "Courier New", monospace, "Droid Sans Fallback";"
fill=
"white"
>
C
</text>
</svg>
\ No newline at end of file
extensions/git-extended/resources/icons/dark/status-copied.svg
0 → 100644
浏览文件 @
094a469d
<svg
width=
"14px"
height=
"14px"
viewBox=
"0 0 100 100"
xmlns=
"http://www.w3.org/2000/svg"
>
<rect
fill=
"#692C77"
x=
"0"
y=
"0"
width=
"100"
height=
"100"
rx=
"35"
ry=
"35"
/>
<text
x=
"50"
y=
"75"
font-size=
"75"
text-anchor=
"middle"
style=
"font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Inconsolata", "Courier New", monospace, "Droid Sans Fallback";"
fill=
"white"
>
C
</text>
</svg>
\ No newline at end of file
extensions/git-extended/resources/icons/dark/status-deleted.svg
0 → 100644
浏览文件 @
094a469d
<svg
width=
"14px"
height=
"14px"
viewBox=
"0 0 100 100"
xmlns=
"http://www.w3.org/2000/svg"
>
<rect
fill=
"#9E121D"
x=
"0"
y=
"0"
width=
"100"
height=
"100"
rx=
"35"
ry=
"35"
/>
<text
x=
"50"
y=
"75"
font-size=
"75"
text-anchor=
"middle"
style=
"font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Inconsolata", "Courier New", monospace, "Droid Sans Fallback";"
fill=
"white"
>
D
</text>
</svg>
\ No newline at end of file
extensions/git-extended/resources/icons/dark/status-ignored.svg
0 → 100644
浏览文件 @
094a469d
<svg
width=
"14px"
height=
"14px"
viewBox=
"0 0 100 100"
xmlns=
"http://www.w3.org/2000/svg"
>
<rect
fill=
"#969696"
x=
"0"
y=
"0"
width=
"100"
height=
"100"
rx=
"35"
ry=
"35"
/>
<text
x=
"50"
y=
"75"
font-size=
"75"
text-anchor=
"middle"
style=
"font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Inconsolata", "Courier New", monospace, "Droid Sans Fallback";"
fill=
"white"
>
I
</text>
</svg>
\ No newline at end of file
extensions/git-extended/resources/icons/dark/status-modified.svg
0 → 100644
浏览文件 @
094a469d
<svg
width=
"14px"
height=
"14px"
viewBox=
"0 0 100 100"
xmlns=
"http://www.w3.org/2000/svg"
>
<rect
fill=
"#1B80B2"
x=
"0"
y=
"0"
width=
"100"
height=
"100"
rx=
"35"
ry=
"35"
/>
<text
x=
"50"
y=
"75"
font-size=
"75"
text-anchor=
"middle"
style=
"font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Inconsolata", "Courier New", monospace, "Droid Sans Fallback";"
fill=
"white"
>
M
</text>
</svg>
\ No newline at end of file
extensions/git-extended/resources/icons/dark/status-renamed.svg
0 → 100644
浏览文件 @
094a469d
<svg
width=
"14px"
height=
"14px"
viewBox=
"0 0 100 100"
xmlns=
"http://www.w3.org/2000/svg"
>
<rect
fill=
"#CC6633"
x=
"0"
y=
"0"
width=
"100"
height=
"100"
rx=
"35"
ry=
"35"
/>
<text
x=
"50"
y=
"75"
font-size=
"75"
text-anchor=
"middle"
style=
"font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Inconsolata", "Courier New", monospace, "Droid Sans Fallback";"
fill=
"white"
>
R
</text>
</svg>
\ No newline at end of file
extensions/git-extended/resources/icons/dark/status-untracked.svg
0 → 100644
浏览文件 @
094a469d
<svg
width=
"14px"
height=
"14px"
viewBox=
"0 0 100 100"
xmlns=
"http://www.w3.org/2000/svg"
>
<rect
fill=
"#6C6C6C"
x=
"0"
y=
"0"
width=
"100"
height=
"100"
rx=
"35"
ry=
"35"
/>
<text
x=
"50"
y=
"75"
font-size=
"75"
text-anchor=
"middle"
style=
"font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Inconsolata", "Courier New", monospace, "Droid Sans Fallback";"
fill=
"white"
>
U
</text>
</svg>
\ No newline at end of file
extensions/git-extended/resources/icons/dark/unstage.svg
0 → 100644
浏览文件 @
094a469d
<svg
width=
"16"
height=
"16"
xmlns=
"http://www.w3.org/2000/svg"
><title>
Layer 1
</title><rect
height=
"3"
width=
"11"
y=
"7"
x=
"3"
fill=
"#C5C5C5"
/></svg>
\ No newline at end of file
extensions/git-extended/resources/icons/light/check.svg
0 → 100644
浏览文件 @
094a469d
<svg
xmlns=
"http://www.w3.org/2000/svg"
width=
"16"
height=
"16"
><polygon
points=
"5.382,13 2.382,7 6.618,7 7,7.764 9.382,3 13.618,3 8.618,13"
fill=
"#F6F6F6"
/><path
d=
"M12 4l-4 8h-2l-2-4h2l1 2 3-6h2z"
fill=
"#424242"
/></svg>
\ No newline at end of file
extensions/git-extended/resources/icons/light/clean.svg
0 → 100644
浏览文件 @
094a469d
<svg
xmlns=
"http://www.w3.org/2000/svg"
width=
"16"
height=
"16"
viewBox=
"-0.994 0 16 16"
enable-background=
"new -0.994 0 16 16"
><path
fill=
"#424242"
d=
"M13 6c0 1.461-.636 2.846-1.746 3.797l-5.584 4.951-1.324-1.496 5.595-4.962c.678-.582 1.061-1.413 1.061-2.29 0-1.654-1.345-3-2.997-3-.71 0-1.399.253-1.938.713l-1.521 1.287h2.448l-1.998 2h-3.996v-4l1.998-2v2.692l1.775-1.504c.899-.766 2.047-1.188 3.232-1.188 2.754 0 4.995 2.243 4.995 5z"
/></svg>
\ No newline at end of file
extensions/git-extended/resources/icons/light/git.svg
0 → 100644
浏览文件 @
094a469d
<svg
xmlns=
"http://www.w3.org/2000/svg"
width=
"32"
height=
"32"
><defs><clipPath><path
d=
"M.06 91.886h91.828v-91.886h-91.828v91.886z"
/></clipPath><clipPath
id=
"a"
><path
d=
"M0 0h92v92h-92v-92z"
/></clipPath></defs><path
d=
"M28.497 14.84l-11.354-11.353c-.653-.654-1.714-.654-2.368 0l-2.357 2.358 2.99 2.991c.695-.235 1.492-.077 2.046.477.557.558.713 1.361.473 2.059l2.882 2.882c.698-.241 1.502-.085 2.059.473.778.778.778 2.039 0 2.818-.779.779-2.04.779-2.819 0-.586-.586-.73-1.446-.434-2.167l-2.688-2.688v7.074c.19.094.369.219.527.377.778.778.778 2.039 0 2.819-.778.778-2.04.778-2.818 0-.778-.779-.778-2.04 0-2.819.192-.192.415-.338.653-.435v-7.14c-.237-.097-.46-.241-.653-.435-.589-.589-.731-1.455-.429-2.179l-2.948-2.949-7.785 7.785c-.654.655-.654 1.715 0 2.369l11.354 11.353c.654.654 1.714.654 2.369 0l11.3-11.301c.654-.654.654-1.715 0-2.369"
fill=
"#424242"
clip-path=
"url(#a)"
/></svg>
\ No newline at end of file
extensions/git-extended/resources/icons/light/open-change.svg
0 → 100644
浏览文件 @
094a469d
<svg
xmlns=
"http://www.w3.org/2000/svg"
width=
"16"
height=
"16"
><path
fill=
"#656565"
d=
"M15 4v6h-2.276c.113-.318.187-.653.226-1h1.05v-5h-2v-2h-4v2.051c-.347.038-.681.112-1 .225v-3.276h5l3 3zm-7 8.949v1.051h-6v-7h2.276c.126-.354.28-.693.485-1h-3.761v9h8v-2.051c-.166.02-.329.051-.5.051l-.5-.051z"
/><path
fill=
"#00539C"
d=
"M12 8.5c0-1.933-1.567-3.5-3.5-3.5s-3.5 1.567-3.5 3.5 1.567 3.5 3.5 3.5c.711 0 1.369-.215 1.922-.578l3.578 3.578 1-1-3.578-3.578c.363-.553.578-1.211.578-1.922zm-3.5 2.5c-1.381 0-2.5-1.119-2.5-2.5s1.119-2.5 2.5-2.5 2.5 1.119 2.5 2.5-1.119 2.5-2.5 2.5z"
/></svg>
\ No newline at end of file
extensions/git-extended/resources/icons/light/open-file.svg
0 → 100644
浏览文件 @
094a469d
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
]>
<svg
xmlns=
"http://www.w3.org/2000/svg"
width=
"16"
height=
"16"
><polygon
fill=
"#656565"
points=
"10,2 7.414,2 8.414,3 9,3 9,3.586 9,4 9,4.414 9,6 12,6 12,13 4,13 4,8 3,8 3,14 13,14 13,5"
/><polygon
fill=
"#00539C"
points=
"5,1 3,1 5,3 1,3 1,5 5,5 3,7 5,7 8,4"
/></svg>
\ No newline at end of file
extensions/git-extended/resources/icons/light/refresh.svg
0 → 100644
浏览文件 @
094a469d
<svg
xmlns=
"http://www.w3.org/2000/svg"
width=
"16"
height=
"16"
><path
d=
"M13.451 5.609l-.579-.939-1.068.812-.076.094c-.335.415-.927 1.341-1.124 2.876l-.021.165.033.163.071.345c0 1.654-1.346 3-3 3-.795 0-1.545-.311-2.107-.868-.563-.567-.873-1.317-.873-2.111 0-1.431 1.007-2.632 2.351-2.929v2.926s2.528-2.087 2.984-2.461h.012l3.061-2.582-4.919-4.1h-1.137v2.404c-3.429.318-6.121 3.211-6.121 6.721 0 1.809.707 3.508 1.986 4.782 1.277 1.282 2.976 1.988 4.784 1.988 3.722 0 6.75-3.028 6.75-6.75 0-1.245-.349-2.468-1.007-3.536z"
fill=
"#F6F6F6"
/><path
d=
"M12.6 6.134l-.094.071c-.269.333-.746 1.096-.91 2.375.057.277.092.495.092.545 0 2.206-1.794 4-4 4-1.098 0-2.093-.445-2.817-1.164-.718-.724-1.163-1.718-1.163-2.815 0-2.206 1.794-4 4-4l.351.025v1.85s1.626-1.342 1.631-1.339l1.869-1.577-3.5-2.917v2.218l-.371-.03c-3.176 0-5.75 2.574-5.75 5.75 0 1.593.648 3.034 1.695 4.076 1.042 1.046 2.482 1.694 4.076 1.694 3.176 0 5.75-2.574 5.75-5.75-.001-1.106-.318-2.135-.859-3.012z"
fill=
"#424242"
/></svg>
\ No newline at end of file
extensions/git-extended/resources/icons/light/stage.svg
0 → 100644
浏览文件 @
094a469d
<svg
width=
"16"
height=
"16"
xmlns=
"http://www.w3.org/2000/svg"
><title>
Layer 1
</title><rect
height=
"11"
width=
"3"
y=
"3"
x=
"7"
fill=
"#424242"
/><rect
height=
"3"
width=
"11"
y=
"7"
x=
"3"
fill=
"#424242"
/></svg>
\ No newline at end of file
extensions/git-extended/resources/icons/light/status-added.svg
0 → 100644
浏览文件 @
094a469d
<svg
width=
"14px"
height=
"14px"
viewBox=
"0 0 100 100"
xmlns=
"http://www.w3.org/2000/svg"
>
<rect
fill=
"#2d883e"
x=
"0"
y=
"0"
width=
"100"
height=
"100"
rx=
"35"
ry=
"35"
/>
<text
x=
"50"
y=
"75"
font-size=
"75"
text-anchor=
"middle"
style=
"font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Inconsolata", "Courier New", monospace, "Droid Sans Fallback";"
fill=
"white"
>
A
</text>
</svg>
\ No newline at end of file
extensions/git-extended/resources/icons/light/status-conflict.svg
0 → 100644
浏览文件 @
094a469d
<svg
width=
"14px"
height=
"14px"
viewBox=
"0 0 100 100"
xmlns=
"http://www.w3.org/2000/svg"
>
<rect
fill=
"#9B4F96"
x=
"0"
y=
"0"
width=
"100"
height=
"100"
rx=
"35"
ry=
"35"
/>
<text
x=
"50"
y=
"75"
font-size=
"75"
text-anchor=
"middle"
style=
"font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Inconsolata", "Courier New", monospace, "Droid Sans Fallback";"
fill=
"white"
>
C
</text>
</svg>
\ No newline at end of file
extensions/git-extended/resources/icons/light/status-copied.svg
0 → 100644
浏览文件 @
094a469d
<svg
width=
"14px"
height=
"14px"
viewBox=
"0 0 100 100"
xmlns=
"http://www.w3.org/2000/svg"
>
<rect
fill=
"#682079"
x=
"0"
y=
"0"
width=
"100"
height=
"100"
rx=
"35"
ry=
"35"
/>
<text
x=
"50"
y=
"75"
font-size=
"75"
text-anchor=
"middle"
style=
"font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Inconsolata", "Courier New", monospace, "Droid Sans Fallback";"
fill=
"white"
>
C
</text>
</svg>
\ No newline at end of file
extensions/git-extended/resources/icons/light/status-deleted.svg
0 → 100644
浏览文件 @
094a469d
<svg
width=
"14px"
height=
"14px"
viewBox=
"0 0 100 100"
xmlns=
"http://www.w3.org/2000/svg"
>
<rect
fill=
"#B9131A"
x=
"0"
y=
"0"
width=
"100"
height=
"100"
rx=
"35"
ry=
"35"
/>
<text
x=
"50"
y=
"75"
font-size=
"75"
text-anchor=
"middle"
style=
"font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Inconsolata", "Courier New", monospace, "Droid Sans Fallback";"
fill=
"white"
>
D
</text>
</svg>
\ No newline at end of file
extensions/git-extended/resources/icons/light/status-ignored.svg
0 → 100644
浏览文件 @
094a469d
<svg
width=
"14px"
height=
"14px"
viewBox=
"0 0 100 100"
xmlns=
"http://www.w3.org/2000/svg"
>
<rect
fill=
"#969696"
x=
"0"
y=
"0"
width=
"100"
height=
"100"
rx=
"35"
ry=
"35"
/>
<text
x=
"50"
y=
"75"
font-size=
"75"
text-anchor=
"middle"
style=
"font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Inconsolata", "Courier New", monospace, "Droid Sans Fallback";"
fill=
"white"
>
I
</text>
</svg>
\ No newline at end of file
extensions/git-extended/resources/icons/light/status-modified.svg
0 → 100644
浏览文件 @
094a469d
<svg
width=
"14px"
height=
"14px"
viewBox=
"0 0 100 100"
xmlns=
"http://www.w3.org/2000/svg"
>
<rect
fill=
"#007ACC"
x=
"0"
y=
"0"
width=
"100"
height=
"100"
rx=
"35"
ry=
"35"
/>
<text
x=
"50"
y=
"75"
font-size=
"75"
text-anchor=
"middle"
style=
"font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Inconsolata", "Courier New", monospace, "Droid Sans Fallback";"
fill=
"white"
>
M
</text>
</svg>
\ No newline at end of file
extensions/git-extended/resources/icons/light/status-renamed.svg
0 → 100644
浏览文件 @
094a469d
<svg
width=
"14px"
height=
"14px"
viewBox=
"0 0 100 100"
xmlns=
"http://www.w3.org/2000/svg"
>
<rect
fill=
"#CC6633"
x=
"0"
y=
"0"
width=
"100"
height=
"100"
rx=
"35"
ry=
"35"
/>
<text
x=
"50"
y=
"75"
font-size=
"75"
text-anchor=
"middle"
style=
"font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Inconsolata", "Courier New", monospace, "Droid Sans Fallback";"
fill=
"white"
>
R
</text>
</svg>
\ No newline at end of file
extensions/git-extended/resources/icons/light/status-untracked.svg
0 → 100644
浏览文件 @
094a469d
<svg
width=
"14px"
height=
"14px"
viewBox=
"0 0 100 100"
xmlns=
"http://www.w3.org/2000/svg"
>
<rect
fill=
"#6C6C6C"
x=
"0"
y=
"0"
width=
"100"
height=
"100"
rx=
"35"
ry=
"35"
/>
<text
x=
"50"
y=
"75"
font-size=
"75"
text-anchor=
"middle"
style=
"font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Inconsolata", "Courier New", monospace, "Droid Sans Fallback";"
fill=
"white"
>
U
</text>
</svg>
\ No newline at end of file
extensions/git-extended/resources/icons/light/unstage.svg
0 → 100644
浏览文件 @
094a469d
<svg
width=
"16"
height=
"16"
xmlns=
"http://www.w3.org/2000/svg"
><title>
Layer 1
</title><rect
height=
"3"
width=
"11"
y=
"7"
x=
"3"
fill=
"#424242"
/></svg>
\ No newline at end of file
extensions/git-extended/resources/icons/unchecked_checkbox.png
0 → 100644
浏览文件 @
094a469d
1.1 KB
extensions/git-extended/src/commitsProvider.ts
0 → 100644
浏览文件 @
094a469d
import
*
as
path
from
'
path
'
;
import
*
as
vscode
from
'
vscode
'
;
import
{
Repository
}
from
'
./common//models/repository
'
;
import
{
getChangedFiles
,
getFile
}
from
'
./common/file
'
;
import
{
getCommits
}
from
'
./common/log
'
;
import
{
Commit
}
from
'
./common/models/commit
'
;
import
{
GitChangeType
}
from
'
./common/models/file
'
;
export
class
CommitTreeItem
implements
vscode
.
TreeItem
{
readonly
iconPath
?:
string
|
vscode
.
Uri
|
{
light
:
string
|
vscode
.
Uri
;
dark
:
string
|
vscode
.
Uri
};
constructor
(
public
readonly
context
:
vscode
.
ExtensionContext
,
public
readonly
label
:
string
,
public
readonly
sha
:
string
,
public
readonly
parentSHAs
:
ReadonlyArray
<
string
>
,
public
readonly
command
?:
vscode
.
Command
,
public
readonly
collapsibleState
?:
vscode
.
TreeItemCollapsibleState
)
{
this
.
collapsibleState
=
1
;
}
}
export
class
FileChangeItem
implements
vscode
.
TreeItem
{
public
iconPath
?:
string
|
vscode
.
Uri
|
{
light
:
string
|
vscode
.
Uri
;
dark
:
string
|
vscode
.
Uri
};
public
filePath
:
string
;
public
sha
:
string
;
public
parentFilePath
:
string
;
public
parentSha
:
string
;
public
command
?:
vscode
.
Command
;
public
comments
?:
any
[];
constructor
(
public
readonly
label
:
string
,
public
readonly
status
:
GitChangeType
,
public
readonly
context
:
vscode
.
ExtensionContext
,
public
readonly
fileName
:
string
,
public
readonly
workspaceRoot
?:
string
)
{
}
public
populateCommandArgs
()
{
if
(
this
.
status
===
GitChangeType
.
MODIFY
)
{
this
.
command
=
{
title
:
'
show diff
'
,
command
:
ShowDiffCommand
.
id
,
arguments
:
[
this
]
};
}
else
if
(
this
.
status
===
GitChangeType
.
DELETE
)
{
this
.
command
=
{
title
:
'
show diff
'
,
command
:
'
vscode.open
'
,
arguments
:
[
vscode
.
Uri
.
file
(
path
.
resolve
(
this
.
workspaceRoot
,
this
.
parentFilePath
))
]
};
}
else
{
this
.
command
=
{
title
:
'
show diff
'
,
command
:
'
vscode.open
'
,
arguments
:
[
vscode
.
Uri
.
file
(
path
.
resolve
(
this
.
workspaceRoot
,
this
.
filePath
))
]
};
}
}
}
class
ShowDiffCommand
{
static
readonly
id
=
'
msgit.showDiff
'
;
static
run
(
item
:
FileChangeItem
)
{
vscode
.
commands
.
executeCommand
(
'
vscode.diff
'
,
vscode
.
Uri
.
file
(
path
.
resolve
(
item
.
workspaceRoot
,
item
.
parentFilePath
)),
vscode
.
Uri
.
file
(
path
.
resolve
(
item
.
workspaceRoot
,
item
.
filePath
)),
item
.
fileName
);
}
}
export
class
CommitsProvider
implements
vscode
.
TreeDataProvider
<
CommitTreeItem
>
{
private
context
:
vscode
.
ExtensionContext
;
private
workspaceRoot
:
string
;
private
repository
:
Repository
;
private
icons
:
any
;
private
_onDidChangeTreeData
:
vscode
.
EventEmitter
<
CommitTreeItem
|
undefined
>
=
new
vscode
.
EventEmitter
<
CommitTreeItem
|
undefined
>
();
readonly
onDidChangeTreeData
:
vscode
.
Event
<
CommitTreeItem
|
undefined
>
=
this
.
_onDidChangeTreeData
.
event
;
activate
(
context
:
vscode
.
ExtensionContext
,
workspaceRoot
:
string
,
repository
:
Repository
)
{
this
.
context
=
context
;
this
.
workspaceRoot
=
workspaceRoot
;
this
.
repository
=
repository
;
vscode
.
window
.
registerTreeDataProvider
<
CommitTreeItem
>
(
'
commits
'
,
this
);
this
.
icons
=
{
light
:
{
Modified
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
light
'
,
'
status-modified.svg
'
)),
Added
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
light
'
,
'
status-added.svg
'
)),
Deleted
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
light
'
,
'
status-deleted.svg
'
)),
Renamed
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
light
'
,
'
status-renamed.svg
'
)),
Copied
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
light
'
,
'
status-copied.svg
'
)),
Untracked
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
light
'
,
'
status-untrackedt.svg
'
)),
Ignored
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
light
'
,
'
status-ignored.svg
'
)),
Conflict
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
light
'
,
'
status-conflict.svg
'
)),
},
dark
:
{
Modified
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
dark
'
,
'
status-modified.svg
'
)),
Added
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
dark
'
,
'
status-added.svg
'
)),
Deleted
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
dark
'
,
'
status-deleted.svg
'
)),
Renamed
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
dark
'
,
'
status-renamed.svg
'
)),
Copied
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
dark
'
,
'
status-copied.svg
'
)),
Untracked
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
dark
'
,
'
status-untracked.svg
'
)),
Ignored
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
dark
'
,
'
status-ignored.svg
'
)),
Conflict
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
dark
'
,
'
status-conflict.svg
'
))
}
};
vscode
.
commands
.
registerCommand
(
'
commits.refresh
'
,
async
(
args
)
=>
{
this
.
_onDidChangeTreeData
.
fire
();
});
vscode
.
commands
.
registerCommand
(
'
commits.revertCommit
'
,
async
(
element
)
=>
{
// TODO
// We can want to allow users to revert several commits
});
vscode
.
commands
.
registerCommand
(
ShowDiffCommand
.
id
,
ShowDiffCommand
.
run
);
}
getTreeItem
(
element
:
CommitTreeItem
|
FileChangeItem
):
vscode
.
TreeItem
{
if
(
element
instanceof
FileChangeItem
)
{
let
iconUri
:
string
;
let
iconDarkUri
:
string
;
switch
(
element
.
status
)
{
case
GitChangeType
.
ADD
:
iconUri
=
this
.
icons
.
light
.
Added
;
iconDarkUri
=
this
.
icons
.
dark
.
Added
;
break
;
case
GitChangeType
.
COPY
:
iconUri
=
this
.
icons
.
light
.
Copied
;
iconDarkUri
=
this
.
icons
.
dark
.
Copied
;
break
;
case
GitChangeType
.
DELETE
:
iconUri
=
this
.
icons
.
light
.
Deleted
;
iconDarkUri
=
this
.
icons
.
dark
.
Deleted
;
break
;
case
GitChangeType
.
MODIFY
:
iconUri
=
this
.
icons
.
light
.
Modified
;
iconDarkUri
=
this
.
icons
.
dark
.
Modified
;
break
;
case
GitChangeType
.
RENAME
:
iconUri
=
this
.
icons
.
light
.
Renamed
;
iconDarkUri
=
this
.
icons
.
dark
.
Renamed
;
break
;
}
element
.
iconPath
=
{
light
:
iconUri
,
dark
:
iconDarkUri
};
return
element
;
}
else
{
return
element
;
}
}
getChildren
(
element
?:
CommitTreeItem
):
Thenable
<
CommitTreeItem
[]
>
{
if
(
!
this
.
workspaceRoot
)
{
return
Promise
.
resolve
([]);
}
return
new
Promise
(
resolve
=>
{
if
(
element
)
{
getChangedFiles
(
this
.
repository
,
element
.
sha
).
then
(
fileChanges
=>
{
let
promises
=
[];
let
results
=
fileChanges
.
map
(
fileChange
=>
{
let
changedItem
=
new
FileChangeItem
(
`
${
fileChange
.
filePath
}
`
,
fileChange
.
status
,
this
.
context
,
this
.
workspaceRoot
);
if
(
fileChange
.
status
===
GitChangeType
.
MODIFY
)
{
promises
.
push
(
Promise
.
all
([
getFile
(
element
.
sha
,
fileChange
.
filePath
).
then
(
targetFile
=>
{
changedItem
.
filePath
=
targetFile
;
changedItem
.
sha
=
element
.
sha
;
}),
getFile
(
element
.
parentSHAs
[
0
],
fileChange
.
filePath
).
then
(
targetFile
=>
{
changedItem
.
parentFilePath
=
targetFile
;
changedItem
.
parentSha
=
element
.
parentSHAs
[
0
];
})]).
then
(()
=>
{
changedItem
.
populateCommandArgs
();
}));
}
else
if
(
fileChange
.
status
===
GitChangeType
.
DELETE
)
{
promises
.
push
(
getFile
(
element
.
parentSHAs
[
0
],
fileChange
.
filePath
).
then
(
targetFile
=>
{
changedItem
.
parentFilePath
=
targetFile
;
changedItem
.
sha
=
element
.
parentSHAs
[
0
];
changedItem
.
populateCommandArgs
();
}));
}
else
{
promises
.
push
(
getFile
(
element
.
sha
,
fileChange
.
filePath
).
then
(
targetFile
=>
{
changedItem
.
filePath
=
targetFile
;
changedItem
.
sha
=
element
.
sha
;
changedItem
.
populateCommandArgs
();
}));
}
return
changedItem
;
});
Promise
.
all
(
promises
).
then
(()
=>
{
resolve
(
results
as
any
);
// TODO
});
});
}
else
{
getCommits
(
this
.
repository
,
'
HEAD
'
,
100
).
then
((
commits
:
Commit
[])
=>
{
let
result
=
commits
.
map
(
commit
=>
{
return
new
CommitTreeItem
(
this
.
context
,
`
${
commit
.
summary
}
`
,
commit
.
sha
,
commit
.
parentSHAs
);
});
resolve
(
result
);
},
(
reason
:
any
)
=>
{
Promise
.
reject
(
reason
);
});
}
});
}
}
extensions/git-extended/src/common/diff.ts
0 → 100644
浏览文件 @
094a469d
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
*
as
path
from
'
path
'
;
import
{
getFileContent
,
writeTmpFile
}
from
'
./file
'
;
import
{
GitChangeType
,
RichFileChange
}
from
'
./models/file
'
;
import
{
Repository
}
from
'
./models/repository
'
;
export
const
MODIFY_DIFF_INFO
=
/diff --git a
\/(\S
+
)
b
\/(\S
+
)
.*
\n
*index.*
\n
*-
{3}
.*
\n
*
\+{3}
.*
\n
*
((
.*
\n
*
)
+
)
/
;
export
const
NEW_FILE_INFO
=
/diff --git a
\/(\S
+
)
b
\/(\S
+
)
.*
\n
*new file mode .*
\n
index.*
\n
*-
{3}
.*
\n
*
\+{3}
.*
\n
*
((
.*
\n
*
)
+
)
/
;
export
const
DELETE_FILE_INFO
=
/diff --git a
\/(\S
+
)
b
\/(\S
+
)
.*
\n
*deleted file mode .*
\n
index.*
\n
*-
{3}
.*
\n
*
\+{3}
.*
\n
*
((
.*
\n
*
)
+
)
/
;
export
const
DIFF_HUNK_INFO
=
/@@
\-(\d
+
)(
,
(\d
+
))?(
\+(\d
+
)(
,
(\d
+
)?))?
@@/
;
async
function
parseModifiedHunkComplete
(
originalContent
,
modifyDiffInfo
,
a
,
b
)
{
let
left
=
originalContent
.
split
(
/
\r
|
\n
|
\r\n
/
);
let
diffHunks
=
modifyDiffInfo
[
3
].
split
(
'
\n
'
);
diffHunks
.
pop
();
// there is one additional line break at the end of the diff ??
let
right
=
[];
let
lastCommonLine
=
0
;
for
(
let
i
=
0
;
i
<
diffHunks
.
length
;
i
++
)
{
let
line
=
diffHunks
[
i
];
if
(
DIFF_HUNK_INFO
.
test
(
line
))
{
let
changeInfo
=
DIFF_HUNK_INFO
.
exec
(
line
);
let
oriStartLine
=
Number
(
changeInfo
[
1
]);
let
oriEndLine
=
Number
(
changeInfo
[
3
])
|
0
;
for
(
let
j
=
lastCommonLine
+
1
;
j
<
oriStartLine
;
j
++
)
{
right
.
push
(
left
[
j
-
1
]);
}
lastCommonLine
=
oriStartLine
+
oriEndLine
-
1
;
}
else
if
(
/^
\+
/
.
test
(
line
))
{
right
.
push
(
line
.
substr
(
1
));
}
else
{
let
codeInFirstLine
=
line
.
substr
(
1
);
right
.
push
(
codeInFirstLine
);
}
}
if
(
lastCommonLine
<
left
.
length
)
{
for
(
let
j
=
lastCommonLine
+
1
;
j
<=
left
.
length
;
j
++
)
{
right
.
push
(
left
[
j
-
1
]);
}
}
let
contentPath
=
await
writeTmpFile
(
right
.
join
(
'
\n
'
),
path
.
extname
(
b
));
let
originalContentPath
=
await
writeTmpFile
(
left
.
join
(
'
\n
'
),
path
.
extname
(
a
));
return
new
RichFileChange
(
contentPath
,
originalContentPath
,
GitChangeType
.
MODIFY
,
b
);
}
async
function
parseModifiedHunkFast
(
modifyDiffInfo
,
a
,
b
)
{
let
left
=
[];
let
right
=
[];
let
diffHunks
=
modifyDiffInfo
[
3
].
split
(
'
\n
'
);
diffHunks
.
pop
();
// there is one additional line break at the end of the diff ??
for
(
let
i
=
0
;
i
<
diffHunks
.
length
;
i
++
)
{
let
line
=
diffHunks
[
i
];
if
(
/@@
\-(\d
+
)(
,
(\d
+
))?(
\+(\d
+
)(
,
(\d
+
)?))?
@@/
.
test
(
line
))
{
// let changeInfo = /@@ \-(\d+)(,(\d+))?( \+(\d+)(,(\d+)?))? @@/.exec(line);
left
.
push
(
line
);
right
.
push
(
line
);
}
else
if
(
/^
\-
/
.
test
(
line
))
{
left
.
push
(
line
.
substr
(
1
));
}
else
if
(
/^
\+
/
.
test
(
line
))
{
right
.
push
(
line
.
substr
(
1
));
}
else
{
let
codeInFirstLine
=
line
.
substr
(
1
);
left
.
push
(
codeInFirstLine
);
right
.
push
(
codeInFirstLine
);
}
}
let
contentPath
=
await
writeTmpFile
(
right
.
join
(
'
\n
'
),
path
.
extname
(
b
));
let
originalContentPath
=
await
writeTmpFile
(
left
.
join
(
'
\n
'
),
path
.
extname
(
a
));
return
new
RichFileChange
(
contentPath
,
originalContentPath
,
GitChangeType
.
MODIFY
,
b
);
}
export
async
function
parseDiff
(
text
:
string
,
repository
:
Repository
,
parentCommit
:
string
)
{
let
reg
=
/diff
((?!
diff
)
.*
\n
*
)
*/g
;
let
match
=
reg
.
exec
(
text
);
let
richFileChanges
:
RichFileChange
[]
=
[];
while
(
match
)
{
let
singleFileDiff
=
match
[
0
];
let
modifyDiffInfo
=
MODIFY_DIFF_INFO
.
exec
(
singleFileDiff
);
if
(
modifyDiffInfo
)
{
let
a
=
modifyDiffInfo
[
1
];
let
b
=
modifyDiffInfo
[
2
];
try
{
let
originalContent
=
await
getFileContent
(
repository
.
path
,
parentCommit
,
a
);
let
richFileChange
=
await
parseModifiedHunkComplete
(
originalContent
,
modifyDiffInfo
,
a
,
b
);
richFileChanges
.
push
(
richFileChange
);
}
catch
(
e
)
{
let
richFileChange
=
await
parseModifiedHunkFast
(
modifyDiffInfo
,
a
,
b
);
richFileChanges
.
push
(
richFileChange
);
}
match
=
reg
.
exec
(
text
);
continue
;
}
let
newDiffInfo
=
NEW_FILE_INFO
.
exec
(
singleFileDiff
);
if
(
newDiffInfo
)
{
let
fileName
=
newDiffInfo
[
1
];
let
diffHunks
=
newDiffInfo
[
3
].
split
(
'
\n
'
);
let
contentArray
=
[];
for
(
let
i
=
0
;
i
<
diffHunks
.
length
;
i
++
)
{
if
(
/@@
\-(\d
+
)(
,
(\d
+
))?(
\+(\d
+
)(
,
(\d
+
)?))?
@@$/
.
test
(
diffHunks
[
i
]))
{
continue
;
}
else
if
(
/@@
\-(\d
+
)(
,
(\d
+
))?(
\+(\d
+
)(
,
(\d
+
)?))?
@@ /
.
test
(
diffHunks
[
i
]))
{
contentArray
.
push
(
diffHunks
[
i
].
replace
(
/@@
\-(\d
+
)(
,
(\d
+
))?(
\+(\d
+
)(
,
(\d
+
)?))?
@@ /
,
''
));
}
else
if
(
/^
\+
/
.
test
(
diffHunks
[
i
]))
{
contentArray
.
push
(
diffHunks
[
i
].
substr
(
1
));
}
}
let
filePath
=
await
writeTmpFile
(
contentArray
.
join
(
'
\n
'
),
path
.
extname
(
fileName
));
let
richFileChange
=
new
RichFileChange
(
filePath
,
filePath
,
GitChangeType
.
ADD
,
fileName
);
richFileChanges
.
push
(
richFileChange
);
match
=
reg
.
exec
(
text
);
continue
;
}
let
deleteDiffInfo
=
DELETE_FILE_INFO
.
exec
(
singleFileDiff
);
if
(
deleteDiffInfo
)
{
let
fileName
=
deleteDiffInfo
[
1
];
let
diffHunks
=
deleteDiffInfo
[
3
].
split
(
'
\n
'
);
let
contentArray
=
[];
for
(
let
i
=
0
;
i
<
diffHunks
.
length
;
i
++
)
{
if
(
/@@
\-(\d
+
)(
,
(\d
+
))?(
\+(\d
+
)(
,
(\d
+
)?))?
@@$/
.
test
(
diffHunks
[
i
]))
{
continue
;
}
else
if
(
/@@
\-(\d
+
)(
,
(\d
+
))?(
\+(\d
+
)(
,
(\d
+
)?))?
@@ /
.
test
(
diffHunks
[
i
]))
{
contentArray
.
push
(
diffHunks
[
i
].
replace
(
/@@
\-(\d
+
)(
,
(\d
+
))?(
\+(\d
+
)(
,
(\d
+
)?))?
@@ /
,
''
));
}
else
if
(
/^
\-
/
.
test
(
diffHunks
[
i
]))
{
contentArray
.
push
(
diffHunks
[
i
].
substr
(
1
));
}
}
let
originalFilePath
=
await
writeTmpFile
(
contentArray
.
join
(
'
\n
'
),
path
.
extname
(
fileName
));
let
filePath
=
await
writeTmpFile
(
''
,
path
.
extname
(
fileName
));
let
richFileChange
=
new
RichFileChange
(
filePath
,
originalFilePath
,
GitChangeType
.
DELETE
,
fileName
);
richFileChanges
.
push
(
richFileChange
);
match
=
reg
.
exec
(
text
);
continue
;
}
match
=
reg
.
exec
(
text
);
}
return
richFileChanges
;
}
\ No newline at end of file
extensions/git-extended/src/common/file.ts
0 → 100644
浏览文件 @
094a469d
import
*
as
fs
from
'
fs
'
;
import
*
as
path
from
'
path
'
;
import
*
as
tmp
from
'
tmp
'
;
import
*
as
vscode
from
'
vscode
'
;
import
{
GitProcess
}
from
'
dugite
'
;
import
{
Repository
}
from
'
./models/repository
'
;
import
{
SlimFileChange
,
GitChangeType
,
fromStatus
}
from
'
./models/file
'
;
/**
* @param content
*
* a
*
* c
*
* b
*
*
* @param ext
*/
export
async
function
writeTmpFile
(
content
:
string
,
ext
:
string
):
Promise
<
string
>
{
return
new
Promise
<
string
>
((
resolve
,
reject
)
=>
{
tmp
.
file
({
postfix
:
ext
},
async
(
err
:
any
,
tmpFilePath
:
string
)
=>
{
if
(
err
)
{
reject
(
err
);
return
;
}
try
{
fs
.
appendFileSync
(
tmpFilePath
,
content
);
resolve
(
tmpFilePath
);
}
catch
(
ex
)
{
reject
(
ex
);
}
});
})
}
export
async
function
getFile
(
commitSha1
:
string
,
localFilePath
:
string
):
Promise
<
string
>
{
const
rootDir
=
vscode
.
workspace
.
rootPath
;
return
new
Promise
<
string
>
((
resolve
,
reject
)
=>
{
if
(
commitSha1
===
undefined
)
{
resolve
(
'
fileUnavailable
'
);
return
;
}
let
ext
=
path
.
extname
(
localFilePath
);
tmp
.
file
({
postfix
:
ext
},
async
(
err
:
any
,
tmpFilePath
:
string
)
=>
{
if
(
err
)
{
reject
(
err
);
return
;
}
try
{
let
data
=
await
getFileContent
(
rootDir
,
commitSha1
,
localFilePath
);
fs
.
appendFileSync
(
tmpFilePath
,
data
);
resolve
(
tmpFilePath
);
}
catch
(
ex
)
{
console
.
log
(
ex
);
reject
(
ex
);
}
});
});
}
export
async
function
getFileContent
(
rootDir
:
string
,
commitSha
:
string
,
sourceFilePath
:
string
):
Promise
<
string
>
{
const
result
=
await
GitProcess
.
exec
([
'
show
'
,
`
${
commitSha
}
:`
+
sourceFilePath
.
replace
(
/
\\
/g
,
'
/
'
)
],
rootDir
);
const
out
=
result
.
stdout
;
const
error
=
result
.
stderr
;
if
(
result
.
exitCode
===
0
)
{
return
out
;
}
else
{
throw
error
;
}
}
export
async
function
getChangedFiles
(
repository
:
Repository
,
sha
:
string
):
Promise
<
ReadonlyArray
<
SlimFileChange
>>
{
const
args
=
[
'
log
'
,
sha
,
'
--name-status
'
,
'
--format=format:
'
,
'
-z
'
,
'
-1
'
];
const
result
=
await
GitProcess
.
exec
(
args
,
repository
.
path
);
const
out
=
result
.
stdout
;
const
lines
=
out
.
split
(
'
\
0
'
);
lines
.
splice
(
-
1
,
1
);
const
files
:
SlimFileChange
[]
=
[];
for
(
let
i
=
0
;
i
<
lines
.
length
;
i
++
)
{
const
statusText
=
lines
[
i
];
const
status
=
fromStatus
(
statusText
);
let
originalPath
:
string
|
undefined
=
undefined
;
if
(
status
===
GitChangeType
.
RENAME
||
status
===
GitChangeType
.
COPY
)
{
originalPath
=
lines
[
++
i
];
}
const
path
=
lines
[
++
i
];
files
.
push
(
new
SlimFileChange
(
path
,
originalPath
,
status
,
null
));
}
return
files
;
}
\ No newline at end of file
extensions/git-extended/src/common/log.ts
0 → 100644
浏览文件 @
094a469d
import
{
Repository
}
from
'
./models/repository
'
;
import
{
Commit
}
from
'
./models/commit
'
;
import
{
GitProcess
}
from
'
dugite
'
;
export
async
function
getParentCommit
(
repository
:
Repository
,
sha
:
string
):
Promise
<
string
>
{
const
result
=
await
GitProcess
.
exec
(
[
'
rev-list
'
,
'
--parents
'
,
'
-n
'
,
'
1
'
,
sha
],
repository
.
path
);
let
commits
=
result
.
stdout
.
split
(
'
'
);
if
(
commits
.
length
>
2
)
{
return
commits
[
1
];
}
else
{
return
null
;
}
}
export
async
function
getCommits
(
repository
:
Repository
,
revisionRange
:
string
,
limit
:
number
,
additionalArgs
:
ReadonlyArray
<
string
>
=
[]):
Promise
<
Commit
[]
>
{
const
delimiter
=
'
1F
'
;
const
delimiterString
=
String
.
fromCharCode
(
parseInt
(
delimiter
,
16
));
const
prettyFormat
=
[
'
%H
'
,
// SHA
'
%s
'
,
// summary
'
%P
'
,
// parent SHAs
].
join
(
`%x
${
delimiter
}
`
);
const
result
=
await
GitProcess
.
exec
([
'
log
'
,
revisionRange
,
`--max-count=
${
limit
}
`
,
`--pretty=
${
prettyFormat
}
`
,
'
-z
'
,
...
additionalArgs
,
],
repository
.
path
);
const
out
=
result
.
stdout
;
const
lines
=
out
.
split
(
'
\
0
'
);
lines
.
splice
(
-
1
,
1
);
const
commits
=
lines
.
map
(
line
=>
{
const
pieces
=
line
.
split
(
delimiterString
);
const
sha
=
pieces
[
0
];
const
summary
=
pieces
[
1
];
const
shaList
=
pieces
[
2
];
const
parentSHAs
=
shaList
.
length
?
shaList
.
split
(
'
'
)
:
[];
return
new
Commit
(
sha
,
summary
,
parentSHAs
);
});
return
commits
;
}
export
async
function
isWorkingTreeClean
(
repository
:
Repository
):
Promise
<
boolean
>
{
const
result
=
await
GitProcess
.
exec
(
[
'
diff-index
'
,
'
--quiet
'
,
'
HEAD
'
,
'
--
'
],
repository
.
path
);
let
exitCode
=
result
.
exitCode
;
if
(
exitCode
!==
0
)
{
return
false
;
}
else
{
return
true
;
}
}
\ No newline at end of file
extensions/git-extended/src/common/models/comment.ts
0 → 100644
浏览文件 @
094a469d
interface
DiffHunkRange
{
originalStart
:
number
;
originalLength
:
number
;
start
:
number
;
length
:
number
;
}
interface
User
{
id
:
string
;
login
:
string
;
}
export
interface
Comment
{
url
:
string
;
id
:
string
;
path
:
string
;
pull_request_review_id
:
string
;
diff_hunk_range
:
DiffHunkRange
;
position
:
number
;
originalPosition
:
number
;
commit_id
:
string
;
original_commit_id
:
string
;
user
:
User
;
body
:
string
;
created_at
:
string
;
updated_at
:
string
;
html_url
:
string
;
}
extensions/git-extended/src/common/models/commit.ts
0 → 100644
浏览文件 @
094a469d
export
class
Commit
{
constructor
(
public
sha
:
string
,
public
summary
:
string
,
public
parentSHAs
:
string
[])
{
}
}
\ No newline at end of file
extensions/git-extended/src/common/models/file.ts
0 → 100644
浏览文件 @
094a469d
export
enum
GitChangeType
{
ADD
,
COPY
,
DELETE
,
MODIFY
,
RENAME
,
TYPE
,
UNKNOWN
,
UNMERGED
}
export
function
fromStatus
(
status
:
string
):
GitChangeType
{
switch
(
status
)
{
case
'
A
'
:
return
GitChangeType
.
ADD
;
case
'
C
'
:
return
GitChangeType
.
COPY
;
case
'
D
'
:
return
GitChangeType
.
DELETE
;
case
'
M
'
:
return
GitChangeType
.
MODIFY
;
case
'
R
'
:
return
GitChangeType
.
RENAME
;
case
'
T
'
:
return
GitChangeType
.
TYPE
;
case
'
X
'
:
return
GitChangeType
.
UNKNOWN
;
case
'
U
'
:
return
GitChangeType
.
UNMERGED
;
}
if
(
status
.
match
(
/R
[
0-9
]
+/
))
{
return
GitChangeType
.
RENAME
;
}
if
(
status
.
match
(
/C
[
0-9
]
+/
))
{
return
GitChangeType
.
COPY
;
}
return
GitChangeType
.
MODIFY
;
}
export
class
SlimFileChange
{
public
originalContent
:
string
;
public
content
:
string
;
constructor
(
public
readonly
filePath
:
string
,
public
readonly
originalFilePath
:
string
,
public
readonly
status
:
GitChangeType
,
public
readonly
fileName
:
string
)
{
}
}
export
class
RichFileChange
{
constructor
(
public
readonly
filePath
:
string
,
public
readonly
originalFilePath
:
string
,
public
readonly
status
:
GitChangeType
,
public
readonly
fileName
:
string
)
{
}
}
\ No newline at end of file
extensions/git-extended/src/common/models/remote.ts
0 → 100644
浏览文件 @
094a469d
export
interface
IRemote
{
readonly
name
:
string
;
readonly
url
:
string
;
}
export
interface
IGitRemoteURL
{
/** The hostname of the remote. */
readonly
hostname
:
string
;
/**
* The owner of the GitHub repository. This will be null if the URL doesn't
* take the form of a GitHub repository URL (e.g., owner/name).
*/
readonly
owner
:
string
|
null
;
/**
* The name of the GitHub repository. This will be null if the URL doesn't
* take the form of a GitHub repository URL (e.g., owner/name).
*/
readonly
name
:
string
|
null
;
}
extensions/git-extended/src/common/models/repository.ts
0 → 100644
浏览文件 @
094a469d
import
{
IGitRemoteURL
}
from
'
./remote
'
;
export
class
GitHubRepository
{
constructor
(
public
name
:
string
,
public
owner
:
string
,
public
url
:
string
)
{
}
}
export
class
Repository
{
public
path
:
string
;
public
remotes
:
IGitRemoteURL
[];
constructor
(
path
:
string
,
remotes
:
IGitRemoteURL
[])
{
this
.
path
=
path
;
this
.
remotes
=
remotes
;
}
}
\ No newline at end of file
extensions/git-extended/src/common/remote.ts
0 → 100644
浏览文件 @
094a469d
import
{
GitProcess
}
from
'
dugite
'
;
import
{
IGitRemoteURL
}
from
'
./models/remote
'
;
export
async
function
getRemotes
(
path
:
string
)
{
const
result
=
await
GitProcess
.
exec
([
'
remote
'
,
'
-v
'
],
path
);
const
output
=
result
.
stdout
;
const
lines
=
output
.
split
(
'
\n
'
);
const
remotes
=
lines
.
filter
(
x
=>
x
.
endsWith
(
'
(fetch)
'
))
.
map
(
x
=>
x
.
split
(
/
\s
+/
))
.
map
(
x
=>
({
name
:
x
[
0
],
url
:
x
[
1
]
}));
return
remotes
;
}
/** Parse the remote information from URL. */
export
function
parseRemote
(
url
:
string
):
IGitRemoteURL
|
null
{
// Examples:
// https://github.com/octocat/Hello-World.git
// https://github.com/octocat/Hello-World.git/
// git@github.com:octocat/Hello-World.git
// git:github.com/octocat/Hello-World.git
const
regexes
=
[
new
RegExp
(
'
^https?://(?:.+@)?(.+)/(.+)/(.+?)(?:/|.git/?)?$
'
),
new
RegExp
(
'
^git@(.+):(.+)/(.+?)(?:/|.git)?$
'
),
new
RegExp
(
'
^git:(.+)/(.+)/(.+?)(?:/|.git)?$
'
),
new
RegExp
(
'
^ssh://git@(.+)/(.+)/(.+?)(?:/|.git)?$
'
)
];
for
(
const
regex
of
regexes
)
{
const
result
=
url
.
match
(
regex
);
if
(
!
result
)
{
continue
;
}
const
hostname
=
result
[
1
];
const
owner
=
result
[
2
];
const
name
=
result
[
3
];
if
(
hostname
)
{
return
{
hostname
,
owner
,
name
};
}
}
return
null
;
}
extensions/git-extended/src/extension.ts
0 → 100644
浏览文件 @
094a469d
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
*
as
vscode
from
'
vscode
'
;
import
{
CommitsProvider
}
from
'
./commitsProvider
'
;
import
{
PRProvider
}
from
'
./prProvider
'
;
import
{
Repository
}
from
'
./common/models/repository
'
;
import
{
getRemotes
,
parseRemote
}
from
'
./common/remote
'
;
export
async
function
activate
(
context
:
vscode
.
ExtensionContext
)
{
const
rootPath
=
vscode
.
workspace
.
rootPath
;
const
remotes
=
await
getRemotes
(
rootPath
);
const
remoteUrls
=
remotes
.
map
(
remote
=>
parseRemote
(
remote
.
url
));
const
repository
=
new
Repository
(
rootPath
,
remoteUrls
);
new
CommitsProvider
().
activate
(
context
,
rootPath
,
repository
);
new
PRProvider
().
activate
(
context
,
rootPath
,
repository
);
}
\ No newline at end of file
extensions/git-extended/src/prProvider.ts
0 → 100644
浏览文件 @
094a469d
import
*
as
vscode
from
'
vscode
'
;
// import { Octokat } from 'octokat';
var
Octokat
=
require
(
'
octokat
'
);
// import * as https from 'https';
// import * as fs from 'fs';
// import * as tmp from 'tmp';
import
*
as
path
from
'
path
'
;
import
*
as
request
from
'
request
'
;
import
{
FileChangeItem
}
from
'
./commitsProvider
'
;
import
{
parseDiff
,
DIFF_HUNK_INFO
}
from
'
./common/diff
'
;
import
{
GitChangeType
}
from
'
./common/models/file
'
;
import
{
Repository
}
from
'
./common//models/repository
'
;
import
{
Comment
}
from
'
./common/models/comment
'
;
import
*
as
_
from
'
lodash
'
;
export
class
PullRequest
{
constructor
(
public
octoPRItem
:
any
)
{
};
}
export
class
PRProvider
implements
vscode
.
TreeDataProvider
<
PullRequest
|
FileChangeItem
>
,
vscode
.
CommentProvider
{
private
_fileChanges
:
FileChangeItem
[];
private
_comments
?:
Comment
[];
private
context
:
vscode
.
ExtensionContext
;
private
workspaceRoot
:
string
;
private
repository
:
Repository
;
private
octo
:
any
;
private
icons
:
any
;
constructor
()
{
this
.
octo
=
new
Octokat
();
}
activate
(
context
:
vscode
.
ExtensionContext
,
workspaceRoot
:
string
,
repository
:
Repository
)
{
this
.
context
=
context
;
this
.
workspaceRoot
=
workspaceRoot
;
this
.
repository
=
repository
;
vscode
.
window
.
registerTreeDataProvider
<
PullRequest
|
FileChangeItem
>
(
'
pr
'
,
this
);
this
.
icons
=
{
light
:
{
Modified
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
light
'
,
'
status-modified.svg
'
)),
Added
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
light
'
,
'
status-added.svg
'
)),
Deleted
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
light
'
,
'
status-deleted.svg
'
)),
Renamed
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
light
'
,
'
status-renamed.svg
'
)),
Copied
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
light
'
,
'
status-copied.svg
'
)),
Untracked
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
light
'
,
'
status-untrackedt.svg
'
)),
Ignored
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
light
'
,
'
status-ignored.svg
'
)),
Conflict
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
light
'
,
'
status-conflict.svg
'
)),
},
dark
:
{
Modified
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
dark
'
,
'
status-modified.svg
'
)),
Added
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
dark
'
,
'
status-added.svg
'
)),
Deleted
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
dark
'
,
'
status-deleted.svg
'
)),
Renamed
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
dark
'
,
'
status-renamed.svg
'
)),
Copied
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
dark
'
,
'
status-copied.svg
'
)),
Untracked
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
dark
'
,
'
status-untracked.svg
'
)),
Ignored
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
dark
'
,
'
status-ignored.svg
'
)),
Conflict
:
context
.
asAbsolutePath
(
path
.
join
(
'
resources
'
,
'
icons
'
,
'
dark
'
,
'
status-conflict.svg
'
))
}
};
vscode
.
workspace
.
registerCommentProvider
(
this
);
}
getTreeItem
(
element
:
PullRequest
|
FileChangeItem
):
vscode
.
TreeItem
{
if
(
element
instanceof
PullRequest
)
{
return
{
label
:
element
.
octoPRItem
.
title
,
collapsibleState
:
1
};
}
else
{
let
iconUri
:
string
;
let
iconDarkUri
:
string
;
switch
(
element
.
status
)
{
case
GitChangeType
.
ADD
:
iconUri
=
this
.
icons
.
light
.
Added
;
iconDarkUri
=
this
.
icons
.
dark
.
Added
;
break
;
case
GitChangeType
.
COPY
:
iconUri
=
this
.
icons
.
light
.
Copied
;
iconDarkUri
=
this
.
icons
.
dark
.
Copied
;
break
;
case
GitChangeType
.
DELETE
:
iconUri
=
this
.
icons
.
light
.
Deleted
;
iconDarkUri
=
this
.
icons
.
dark
.
Deleted
;
break
;
case
GitChangeType
.
MODIFY
:
iconUri
=
this
.
icons
.
light
.
Modified
;
iconDarkUri
=
this
.
icons
.
dark
.
Modified
;
break
;
case
GitChangeType
.
RENAME
:
iconUri
=
this
.
icons
.
light
.
Renamed
;
iconDarkUri
=
this
.
icons
.
dark
.
Renamed
;
break
;
}
element
.
iconPath
=
{
light
:
iconUri
,
dark
:
iconDarkUri
};
return
element
;
}
}
getChildren
(
element
?:
PullRequest
):
PullRequest
[]
|
Thenable
<
PullRequest
[]
>
|
FileChangeItem
[]
|
Thenable
<
FileChangeItem
[]
>
{
if
(
element
)
{
return
new
Promise
<
FileChangeItem
[]
>
((
resolve
,
rxeject
)
=>
{
request
({
followAllRedirects
:
true
,
url
:
element
.
octoPRItem
.
diffUrl
},
async
(
error
,
response
,
body
)
=>
{
// map comments to FileChangeItem
// registerCommentProvider
const
rawComments
=
await
element
.
octoPRItem
.
reviewComments
.
fetch
();
const
comments
:
Comment
[]
=
parseComments
(
rawComments
.
items
);
let
richContentChanges
=
await
parseDiff
(
body
,
this
.
repository
,
element
.
octoPRItem
.
base
.
sha
);
let
fileChanges
=
richContentChanges
.
map
(
change
=>
{
let
changedItem
=
new
FileChangeItem
(
change
.
fileName
?
change
.
fileName
:
change
.
filePath
,
change
.
status
,
this
.
context
,
change
.
fileName
,
this
.
workspaceRoot
);
changedItem
.
filePath
=
change
.
filePath
;
changedItem
.
parentFilePath
=
change
.
originalFilePath
;
changedItem
.
populateCommandArgs
();
return
changedItem
;
});
this
.
_fileChanges
=
fileChanges
;
this
.
_comments
=
comments
;
vscode
.
workspace
.
onDidOpenTextDocument
(
e
=>
{
let
matchingComments
=
getMatchingCommentsForDiffViewEditor
(
e
.
fileName
,
fileChanges
,
comments
);
console
.
log
(
'
---diff editor---
'
)
for
(
let
i
=
0
;
i
<
matchingComments
.
length
;
i
++
)
{
let
cm
=
matchingComments
[
i
];
console
.
log
(
`after line:
${
cm
.
diff_hunk_range
.
start
+
cm
.
position
-
1
-
1
}
,
${
'
@
'
+
cm
.
user
.
login
}
: '
${
cm
.
body
}
'`
);
}
matchingComments
=
getMatchingCommentsForNormalEditor
(
e
.
fileName
,
this
.
workspaceRoot
,
comments
);
console
.
log
(
'
---editor---
'
)
for
(
let
i
=
0
;
i
<
matchingComments
.
length
;
i
++
)
{
let
cm
=
matchingComments
[
i
];
console
.
log
(
`after line:
${
cm
.
diff_hunk_range
.
start
+
cm
.
position
-
1
-
1
}
,
${
'
@
'
+
cm
.
user
.
login
}
: '
${
cm
.
body
}
'`
);
}
});
resolve
(
fileChanges
);
});
});
}
else
{
if
(
this
.
repository
.
remotes
&&
this
.
repository
.
remotes
.
length
>
0
)
{
let
promises
=
this
.
repository
.
remotes
.
map
(
remote
=>
this
.
octo
.
repos
(
remote
.
owner
,
remote
.
name
).
pulls
.
fetch
().
then
(
prs
=>
{
return
prs
.
items
.
map
(
item
=>
new
PullRequest
(
item
));
}));
return
Promise
.
all
(
promises
).
then
(
values
=>
{
let
prs
=
[];
values
.
forEach
(
value
=>
{
prs
.
push
(...
value
);
});
return
prs
;
});
}
return
[];
}
}
async
provideComments
(
document
:
vscode
.
TextDocument
):
Promise
<
vscode
.
CommentThread
[]
>
{
if
(
!
this
.
_comments
)
{
return
[];
}
let
matchingComments
=
getMatchingCommentsForDiffViewEditor
(
document
.
fileName
,
this
.
_fileChanges
,
this
.
_comments
);
if
(
!
matchingComments
||
!
matchingComments
.
length
)
{
matchingComments
=
getMatchingCommentsForNormalEditor
(
document
.
fileName
,
this
.
workspaceRoot
,
this
.
_comments
);
}
if
(
!
matchingComments
||
!
matchingComments
.
length
)
{
return
[];
}
let
sections
=
_
.
groupBy
(
matchingComments
,
comment
=>
comment
.
position
);
let
ret
=
[];
for
(
let
i
in
sections
)
{
let
comments
=
sections
[
i
];
const
comment
=
comments
[
0
];
const
pos
=
new
vscode
.
Position
(
comment
.
diff_hunk_range
.
start
+
comment
.
position
-
1
-
1
,
0
);
const
range
=
new
vscode
.
Range
(
pos
,
pos
);
ret
.
push
({
range
,
comments
:
comments
.
map
(
comment
=>
{
return
{
body
:
new
vscode
.
MarkdownString
(
comment
.
body
),
userName
:
comment
.
user
.
login
};
})
});
}
return
ret
;
}
}
function
parseComments
(
comments
:
any
[]):
Comment
[]
{
for
(
let
i
=
0
;
i
<
comments
.
length
;
i
++
)
{
let
diff_hunk
=
comments
[
i
].
diffHunk
;
let
hunk_info
=
DIFF_HUNK_INFO
.
exec
(
diff_hunk
);
let
oriStartLine
=
Number
(
hunk_info
[
1
]);
let
oriLen
=
Number
(
hunk_info
[
3
])
|
0
;
let
startLine
=
Number
(
hunk_info
[
5
]);
let
len
=
Number
(
hunk_info
[
7
])
|
0
;
comments
[
i
].
diff_hunk_range
=
{
originalStart
:
oriStartLine
,
originalLength
:
oriLen
,
start
:
startLine
,
length
:
len
};
}
return
comments
;
}
function
getMatchingCommentsForDiffViewEditor
(
filePath
:
string
,
items
:
FileChangeItem
[],
comments
:
Comment
[]):
Comment
[]
{
let
fileChangeItem
=
items
.
filter
(
item
=>
filePath
===
path
.
resolve
(
item
.
workspaceRoot
,
item
.
filePath
));
if
(
fileChangeItem
.
length
===
0
)
{
return
[];
}
else
{
let
fileName
=
fileChangeItem
[
0
].
fileName
;
let
matchingComments
=
comments
.
filter
(
comment
=>
comment
.
path
===
fileName
);
return
matchingComments
;
}
}
function
getMatchingCommentsForNormalEditor
(
filePath
:
string
,
workspaceRoot
:
string
,
comments
:
Comment
[]):
Comment
[]
{
// @todo, we should check commit id
let
matchingComments
=
comments
.
filter
(
comment
=>
path
.
resolve
(
workspaceRoot
,
comment
.
path
)
===
filePath
);
return
matchingComments
;
}
extensions/git-extended/src/typings/ref.d.ts
0 → 100644
浏览文件 @
094a469d
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/// <reference path='../../../../src/vs/vscode.d.ts'/>
/// <reference path='../../../../src/vs/vscode.proposed.d.ts'/>
extensions/git-extended/tsconfig.json
0 → 100644
浏览文件 @
094a469d
{
"compilerOptions"
:
{
"module"
:
"commonjs"
,
"target"
:
"es6"
,
"outDir"
:
"out"
,
"noUnusedLocals"
:
true
,
"lib"
:
[
"es6"
],
"sourceMap"
:
true
,
"rootDir"
:
"./src"
,
"jsx"
:
"react"
},
"exclude"
:
[
"node_modules"
,
".vscode-test"
]
}
extensions/git-extended/yarn.lock
0 → 100644
浏览文件 @
094a469d
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@types/node@*":
version "9.6.2"
resolved "https://registry.yarnpkg.com/@types/node/-/node-9.6.2.tgz#e49ac1adb458835e95ca6487bc20f916b37aff23"
ajv@^5.1.0:
version "5.5.2"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
dependencies:
co "^4.6.0"
fast-deep-equal "^1.0.0"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.3.0"
asn1@~0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
aws-sign2@~0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
aws4@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
bcrypt-pbkdf@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d"
dependencies:
tweetnacl "^0.14.3"
boom@4.x.x:
version "4.3.1"
resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31"
dependencies:
hoek "4.x.x"
boom@5.x.x:
version "5.2.0"
resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02"
dependencies:
hoek "4.x.x"
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
checksum@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/checksum/-/checksum-0.1.1.tgz#dc6527d4c90be8560dbd1ed4cecf3297d528e9e9"
dependencies:
optimist "~0.3.5"
chownr@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181"
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
combined-stream@1.0.6, combined-stream@~1.0.5:
version "1.0.6"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818"
dependencies:
delayed-stream "~1.0.0"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
core-util-is@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
cryptiles@3.x.x:
version "3.1.2"
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe"
dependencies:
boom "5.x.x"
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
dependencies:
assert-plus "^1.0.0"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
dugite@^1.28.0:
version "1.61.0"
resolved "https://registry.yarnpkg.com/dugite/-/dugite-1.61.0.tgz#d5dad047af478c1312f8b791eb56d9935e6fc47d"
dependencies:
checksum "^0.1.1"
mkdirp "^0.5.1"
progress "^2.0.0"
request "^2.83.0"
rimraf "^2.5.4"
tar "^4.0.2"
ecc-jsbn@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
dependencies:
jsbn "~0.1.0"
extend@~3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
extsprintf@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
extsprintf@^1.2.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
fast-deep-equal@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614"
fast-json-stable-stringify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
form-data@~2.3.1:
version "2.3.2"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099"
dependencies:
asynckit "^0.4.0"
combined-stream "1.0.6"
mime-types "^2.1.12"
fs-minipass@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d"
dependencies:
minipass "^2.2.1"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
getpass@^0.1.1:
version "0.1.7"
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
dependencies:
assert-plus "^1.0.0"
glob@^7.0.5:
version "7.1.2"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
har-validator@~5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd"
dependencies:
ajv "^5.1.0"
har-schema "^2.0.0"
hawk@~6.0.2:
version "6.0.2"
resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038"
dependencies:
boom "4.x.x"
cryptiles "3.x.x"
hoek "4.x.x"
sntp "2.x.x"
hoek@4.x.x:
version "4.2.1"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb"
http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
dependencies:
assert-plus "^1.0.0"
jsprim "^1.2.2"
sshpk "^1.7.0"
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
dependencies:
once "^1.3.0"
wrappy "1"
inherits@2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
json-schema-traverse@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
jsprim@^1.2.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
dependencies:
assert-plus "1.0.0"
extsprintf "1.3.0"
json-schema "0.2.3"
verror "1.10.0"
lodash@4.17.5, lodash@^4.16.4:
version "4.17.5"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511"
mime-db@~1.33.0:
version "1.33.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db"
mime-types@^2.1.12, mime-types@~2.1.17:
version "2.1.18"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8"
dependencies:
mime-db "~1.33.0"
minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
dependencies:
brace-expansion "^1.1.7"
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
minipass@^2.2.1, minipass@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.2.4.tgz#03c824d84551ec38a8d1bb5bc350a5a30a354a40"
dependencies:
safe-buffer "^5.1.1"
yallist "^3.0.0"
minizlib@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb"
dependencies:
minipass "^2.2.1"
mkdirp@^0.5.0, mkdirp@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
dependencies:
minimist "0.0.8"
oauth-sign@~0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
octokat@^0.8.0:
version "0.8.0"
resolved "https://registry.yarnpkg.com/octokat/-/octokat-0.8.0.tgz#50841ca255743f91a715d11a1bde76f2eefcd97a"
dependencies:
lodash "^4.16.4"
xmlhttprequest "~1.8.0"
once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
dependencies:
wrappy "1"
optimist@~0.3.5:
version "0.3.7"
resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.3.7.tgz#c90941ad59e4273328923074d2cf2e7cbc6ec0d9"
dependencies:
wordwrap "~0.0.2"
os-tmpdir@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
progress@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f"
punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
qs@~6.5.1:
version "6.5.1"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
request@^2.81.0, request@^2.83.0:
version "2.85.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.85.0.tgz#5a03615a47c61420b3eb99b7dba204f83603e1fa"
dependencies:
aws-sign2 "~0.7.0"
aws4 "^1.6.0"
caseless "~0.12.0"
combined-stream "~1.0.5"
extend "~3.0.1"
forever-agent "~0.6.1"
form-data "~2.3.1"
har-validator "~5.0.3"
hawk "~6.0.2"
http-signature "~1.2.0"
is-typedarray "~1.0.0"
isstream "~0.1.2"
json-stringify-safe "~5.0.1"
mime-types "~2.1.17"
oauth-sign "~0.8.2"
performance-now "^2.1.0"
qs "~6.5.1"
safe-buffer "^5.1.1"
stringstream "~0.0.5"
tough-cookie "~2.3.3"
tunnel-agent "^0.6.0"
uuid "^3.1.0"
rimraf@^2.5.4:
version "2.6.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
dependencies:
glob "^7.0.5"
safe-buffer@^5.0.1, safe-buffer@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
sntp@2.x.x:
version "2.1.0"
resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8"
dependencies:
hoek "4.x.x"
sshpk@^1.7.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.14.1.tgz#130f5975eddad963f1d56f92b9ac6c51fa9f83eb"
dependencies:
asn1 "~0.2.3"
assert-plus "^1.0.0"
dashdash "^1.12.0"
getpass "^0.1.1"
optionalDependencies:
bcrypt-pbkdf "^1.0.0"
ecc-jsbn "~0.1.1"
jsbn "~0.1.0"
tweetnacl "~0.14.0"
stringstream@~0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
tar@^4.0.2:
version "4.4.1"
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.1.tgz#b25d5a8470c976fd7a9a8a350f42c59e9fa81749"
dependencies:
chownr "^1.0.1"
fs-minipass "^1.2.5"
minipass "^2.2.4"
minizlib "^1.1.0"
mkdirp "^0.5.0"
safe-buffer "^5.1.1"
yallist "^3.0.2"
tmp@^0.0.31:
version "0.0.31"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7"
dependencies:
os-tmpdir "~1.0.1"
tough-cookie@~2.3.3:
version "2.3.4"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655"
dependencies:
punycode "^1.4.1"
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
dependencies:
safe-buffer "^5.0.1"
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
typescript@^2.1.4:
version "2.8.1"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.8.1.tgz#6160e4f8f195d5ba81d4876f9c0cc1fbc0820624"
uuid@^3.1.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14"
verror@1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
dependencies:
assert-plus "^1.0.0"
core-util-is "1.0.2"
extsprintf "^1.2.0"
wordwrap@~0.0.2:
version "0.0.3"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
xmlhttprequest@~1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc"
yallist@^3.0.0, yallist@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9"
src/vs/editor/common/modes.ts
浏览文件 @
094a469d
...
...
@@ -936,6 +936,22 @@ export interface Command {
tooltip
?:
string
;
arguments
?:
any
[];
}
export
interface
CommentThread
{
readonly
range
:
IRange
;
readonly
comments
:
Comment
[];
}
export
interface
Comment
{
readonly
body
:
IMarkdownString
;
readonly
userName
:
string
;
}
export
interface
CommentProvider
{
provideComments
(
model
:
model
.
ITextModel
,
token
:
CancellationToken
):
CommentThread
[];
}
export
interface
ICodeLensSymbol
{
range
:
IRange
;
id
?:
string
;
...
...
src/vs/editor/contrib/review/review.ts
浏览文件 @
094a469d
...
...
@@ -5,6 +5,7 @@
'
use strict
'
;
import
'
vs/css!./review
'
;
import
*
as
modes
from
'
vs/editor/common/modes
'
;
import
{
IEditorContribution
}
from
'
vs/editor/common/editorCommon
'
;
import
{
ICodeEditor
,
IEditorMouseEvent
,
MouseTargetType
,
IViewZone
}
from
'
vs/editor/browser/editorBrowser
'
;
import
{
IDisposable
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
...
...
@@ -13,10 +14,8 @@ import { registerEditorContribution } from 'vs/editor/browser/editorExtensions';
import
{
ModelDecorationOptions
}
from
'
vs/editor/common/model/textModel
'
;
import
{
TrackedRangeStickiness
}
from
'
vs/editor/common/model
'
;
import
{
ZoneWidget
,
IOptions
}
from
'
../zoneWidget/zoneWidget
'
;
import
{
MarkdownString
}
from
'
vs/base/common/htmlContent
'
;
import
{
renderMarkdown
}
from
'
vs/base/browser/htmlContentRenderer
'
;
import
{
IComment
,
getComments
}
from
'
vs/editor/contrib/review/reviewProvider
'
;
import
{
RawContextKey
,
IContextKeyService
,
IContextKey
,
ContextKeyExpr
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
RawContextKey
,
IContextKeyService
,
IContextKey
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
KeybindingsRegistry
}
from
'
vs/platform/keybinding/common/keybindingsRegistry
'
;
import
{
KeyCode
,
KeyMod
}
from
'
vs/base/common/keyCodes
'
;
import
{
ServicesAccessor
}
from
'
vs/platform/instantiation/common/instantiation
'
;
...
...
@@ -67,7 +66,7 @@ export class ReviewZoneWidget extends ZoneWidget {
container
.
appendChild
(
this
.
_domNode
);
}
display
(
comments
:
I
Comment
[],
lineNumber
:
number
)
{
display
(
comments
:
modes
.
Comment
[],
lineNumber
:
number
)
{
this
.
show
({
lineNumber
:
lineNumber
,
column
:
1
},
2
);
for
(
let
i
=
0
;
i
<
comments
.
length
;
i
++
)
{
...
...
@@ -76,21 +75,21 @@ export class ReviewZoneWidget extends ZoneWidget {
let
header
=
document
.
createElement
(
'
h4
'
);
let
author
=
document
.
createElement
(
'
strong
'
);
author
.
className
=
'
author
'
;
author
.
innerText
=
comments
[
i
].
user
;
let
time
=
document
.
createElement
(
'
span
'
);
time
.
className
=
'
created_at
'
;
time
.
innerText
=
comments
[
i
].
created_at
;
author
.
innerText
=
comments
[
i
].
user
Name
;
//
let time = document.createElement('span');
//
time.className = 'created_at';
//
time.innerText = comments[i].created_at;
header
.
appendChild
(
author
);
header
.
appendChild
(
time
);
//
header.appendChild(time);
singleCommentContainer
.
appendChild
(
header
);
let
body
=
document
.
createElement
(
'
div
'
);
body
.
className
=
'
comment-body
'
;
singleCommentContainer
.
appendChild
(
body
);
let
md
=
new
MarkdownString
(
comments
[
i
].
body
)
;
let
md
=
comments
[
i
].
body
;
body
.
appendChild
(
renderMarkdown
(
md
));
this
.
_domNode
.
appendChild
(
singleCommentContainer
);
// this._domNode.appendChild(document.createElement('textarea'));
}
// this._domNode.appendChild(document.createElement('textarea'));
this
.
_resizeObserver
=
new
ResizeObserver
(
entries
=>
{
if
(
entries
[
0
].
target
===
this
.
_domNode
)
{
const
lineHeight
=
this
.
editor
.
getConfiguration
().
lineHeight
;
...
...
@@ -111,7 +110,6 @@ export class ReviewZoneWidget extends ZoneWidget {
}
export
class
ReviewController
implements
IEditorContribution
{
private
globalToDispose
:
IDisposable
[];
private
localToDispose
:
IDisposable
[];
private
editor
:
ICodeEditor
;
...
...
@@ -119,16 +117,18 @@ export class ReviewController implements IEditorContribution {
private
_domNode
:
HTMLElement
;
private
_zoneWidget
:
ReviewZoneWidget
;
private
_reviewPanelVisible
:
IContextKey
<
boolean
>
;
private
_commentThreads
:
modes
.
CommentThread
[];
constructor
(
editor
:
ICodeEditor
,
@
IContextKeyService
contextKeyService
:
IContextKeyService
,
@
IContextKeyService
contextKeyService
:
IContextKeyService
)
{
this
.
editor
=
editor
;
this
.
globalToDispose
=
[];
this
.
localToDispose
=
[];
this
.
decorationIDs
=
[];
this
.
mouseDownInfo
=
null
;
this
.
_commentThreads
=
[];
this
.
_reviewPanelVisible
=
ctxReviewPanelVisible
.
bindTo
(
contextKeyService
);
this
.
_domNode
=
document
.
createElement
(
'
div
'
);
...
...
@@ -161,20 +161,6 @@ export class ReviewController implements IEditorContribution {
this
.
localToDispose
.
push
(
this
.
editor
.
onMouseDown
(
e
=>
this
.
onEditorMouseDown
(
e
)));
this
.
localToDispose
.
push
(
this
.
editor
.
onMouseUp
(
e
=>
this
.
onEditorMouseUp
(
e
)));
this
.
editor
.
changeDecorations
(
accessor
=>
{
this
.
decorationIDs
=
accessor
.
deltaDecorations
(
this
.
decorationIDs
,
[
{
range
:
{
startLineNumber
:
6
,
startColumn
:
1
,
endLineNumber
:
6
,
endColumn
:
1
},
options
:
REVIEWL_DECORATION
}
]);
});
}
private
mouseDownInfo
:
{
lineNumber
:
number
,
iconClicked
:
boolean
};
...
...
@@ -232,9 +218,30 @@ export class ReviewController implements IEditorContribution {
this
.
_reviewPanelVisible
.
set
(
true
);
this
.
_zoneWidget
=
new
ReviewZoneWidget
(
this
.
editor
);
this
.
_zoneWidget
.
display
(
getComments
(
),
lineNumber
);
this
.
_zoneWidget
.
display
(
this
.
getComments
(
lineNumber
),
lineNumber
);
}
getComments
(
line
:
number
):
modes
.
Comment
[]
{
for
(
let
i
=
0
;
i
<
this
.
_commentThreads
.
length
;
i
++
)
{
if
(
this
.
_commentThreads
[
i
].
range
.
startLineNumber
===
line
)
{
return
this
.
_commentThreads
[
i
].
comments
;
}
}
return
[];
}
setComments
(
commentThreads
:
modes
.
CommentThread
[]):
void
{
this
.
_commentThreads
=
commentThreads
;
this
.
editor
.
changeDecorations
(
accessor
=>
{
this
.
decorationIDs
=
accessor
.
deltaDecorations
(
this
.
decorationIDs
,
commentThreads
.
map
(
thread
=>
({
range
:
thread
.
range
,
options
:
REVIEWL_DECORATION
})));
});
}
public
closeWidget
():
void
{
this
.
_reviewPanelVisible
.
reset
();
...
...
src/vs/monaco.d.ts
浏览文件 @
094a469d
...
...
@@ -4998,6 +4998,20 @@ declare namespace monaco.languages {
arguments
?:
any
[];
}
export
interface
CommentThread
{
readonly
range
:
IRange
;
readonly
comments
:
Comment
[];
}
export
interface
Comment
{
readonly
body
:
IMarkdownString
;
readonly
userName
:
string
;
}
export
interface
CommentProvider
{
provideComments
(
model
:
editor
.
ITextModel
,
token
:
CancellationToken
):
CommentThread
[];
}
export
interface
ICodeLensSymbol
{
range
:
IRange
;
id
?:
string
;
...
...
src/vs/vscode.proposed.d.ts
浏览文件 @
094a469d
...
...
@@ -723,4 +723,26 @@ declare module 'vscode' {
}
//#endregion
interface
CommentThread
{
range
:
Range
;
comments
:
Comment
[];
}
interface
Comment
{
body
:
MarkdownString
;
userName
:
string
;
}
/**
* TODO: force update event?
* TODO: resolve step?
*/
interface
CommentProvider
{
provideComments
(
document
:
TextDocument
,
token
:
CancellationToken
):
Promise
<
CommentThread
[]
>
;
}
namespace
workspace
{
export
function
registerCommentProvider
(
provider
:
CommentProvider
):
Disposable
;
}
}
src/vs/workbench/api/electron-browser/extensionHost.contribution.ts
浏览文件 @
094a469d
...
...
@@ -48,6 +48,7 @@ import './mainThreadTerminalService';
import
'
./mainThreadTreeViews
'
;
import
'
./mainThreadLogService
'
;
import
'
./mainThreadWebview
'
;
import
'
./mainThreadComments
'
;
import
'
./mainThreadWindow
'
;
import
'
./mainThreadWorkspace
'
;
...
...
src/vs/workbench/api/electron-browser/mainThreadComments.ts
0 → 100644
浏览文件 @
094a469d
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
{
Disposable
,
IDisposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
ICodeEditor
}
from
'
vs/editor/browser/editorBrowser
'
;
import
{
ICodeEditorService
}
from
'
vs/editor/browser/services/codeEditorService
'
;
import
{
ITextModel
}
from
'
vs/editor/common/model
'
;
import
*
as
modes
from
'
vs/editor/common/modes
'
;
import
{
ReviewController
}
from
'
vs/editor/contrib/review/review
'
;
import
{
extHostNamedCustomer
}
from
'
vs/workbench/api/electron-browser/extHostCustomers
'
;
import
{
IEditorGroupService
}
from
'
vs/workbench/services/group/common/groupService
'
;
import
{
keys
}
from
'
../../../base/common/map
'
;
import
{
IWorkbenchEditorService
}
from
'
../../services/editor/common/editorService
'
;
import
{
ExtHostCommentsShape
,
ExtHostContext
,
IExtHostContext
,
MainContext
,
MainThreadCommentsShape
}
from
'
../node/extHost.protocol
'
;
@
extHostNamedCustomer
(
MainContext
.
MainThreadComments
)
export
class
MainThreadComments
extends
Disposable
implements
MainThreadCommentsShape
{
private
_proxy
:
ExtHostCommentsShape
;
private
_providers
=
new
Map
<
number
,
IDisposable
>
();
constructor
(
extHostContext
:
IExtHostContext
,
@
IEditorGroupService
editorGroupService
:
IEditorGroupService
,
@
IWorkbenchEditorService
workbenchEditorService
:
IWorkbenchEditorService
,
@
ICodeEditorService
private
_codeEditorService
:
ICodeEditorService
)
{
super
();
this
.
_proxy
=
extHostContext
.
getProxy
(
ExtHostContext
.
ExtHostComments
);
editorGroupService
.
onEditorsChanged
(
e
=>
{
const
outerEditor
=
this
.
getFocusedEditor
();
if
(
!
outerEditor
)
{
return
;
}
const
controller
=
ReviewController
.
get
(
outerEditor
);
if
(
!
controller
)
{
return
;
}
this
.
provideComments
(
outerEditor
.
getModel
()).
then
(
commentThreads
=>
{
controller
.
setComments
(
commentThreads
);
});
});
}
$registerCommentProvider
(
handle
:
number
):
void
{
this
.
_providers
.
set
(
handle
,
undefined
);
}
$unregisterCommentProvider
(
handle
:
number
):
void
{
throw
new
Error
(
'
Method not implemented.
'
);
}
dispose
():
void
{
throw
new
Error
(
'
Method not implemented.
'
);
}
getFocusedEditor
():
ICodeEditor
{
let
editor
=
this
.
_codeEditorService
.
getFocusedCodeEditor
();
// if\
return
editor
;
}
async
provideComments
(
model
:
ITextModel
):
Promise
<
modes
.
CommentThread
[]
>
{
const
result
:
modes
.
CommentThread
[]
=
[];
for
(
const
handle
of
keys
(
this
.
_providers
))
{
result
.
push
(...
await
this
.
_proxy
.
$providerComments
(
handle
,
model
.
uri
));
}
return
result
;
}
}
src/vs/workbench/api/node/extHost.api.impl.ts
浏览文件 @
094a469d
...
...
@@ -58,6 +58,7 @@ import { isFalsyOrEmpty } from 'vs/base/common/arrays';
import
{
OverviewRulerLane
}
from
'
vs/editor/common/model
'
;
import
{
ExtHostLogService
}
from
'
vs/workbench/api/node/extHostLogService
'
;
import
{
ExtHostWebviews
}
from
'
vs/workbench/api/node/extHostWebview
'
;
import
{
ExtHostComments
}
from
'
./extHostComments
'
;
export
interface
IExtensionApiFactory
{
(
extension
:
IExtensionDescription
):
typeof
vscode
;
...
...
@@ -119,6 +120,7 @@ export function createApiFactory(
const
extHostWindow
=
rpcProtocol
.
set
(
ExtHostContext
.
ExtHostWindow
,
new
ExtHostWindow
(
rpcProtocol
));
rpcProtocol
.
set
(
ExtHostContext
.
ExtHostExtensionService
,
extensionService
);
const
extHostProgress
=
rpcProtocol
.
set
(
ExtHostContext
.
ExtHostProgress
,
new
ExtHostProgress
(
rpcProtocol
.
getProxy
(
MainContext
.
MainThreadProgress
)));
const
exthostCommentProviders
=
rpcProtocol
.
set
(
ExtHostContext
.
ExtHostComments
,
new
ExtHostComments
(
rpcProtocol
,
extHostDocuments
));
// Check that no named customers are missing
const
expected
:
ProxyIdentifier
<
any
>
[]
=
Object
.
keys
(
ExtHostContext
).
map
((
key
)
=>
ExtHostContext
[
key
]);
...
...
@@ -540,6 +542,9 @@ export function createApiFactory(
}),
registerSearchProvider
:
proposedApiFunction
(
extension
,
(
scheme
,
provider
)
=>
{
return
extHostFileSystem
.
registerSearchProvider
(
scheme
,
provider
);
}),
registerCommentProvider
:
proposedApiFunction
(
extension
,
(
provider
:
vscode
.
CommentProvider
)
=>
{
return
exthostCommentProviders
.
registerCommentProvider
(
provider
);
})
};
...
...
src/vs/workbench/api/node/extHost.protocol.ts
浏览文件 @
094a469d
...
...
@@ -104,6 +104,11 @@ export interface MainThreadCommandsShape extends IDisposable {
$getCommands
():
Thenable
<
string
[]
>
;
}
export
interface
MainThreadCommentsShape
extends
IDisposable
{
$registerCommentProvider
(
handle
:
number
):
void
;
$unregisterCommentProvider
(
handle
:
number
):
void
;
}
export
interface
MainThreadConfigurationShape
extends
IDisposable
{
$updateConfigurationOption
(
target
:
ConfigurationTarget
,
key
:
string
,
value
:
any
,
resource
:
UriComponents
):
TPromise
<
void
>
;
$removeConfigurationOption
(
target
:
ConfigurationTarget
,
key
:
string
,
resource
:
UriComponents
):
TPromise
<
void
>
;
...
...
@@ -813,10 +818,15 @@ export interface ExtHostProgressShape {
$acceptProgressCanceled
(
handle
:
number
):
void
;
}
export
interface
ExtHostCommentsShape
{
$providerComments
(
handle
:
number
,
document
:
UriComponents
):
TPromise
<
modes
.
CommentThread
[]
>
;
}
// --- proxy identifiers
export
const
MainContext
=
{
MainThreadCommands
:
<
ProxyIdentifier
<
MainThreadCommandsShape
>>
createMainId
<
MainThreadCommandsShape
>
(
'
MainThreadCommands
'
),
MainThreadComments
:
createMainId
<
MainThreadCommentsShape
>
(
'
MainThreadComments
'
),
MainThreadConfiguration
:
createMainId
<
MainThreadConfigurationShape
>
(
'
MainThreadConfiguration
'
),
MainThreadDebugService
:
createMainId
<
MainThreadDebugServiceShape
>
(
'
MainThreadDebugService
'
),
MainThreadDecorations
:
createMainId
<
MainThreadDecorationsShape
>
(
'
MainThreadDecorations
'
),
...
...
@@ -871,5 +881,6 @@ export const ExtHostContext = {
ExtHostWorkspace
:
createExtId
<
ExtHostWorkspaceShape
>
(
'
ExtHostWorkspace
'
),
ExtHostWindow
:
createExtId
<
ExtHostWindowShape
>
(
'
ExtHostWindow
'
),
ExtHostWebviews
:
createExtId
<
ExtHostWebviewsShape
>
(
'
ExtHostWebviews
'
),
ExtHostProgress
:
createMainId
<
ExtHostProgressShape
>
(
'
ExtHostProgress
'
)
ExtHostProgress
:
createMainId
<
ExtHostProgressShape
>
(
'
ExtHostProgress
'
),
ExtHostComments
:
createMainId
<
ExtHostCommentsShape
>
(
'
ExtHostComments
'
)
};
src/vs/workbench/api/node/extHostComments.ts
0 → 100644
浏览文件 @
094a469d
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
{
asWinJsPromise
}
from
'
vs/base/common/async
'
;
import
{
values
}
from
'
vs/base/common/map
'
;
import
URI
,
{
UriComponents
}
from
'
vs/base/common/uri
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
*
as
modes
from
'
vs/editor/common/modes
'
;
import
{
ExtHostDocuments
}
from
'
vs/workbench/api/node/extHostDocuments
'
;
import
*
as
vscode
from
'
vscode
'
;
import
{
flatten
}
from
'
../../../base/common/arrays
'
;
import
{
ExtHostCommentsShape
,
IMainContext
,
MainContext
,
MainThreadCommentsShape
}
from
'
./extHost.protocol
'
;
import
*
as
extHostTypeConverter
from
'
vs/workbench/api/node/extHostTypeConverters
'
;
export
class
ExtHostComments
implements
ExtHostCommentsShape
{
private
static
handlePool
=
0
;
private
_proxy
:
MainThreadCommentsShape
;
private
_providers
=
new
Map
<
number
,
vscode
.
CommentProvider
>
();
constructor
(
mainContext
:
IMainContext
,
private
readonly
_documents
:
ExtHostDocuments
,
)
{
this
.
_proxy
=
mainContext
.
getProxy
(
MainContext
.
MainThreadComments
);
}
registerCommentProvider
(
provider
:
vscode
.
CommentProvider
):
vscode
.
Disposable
{
const
handle
=
ExtHostComments
.
handlePool
++
;
this
.
_providers
.
set
(
handle
,
provider
);
this
.
_proxy
.
$registerCommentProvider
(
handle
);
return
{
dispose
:
()
=>
{
this
.
_proxy
.
$unregisterCommentProvider
(
handle
);
this
.
_providers
.
delete
(
handle
);
}
};
}
$providerComments
(
handle
:
number
,
uri
:
UriComponents
):
TPromise
<
modes
.
CommentThread
[]
>
{
const
data
=
this
.
_documents
.
getDocumentData
(
URI
.
revive
(
uri
));
if
(
!
data
||
!
data
.
document
)
{
return
TPromise
.
as
([]);
}
return
asWinJsPromise
(
token
=>
{
const
allProviderResults
=
values
(
this
.
_providers
).
map
(
provider
=>
provider
.
provideComments
(
data
.
document
,
token
));
return
TPromise
.
join
(
allProviderResults
);
})
.
then
(
flatten
)
.
then
(
comments
=>
comments
.
map
(
convertCommentThread
));
}
}
function
convertCommentThread
(
vscodeCommentThread
:
vscode
.
CommentThread
):
modes
.
CommentThread
{
return
{
range
:
extHostTypeConverter
.
fromRange
(
vscodeCommentThread
.
range
),
comments
:
vscodeCommentThread
.
comments
.
map
(
convertComment
)
};
}
function
convertComment
(
vscodeComment
:
vscode
.
Comment
):
modes
.
Comment
{
return
{
body
:
extHostTypeConverter
.
MarkdownString
.
from
(
vscodeComment
.
body
),
userName
:
vscodeComment
.
userName
};
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录