Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
92dd8208
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,发现更多精彩内容 >>
提交
92dd8208
编写于
11月 16, 2016
作者:
J
Joao Moreno
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
wip: dirtydiff as a workbench concept
上级
19c20239
变更
9
显示空白变更内容
内联
并排
Showing
9 changed file
with
394 addition
and
345 deletion
+394
-345
src/vs/workbench/electron-browser/workbench.main.ts
src/vs/workbench/electron-browser/workbench.main.ts
+2
-0
src/vs/workbench/electron-browser/workbench.ts
src/vs/workbench/electron-browser/workbench.ts
+5
-0
src/vs/workbench/parts/git/browser/gitWorkbenchContributions.ts
.../workbench/parts/git/browser/gitWorkbenchContributions.ts
+0
-342
src/vs/workbench/parts/git/common/gitDirtyDiff.ts
src/vs/workbench/parts/git/common/gitDirtyDiff.ts
+80
-0
src/vs/workbench/parts/git/electron-browser/git.contribution.ts
.../workbench/parts/git/electron-browser/git.contribution.ts
+8
-3
src/vs/workbench/parts/scm/browser/dirtydiffDecorator.ts
src/vs/workbench/parts/scm/browser/dirtydiffDecorator.ts
+218
-0
src/vs/workbench/parts/scm/browser/scm.contribution.ts
src/vs/workbench/parts/scm/browser/scm.contribution.ts
+13
-0
src/vs/workbench/services/scm/common/dirtydiff.ts
src/vs/workbench/services/scm/common/dirtydiff.ts
+25
-0
src/vs/workbench/services/scm/common/dirtydiffService.ts
src/vs/workbench/services/scm/common/dirtydiffService.ts
+43
-0
未找到文件。
src/vs/workbench/electron-browser/workbench.main.ts
浏览文件 @
92dd8208
...
...
@@ -40,6 +40,8 @@ import 'vs/workbench/parts/search/browser/search.contribution';
import
'
vs/workbench/parts/search/browser/searchViewlet
'
;
// can be packaged separately
import
'
vs/workbench/parts/search/browser/openAnythingHandler
'
;
// can be packaged separately
import
'
vs/workbench/parts/scm/browser/scm.contribution
'
;
import
'
vs/workbench/parts/git/electron-browser/git.contribution
'
;
import
'
vs/workbench/parts/git/browser/gitQuickOpen
'
;
import
'
vs/workbench/parts/git/browser/gitActions.contribution
'
;
...
...
src/vs/workbench/electron-browser/workbench.ts
浏览文件 @
92dd8208
...
...
@@ -75,6 +75,8 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import
{
SyncDescriptor
}
from
'
vs/platform/instantiation/common/descriptors
'
;
import
{
TextFileService
}
from
'
vs/workbench/services/textfile/electron-browser/textFileService
'
;
import
{
ITextFileService
}
from
'
vs/workbench/services/textfile/common/textfiles
'
;
import
{
IDirtyDiffService
}
from
'
vs/workbench/services/scm/common/dirtydiff
'
;
import
{
DirtyDiffService
}
from
'
vs/workbench/services/scm/common/dirtydiffService
'
;
import
{
TextModelResolverService
}
from
'
vs/workbench/services/textmodelResolver/common/textModelResolverService
'
;
import
{
ITextModelResolverService
}
from
'
vs/platform/textmodelResolver/common/resolver
'
;
import
{
ServiceCollection
}
from
'
vs/platform/instantiation/common/serviceCollection
'
;
...
...
@@ -456,6 +458,9 @@ export class Workbench implements IPartService {
// Text File Service
serviceCollection
.
set
(
ITextFileService
,
this
.
instantiationService
.
createInstance
(
TextFileService
));
// DirtyDiff Service
serviceCollection
.
set
(
IDirtyDiffService
,
this
.
instantiationService
.
createInstance
(
DirtyDiffService
));
// Backup Model Service
serviceCollection
.
set
(
IBackupModelService
,
this
.
instantiationService
.
createInstance
(
BackupModelService
));
...
...
src/vs/workbench/parts/git/browser/gitWorkbenchContributions.ts
浏览文件 @
92dd8208
...
...
@@ -8,14 +8,9 @@
import
'
vs/css!./media/git.contribution
'
;
import
nls
=
require
(
'
vs/nls
'
);
import
async
=
require
(
'
vs/base/common/async
'
);
import
errors
=
require
(
'
vs/base/common/errors
'
);
import
paths
=
require
(
'
vs/base/common/paths
'
);
import
lifecycle
=
require
(
'
vs/base/common/lifecycle
'
);
import
winjs
=
require
(
'
vs/base/common/winjs.base
'
);
import
ext
=
require
(
'
vs/workbench/common/contributions
'
);
import
git
=
require
(
'
vs/workbench/parts/git/common/git
'
);
import
common
=
require
(
'
vs/editor/common/editorCommon
'
);
import
widget
=
require
(
'
vs/editor/browser/codeEditor
'
);
import
viewlet
=
require
(
'
vs/workbench/browser/viewlet
'
);
import
statusbar
=
require
(
'
vs/workbench/browser/parts/statusbar/statusbar
'
);
import
platform
=
require
(
'
vs/platform/platform
'
);
...
...
@@ -30,18 +25,10 @@ import quickopen = require('vs/workbench/browser/quickopen');
import
'
vs/workbench/parts/git/browser/gitEditorContributions
'
;
import
{
IActivityService
,
ProgressBadge
,
NumberBadge
}
from
'
vs/workbench/services/activity/common/activityService
'
;
import
{
IEventService
}
from
'
vs/platform/event/common/event
'
;
import
{
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
IMessageService
}
from
'
vs/platform/message/common/message
'
;
import
{
IWorkspaceContextService
}
from
'
vs/platform/workspace/common/workspace
'
;
import
{
IViewletService
}
from
'
vs/workbench/services/viewlet/browser/viewlet
'
;
import
{
IWorkbenchEditorService
}
from
'
vs/workbench/services/editor/common/editorService
'
;
import
{
KeyMod
,
KeyCode
}
from
'
vs/base/common/keyCodes
'
;
import
{
IModelService
}
from
'
vs/editor/common/services/modelService
'
;
import
{
RawText
}
from
'
vs/editor/common/model/textModel
'
;
import
{
IEditorWorkerService
}
from
'
vs/editor/common/services/editorWorkerService
'
;
import
URI
from
'
vs/base/common/uri
'
;
import
{
IEditorGroupService
}
from
'
vs/workbench/services/group/common/groupService
'
;
import
{
Schemas
}
from
'
vs/base/common/network
'
;
import
IGitService
=
git
.
IGitService
;
...
...
@@ -120,330 +107,6 @@ export class StatusUpdater implements ext.IWorkbenchContribution {
}
}
class
DirtyDiffModelDecorator
{
static
ID
=
'
vs.git.editor.dirtyDiffDecorator
'
;
static
MODIFIED_DECORATION_OPTIONS
:
common
.
IModelDecorationOptions
=
{
linesDecorationsClassName
:
'
git-dirty-modified-diff-glyph
'
,
isWholeLine
:
true
,
overviewRuler
:
{
color
:
'
rgba(0, 122, 204, 0.6)
'
,
darkColor
:
'
rgba(0, 122, 204, 0.6)
'
,
position
:
common
.
OverviewRulerLane
.
Left
}
};
static
ADDED_DECORATION_OPTIONS
:
common
.
IModelDecorationOptions
=
{
linesDecorationsClassName
:
'
git-dirty-added-diff-glyph
'
,
isWholeLine
:
true
,
overviewRuler
:
{
color
:
'
rgba(0, 122, 204, 0.6)
'
,
darkColor
:
'
rgba(0, 122, 204, 0.6)
'
,
position
:
common
.
OverviewRulerLane
.
Left
}
};
static
DELETED_DECORATION_OPTIONS
:
common
.
IModelDecorationOptions
=
{
linesDecorationsClassName
:
'
git-dirty-deleted-diff-glyph
'
,
isWholeLine
:
true
,
overviewRuler
:
{
color
:
'
rgba(0, 122, 204, 0.6)
'
,
darkColor
:
'
rgba(0, 122, 204, 0.6)
'
,
position
:
common
.
OverviewRulerLane
.
Left
}
};
private
modelService
:
IModelService
;
private
editorWorkerService
:
IEditorWorkerService
;
private
editorService
:
IWorkbenchEditorService
;
private
contextService
:
IWorkspaceContextService
;
private
gitService
:
IGitService
;
private
model
:
common
.
IModel
;
private
_originalContentsURI
:
URI
;
private
path
:
string
;
private
decorations
:
string
[];
private
delayer
:
async
.
ThrottledDelayer
<
void
>
;
private
diffDelayer
:
async
.
ThrottledDelayer
<
void
>
;
private
toDispose
:
lifecycle
.
IDisposable
[];
constructor
(
model
:
common
.
IModel
,
path
:
string
,
@
IModelService
modelService
:
IModelService
,
@
IEditorWorkerService
editorWorkerService
:
IEditorWorkerService
,
@
IWorkbenchEditorService
editorService
:
IWorkbenchEditorService
,
@
IWorkspaceContextService
contextService
:
IWorkspaceContextService
,
@
IGitService
gitService
:
IGitService
)
{
this
.
modelService
=
modelService
;
this
.
editorWorkerService
=
editorWorkerService
;
this
.
editorService
=
editorService
;
this
.
contextService
=
contextService
;
this
.
gitService
=
gitService
;
this
.
model
=
model
;
this
.
_originalContentsURI
=
model
.
uri
.
with
({
scheme
:
Schemas
.
internal
});
this
.
path
=
path
;
this
.
decorations
=
[];
this
.
delayer
=
new
async
.
ThrottledDelayer
<
void
>
(
500
);
this
.
diffDelayer
=
new
async
.
ThrottledDelayer
<
void
>
(
200
);
this
.
toDispose
=
[];
this
.
toDispose
.
push
(
model
.
onDidChangeContent
(()
=>
this
.
triggerDiff
()));
this
.
toDispose
.
push
(
this
.
gitService
.
addListener2
(
git
.
ServiceEvents
.
STATE_CHANGED
,
()
=>
this
.
onChanges
()));
this
.
toDispose
.
push
(
this
.
gitService
.
addListener2
(
git
.
ServiceEvents
.
OPERATION_END
,
e
=>
{
if
(
e
.
operation
.
id
!==
git
.
ServiceOperations
.
BACKGROUND_FETCH
)
{
this
.
onChanges
();
}
}));
this
.
onChanges
();
}
private
onChanges
():
void
{
if
(
!
this
.
gitService
)
{
return
;
}
if
(
this
.
gitService
.
getState
()
!==
git
.
ServiceState
.
OK
)
{
return
;
}
// go through all interesting models
this
.
trigger
();
}
private
trigger
():
void
{
this
.
delayer
.
trigger
(()
=>
this
.
diffOriginalContents
())
.
done
(
null
,
errors
.
onUnexpectedError
);
}
private
diffOriginalContents
():
winjs
.
TPromise
<
void
>
{
return
this
.
getOriginalContents
()
.
then
(
contents
=>
{
if
(
!
this
.
model
||
this
.
model
.
isDisposed
())
{
return
;
// disposed
}
if
(
!
contents
)
{
// untracked file
this
.
modelService
.
destroyModel
(
this
.
_originalContentsURI
);
return
this
.
triggerDiff
();
}
let
originalModel
=
this
.
modelService
.
getModel
(
this
.
_originalContentsURI
);
if
(
originalModel
)
{
let
contentsRawText
=
RawText
.
fromStringWithModelOptions
(
contents
,
originalModel
);
// return early if nothing has changed
if
(
originalModel
.
equals
(
contentsRawText
))
{
return
winjs
.
TPromise
.
as
(
null
);
}
// we already have the original contents
originalModel
.
setValueFromRawText
(
contentsRawText
);
}
else
{
// this is the first time we load the original contents
this
.
modelService
.
createModel
(
contents
,
null
,
this
.
_originalContentsURI
);
}
return
this
.
triggerDiff
();
});
}
private
getOriginalContents
():
winjs
.
TPromise
<
string
>
{
var
gitModel
=
this
.
gitService
.
getModel
();
var
treeish
=
gitModel
.
getStatus
().
find
(
this
.
path
,
git
.
StatusType
.
INDEX
)
?
'
~
'
:
'
HEAD
'
;
return
this
.
gitService
.
buffer
(
this
.
path
,
treeish
);
}
private
triggerDiff
():
winjs
.
Promise
{
if
(
!
this
.
diffDelayer
)
{
return
winjs
.
TPromise
.
as
(
null
);
}
return
this
.
diffDelayer
.
trigger
(()
=>
{
if
(
!
this
.
model
||
this
.
model
.
isDisposed
())
{
return
winjs
.
TPromise
.
as
<
any
>
([]);
// disposed
}
return
this
.
editorWorkerService
.
computeDirtyDiff
(
this
.
_originalContentsURI
,
this
.
model
.
uri
,
true
);
}).
then
((
diff
:
common
.
IChange
[])
=>
{
if
(
!
this
.
model
||
this
.
model
.
isDisposed
())
{
return
;
// disposed
}
return
this
.
decorations
=
this
.
model
.
deltaDecorations
(
this
.
decorations
,
DirtyDiffModelDecorator
.
changesToDecorations
(
diff
||
[]));
});
}
private
static
changesToDecorations
(
diff
:
common
.
IChange
[]):
common
.
IModelDeltaDecoration
[]
{
return
diff
.
map
((
change
)
=>
{
var
startLineNumber
=
change
.
modifiedStartLineNumber
;
var
endLineNumber
=
change
.
modifiedEndLineNumber
||
startLineNumber
;
// Added
if
(
change
.
originalEndLineNumber
===
0
)
{
return
{
range
:
{
startLineNumber
:
startLineNumber
,
startColumn
:
1
,
endLineNumber
:
endLineNumber
,
endColumn
:
1
},
options
:
DirtyDiffModelDecorator
.
ADDED_DECORATION_OPTIONS
};
}
// Removed
if
(
change
.
modifiedEndLineNumber
===
0
)
{
return
{
range
:
{
startLineNumber
:
startLineNumber
,
startColumn
:
1
,
endLineNumber
:
startLineNumber
,
endColumn
:
1
},
options
:
DirtyDiffModelDecorator
.
DELETED_DECORATION_OPTIONS
};
}
// Modified
return
{
range
:
{
startLineNumber
:
startLineNumber
,
startColumn
:
1
,
endLineNumber
:
endLineNumber
,
endColumn
:
1
},
options
:
DirtyDiffModelDecorator
.
MODIFIED_DECORATION_OPTIONS
};
});
}
public
dispose
():
void
{
this
.
modelService
.
destroyModel
(
this
.
_originalContentsURI
);
this
.
toDispose
=
lifecycle
.
dispose
(
this
.
toDispose
);
if
(
this
.
model
&&
!
this
.
model
.
isDisposed
())
{
this
.
model
.
deltaDecorations
(
this
.
decorations
,
[]);
}
this
.
model
=
null
;
this
.
decorations
=
null
;
if
(
this
.
delayer
)
{
this
.
delayer
.
cancel
();
this
.
delayer
=
null
;
}
if
(
this
.
diffDelayer
)
{
this
.
diffDelayer
.
cancel
();
this
.
diffDelayer
=
null
;
}
}
}
export
class
DirtyDiffDecorator
implements
ext
.
IWorkbenchContribution
{
private
gitService
:
IGitService
;
private
messageService
:
IMessageService
;
private
editorService
:
IWorkbenchEditorService
;
private
eventService
:
IEventService
;
private
contextService
:
IWorkspaceContextService
;
private
instantiationService
:
IInstantiationService
;
private
models
:
common
.
IModel
[];
private
decorators
:
{
[
modelId
:
string
]:
DirtyDiffModelDecorator
};
private
toDispose
:
lifecycle
.
IDisposable
[];
constructor
(
@
IGitService
gitService
:
IGitService
,
@
IMessageService
messageService
:
IMessageService
,
@
IWorkbenchEditorService
editorService
:
IWorkbenchEditorService
,
@
IEditorGroupService
editorGroupService
:
IEditorGroupService
,
@
IEventService
eventService
:
IEventService
,
@
IWorkspaceContextService
contextService
:
IWorkspaceContextService
,
@
IInstantiationService
instantiationService
:
IInstantiationService
)
{
this
.
gitService
=
gitService
;
this
.
messageService
=
messageService
;
this
.
editorService
=
editorService
;
this
.
eventService
=
eventService
;
this
.
contextService
=
contextService
;
this
.
instantiationService
=
instantiationService
;
this
.
models
=
[];
this
.
decorators
=
Object
.
create
(
null
);
this
.
toDispose
=
[];
this
.
toDispose
.
push
(
editorGroupService
.
onEditorsChanged
(()
=>
this
.
onEditorsChanged
()));
this
.
toDispose
.
push
(
gitService
.
addListener2
(
git
.
ServiceEvents
.
DISPOSE
,
()
=>
this
.
dispose
()));
}
public
getId
():
string
{
return
'
git.DirtyDiffModelDecorator
'
;
}
private
onEditorsChanged
():
void
{
// HACK: This is the best current way of figuring out whether to draw these decorations
// or not. Needs context from the editor, to know whether it is a diff editor, in place editor
// etc.
const
repositoryRoot
=
this
.
gitService
.
getModel
().
getRepositoryRoot
();
// If there is no repository root, just wait until that changes
if
(
typeof
repositoryRoot
!==
'
string
'
)
{
this
.
gitService
.
addOneTimeDisposableListener
(
git
.
ServiceEvents
.
STATE_CHANGED
,
()
=>
this
.
onEditorsChanged
());
this
.
models
.
forEach
(
m
=>
this
.
onModelInvisible
(
m
));
this
.
models
=
[];
return
;
}
const
models
=
this
.
editorService
.
getVisibleEditors
()
// map to the editor controls
.
map
(
e
=>
e
.
getControl
())
// only interested in code editor widgets
.
filter
(
c
=>
c
instanceof
widget
.
CodeEditor
)
// map to models
.
map
(
e
=>
(
<
widget
.
CodeEditor
>
e
).
getModel
())
// remove nulls and duplicates
.
filter
((
m
,
i
,
a
)
=>
!!
m
&&
a
.
indexOf
(
m
,
i
+
1
)
===
-
1
)
// get the associated resource
.
map
(
m
=>
({
model
:
m
,
resource
:
m
.
uri
}))
// remove nulls
.
filter
(
p
=>
!!
p
.
resource
&&
// and invalid resources
(
p
.
resource
.
scheme
===
'
file
'
&&
paths
.
isEqualOrParent
(
p
.
resource
.
fsPath
,
repositoryRoot
))
)
// get paths
.
map
(
p
=>
({
model
:
p
.
model
,
path
:
paths
.
normalize
(
paths
.
relative
(
repositoryRoot
,
p
.
resource
.
fsPath
))
}))
// remove nulls and inside .git files
.
filter
(
p
=>
!!
p
.
path
&&
p
.
path
.
indexOf
(
'
.git/
'
)
===
-
1
);
var
newModels
=
models
.
filter
(
p
=>
this
.
models
.
every
(
m
=>
p
.
model
!==
m
));
var
oldModels
=
this
.
models
.
filter
(
m
=>
models
.
every
(
p
=>
p
.
model
!==
m
));
newModels
.
forEach
(
p
=>
this
.
onModelVisible
(
p
.
model
,
p
.
path
));
oldModels
.
forEach
(
m
=>
this
.
onModelInvisible
(
m
));
this
.
models
=
models
.
map
(
p
=>
p
.
model
);
}
private
onModelVisible
(
model
:
common
.
IModel
,
path
:
string
):
void
{
this
.
decorators
[
model
.
id
]
=
this
.
instantiationService
.
createInstance
(
DirtyDiffModelDecorator
,
model
,
path
);
}
private
onModelInvisible
(
model
:
common
.
IModel
):
void
{
this
.
decorators
[
model
.
id
].
dispose
();
delete
this
.
decorators
[
model
.
id
];
}
public
dispose
():
void
{
this
.
toDispose
=
lifecycle
.
dispose
(
this
.
toDispose
);
this
.
models
.
forEach
(
m
=>
this
.
decorators
[
m
.
id
].
dispose
());
this
.
models
=
null
;
this
.
decorators
=
null
;
}
}
export
const
VIEWLET_ID
=
'
workbench.view.git
'
;
class
OpenGitViewletAction
extends
viewlet
.
ToggleViewletAction
{
...
...
@@ -500,11 +163,6 @@ export function registerContributions(): void {
StatusUpdater
);
// Register DirtyDiffDecorator
(
<
ext
.
IWorkbenchContributionsRegistry
>
platform
.
Registry
.
as
(
ext
.
Extensions
.
Workbench
)).
registerWorkbenchContribution
(
DirtyDiffDecorator
);
// Register Quick Open for git
(
<
quickopen
.
IQuickOpenRegistry
>
platform
.
Registry
.
as
(
quickopen
.
Extensions
.
Quickopen
)).
registerQuickOpenHandler
(
new
quickopen
.
QuickOpenHandlerDescriptor
(
...
...
src/vs/workbench/parts/git/common/gitDirtyDiff.ts
0 → 100644
浏览文件 @
92dd8208
/*---------------------------------------------------------------------------------------------
* 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
{
IModelService
}
from
'
vs/editor/common/services/modelService
'
;
import
URI
from
'
vs/base/common/uri
'
;
import
{
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
{
onUnexpectedError
}
from
'
vs/base/common/errors
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
IModel
}
from
'
vs/editor/common/editorCommon
'
;
import
{
ITextModelResolverService
,
ITextModelContentProvider
}
from
'
vs/platform/textmodelResolver/common/resolver
'
;
import
{
IDirtyDiffTextDocumentProvider
,
IDirtyDiffService
}
from
'
vs/workbench/services/scm/common/dirtydiff
'
;
import
{
IGitService
,
StatusType
,
ServiceEvents
,
ServiceOperations
,
ServiceState
}
from
'
vs/workbench/parts/git/common/git
'
;
import
{
IWorkbenchContribution
}
from
'
vs/workbench/common/contributions
'
;
export
class
GitContentProvider
implements
IWorkbenchContribution
,
ITextModelContentProvider
,
IDirtyDiffTextDocumentProvider
{
constructor
(
@
ITextModelResolverService
textModelResolverService
:
ITextModelResolverService
,
@
IModelService
private
modelService
:
IModelService
,
@
IDirtyDiffService
private
dirtyDiffService
:
IDirtyDiffService
,
@
IGitService
private
gitService
:
IGitService
)
{
this
.
dirtyDiffService
.
registerDirtyDiffTextDocumentProvider
(
this
);
textModelResolverService
.
registerTextModelContentProvider
(
'
git-index
'
,
this
);
}
getDirtyDiffTextDocument
(
resource
:
URI
):
TPromise
<
URI
>
{
return
TPromise
.
as
(
resource
.
with
({
scheme
:
'
git-index
'
}));
}
provideTextContent
(
uri
:
URI
):
TPromise
<
IModel
>
{
if
(
uri
.
scheme
!==
'
git-index
'
)
{
return
null
;
}
const
gitModel
=
this
.
gitService
.
getModel
();
const
path
=
uri
.
fsPath
;
const
treeish
=
gitModel
.
getStatus
().
find
(
path
,
StatusType
.
INDEX
)
?
'
~
'
:
'
HEAD
'
;
return
this
.
gitService
.
buffer
(
path
,
treeish
)
.
then
(
contents
=>
this
.
modelService
.
createModel
(
contents
,
null
,
uri
))
.
then
(
model
=>
{
const
trigger
=
()
=>
{
this
.
gitService
.
buffer
(
path
,
treeish
).
then
(
contents
=>
model
.
setValue
(
contents
))
.
done
(
null
,
onUnexpectedError
);
};
const
onChanges
=
()
=>
{
if
(
this
.
gitService
.
getState
()
!==
ServiceState
.
OK
)
{
return
;
}
trigger
();
};
const
disposables
=
[
this
.
gitService
.
addListener2
(
ServiceEvents
.
STATE_CHANGED
,
onChanges
),
this
.
gitService
.
addListener2
(
ServiceEvents
.
OPERATION_END
,
e
=>
{
if
(
e
.
operation
.
id
!==
ServiceOperations
.
BACKGROUND_FETCH
)
{
onChanges
();
}
})
];
model
.
onWillDispose
(()
=>
{
dispose
(
disposables
);
});
return
model
;
});
}
getId
():
string
{
return
'
git.contentprovider
'
;
}
}
\ No newline at end of file
src/vs/workbench/parts/git/electron-browser/git.contribution.ts
浏览文件 @
92dd8208
...
...
@@ -10,15 +10,20 @@ import { IGitService } from 'vs/workbench/parts/git/common/git';
import
{
registerSingleton
}
from
'
vs/platform/instantiation/common/extensions
'
;
import
{
SyncActionDescriptor
}
from
'
vs/platform/actions/common/actions
'
;
import
{
Registry
}
from
'
vs/platform/platform
'
;
import
{
Extensions
as
WorkbenchExtensions
,
IWorkbenchActionRegistry
}
from
'
vs/workbench/common/actionRegistry
'
;
import
{
CloneAction
}
from
'
./gitActions
'
;
import
{
GitContentProvider
}
from
'
../common/gitDirtyDiff
'
;
import
{
IWorkbenchActionRegistry
,
Extensions
as
WorkbenchActionExtensions
}
from
'
vs/workbench/common/actionRegistry
'
;
import
{
IWorkbenchContributionsRegistry
,
Extensions
as
WorkbenchExtensions
}
from
'
vs/workbench/common/contributions
'
;
registerContributions
();
// Register Service
registerSingleton
(
IGitService
,
ElectronGitService
);
const
workbenchActionRegistry
=
Registry
.
as
<
IWorkbenchActionRegistry
>
(
WorkbenchExtensions
.
WorkbenchActions
);
const
category
=
localize
(
'
git
'
,
"
Git
"
);
workbenchActionRegistry
.
registerWorkbenchAction
(
new
SyncActionDescriptor
(
CloneAction
,
CloneAction
.
ID
,
CloneAction
.
LABEL
),
'
Git: Clone
'
,
category
);
\ No newline at end of file
Registry
.
as
<
IWorkbenchActionRegistry
>
(
WorkbenchActionExtensions
.
WorkbenchActions
)
.
registerWorkbenchAction
(
new
SyncActionDescriptor
(
CloneAction
,
CloneAction
.
ID
,
CloneAction
.
LABEL
),
'
Git: Clone
'
,
category
);
Registry
.
as
<
IWorkbenchContributionsRegistry
>
(
WorkbenchExtensions
.
Workbench
)
.
registerWorkbenchContribution
(
GitContentProvider
);
\ No newline at end of file
src/vs/workbench/parts/scm/browser/dirtydiffDecorator.ts
0 → 100644
浏览文件 @
92dd8208
/*---------------------------------------------------------------------------------------------
* 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
{
ThrottledDelayer
}
from
'
vs/base/common/async
'
;
import
*
as
lifecycle
from
'
vs/base/common/lifecycle
'
;
import
*
as
winjs
from
'
vs/base/common/winjs.base
'
;
import
*
as
ext
from
'
vs/workbench/common/contributions
'
;
import
*
as
common
from
'
vs/editor/common/editorCommon
'
;
import
*
as
widget
from
'
vs/editor/browser/codeEditor
'
;
import
{
IEventService
}
from
'
vs/platform/event/common/event
'
;
import
{
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
IMessageService
}
from
'
vs/platform/message/common/message
'
;
import
{
IWorkspaceContextService
}
from
'
vs/platform/workspace/common/workspace
'
;
import
{
IWorkbenchEditorService
}
from
'
vs/workbench/services/editor/common/editorService
'
;
import
{
IModelService
}
from
'
vs/editor/common/services/modelService
'
;
import
{
IEditorWorkerService
}
from
'
vs/editor/common/services/editorWorkerService
'
;
import
URI
from
'
vs/base/common/uri
'
;
import
{
IEditorGroupService
}
from
'
vs/workbench/services/group/common/groupService
'
;
import
{
IDirtyDiffService
}
from
'
vs/workbench/services/scm/common/dirtydiff
'
;
class
DirtyDiffModelDecorator
{
static
MODIFIED_DECORATION_OPTIONS
:
common
.
IModelDecorationOptions
=
{
linesDecorationsClassName
:
'
git-dirty-modified-diff-glyph
'
,
isWholeLine
:
true
,
overviewRuler
:
{
color
:
'
rgba(0, 122, 204, 0.6)
'
,
darkColor
:
'
rgba(0, 122, 204, 0.6)
'
,
position
:
common
.
OverviewRulerLane
.
Left
}
};
static
ADDED_DECORATION_OPTIONS
:
common
.
IModelDecorationOptions
=
{
linesDecorationsClassName
:
'
git-dirty-added-diff-glyph
'
,
isWholeLine
:
true
,
overviewRuler
:
{
color
:
'
rgba(0, 122, 204, 0.6)
'
,
darkColor
:
'
rgba(0, 122, 204, 0.6)
'
,
position
:
common
.
OverviewRulerLane
.
Left
}
};
static
DELETED_DECORATION_OPTIONS
:
common
.
IModelDecorationOptions
=
{
linesDecorationsClassName
:
'
git-dirty-deleted-diff-glyph
'
,
isWholeLine
:
true
,
overviewRuler
:
{
color
:
'
rgba(0, 122, 204, 0.6)
'
,
darkColor
:
'
rgba(0, 122, 204, 0.6)
'
,
position
:
common
.
OverviewRulerLane
.
Left
}
};
private
decorations
:
string
[];
private
diffDelayer
:
ThrottledDelayer
<
void
>
;
private
toDispose
:
lifecycle
.
IDisposable
[];
constructor
(
private
model
:
common
.
IModel
,
private
uri
:
URI
,
@
IDirtyDiffService
private
dirtyDiffService
:
IDirtyDiffService
,
@
IModelService
private
modelService
:
IModelService
,
@
IEditorWorkerService
private
editorWorkerService
:
IEditorWorkerService
,
@
IWorkbenchEditorService
private
editorService
:
IWorkbenchEditorService
,
@
IWorkspaceContextService
private
contextService
:
IWorkspaceContextService
)
{
this
.
decorations
=
[];
this
.
diffDelayer
=
new
ThrottledDelayer
<
void
>
(
200
);
this
.
toDispose
=
[];
this
.
triggerDiff
();
this
.
toDispose
.
push
(
model
.
onDidChangeContent
(()
=>
this
.
triggerDiff
()));
}
private
triggerDiff
():
winjs
.
Promise
{
if
(
!
this
.
diffDelayer
)
{
return
winjs
.
TPromise
.
as
(
null
);
}
return
this
.
dirtyDiffService
.
getDirtyDiffTextDocument
(
this
.
uri
).
then
(
originalUri
=>
{
return
this
.
diffDelayer
.
trigger
(()
=>
{
if
(
!
this
.
model
||
this
.
model
.
isDisposed
())
{
return
winjs
.
TPromise
.
as
<
any
>
([]);
// disposed
}
return
this
.
editorWorkerService
.
computeDirtyDiff
(
originalUri
,
this
.
model
.
uri
,
true
);
}).
then
((
diff
:
common
.
IChange
[])
=>
{
if
(
!
this
.
model
||
this
.
model
.
isDisposed
())
{
return
;
// disposed
}
return
this
.
decorations
=
this
.
model
.
deltaDecorations
(
this
.
decorations
,
DirtyDiffModelDecorator
.
changesToDecorations
(
diff
||
[]));
});
});
}
private
static
changesToDecorations
(
diff
:
common
.
IChange
[]):
common
.
IModelDeltaDecoration
[]
{
return
diff
.
map
((
change
)
=>
{
const
startLineNumber
=
change
.
modifiedStartLineNumber
;
const
endLineNumber
=
change
.
modifiedEndLineNumber
||
startLineNumber
;
// Added
if
(
change
.
originalEndLineNumber
===
0
)
{
return
{
range
:
{
startLineNumber
:
startLineNumber
,
startColumn
:
1
,
endLineNumber
:
endLineNumber
,
endColumn
:
1
},
options
:
DirtyDiffModelDecorator
.
ADDED_DECORATION_OPTIONS
};
}
// Removed
if
(
change
.
modifiedEndLineNumber
===
0
)
{
return
{
range
:
{
startLineNumber
:
startLineNumber
,
startColumn
:
1
,
endLineNumber
:
startLineNumber
,
endColumn
:
1
},
options
:
DirtyDiffModelDecorator
.
DELETED_DECORATION_OPTIONS
};
}
// Modified
return
{
range
:
{
startLineNumber
:
startLineNumber
,
startColumn
:
1
,
endLineNumber
:
endLineNumber
,
endColumn
:
1
},
options
:
DirtyDiffModelDecorator
.
MODIFIED_DECORATION_OPTIONS
};
});
}
dispose
():
void
{
this
.
toDispose
=
lifecycle
.
dispose
(
this
.
toDispose
);
if
(
this
.
model
&&
!
this
.
model
.
isDisposed
())
{
this
.
model
.
deltaDecorations
(
this
.
decorations
,
[]);
}
this
.
model
=
null
;
this
.
decorations
=
null
;
if
(
this
.
diffDelayer
)
{
this
.
diffDelayer
.
cancel
();
this
.
diffDelayer
=
null
;
}
}
}
export
class
DirtyDiffDecorator
implements
ext
.
IWorkbenchContribution
{
private
models
:
common
.
IModel
[]
=
[];
private
decorators
:
{
[
modelId
:
string
]:
DirtyDiffModelDecorator
}
=
Object
.
create
(
null
);
private
toDispose
:
lifecycle
.
IDisposable
[]
=
[];
constructor
(
@
IMessageService
private
messageService
:
IMessageService
,
@
IWorkbenchEditorService
private
editorService
:
IWorkbenchEditorService
,
@
IEditorGroupService
editorGroupService
:
IEditorGroupService
,
@
IEventService
private
eventService
:
IEventService
,
@
IWorkspaceContextService
private
contextService
:
IWorkspaceContextService
,
@
IInstantiationService
private
instantiationService
:
IInstantiationService
)
{
this
.
toDispose
.
push
(
editorGroupService
.
onEditorsChanged
(()
=>
this
.
onEditorsChanged
()));
}
getId
():
string
{
return
'
git.DirtyDiffModelDecorator
'
;
}
private
onEditorsChanged
():
void
{
// HACK: This is the best current way of figuring out whether to draw these decorations
// or not. Needs context from the editor, to know whether it is a diff editor, in place editor
// etc.
const
models
=
this
.
editorService
.
getVisibleEditors
()
// map to the editor controls
.
map
(
e
=>
e
.
getControl
())
// only interested in code editor widgets
.
filter
(
c
=>
c
instanceof
widget
.
CodeEditor
)
// map to models
.
map
(
e
=>
(
<
widget
.
CodeEditor
>
e
).
getModel
())
// remove nulls and duplicates
.
filter
((
m
,
i
,
a
)
=>
!!
m
&&
!!
m
.
uri
&&
a
.
indexOf
(
m
,
i
+
1
)
===
-
1
)
// get the associated resource
.
map
(
m
=>
({
model
:
m
,
uri
:
m
.
uri
}));
const
newModels
=
models
.
filter
(
p
=>
this
.
models
.
every
(
m
=>
p
.
model
!==
m
));
const
oldModels
=
this
.
models
.
filter
(
m
=>
models
.
every
(
p
=>
p
.
model
!==
m
));
newModels
.
forEach
(({
model
,
uri
})
=>
this
.
onModelVisible
(
model
,
uri
));
oldModels
.
forEach
(
m
=>
this
.
onModelInvisible
(
m
));
this
.
models
=
models
.
map
(
p
=>
p
.
model
);
}
private
onModelVisible
(
model
:
common
.
IModel
,
uri
:
URI
):
void
{
this
.
decorators
[
model
.
id
]
=
this
.
instantiationService
.
createInstance
(
DirtyDiffModelDecorator
,
model
,
uri
);
}
private
onModelInvisible
(
model
:
common
.
IModel
):
void
{
this
.
decorators
[
model
.
id
].
dispose
();
delete
this
.
decorators
[
model
.
id
];
}
dispose
():
void
{
this
.
toDispose
=
lifecycle
.
dispose
(
this
.
toDispose
);
this
.
models
.
forEach
(
m
=>
this
.
decorators
[
m
.
id
].
dispose
());
this
.
models
=
null
;
this
.
decorators
=
null
;
}
}
src/vs/workbench/parts/scm/browser/scm.contribution.ts
0 → 100644
浏览文件 @
92dd8208
/*---------------------------------------------------------------------------------------------
* 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
{
Registry
}
from
'
vs/platform/platform
'
;
import
{
IWorkbenchContributionsRegistry
,
Extensions
as
WorkbenchExtensions
}
from
'
vs/workbench/common/contributions
'
;
import
{
DirtyDiffDecorator
}
from
'
./dirtydiffDecorator
'
;
Registry
.
as
<
IWorkbenchContributionsRegistry
>
(
WorkbenchExtensions
.
Workbench
)
.
registerWorkbenchContribution
(
DirtyDiffDecorator
);
\ No newline at end of file
src/vs/workbench/services/scm/common/dirtydiff.ts
0 → 100644
浏览文件 @
92dd8208
/*---------------------------------------------------------------------------------------------
* 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
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
URI
from
'
vs/base/common/uri
'
;
import
{
createDecorator
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
IDisposable
}
from
'
vs/base/common/lifecycle
'
;
export
interface
IDirtyDiffTextDocumentProvider
{
getDirtyDiffTextDocument
(
resource
:
URI
):
TPromise
<
URI
>
;
}
export
const
IDirtyDiffService
=
createDecorator
<
IDirtyDiffService
>
(
'
dirtyDiff
'
);
export
interface
IDirtyDiffService
{
_serviceBrand
:
any
;
getDirtyDiffTextDocument
(
resource
:
URI
):
TPromise
<
URI
>
;
registerDirtyDiffTextDocumentProvider
(
provider
:
IDirtyDiffTextDocumentProvider
):
IDisposable
;
}
\ No newline at end of file
src/vs/workbench/services/scm/common/dirtydiffService.ts
0 → 100644
浏览文件 @
92dd8208
/*---------------------------------------------------------------------------------------------
* 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
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
URI
from
'
vs/base/common/uri
'
;
import
{
IDisposable
,
toDisposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
IDirtyDiffService
,
IDirtyDiffTextDocumentProvider
}
from
'
./dirtydiff
'
;
export
class
DirtyDiffService
implements
IDirtyDiffService
{
_serviceBrand
;
private
providers
:
IDirtyDiffTextDocumentProvider
[]
=
[];
getDirtyDiffTextDocument
(
resource
:
URI
):
TPromise
<
URI
>
{
// TODO@Joao: just take the first
const
[
provider
]
=
this
.
providers
;
if
(
!
provider
)
{
return
TPromise
.
as
(
null
);
}
return
provider
.
getDirtyDiffTextDocument
(
resource
);
}
registerDirtyDiffTextDocumentProvider
(
provider
:
IDirtyDiffTextDocumentProvider
):
IDisposable
{
this
.
providers
=
[
provider
,
...
this
.
providers
];
return
toDisposable
(()
=>
{
const
index
=
this
.
providers
.
indexOf
(
provider
);
if
(
index
<
0
)
{
return
;
}
this
.
providers
.
splice
(
index
,
1
);
});
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录