Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
61ec8f62
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,发现更多精彩内容 >>
提交
61ec8f62
编写于
1月 04, 2017
作者:
S
Sandeep Somavarapu
提交者:
GitHub
1月 04, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #18108 from Microsoft/sandy081/exploreConfiguration
Improve edit action and search in Settings editor
上级
618dbf47
7a6dfcf0
变更
9
展开全部
隐藏空白更改
内联
并排
Showing
9 changed file
with
555 addition
and
360 deletion
+555
-360
src/vs/base/common/filters.ts
src/vs/base/common/filters.ts
+11
-8
src/vs/base/test/common/filters.test.ts
src/vs/base/test/common/filters.test.ts
+3
-0
src/vs/workbench/common/editor/rangeDecorations.ts
src/vs/workbench/common/editor/rangeDecorations.ts
+7
-4
src/vs/workbench/parts/preferences/browser/media/preferences.css
...workbench/parts/preferences/browser/media/preferences.css
+6
-9
src/vs/workbench/parts/preferences/browser/preferencesEditor.ts
.../workbench/parts/preferences/browser/preferencesEditor.ts
+288
-209
src/vs/workbench/parts/preferences/browser/preferencesService.ts
...workbench/parts/preferences/browser/preferencesService.ts
+10
-60
src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts
...workbench/parts/preferences/browser/preferencesWidgets.ts
+88
-0
src/vs/workbench/parts/preferences/common/preferences.ts
src/vs/workbench/parts/preferences/common/preferences.ts
+8
-7
src/vs/workbench/parts/preferences/common/preferencesModels.ts
...s/workbench/parts/preferences/common/preferencesModels.ts
+134
-63
未找到文件。
src/vs/base/common/filters.ts
浏览文件 @
61ec8f62
...
...
@@ -272,10 +272,11 @@ export function matchesCamelCase(word: string, camelCaseWord: string): IMatch[]
}
// Matches beginning of words supporting non-ASCII languages
// E.g. "gp" or "g p" will match "Git: Pull"
// If `contiguous` is true then matches word with beginnings of the words in the target. E.g. "pul" will match "Git: Pull"
// Otherwise also matches sub string of the word with beginnings of the words in the target. E.g. "gp" or "g p" will match "Git: Pull"
// Useful in cases where the target is words (e.g. command labels)
export
function
matchesWords
(
word
:
string
,
target
:
string
):
IMatch
[]
{
export
function
matchesWords
(
word
:
string
,
target
:
string
,
contiguous
:
boolean
=
false
):
IMatch
[]
{
if
(
!
target
||
target
.
length
===
0
)
{
return
null
;
}
...
...
@@ -283,14 +284,14 @@ export function matchesWords(word: string, target: string): IMatch[] {
let
result
:
IMatch
[]
=
null
;
let
i
=
0
;
while
(
i
<
target
.
length
&&
(
result
=
_matchesWords
(
word
.
toLowerCase
(),
target
,
0
,
i
))
===
null
)
{
while
(
i
<
target
.
length
&&
(
result
=
_matchesWords
(
word
.
toLowerCase
(),
target
,
0
,
i
,
contiguous
))
===
null
)
{
i
=
nextWord
(
target
,
i
+
1
);
}
return
result
;
}
function
_matchesWords
(
word
:
string
,
target
:
string
,
i
:
number
,
j
:
number
):
IMatch
[]
{
function
_matchesWords
(
word
:
string
,
target
:
string
,
i
:
number
,
j
:
number
,
contiguous
:
boolean
):
IMatch
[]
{
if
(
i
===
word
.
length
)
{
return
[];
}
else
if
(
j
===
target
.
length
)
{
...
...
@@ -300,10 +301,12 @@ function _matchesWords(word: string, target: string, i: number, j: number): IMat
}
else
{
let
result
:
IMatch
[]
=
null
;
let
nextWordIndex
=
j
+
1
;
result
=
_matchesWords
(
word
,
target
,
i
+
1
,
j
+
1
);
while
(
!
result
&&
(
nextWordIndex
=
nextWord
(
target
,
nextWordIndex
))
<
target
.
length
)
{
result
=
_matchesWords
(
word
,
target
,
i
+
1
,
nextWordIndex
);
nextWordIndex
++
;
result
=
_matchesWords
(
word
,
target
,
i
+
1
,
j
+
1
,
contiguous
);
if
(
!
contiguous
)
{
while
(
!
result
&&
(
nextWordIndex
=
nextWord
(
target
,
nextWordIndex
))
<
target
.
length
)
{
result
=
_matchesWords
(
word
,
target
,
i
+
1
,
nextWordIndex
,
contiguous
);
nextWordIndex
++
;
}
}
return
result
===
null
?
null
:
join
({
start
:
j
,
end
:
j
+
1
},
result
);
}
...
...
src/vs/base/test/common/filters.test.ts
浏览文件 @
61ec8f62
...
...
@@ -186,5 +186,8 @@ suite('Filters', () => {
filterOk
(
matchesWords
,
'
git プル
'
,
'
git: プル
'
,
[{
start
:
0
,
end
:
3
},
{
start
:
4
,
end
:
7
}]);
filterOk
(
matchesWords
,
'
öäk
'
,
'
Öhm: Älles Klar
'
,
[{
start
:
0
,
end
:
1
},
{
start
:
5
,
end
:
6
},
{
start
:
11
,
end
:
12
}]);
assert
.
ok
(
matchesWords
(
'
gipu
'
,
'
Category: Git: Pull
'
,
true
)
===
null
);
assert
.
deepEqual
(
matchesWords
(
'
pu
'
,
'
Category: Git: Pull
'
,
true
),
[{
start
:
15
,
end
:
17
}]);
});
});
src/vs/workbench/common/editor/rangeDecorations.ts
浏览文件 @
61ec8f62
...
...
@@ -62,7 +62,8 @@ export class RangeHighlightDecorations implements IDisposable {
this
.
editor
=
editor
;
this
.
editorDisposables
.
push
(
this
.
editor
.
onDidChangeCursorPosition
((
e
:
editorCommon
.
ICursorPositionChangedEvent
)
=>
{
if
(
e
.
reason
===
editorCommon
.
CursorChangeReason
.
Explicit
e
.
reason
===
editorCommon
.
CursorChangeReason
.
NotSet
||
e
.
reason
===
editorCommon
.
CursorChangeReason
.
Explicit
||
e
.
reason
===
editorCommon
.
CursorChangeReason
.
Undo
||
e
.
reason
===
editorCommon
.
CursorChangeReason
.
Redo
)
{
...
...
@@ -95,8 +96,10 @@ export class RangeHighlightDecorations implements IDisposable {
}
public
dispose
()
{
this
.
removeHighlightRange
();
this
.
disposeEditorListeners
();
this
.
editor
=
null
;
if
(
this
.
editor
&&
this
.
editor
.
getModel
())
{
this
.
removeHighlightRange
();
this
.
disposeEditorListeners
();
this
.
editor
=
null
;
}
}
}
\ No newline at end of file
src/vs/workbench/parts/preferences/browser/media/preferences.css
浏览文件 @
61ec8f62
...
...
@@ -147,19 +147,16 @@
background
:
url(collapsed-dark.svg)
50%
50%
no-repeat
;
}
.monaco-editor
.view-line
:hover
.copySetting
:after
{
cursor
:
pointer
;
content
:
" "
;
.monaco-editor
.edit-preferences-widget
{
background
:
url('edit.svg')
center
center
no-repeat
;
margin-left
:
1em
;
display
:
inline-block
;
position
:
absolute
;
height
:
100%
;
transform
:
rotate
(
-90deg
);
width
:
16px
;
height
:
16px
;
cursor
:
pointer
;
}
.monaco-editor.hc-black
.
view-line
:hover
.copySetting
:after
,
.monaco-editor.vs-dark
.
view-line
:hover
.copySetting
:after
{
.monaco-editor.hc-black
.
edit-preferences-widget
,
.monaco-editor.vs-dark
.
edit-preferences-widget
{
background
:
url('edit_inverse.svg')
center
center
no-repeat
;
}
...
...
src/vs/workbench/parts/preferences/browser/preferencesEditor.ts
浏览文件 @
61ec8f62
此差异已折叠。
点击以展开。
src/vs/workbench/parts/preferences/browser/preferencesService.ts
浏览文件 @
61ec8f62
...
...
@@ -10,8 +10,7 @@ import URI from 'vs/base/common/uri';
import
{
LinkedMap
as
Map
}
from
'
vs/base/common/map
'
;
import
*
as
labels
from
'
vs/base/common/labels
'
;
import
{
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
parseTree
,
findNodeAtLocation
}
from
'
vs/base/common/json
'
;
import
{
toResource
,
SideBySideEditorInput
,
EditorInput
}
from
'
vs/workbench/common/editor
'
;
import
{
SideBySideEditorInput
,
EditorInput
}
from
'
vs/workbench/common/editor
'
;
import
{
IWorkbenchEditorService
}
from
'
vs/workbench/services/editor/common/editorService
'
;
import
{
IWorkspaceContextService
}
from
'
vs/platform/workspace/common/workspace
'
;
import
{
IWorkspaceConfigurationService
,
WORKSPACE_CONFIG_DEFAULT_PATH
}
from
'
vs/workbench/services/configuration/common/configuration
'
;
...
...
@@ -23,9 +22,7 @@ import { IMessageService, Severity, IChoiceService } from 'vs/platform/message/c
import
{
IExtensionService
}
from
'
vs/platform/extensions/common/extensions
'
;
import
{
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
IEnvironmentService
}
from
'
vs/platform/environment/common/environment
'
;
import
{
ICodeEditor
}
from
'
vs/editor/browser/editorBrowser
'
;
import
*
as
editorCommon
from
'
vs/editor/common/editorCommon
'
;
import
{
IConfigurationEditingService
,
ConfigurationTarget
,
IConfigurationValue
}
from
'
vs/workbench/services/configuration/common/configurationEditing
'
;
import
{
IConfigurationEditingService
,
ConfigurationTarget
}
from
'
vs/workbench/services/configuration/common/configurationEditing
'
;
import
{
IPreferencesService
,
IPreferencesEditorModel
}
from
'
vs/workbench/parts/preferences/common/preferences
'
;
import
{
SettingsEditorModel
,
DefaultSettingsEditorModel
,
DefaultKeybindingsEditorModel
}
from
'
vs/workbench/parts/preferences/common/preferencesModels
'
;
import
{
ITelemetryService
}
from
'
vs/platform/telemetry/common/telemetry
'
;
...
...
@@ -44,9 +41,6 @@ interface IWorkbenchSettingsConfiguration {
export
class
PreferencesService
extends
Disposable
implements
IPreferencesService
{
static
DEFAULT_SETTINGS_URI
:
URI
=
URI
.
from
({
scheme
:
network
.
Schemas
.
vscode
,
authority
:
'
defaultsettings
'
,
path
:
'
/settings.json
'
});
static
DEFAULT_KEY_BINDINGS_URI
:
URI
=
URI
.
from
({
scheme
:
network
.
Schemas
.
vscode
,
authority
:
'
defaultsettings
'
,
path
:
'
/keybindings.json
'
});
_serviceBrand
:
any
;
// TODO:@sandy merge these models into editor inputs by extending resource editor model
...
...
@@ -74,13 +68,16 @@ export class PreferencesService extends Disposable implements IPreferencesServic
this
.
defaultPreferencesEditorModels
=
new
Map
<
URI
,
IPreferencesEditorModel
>
();
}
readonly
defaultSettingsResource
=
URI
.
from
({
scheme
:
network
.
Schemas
.
vscode
,
authority
:
'
defaultsettings
'
,
path
:
'
/settings.json
'
});
readonly
defaultKeybindingsResource
=
URI
.
from
({
scheme
:
network
.
Schemas
.
vscode
,
authority
:
'
defaultsettings
'
,
path
:
'
/keybindings.json
'
});
createDefaultPreferencesEditorModel
(
uri
:
URI
):
TPromise
<
IPreferencesEditorModel
>
{
const
editorModel
=
this
.
defaultPreferencesEditorModels
.
get
(
uri
);
if
(
editorModel
)
{
return
TPromise
.
as
(
editorModel
);
}
if
(
PreferencesService
.
DEFAULT_SETTINGS_URI
.
fsPath
===
uri
.
fsPath
)
{
if
(
this
.
defaultSettingsResource
.
fsPath
===
uri
.
fsPath
)
{
return
TPromise
.
join
<
any
>
([
this
.
extensionService
.
onReady
(),
this
.
fetchMostCommonlyUsedSettings
()])
.
then
(
result
=>
{
const
mostCommonSettings
=
result
[
1
];
...
...
@@ -90,7 +87,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic
});
}
if
(
PreferencesService
.
DEFAULT_KEY_BINDINGS_URI
.
fsPath
===
uri
.
fsPath
)
{
if
(
this
.
defaultKeybindingsResource
.
fsPath
===
uri
.
fsPath
)
{
const
model
=
this
.
instantiationService
.
createInstance
(
DefaultKeybindingsEditorModel
,
uri
);
this
.
defaultPreferencesEditorModels
.
set
(
uri
,
model
);
return
TPromise
.
wrap
(
model
);
...
...
@@ -135,7 +132,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic
openGlobalKeybindingSettings
():
TPromise
<
void
>
{
const
emptyContents
=
'
//
'
+
nls
.
localize
(
'
emptyKeybindingsHeader
'
,
"
Place your key bindings in this file to overwrite the defaults
"
)
+
'
\n
[
\n
]
'
;
return
this
.
openTwoEditors
(
PreferencesService
.
DEFAULT_KEY_BINDINGS_URI
,
URI
.
file
(
this
.
environmentService
.
appKeybindingsPath
),
emptyContents
).
then
(()
=>
null
);
return
this
.
openTwoEditors
(
this
.
defaultKeybindingsResource
,
URI
.
file
(
this
.
environmentService
.
appKeybindingsPath
),
emptyContents
).
then
(()
=>
null
);
}
private
openEditableSettings
(
configurationTarget
:
ConfigurationTarget
):
TPromise
<
IEditor
>
{
...
...
@@ -147,19 +144,6 @@ export class PreferencesService extends Disposable implements IPreferencesServic
}));
}
public
copyConfiguration
(
configurationValue
:
IConfigurationValue
):
void
{
const
configurationTarget
=
this
.
getConfigurationTargetForCurrentActiveEditor
();
if
(
configurationTarget
!==
null
)
{
this
.
telemetryService
.
publicLog
(
'
defaultSettingsActions.copySetting
'
,
{
userConfigurationKeys
:
[
configurationValue
.
key
]
});
const
editorControl
=
<
ICodeEditor
>
this
.
editorService
.
getActiveEditor
().
getControl
();
this
.
configurationEditingService
.
writeConfiguration
(
configurationTarget
,
configurationValue
,
{
writeToBuffer
:
true
,
autoSave
:
true
})
.
then
(()
=>
{
editorControl
.
focus
();
editorControl
.
setSelection
(
this
.
getSelectionRange
(
configurationValue
.
key
,
editorControl
.
getModel
()));
},
error
=>
this
.
messageService
.
show
(
Severity
.
Error
,
error
));
}
}
private
resolveSettingsEditorModel
(
configurationTarget
:
ConfigurationTarget
):
TPromise
<
SettingsEditorModel
>
{
const
settingsUri
=
this
.
getEditableSettingsURI
(
configurationTarget
);
if
(
settingsUri
)
{
...
...
@@ -225,12 +209,12 @@ export class PreferencesService extends Disposable implements IPreferencesServic
switch
(
configurationTarget
)
{
case
ConfigurationTarget
.
USER
:
if
(
!
this
.
defaultSettingsEditorInputForUser
)
{
this
.
defaultSettingsEditorInputForUser
=
this
.
_register
(
this
.
instantiationService
.
createInstance
(
DefaultPreferencesEditorInput
,
PreferencesService
.
DEFAULT_SETTINGS_URI
));
this
.
defaultSettingsEditorInputForUser
=
this
.
_register
(
this
.
instantiationService
.
createInstance
(
DefaultPreferencesEditorInput
,
this
.
defaultSettingsResource
));
}
return
this
.
defaultSettingsEditorInputForUser
;
case
ConfigurationTarget
.
WORKSPACE
:
if
(
!
this
.
defaultSettingsEditorInputForWorkspace
)
{
this
.
defaultSettingsEditorInputForWorkspace
=
this
.
_register
(
this
.
instantiationService
.
createInstance
(
DefaultPreferencesEditorInput
,
PreferencesService
.
DEFAULT_SETTINGS_URI
));
this
.
defaultSettingsEditorInputForWorkspace
=
this
.
_register
(
this
.
instantiationService
.
createInstance
(
DefaultPreferencesEditorInput
,
this
.
defaultSettingsResource
));
}
return
this
.
defaultSettingsEditorInputForWorkspace
;
}
...
...
@@ -271,40 +255,6 @@ export class PreferencesService extends Disposable implements IPreferencesServic
});
}
private
getConfigurationTargetForCurrentActiveEditor
():
ConfigurationTarget
{
const
activeEditor
=
this
.
editorService
.
getActiveEditor
();
if
(
activeEditor
)
{
const
file
=
toResource
(
activeEditor
.
input
,
{
supportSideBySide
:
true
,
filter
:
'
file
'
});
if
(
file
)
{
return
this
.
getConfigurationTarget
(
file
);
}
}
return
null
;
}
private
getConfigurationTarget
(
resource
:
URI
):
ConfigurationTarget
{
if
(
this
.
getEditableSettingsURI
(
ConfigurationTarget
.
USER
).
fsPath
===
resource
.
fsPath
)
{
return
ConfigurationTarget
.
USER
;
}
const
workspaceSettingsUri
=
this
.
getEditableSettingsURI
(
ConfigurationTarget
.
WORKSPACE
);
if
(
workspaceSettingsUri
&&
workspaceSettingsUri
.
fsPath
===
resource
.
fsPath
)
{
return
ConfigurationTarget
.
WORKSPACE
;
}
return
null
;
}
private
getSelectionRange
(
setting
:
string
,
model
:
editorCommon
.
IModel
):
editorCommon
.
IRange
{
const
tree
=
parseTree
(
model
.
getValue
());
const
node
=
findNodeAtLocation
(
tree
,
[
setting
]);
const
position
=
model
.
getPositionAt
(
node
.
offset
);
return
{
startLineNumber
:
position
.
lineNumber
,
startColumn
:
position
.
column
,
endLineNumber
:
position
.
lineNumber
,
endColumn
:
position
.
column
+
node
.
length
};
}
private
fetchMostCommonlyUsedSettings
():
TPromise
<
string
[]
>
{
return
TPromise
.
wrap
([
'
editor.fontSize
'
,
...
...
src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts
浏览文件 @
61ec8f62
...
...
@@ -344,4 +344,92 @@ export class SettingsCountWidget extends Widget implements IOverlayWidget {
preference
:
null
};
}
}
export
class
EditPreferenceWidget
<
T
>
extends
Widget
implements
IOverlayWidget
{
private
static
counter
:
number
=
1
;
private
_domNode
:
HTMLElement
;
private
_visible
:
boolean
;
private
_line
:
number
;
private
_id
:
string
;
private
_preferences
:
T
[];
private
_onClick
:
Emitter
<
void
>
=
new
Emitter
<
void
>
();
public
get
onClick
():
Event
<
void
>
{
return
this
.
_onClick
.
event
;
}
private
_onMouseOver
:
Emitter
<
void
>
=
new
Emitter
<
void
>
();
public
get
onMouseOver
():
Event
<
void
>
{
return
this
.
_onMouseOver
.
event
;
}
constructor
(
private
editor
:
ICodeEditor
,
@
IContextMenuService
contextMenuService
:
IContextMenuService
)
{
super
();
this
.
_id
=
'
preferences.editPreferenceWidget
'
+
EditPreferenceWidget
.
counter
++
;
this
.
editor
.
addOverlayWidget
(
this
);
this
.
_register
(
this
.
editor
.
onDidScrollChange
(()
=>
{
if
(
this
.
_visible
)
{
this
.
_layout
();
}
}));
}
public
dispose
():
void
{
this
.
editor
.
removeOverlayWidget
(
this
);
super
.
dispose
();
}
getId
():
string
{
return
this
.
_id
;
}
getDomNode
():
HTMLElement
{
if
(
!
this
.
_domNode
)
{
this
.
_domNode
=
document
.
createElement
(
'
div
'
);
this
.
_domNode
.
style
.
width
=
'
20px
'
;
this
.
_domNode
.
style
.
height
=
'
20px
'
;
this
.
_domNode
.
className
=
'
edit-preferences-widget hidden
'
;
this
.
onclick
(
this
.
_domNode
,
e
=>
this
.
_onClick
.
fire
());
this
.
onmouseover
(
this
.
_domNode
,
e
=>
this
.
_onMouseOver
.
fire
());
}
return
this
.
_domNode
;
}
getPosition
():
IOverlayWidgetPosition
{
return
null
;
}
getLine
():
number
{
return
this
.
_line
;
}
show
(
line
:
number
,
preferences
:
T
[]):
void
{
this
.
_preferences
=
preferences
;
if
(
!
this
.
_visible
||
this
.
_line
!==
line
)
{
this
.
_line
=
line
;
this
.
_visible
=
true
;
this
.
_layout
();
}
}
get
preferences
():
T
[]
{
return
this
.
_preferences
;
}
hide
():
void
{
if
(
this
.
_visible
)
{
this
.
_visible
=
false
;
this
.
_domNode
.
classList
.
add
(
'
hidden
'
);
}
}
private
_layout
():
void
{
const
topForLineNumber
=
this
.
editor
.
getTopForLineNumber
(
this
.
_line
);
const
editorScrollTop
=
this
.
editor
.
getScrollTop
();
this
.
_domNode
.
style
.
top
=
`
${
topForLineNumber
-
editorScrollTop
-
2
}
px`
;
this
.
_domNode
.
style
.
left
=
'
0px
'
;
this
.
_domNode
.
classList
.
remove
(
'
hidden
'
);
}
}
\ No newline at end of file
src/vs/workbench/parts/preferences/common/preferences.ts
浏览文件 @
61ec8f62
...
...
@@ -8,7 +8,6 @@ import { TPromise } from 'vs/base/common/winjs.base';
import
{
LinkedMap
as
Map
}
from
'
vs/base/common/map
'
;
import
{
IRange
}
from
'
vs/editor/common/editorCommon
'
;
import
{
createDecorator
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
IConfigurationValue
}
from
'
vs/workbench/services/configuration/common/configurationEditing
'
;
import
{
RawContextKey
}
from
'
vs/platform/contextkey/common/contextkey
'
;
export
interface
ISettingsGroup
{
...
...
@@ -20,8 +19,8 @@ export interface ISettingsGroup {
}
export
interface
ISettingsSection
{
description
Range
?:
IRange
;
description
?:
string
;
title
Range
?:
IRange
;
title
?:
string
;
settings
:
ISetting
[];
}
...
...
@@ -31,8 +30,8 @@ export interface ISetting {
keyRange
:
IRange
;
value
:
any
;
valueRange
:
IRange
;
description
:
string
;
descriptionRange
:
IRange
;
description
:
string
[]
;
descriptionRange
s
:
IRange
[]
;
}
export
interface
IFilterResult
{
...
...
@@ -49,6 +48,7 @@ export interface IPreferencesEditorModel {
export
interface
ISettingsEditorModel
extends
IPreferencesEditorModel
{
settingsGroups
:
ISettingsGroup
[];
groupsTerms
:
string
[];
getSetting
(
key
:
string
):
ISetting
;
filterSettings
(
filter
:
string
):
IFilterResult
;
}
...
...
@@ -60,14 +60,15 @@ export const IPreferencesService = createDecorator<IPreferencesService>('prefere
export
interface
IPreferencesService
{
_serviceBrand
:
any
;
defaultSettingsResource
:
URI
;
defaultKeybindingsResource
:
URI
;
createDefaultPreferencesEditorModel
(
uri
:
URI
):
TPromise
<
IPreferencesEditorModel
>
;
resolvePreferencesEditorModel
(
uri
:
URI
):
TPromise
<
IPreferencesEditorModel
>
;
openGlobalSettings
():
TPromise
<
void
>
;
openWorkspaceSettings
():
TPromise
<
void
>
;
openGlobalKeybindingSettings
():
TPromise
<
void
>
;
copyConfiguration
(
configurationValue
:
IConfigurationValue
):
void
;
}
export
const
CONTEXT_DEFAULT_SETTINGS_EDITOR
=
new
RawContextKey
<
boolean
>
(
'
defaultSettingsEditor
'
,
false
);
...
...
src/vs/workbench/parts/preferences/common/preferencesModels.ts
浏览文件 @
61ec8f62
...
...
@@ -12,16 +12,15 @@ import { Disposable } from 'vs/base/common/lifecycle';
import
{
Registry
}
from
'
vs/platform/platform
'
;
import
{
visit
,
JSONVisitor
}
from
'
vs/base/common/json
'
;
import
{
IModel
,
IRange
}
from
'
vs/editor/common/editorCommon
'
;
import
{
IJSONSchema
}
from
'
vs/base/common/jsonSchema
'
;
import
{
IConfigurationNode
,
IConfigurationRegistry
,
Extensions
}
from
'
vs/platform/configuration/common/configurationRegistry
'
;
import
{
ISettingsEditorModel
,
IKeybindingsEditorModel
,
ISettingsGroup
,
ISetting
,
IFilterResult
,
ISettingsSection
}
from
'
vs/workbench/parts/preferences/common/preferences
'
;
import
{
IKeybindingService
}
from
'
vs/platform/keybinding/common/keybinding
'
;
import
{
ConfigurationTarget
}
from
'
vs/workbench/services/configuration/common/configurationEditing
'
;
import
{
I
Filter
,
IMatch
,
or
,
matchesContiguousSubString
,
matchesPrefix
,
matchesFuzzy
,
matchesWords
}
from
'
vs/base/common/filters
'
;
import
{
I
Match
,
or
,
matchesContiguousSubString
,
matchesPrefix
,
matchesCamelCase
,
matchesWords
}
from
'
vs/base/common/filters
'
;
export
abstract
class
AbstractSettingsModel
extends
Disposable
{
static
_fuzzyFilter
:
IFilter
=
or
(
matchesPrefix
,
matchesContiguousSubString
,
matchesWords
,
matchesFuzzy
);
public
get
groupsTerms
():
string
[]
{
return
this
.
settingsGroups
.
map
(
group
=>
'
@
'
+
group
.
id
);
}
...
...
@@ -53,7 +52,7 @@ export abstract class AbstractSettingsModel extends Disposable {
for
(
const
section
of
group
.
sections
)
{
const
settings
:
ISetting
[]
=
[];
for
(
const
setting
of
section
.
settings
)
{
const
settingMatches
=
this
.
_findMatchesInSetting
(
filter
,
regex
,
setting
);
const
settingMatches
=
this
.
_findMatchesInSetting
(
filter
,
setting
);
if
(
groupMatched
||
settingMatches
.
length
>
0
)
{
settings
.
push
(
setting
);
}
...
...
@@ -61,9 +60,9 @@ export abstract class AbstractSettingsModel extends Disposable {
}
if
(
settings
.
length
)
{
sections
.
push
({
description
:
section
.
description
,
title
:
section
.
title
,
settings
,
descriptionRange
:
section
.
description
Range
titleRange
:
section
.
title
Range
});
}
}
...
...
@@ -88,7 +87,113 @@ export abstract class AbstractSettingsModel extends Disposable {
return
null
;
}
protected
abstract
_findMatchesInSetting
(
searchString
:
string
,
searchRegex
:
RegExp
,
setting
:
ISetting
):
IRange
[];
public
getSetting
(
key
:
string
):
ISetting
{
for
(
const
group
of
this
.
settingsGroups
)
{
for
(
const
section
of
group
.
sections
)
{
for
(
const
setting
of
section
.
settings
)
{
if
(
key
===
setting
.
key
)
{
return
setting
;
}
}
}
}
return
null
;
}
private
_findMatchesInSetting
(
searchString
:
string
,
setting
:
ISetting
):
IRange
[]
{
const
registry
:
{
[
qualifiedKey
:
string
]:
IJSONSchema
}
=
Registry
.
as
<
IConfigurationRegistry
>
(
Extensions
.
Configuration
).
getConfigurationProperties
();
const
schema
:
IJSONSchema
=
registry
[
setting
.
key
];
let
words
=
searchString
.
split
(
'
'
);
let
descriptionMatchingWords
:
Map
<
string
,
IRange
[]
>
=
new
Map
<
string
,
IRange
[]
>
();
let
keyMatchingWords
:
Map
<
string
,
IRange
[]
>
=
new
Map
<
string
,
IRange
[]
>
();
let
valueMatchingWords
:
Map
<
string
,
IRange
[]
>
=
new
Map
<
string
,
IRange
[]
>
();
const
settingKeyAsWords
:
string
=
setting
.
key
.
split
(
'
.
'
).
join
(
'
'
);
for
(
const
word
of
words
)
{
for
(
let
lineIndex
=
0
;
lineIndex
<
setting
.
description
.
length
;
lineIndex
++
)
{
const
descriptionMatches
=
matchesWords
(
word
,
setting
.
description
[
lineIndex
],
true
);
if
(
descriptionMatches
)
{
descriptionMatchingWords
.
set
(
word
,
descriptionMatches
.
map
(
match
=>
this
.
toDescriptionRange
(
setting
,
match
,
lineIndex
)));
}
}
const
keyMatches
=
or
(
matchesWords
,
matchesCamelCase
)(
word
,
settingKeyAsWords
);
if
(
keyMatches
)
{
keyMatchingWords
.
set
(
word
,
keyMatches
.
map
(
match
=>
this
.
toKeyRange
(
setting
,
match
)));
}
if
(
schema
.
type
===
'
string
'
||
schema
.
enum
)
{
const
valueMatches
=
matchesContiguousSubString
(
word
,
setting
.
value
);
if
(
valueMatches
)
{
valueMatchingWords
.
set
(
word
,
valueMatches
.
map
(
match
=>
this
.
toValueRange
(
setting
,
match
)));
}
else
if
(
schema
.
enum
&&
schema
.
enum
.
some
(
enumValue
=>
!!
matchesContiguousSubString
(
word
,
enumValue
)))
{
valueMatchingWords
.
set
(
word
,
[]);
}
}
}
const
descriptionRanges
:
IRange
[]
=
[];
for
(
let
lineIndex
=
0
;
lineIndex
<
setting
.
description
.
length
;
lineIndex
++
)
{
const
matches
=
or
(
matchesContiguousSubString
)(
searchString
,
setting
.
description
[
lineIndex
])
||
[];
descriptionRanges
.
push
(...
matches
.
map
(
match
=>
this
.
toDescriptionRange
(
setting
,
match
,
lineIndex
)));
}
if
(
descriptionRanges
.
length
===
0
)
{
descriptionRanges
.
push
(...
this
.
getRangesForWords
(
words
,
descriptionMatchingWords
,
[
keyMatchingWords
,
valueMatchingWords
]));
}
const
keyMatches
=
or
(
matchesPrefix
,
matchesContiguousSubString
)(
searchString
,
setting
.
key
);
const
keyRanges
:
IRange
[]
=
keyMatches
?
keyMatches
.
map
(
match
=>
this
.
toKeyRange
(
setting
,
match
))
:
this
.
getRangesForWords
(
words
,
keyMatchingWords
,
[
descriptionMatchingWords
,
valueMatchingWords
]);
let
valueRanges
:
IRange
[]
=
[];
if
(
typeof
setting
.
value
===
'
string
'
)
{
const
valueMatches
=
or
(
matchesPrefix
,
matchesContiguousSubString
)(
searchString
,
setting
.
value
);
valueRanges
=
valueMatches
?
valueMatches
.
map
(
match
=>
this
.
toValueRange
(
setting
,
match
))
:
this
.
getRangesForWords
(
words
,
valueMatchingWords
,
[
keyMatchingWords
,
descriptionMatchingWords
]);
}
return
[...
descriptionRanges
,
...
keyRanges
,
...
valueRanges
];
}
private
getRangesForWords
(
words
:
string
[],
from
:
Map
<
string
,
IRange
[]
>
,
others
:
Map
<
string
,
IRange
[]
>
[]):
IRange
[]
{
const
result
:
IRange
[]
=
[];
for
(
const
word
of
words
)
{
const
ranges
=
from
.
get
(
word
);
if
(
ranges
)
{
result
.
push
(...
ranges
);
}
else
if
(
others
.
every
(
o
=>
!
o
.
has
(
word
)))
{
return
[];
}
}
return
result
;
}
private
toKeyRange
(
setting
:
ISetting
,
match
:
IMatch
):
IRange
{
return
{
startLineNumber
:
setting
.
keyRange
.
startLineNumber
,
startColumn
:
setting
.
keyRange
.
startColumn
+
match
.
start
,
endLineNumber
:
setting
.
keyRange
.
startLineNumber
,
endColumn
:
setting
.
keyRange
.
startColumn
+
match
.
end
};
}
private
toDescriptionRange
(
setting
:
ISetting
,
match
:
IMatch
,
lineIndex
:
number
):
IRange
{
return
{
startLineNumber
:
setting
.
descriptionRanges
[
lineIndex
].
startLineNumber
+
lineIndex
,
startColumn
:
setting
.
descriptionRanges
[
lineIndex
].
startColumn
+
match
.
start
,
endLineNumber
:
setting
.
descriptionRanges
[
lineIndex
].
startLineNumber
+
lineIndex
,
endColumn
:
setting
.
descriptionRanges
[
lineIndex
].
startColumn
+
match
.
end
};
}
private
toValueRange
(
setting
:
ISetting
,
match
:
IMatch
):
IRange
{
return
{
startLineNumber
:
setting
.
valueRange
.
startLineNumber
,
startColumn
:
setting
.
valueRange
.
startColumn
+
match
.
start
+
1
,
endLineNumber
:
setting
.
valueRange
.
startLineNumber
,
endColumn
:
setting
.
valueRange
.
startColumn
+
match
.
end
+
1
};
}
public
abstract
settingsGroups
:
ISettingsGroup
[];
}
...
...
@@ -183,7 +288,7 @@ export class SettingsEditorModel extends AbstractSettingsModel implements ISetti
// setting started
let
settingStartPosition
=
model
.
getPositionAt
(
offset
);
settings
.
push
({
description
:
''
,
description
:
[]
,
key
:
name
,
keyRange
:
{
startLineNumber
:
settingStartPosition
.
lineNumber
,
...
...
@@ -199,7 +304,7 @@ export class SettingsEditorModel extends AbstractSettingsModel implements ISetti
},
value
:
null
,
valueRange
:
null
,
descriptionRange
:
null
,
descriptionRange
s
:
null
,
});
}
},
...
...
@@ -248,6 +353,10 @@ export class SettingsEditorModel extends AbstractSettingsModel implements ISetti
},
onLiteralValue
:
onValue
,
onError
:
(
error
)
=>
{
const
setting
=
settings
[
settings
.
length
-
1
];
if
(
!
setting
.
range
||
!
setting
.
keyRange
||
!
setting
.
valueRange
)
{
settings
.
pop
();
}
}
};
visit
(
model
.
getValue
(),
visitor
);
...
...
@@ -262,20 +371,6 @@ export class SettingsEditorModel extends AbstractSettingsModel implements ISetti
range
}]
:
[];
}
protected
_findMatchesInSetting
(
searchString
:
string
,
searchRegex
:
RegExp
,
setting
:
ISetting
):
IRange
[]
{
const
result
:
IRange
[]
=
[];
for
(
let
lineNumber
=
setting
.
range
.
startLineNumber
;
lineNumber
<=
setting
.
range
.
endLineNumber
;
lineNumber
++
)
{
result
.
push
(...
this
.
_findMatchesInLine
(
searchString
,
lineNumber
));
}
return
result
;
}
private
_findMatchesInLine
(
searchString
:
string
,
lineNumber
:
number
):
IRange
[]
{
return
this
.
model
.
findMatches
(
searchString
,
{
startLineNumber
:
lineNumber
,
startColumn
:
this
.
model
.
getLineMinColumn
(
lineNumber
),
endLineNumber
:
lineNumber
,
endColumn
:
this
.
model
.
getLineMaxColumn
(
lineNumber
),
},
false
,
false
,
false
);
}
}
export
class
DefaultSettingsEditorModel
extends
AbstractSettingsModel
implements
ISettingsEditorModel
{
...
...
@@ -383,7 +478,7 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements
result
.
push
(
settingsGroup
);
}
}
else
{
settingsGroup
.
sections
[
settingsGroup
.
sections
.
length
-
1
].
description
=
config
.
title
;
settingsGroup
.
sections
[
settingsGroup
.
sections
.
length
-
1
].
title
=
config
.
title
;
}
}
if
(
config
.
properties
)
{
...
...
@@ -394,8 +489,8 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements
const
configurationSettings
:
ISetting
[]
=
Object
.
keys
(
config
.
properties
).
map
((
key
)
=>
{
const
prop
=
config
.
properties
[
key
];
const
value
=
prop
.
default
;
const
description
=
prop
.
description
||
''
;
return
{
key
,
value
,
description
,
range
:
null
,
keyRange
:
null
,
valueRange
:
null
,
descriptionRange
:
null
};
const
description
=
(
prop
.
description
||
''
).
split
(
'
\n
'
)
;
return
{
key
,
value
,
description
,
range
:
null
,
keyRange
:
null
,
valueRange
:
null
,
descriptionRange
s
:
[]
};
});
settingsGroup
.
sections
[
settingsGroup
.
sections
.
length
-
1
].
settings
.
push
(...
configurationSettings
);
}
...
...
@@ -449,16 +544,20 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements
this
.
_contentByLines
.
push
(
''
);
let
groupStart
=
this
.
_contentByLines
.
length
+
1
;
for
(
const
section
of
group
.
sections
)
{
if
(
section
.
description
)
{
if
(
section
.
title
)
{
let
sectionTitleStart
=
this
.
_contentByLines
.
length
+
1
;
this
.
addDescription
(
section
.
description
,
this
.
indent
,
this
.
_contentByLines
);
section
.
description
Range
=
{
startLineNumber
:
sectionTitleStart
,
startColumn
:
1
,
endLineNumber
:
this
.
_contentByLines
.
length
,
endColumn
:
this
.
_contentByLines
[
this
.
_contentByLines
.
length
-
1
].
length
};
this
.
addDescription
(
[
section
.
title
]
,
this
.
indent
,
this
.
_contentByLines
);
section
.
title
Range
=
{
startLineNumber
:
sectionTitleStart
,
startColumn
:
1
,
endLineNumber
:
this
.
_contentByLines
.
length
,
endColumn
:
this
.
_contentByLines
[
this
.
_contentByLines
.
length
-
1
].
length
};
}
for
(
const
setting
of
section
.
settings
)
{
const
settingStart
=
this
.
_contentByLines
.
length
+
1
;
this
.
addDescription
(
setting
.
description
,
this
.
indent
,
this
.
_contentByLines
);
setting
.
descriptionRange
=
{
startLineNumber
:
settingStart
,
startColumn
:
1
,
endLineNumber
:
this
.
_contentByLines
.
length
,
endColumn
:
this
.
_contentByLines
[
this
.
_contentByLines
.
length
-
1
].
length
};
setting
.
descriptionRanges
=
[];
const
descriptionPreValue
=
this
.
indent
+
'
//
'
;
for
(
const
line
of
setting
.
description
)
{
this
.
_contentByLines
.
push
(
descriptionPreValue
+
line
);
setting
.
descriptionRanges
.
push
({
startLineNumber
:
this
.
_contentByLines
.
length
,
startColumn
:
this
.
_contentByLines
[
this
.
_contentByLines
.
length
-
1
].
indexOf
(
line
)
+
1
,
endLineNumber
:
this
.
_contentByLines
.
length
,
endColumn
:
this
.
_contentByLines
[
this
.
_contentByLines
.
length
-
1
].
length
});
}
let
preValueConent
=
this
.
indent
;
const
keyString
=
JSON
.
stringify
(
setting
.
key
);
...
...
@@ -489,41 +588,13 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements
return
lastSetting
;
}
private
addDescription
(
description
:
string
,
indent
:
string
,
result
:
string
[])
{
const
multiLines
=
description
.
split
(
'
\n
'
);
for
(
const
line
of
multiLines
)
{
private
addDescription
(
description
:
string
[],
indent
:
string
,
result
:
string
[])
{
for
(
const
line
of
description
)
{
result
.
push
(
indent
+
'
//
'
+
line
);
}
}
protected
_findMatchesInSetting
(
searchString
:
string
,
searchRegex
:
RegExp
,
setting
:
ISetting
):
IRange
[]
{
const
result
:
IRange
[]
=
[...
this
.
_findMatchesInDescription
(
searchString
,
setting
)];
for
(
let
lineNumber
=
setting
.
valueRange
.
startLineNumber
;
lineNumber
<=
setting
.
valueRange
.
endLineNumber
;
lineNumber
++
)
{
result
.
push
(...
this
.
_findMatchesInLine
(
searchRegex
,
lineNumber
));
}
return
result
;
}
private
_findMatchesInDescription
(
searchString
:
string
,
setting
:
ISetting
):
IRange
[]
{
const
result
:
IRange
[]
=
[];
for
(
let
lineNumber
=
setting
.
descriptionRange
.
startLineNumber
;
lineNumber
<=
setting
.
descriptionRange
.
endLineNumber
;
lineNumber
++
)
{
const
content
=
this
.
_contentByLines
[
lineNumber
-
1
];
const
matches
:
IMatch
[]
=
AbstractSettingsModel
.
_fuzzyFilter
(
searchString
,
content
);
if
(
matches
)
{
result
.
push
(...
matches
.
map
(
match
=>
{
return
<
IRange
>
{
startLineNumber
:
lineNumber
,
startColumn
:
match
.
start
+
1
,
endLineNumber
:
lineNumber
,
endColumn
:
match
.
end
+
1
};
}));
}
}
return
result
;
}
private
_findMatchesInLine
(
searchRegex
:
RegExp
,
lineNumber
:
number
):
IRange
[]
{
/*private _findMatchesInLine(searchRegex: RegExp, lineNumber: number): IRange[] {
const result: IRange[] = [];
const text = this._contentByLines[lineNumber - 1];
var m: RegExpExecArray;
...
...
@@ -541,7 +612,7 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements
}
} while (m);
return result;
}
}
*/
}
export
class
DefaultKeybindingsEditorModel
implements
IKeybindingsEditorModel
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录