Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
1800414c
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,发现更多精彩内容 >>
提交
1800414c
编写于
4月 28, 2018
作者:
R
Rob Lourens
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
#3355 - implement setting change telemetry
上级
61aa2e58
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
145 addition
and
25 deletion
+145
-25
src/vs/workbench/parts/preferences/browser/settingsEditor2.ts
...vs/workbench/parts/preferences/browser/settingsEditor2.ts
+145
-25
未找到文件。
src/vs/workbench/parts/preferences/browser/settingsEditor2.ts
浏览文件 @
1800414c
...
...
@@ -4,6 +4,9 @@
*--------------------------------------------------------------------------------------------*/
import
*
as
DOM
from
'
vs/base/browser/dom
'
;
import
*
as
arrays
from
'
vs/base/common/arrays
'
;
import
*
as
objects
from
'
vs/base/common/objects
'
;
import
{
Button
}
from
'
vs/base/browser/ui/button/button
'
;
import
{
InputBox
}
from
'
vs/base/browser/ui/inputbox/inputBox
'
;
import
{
IDelegate
,
IRenderer
}
from
'
vs/base/browser/ui/list/list
'
;
import
{
List
}
from
'
vs/base/browser/ui/list/listWidget
'
;
...
...
@@ -11,6 +14,7 @@ import { SelectBox } from 'vs/base/browser/ui/selectBox/selectBox';
import
{
IAction
}
from
'
vs/base/common/actions
'
;
import
{
Delayer
,
ThrottledDelayer
}
from
'
vs/base/common/async
'
;
import
{
Color
}
from
'
vs/base/common/color
'
;
import
{
getErrorMessage
,
isPromiseCanceledError
}
from
'
vs/base/common/errors
'
;
import
{
Emitter
,
Event
}
from
'
vs/base/common/event
'
;
import
{
IDisposable
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
...
...
@@ -19,23 +23,21 @@ import { localize } from 'vs/nls';
import
{
ConfigurationTarget
,
IConfigurationService
}
from
'
vs/platform/configuration/common/configuration
'
;
import
{
IContextKey
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
IContextMenuService
,
IContextViewService
}
from
'
vs/platform/contextview/browser/contextView
'
;
import
{
IEditor
}
from
'
vs/platform/editor/common/editor
'
;
import
{
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
WorkbenchList
}
from
'
vs/platform/list/browser/listService
'
;
import
{
ILogService
}
from
'
vs/platform/log/common/log
'
;
import
{
ITelemetryService
}
from
'
vs/platform/telemetry/common/telemetry
'
;
import
{
attachInputBoxStyler
,
attachSelectBoxStyler
,
attachButtonStyler
}
from
'
vs/platform/theme/common/styler
'
;
import
{
IThemeService
,
registerThemingParticipant
,
ITheme
,
ICssStyleCollector
}
from
'
vs/platform/theme/common/themeService
'
;
import
{
registerColor
}
from
'
vs/platform/theme/common/colorRegistry
'
;
import
{
attachButtonStyler
,
attachInputBoxStyler
,
attachSelectBoxStyler
}
from
'
vs/platform/theme/common/styler
'
;
import
{
ICssStyleCollector
,
ITheme
,
IThemeService
,
registerThemingParticipant
}
from
'
vs/platform/theme/common/themeService
'
;
import
{
BaseEditor
}
from
'
vs/workbench/browser/parts/editor/baseEditor
'
;
import
{
EditorOptions
}
from
'
vs/workbench/common/editor
'
;
import
{
SearchWidget
,
SettingsTargetsWidget
}
from
'
vs/workbench/parts/preferences/browser/preferencesWidgets
'
;
import
{
IPreferencesService
,
ISe
tting
,
ISettingsEditorModel
,
ISearchResult
}
from
'
vs/workbench/services/preferences/common/preferences
'
;
import
{
SearchWidget
,
SettingsTargetsWidget
,
SettingsTarget
}
from
'
vs/workbench/parts/preferences/browser/preferencesWidgets
'
;
import
{
IPreferencesService
,
ISe
archResult
,
ISetting
,
ISettingsEditorModel
}
from
'
vs/workbench/services/preferences/common/preferences
'
;
import
{
PreferencesEditorInput2
}
from
'
vs/workbench/services/preferences/common/preferencesEditorInput
'
;
import
{
DefaultSettingsEditorModel
}
from
'
vs/workbench/services/preferences/common/preferencesModels
'
;
import
{
Button
}
from
'
vs/base/browser/ui/button/button
'
;
import
{
IPreferencesSearchService
,
ISearchProvider
}
from
'
../common/preferences
'
;
import
{
isPromiseCanceledError
,
getErrorMessage
}
from
'
vs/base/common/errors
'
;
import
{
ILogService
}
from
'
vs/platform/log/common/log
'
;
import
{
registerColor
}
from
'
vs/platform/theme/common/colorRegistry
'
;
import
{
IEditor
}
from
'
vs/platform/editor/common/editor
'
;
const
SETTINGS_ENTRY_TEMPLATE_ID
=
'
settings.entry.template
'
;
const
SETTINGS_GROUP_ENTRY_TEMPLATE_ID
=
'
settings.group.template
'
;
...
...
@@ -106,6 +108,7 @@ export class SettingsEditor2 extends BaseEditor {
private
dimension
:
DOM
.
Dimension
;
private
searchFocusContextKey
:
IContextKey
<
boolean
>
;
private
delayedModifyLogging
:
Delayer
<
void
>
;
private
delayedFilterLogging
:
Delayer
<
void
>
;
private
localSearchDelayer
:
Delayer
<
void
>
;
private
remoteSearchThrottle
:
ThrottledDelayer
<
void
>
;
...
...
@@ -113,7 +116,8 @@ export class SettingsEditor2 extends BaseEditor {
private
currentLocalSearchProvider
:
ISearchProvider
;
private
currentRemoteSearchProvider
:
ISearchProvider
;
private
searchResults
:
ISearchResult
[];
private
searchResultModel
:
SearchResultModel
;
private
pendingSettingModifiedReport
:
{
key
:
string
,
value
:
any
};
constructor
(
@
ITelemetryService
telemetryService
:
ITelemetryService
,
...
...
@@ -126,9 +130,11 @@ export class SettingsEditor2 extends BaseEditor {
@
ILogService
private
logService
:
ILogService
)
{
super
(
SettingsEditor2
.
ID
,
telemetryService
,
themeService
);
this
.
delayedModifyLogging
=
new
Delayer
<
void
>
(
1000
);
this
.
delayedFilterLogging
=
new
Delayer
<
void
>
(
1000
);
this
.
localSearchDelayer
=
new
Delayer
(
100
);
this
.
remoteSearchThrottle
=
new
ThrottledDelayer
(
200
);
this
.
searchResultModel
=
new
SearchResultModel
();
this
.
_register
(
configurationService
.
onDidChangeConfiguration
(()
=>
this
.
render
()));
}
...
...
@@ -275,6 +281,79 @@ export class SettingsEditor2 extends BaseEditor {
private
onDidChangeSetting
(
key
:
string
,
value
:
any
):
void
{
// ConfigurationService displays the error
this
.
configurationService
.
updateValue
(
key
,
value
,
<
ConfigurationTarget
>
this
.
settingsTargetsWidget
.
settingsTarget
);
const
reportModifiedProps
=
{
key
,
query
:
this
.
searchWidget
.
getValue
(),
searchResults
:
this
.
searchResultModel
.
getUniqueResults
(),
rawResults
:
this
.
searchResultModel
.
getRawResults
(),
showConfiguredOnly
:
this
.
showConfiguredSettingsOnly
,
isReset
:
typeof
value
===
'
undefined
'
,
settingsTarget
:
this
.
settingsTargetsWidget
.
settingsTarget
as
SettingsTarget
};
if
(
this
.
pendingSettingModifiedReport
&&
key
!==
this
.
pendingSettingModifiedReport
.
key
)
{
this
.
reportModifiedSetting
(
reportModifiedProps
);
}
this
.
pendingSettingModifiedReport
=
{
key
,
value
};
this
.
delayedModifyLogging
.
trigger
(()
=>
this
.
reportModifiedSetting
(
reportModifiedProps
));
}
private
reportModifiedSetting
(
props
:
{
key
:
string
,
query
:
string
,
searchResults
:
ISearchResult
[],
rawResults
:
ISearchResult
[],
showConfiguredOnly
:
boolean
,
isReset
:
boolean
,
settingsTarget
:
SettingsTarget
}):
void
{
this
.
pendingSettingModifiedReport
=
null
;
const
remoteResult
=
props
.
searchResults
&&
props
.
searchResults
[
SearchResultIdx
.
Remote
];
const
localResult
=
props
.
searchResults
&&
props
.
searchResults
[
SearchResultIdx
.
Local
];
let
groupId
=
undefined
;
let
nlpIndex
=
undefined
;
let
displayIndex
=
undefined
;
if
(
props
.
searchResults
)
{
const
localIndex
=
arrays
.
firstIndex
(
localResult
.
filterMatches
,
m
=>
m
.
setting
.
key
===
props
.
key
);
groupId
=
localIndex
>=
0
?
'
local
'
:
'
remote
'
;
displayIndex
=
localIndex
>=
0
?
localIndex
:
remoteResult
&&
(
arrays
.
firstIndex
(
remoteResult
.
filterMatches
,
m
=>
m
.
setting
.
key
===
props
.
key
)
+
localResult
.
filterMatches
.
length
);
const
rawResults
=
this
.
searchResultModel
.
getRawResults
();
if
(
rawResults
[
SearchResultIdx
.
Remote
])
{
const
_nlpIndex
=
arrays
.
firstIndex
(
rawResults
[
SearchResultIdx
.
Remote
].
filterMatches
,
m
=>
m
.
setting
.
key
===
props
.
key
);
nlpIndex
=
_nlpIndex
>=
0
?
_nlpIndex
:
undefined
;
}
}
const
reportedTarget
=
props
.
settingsTarget
===
ConfigurationTarget
.
USER
?
'
user
'
:
props
.
settingsTarget
===
ConfigurationTarget
.
WORKSPACE
?
'
workspace
'
:
'
folder
'
;
const
data
=
{
key
:
props
.
key
,
query
:
props
.
query
,
groupId
,
nlpIndex
,
displayIndex
,
showConfiguredOnly
:
props
.
showConfiguredOnly
,
isReset
:
props
.
isReset
,
target
:
reportedTarget
};
/* __GDPR__
"settingEditor.settingModified" : {
"key" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"query" : { "classification": "CustomerContent", "purpose": "FeatureInsight" },
"groupId" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"nlpIndex" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"displayIndex" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"showConfiguredOnly" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"isReset" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"target" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this
.
telemetryService
.
publicLog
(
'
settingEditor.settingModified
'
,
data
);
}
private
render
():
TPromise
<
any
>
{
...
...
@@ -290,8 +369,8 @@ export class SettingsEditor2 extends BaseEditor {
const
query
=
this
.
searchWidget
.
getValue
().
trim
();
this
.
delayedFilterLogging
.
cancel
();
this
.
triggerSearch
(
query
).
then
(()
=>
{
if
(
query
&&
this
.
searchResult
s
)
{
this
.
delayedFilterLogging
.
trigger
(()
=>
this
.
reportFilteringUsed
(
query
,
this
.
searchResult
s
));
if
(
query
&&
this
.
searchResult
Model
.
hasResults
()
)
{
this
.
delayedFilterLogging
.
trigger
(()
=>
this
.
reportFilteringUsed
(
query
,
this
.
searchResult
Model
.
getUniqueResults
()
));
}
});
}
...
...
@@ -307,7 +386,7 @@ export class SettingsEditor2 extends BaseEditor {
this
.
localSearchDelayer
.
cancel
();
this
.
remoteSearchThrottle
.
cancel
();
this
.
searchResult
s
=
null
;
this
.
searchResult
Model
.
clear
()
;
this
.
renderEntries
();
return
TPromise
.
wrap
(
null
);
}
...
...
@@ -324,14 +403,8 @@ export class SettingsEditor2 extends BaseEditor {
const
counts
=
{};
const
filterResult
=
results
[
SearchResultIdx
.
Local
];
counts
[
'
filterResult
'
]
=
filterResult
.
filterMatches
.
length
;
if
(
nlpResult
&&
nlpResult
.
filterMatches
.
length
)
{
const
localMatchKeys
=
new
Set
();
filterResult
.
filterMatches
.
forEach
(
m
=>
localMatchKeys
.
add
(
m
.
setting
.
key
));
counts
[
'
nlpResult
'
]
=
nlpResult
.
filterMatches
.
filter
(
m
=>
!
localMatchKeys
.
has
(
m
.
setting
.
key
))
.
length
;
if
(
nlpResult
)
{
counts
[
'
nlpResult
'
]
=
nlpResult
.
filterMatches
.
length
;
}
const
requestCount
=
nlpMetadata
&&
nlpMetadata
.
requestCount
;
...
...
@@ -370,8 +443,7 @@ export class SettingsEditor2 extends BaseEditor {
return
TPromise
.
join
(
filterPs
).
then
(
results
=>
{
const
[
result
]
=
results
;
this
.
searchResults
=
this
.
searchResults
||
[];
this
.
searchResults
[
type
]
=
result
;
this
.
searchResultModel
.
setResult
(
type
,
result
);
return
this
.
render
();
});
}
...
...
@@ -431,8 +503,8 @@ export class SettingsEditor2 extends BaseEditor {
const
focusedRowItem
=
DOM
.
findParentWithClass
(
<
HTMLElement
>
document
.
activeElement
,
'
monaco-list-row
'
);
const
focusedRowId
=
focusedRowItem
&&
focusedRowItem
.
id
;
const
entries
=
this
.
searchResult
s
?
this
.
getEntriesFromSearch
(
this
.
searchResult
s
)
:
const
entries
=
this
.
searchResult
Model
.
hasResults
()
?
this
.
getEntriesFromSearch
(
this
.
searchResult
Model
.
getUniqueResults
()
)
:
this
.
getEntriesFromModel
();
this
.
settingsList
.
splice
(
0
,
this
.
settingsList
.
length
,
entries
);
...
...
@@ -775,3 +847,51 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
collector
.
addRule
(
`.settings-editor > .settings-body > .settings-list-container .monaco-list-row.is-configured .setting-value-checkbox::after { background-color:
${
configuredItemBackgroundColor
}
; }`
);
}
});
class
SearchResultModel
{
private
rawSearchResults
:
ISearchResult
[];
private
cachedUniqueSearchResults
:
ISearchResult
[];
getUniqueResults
():
ISearchResult
[]
{
if
(
this
.
cachedUniqueSearchResults
)
{
return
this
.
cachedUniqueSearchResults
;
}
if
(
!
this
.
rawSearchResults
)
{
return
null
;
}
const
localMatchKeys
=
new
Set
();
const
localResult
=
objects
.
deepClone
(
this
.
rawSearchResults
[
SearchResultIdx
.
Local
]);
if
(
localResult
)
{
localResult
.
filterMatches
.
forEach
(
m
=>
localMatchKeys
.
add
(
m
.
setting
.
key
));
}
const
remoteResult
=
objects
.
deepClone
(
this
.
rawSearchResults
[
SearchResultIdx
.
Remote
]);
if
(
remoteResult
)
{
remoteResult
.
filterMatches
=
remoteResult
.
filterMatches
.
filter
(
m
=>
!
localMatchKeys
.
has
(
m
.
setting
.
key
));
}
this
.
cachedUniqueSearchResults
=
[
localResult
,
remoteResult
];
return
this
.
cachedUniqueSearchResults
;
}
getRawResults
():
ISearchResult
[]
{
return
this
.
rawSearchResults
;
}
hasResults
():
boolean
{
return
!!
this
.
rawSearchResults
;
}
clear
():
void
{
this
.
cachedUniqueSearchResults
=
null
;
this
.
rawSearchResults
=
null
;
}
setResult
(
type
:
SearchResultIdx
,
result
:
ISearchResult
):
void
{
this
.
cachedUniqueSearchResults
=
null
;
this
.
rawSearchResults
=
this
.
rawSearchResults
||
[];
this
.
rawSearchResults
[
type
]
=
result
;
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录