Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
a3b83e9d
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,发现更多精彩内容 >>
提交
a3b83e9d
编写于
8月 17, 2016
作者:
J
Joao Moreno
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
debt: remove user settings!
上级
0c6503e1
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
198 addition
and
243 deletion
+198
-243
src/vs/base/node/userSettings.ts
src/vs/base/node/userSettings.ts
+0
-234
src/vs/code/electron-main/settings.ts
src/vs/code/electron-main/settings.ts
+198
-9
未找到文件。
src/vs/base/node/userSettings.ts
已删除
100644 → 0
浏览文件 @
0c6503e1
/*---------------------------------------------------------------------------------------------
* 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
fs
from
'
fs
'
;
import
*
as
path
from
'
path
'
;
import
*
as
json
from
'
vs/base/common/json
'
;
import
*
as
objects
from
'
vs/base/common/objects
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
Event
,
{
Emitter
}
from
'
vs/base/common/event
'
;
export
interface
ISettings
{
settings
:
any
;
settingsParseErrors
?:
string
[];
keybindings
:
any
;
}
export
class
UserSettings
{
private
static
CHANGE_BUFFER_DELAY
=
300
;
globalSettings
:
ISettings
;
private
timeoutHandle
:
number
;
private
watcher
:
fs
.
FSWatcher
;
private
appSettingsPath
:
string
;
private
appKeybindingsPath
:
string
;
private
_onChange
:
Emitter
<
ISettings
>
;
constructor
(
appSettingsPath
:
string
,
appKeybindingsPath
:
string
)
{
this
.
appSettingsPath
=
appSettingsPath
;
this
.
appKeybindingsPath
=
appKeybindingsPath
;
this
.
_onChange
=
new
Emitter
<
ISettings
>
();
this
.
registerWatchers
();
}
static
getValue
(
userDataPath
:
string
,
key
:
string
,
fallback
?:
any
):
TPromise
<
any
>
{
// TODO@joao cleanup!
const
appSettingsPath
=
path
.
join
(
userDataPath
,
'
User
'
,
'
settings.json
'
);
return
new
TPromise
((
c
,
e
)
=>
{
fs
.
readFile
(
appSettingsPath
,
(
error
/* ignore */
,
fileContents
)
=>
{
let
root
=
Object
.
create
(
null
);
let
content
=
fileContents
?
fileContents
.
toString
()
:
'
{}
'
;
let
contents
=
Object
.
create
(
null
);
try
{
contents
=
json
.
parse
(
content
);
}
catch
(
error
)
{
// ignore parse problem
}
for
(
let
key
in
contents
)
{
UserSettings
.
setNode
(
root
,
key
,
contents
[
key
]);
}
return
c
(
UserSettings
.
doGetValue
(
root
,
key
,
fallback
));
});
});
}
get
onChange
():
Event
<
ISettings
>
{
return
this
.
_onChange
.
event
;
}
getValue
(
key
:
string
,
fallback
?:
any
):
any
{
return
UserSettings
.
doGetValue
(
this
.
globalSettings
.
settings
,
key
,
fallback
);
}
private
static
doGetValue
(
globalSettings
:
any
,
key
:
string
,
fallback
?:
any
):
any
{
if
(
!
key
)
{
return
fallback
;
}
let
value
=
globalSettings
;
let
parts
=
key
.
split
(
'
\
.
'
);
while
(
parts
.
length
&&
value
)
{
let
part
=
parts
.
shift
();
value
=
value
[
part
];
}
return
typeof
value
!==
'
undefined
'
?
value
:
fallback
;
}
private
registerWatchers
():
void
{
let
self
=
this
;
function
attachSettingsChangeWatcher
(
watchPath
:
string
):
void
{
self
.
watcher
=
fs
.
watch
(
watchPath
);
self
.
watcher
.
on
(
'
change
'
,
()
=>
self
.
onSettingsFileChange
());
}
// Attach a watcher to the settings directory
attachSettingsChangeWatcher
(
path
.
dirname
(
this
.
appSettingsPath
));
// Follow symlinks for settings and keybindings and attach watchers if they resolve
let
followSymlinkPaths
=
[
this
.
appSettingsPath
,
this
.
appKeybindingsPath
];
followSymlinkPaths
.
forEach
((
path
)
=>
{
fs
.
lstat
(
path
,
(
err
,
stats
)
=>
{
if
(
err
)
{
return
;
}
if
(
stats
.
isSymbolicLink
()
&&
!
stats
.
isDirectory
())
{
fs
.
readlink
(
path
,
(
err
,
realPath
)
=>
{
if
(
err
)
{
return
;
}
attachSettingsChangeWatcher
(
realPath
);
});
}
});
});
}
private
onSettingsFileChange
():
void
{
// we can get multiple change events for one change, so we buffer through a timeout
if
(
this
.
timeoutHandle
)
{
global
.
clearTimeout
(
this
.
timeoutHandle
);
this
.
timeoutHandle
=
null
;
}
this
.
timeoutHandle
=
global
.
setTimeout
(()
=>
{
// Reload
let
didChange
=
this
.
loadSync
();
// Emit event
if
(
didChange
)
{
this
.
_onChange
.
fire
(
this
.
globalSettings
);
}
},
UserSettings
.
CHANGE_BUFFER_DELAY
);
}
loadSync
():
boolean
{
let
loadedSettings
=
this
.
doLoadSync
();
if
(
!
objects
.
equals
(
loadedSettings
,
this
.
globalSettings
))
{
// Keep in class
this
.
globalSettings
=
loadedSettings
;
return
true
;
// changed value
}
return
false
;
// no changed value
}
private
doLoadSync
():
ISettings
{
let
settings
=
this
.
doLoadSettingsSync
();
return
{
settings
:
settings
.
contents
,
settingsParseErrors
:
settings
.
parseErrors
,
keybindings
:
this
.
doLoadKeybindingsSync
()
};
}
private
doLoadSettingsSync
():
{
contents
:
any
;
parseErrors
?:
string
[];
}
{
let
root
=
Object
.
create
(
null
);
let
content
=
'
{}
'
;
try
{
content
=
fs
.
readFileSync
(
this
.
appSettingsPath
).
toString
();
}
catch
(
error
)
{
// ignore
}
let
contents
=
Object
.
create
(
null
);
try
{
contents
=
json
.
parse
(
content
);
}
catch
(
error
)
{
// parse problem
return
{
contents
:
Object
.
create
(
null
),
parseErrors
:
[
this
.
appSettingsPath
]
};
}
for
(
let
key
in
contents
)
{
UserSettings
.
setNode
(
root
,
key
,
contents
[
key
]);
}
return
{
contents
:
root
};
}
private
static
setNode
(
root
:
any
,
key
:
string
,
value
:
any
):
any
{
let
segments
=
key
.
split
(
'
.
'
);
let
last
=
segments
.
pop
();
let
curr
=
root
;
segments
.
forEach
((
s
)
=>
{
let
obj
=
curr
[
s
];
switch
(
typeof
obj
)
{
case
'
undefined
'
:
obj
=
curr
[
s
]
=
{};
break
;
case
'
object
'
:
break
;
default
:
console
.
log
(
'
Conflicting user settings:
'
+
key
+
'
at
'
+
s
+
'
with
'
+
JSON
.
stringify
(
obj
));
}
curr
=
obj
;
});
curr
[
last
]
=
value
;
}
private
doLoadKeybindingsSync
():
any
{
try
{
return
json
.
parse
(
fs
.
readFileSync
(
this
.
appKeybindingsPath
).
toString
());
}
catch
(
error
)
{
// Ignore loading and parsing errors
}
return
[];
}
dispose
():
void
{
if
(
this
.
watcher
)
{
this
.
watcher
.
close
();
this
.
watcher
=
null
;
}
}
}
\ No newline at end of file
src/vs/code/electron-main/settings.ts
浏览文件 @
a3b83e9d
...
...
@@ -6,14 +6,22 @@
'
use strict
'
;
import
{
app
}
from
'
electron
'
;
import
*
as
fs
from
'
fs
'
;
import
*
as
path
from
'
path
'
;
import
*
as
json
from
'
vs/base/common/json
'
;
import
*
as
objects
from
'
vs/base/common/objects
'
;
import
{
createDecorator
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
UserSettings
,
ISettings
}
from
'
vs/base/node/userSettings
'
;
import
{
IEnvService
}
from
'
vs/code/electron-main/env
'
;
import
Event
from
'
vs/base/common/event
'
;
import
Event
,
{
Emitter
}
from
'
vs/base/common/event
'
;
export
const
ISettingsService
=
createDecorator
<
ISettingsService
>
(
'
settingsService
'
);
// TODO@Joao TODO@Ben - this needs to die
export
interface
ISettings
{
settings
:
any
;
settingsParseErrors
?:
string
[];
keybindings
:
any
;
}
export
interface
ISettingsService
{
_serviceBrand
:
any
;
globalSettings
:
ISettings
;
...
...
@@ -22,20 +30,47 @@ export interface ISettingsService {
onChange
:
Event
<
ISettings
>
;
}
export
class
SettingsManager
extends
UserSettings
implements
ISettingsService
{
/**
* TODO@Joao TODO@Ben - this needs to die
*
* We need to decouple the settings with the keybindings.
* We need to have each participant (renderer, main, cli, shared) be able
* to listen on changes to each of these files, independently.
*/
export
class
SettingsManager
implements
ISettingsService
{
_serviceBrand
:
any
;
private
static
CHANGE_BUFFER_DELAY
=
300
;
globalSettings
:
ISettings
;
private
timeoutHandle
:
number
;
private
watcher
:
fs
.
FSWatcher
;
private
appSettingsPath
:
string
;
private
appKeybindingsPath
:
string
;
private
_onChange
:
Emitter
<
ISettings
>
;
constructor
(@
IEnvService
envService
:
IEnvService
)
{
super
(
envService
.
appSettingsPath
,
envService
.
appKeybindingsPath
);
this
.
appSettingsPath
=
envService
.
appSettingsPath
;
this
.
appKeybindingsPath
=
envService
.
appKeybindingsPath
;
this
.
_onChange
=
new
Emitter
<
ISettings
>
();
app
.
on
(
'
will-quit
'
,
()
=>
{
this
.
dispose
();
});
this
.
registerWatchers
();
app
.
on
(
'
will-quit
'
,
()
=>
this
.
dispose
());
}
loadSync
():
boolean
{
const
settingsChanged
=
super
.
loadSync
();
let
settingsChanged
=
false
;
let
loadedSettings
=
this
.
doLoadSync
();
if
(
!
objects
.
equals
(
loadedSettings
,
this
.
globalSettings
))
{
// Keep in class
this
.
globalSettings
=
loadedSettings
;
settingsChanged
=
true
;
// changed value
}
// Store into global so that any renderer can access the value with remote.getGlobal()
if
(
settingsChanged
)
{
...
...
@@ -44,4 +79,158 @@ export class SettingsManager extends UserSettings implements ISettingsService {
return
settingsChanged
;
}
get
onChange
():
Event
<
ISettings
>
{
return
this
.
_onChange
.
event
;
}
getValue
(
key
:
string
,
fallback
?:
any
):
any
{
return
SettingsManager
.
doGetValue
(
this
.
globalSettings
.
settings
,
key
,
fallback
);
}
private
static
doGetValue
(
globalSettings
:
any
,
key
:
string
,
fallback
?:
any
):
any
{
if
(
!
key
)
{
return
fallback
;
}
let
value
=
globalSettings
;
let
parts
=
key
.
split
(
'
\
.
'
);
while
(
parts
.
length
&&
value
)
{
let
part
=
parts
.
shift
();
value
=
value
[
part
];
}
return
typeof
value
!==
'
undefined
'
?
value
:
fallback
;
}
private
registerWatchers
():
void
{
let
self
=
this
;
function
attachSettingsChangeWatcher
(
watchPath
:
string
):
void
{
self
.
watcher
=
fs
.
watch
(
watchPath
);
self
.
watcher
.
on
(
'
change
'
,
()
=>
self
.
onSettingsFileChange
());
}
// Attach a watcher to the settings directory
attachSettingsChangeWatcher
(
path
.
dirname
(
this
.
appSettingsPath
));
// Follow symlinks for settings and keybindings and attach watchers if they resolve
let
followSymlinkPaths
=
[
this
.
appSettingsPath
,
this
.
appKeybindingsPath
];
followSymlinkPaths
.
forEach
((
path
)
=>
{
fs
.
lstat
(
path
,
(
err
,
stats
)
=>
{
if
(
err
)
{
return
;
}
if
(
stats
.
isSymbolicLink
()
&&
!
stats
.
isDirectory
())
{
fs
.
readlink
(
path
,
(
err
,
realPath
)
=>
{
if
(
err
)
{
return
;
}
attachSettingsChangeWatcher
(
realPath
);
});
}
});
});
}
private
onSettingsFileChange
():
void
{
// we can get multiple change events for one change, so we buffer through a timeout
if
(
this
.
timeoutHandle
)
{
global
.
clearTimeout
(
this
.
timeoutHandle
);
this
.
timeoutHandle
=
null
;
}
this
.
timeoutHandle
=
global
.
setTimeout
(()
=>
{
// Reload
let
didChange
=
this
.
loadSync
();
// Emit event
if
(
didChange
)
{
this
.
_onChange
.
fire
(
this
.
globalSettings
);
}
},
SettingsManager
.
CHANGE_BUFFER_DELAY
);
}
private
doLoadSync
():
ISettings
{
let
settings
=
this
.
doLoadSettingsSync
();
return
{
settings
:
settings
.
contents
,
settingsParseErrors
:
settings
.
parseErrors
,
keybindings
:
this
.
doLoadKeybindingsSync
()
};
}
private
doLoadSettingsSync
():
{
contents
:
any
;
parseErrors
?:
string
[];
}
{
let
root
=
Object
.
create
(
null
);
let
content
=
'
{}
'
;
try
{
content
=
fs
.
readFileSync
(
this
.
appSettingsPath
).
toString
();
}
catch
(
error
)
{
// ignore
}
let
contents
=
Object
.
create
(
null
);
try
{
contents
=
json
.
parse
(
content
);
}
catch
(
error
)
{
// parse problem
return
{
contents
:
Object
.
create
(
null
),
parseErrors
:
[
this
.
appSettingsPath
]
};
}
for
(
let
key
in
contents
)
{
SettingsManager
.
setNode
(
root
,
key
,
contents
[
key
]);
}
return
{
contents
:
root
};
}
private
static
setNode
(
root
:
any
,
key
:
string
,
value
:
any
):
any
{
let
segments
=
key
.
split
(
'
.
'
);
let
last
=
segments
.
pop
();
let
curr
=
root
;
segments
.
forEach
((
s
)
=>
{
let
obj
=
curr
[
s
];
switch
(
typeof
obj
)
{
case
'
undefined
'
:
obj
=
curr
[
s
]
=
{};
break
;
case
'
object
'
:
break
;
default
:
console
.
log
(
'
Conflicting user settings:
'
+
key
+
'
at
'
+
s
+
'
with
'
+
JSON
.
stringify
(
obj
));
}
curr
=
obj
;
});
curr
[
last
]
=
value
;
}
private
doLoadKeybindingsSync
():
any
{
try
{
return
json
.
parse
(
fs
.
readFileSync
(
this
.
appKeybindingsPath
).
toString
());
}
catch
(
error
)
{
// Ignore loading and parsing errors
}
return
[];
}
dispose
():
void
{
if
(
this
.
watcher
)
{
this
.
watcher
.
close
();
this
.
watcher
=
null
;
}
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录