Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
73ba6625
V
vscode
项目概览
掘金者说
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
73ba6625
编写于
10月 07, 2016
作者:
C
Christof Marti
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Incrementally decode find result (fixes #11842)
上级
4315160d
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
103 addition
and
89 deletion
+103
-89
src/vs/workbench/services/search/node/fileSearch.ts
src/vs/workbench/services/search/node/fileSearch.ts
+103
-89
未找到文件。
src/vs/workbench/services/search/node/fileSearch.ts
浏览文件 @
73ba6625
...
...
@@ -6,7 +6,7 @@
'
use strict
'
;
import
*
as
childProcess
from
'
child_process
'
;
import
{
StringDecoder
}
from
'
string_decoder
'
;
import
{
StringDecoder
,
NodeStringDecoder
}
from
'
string_decoder
'
;
import
{
toErrorMessage
}
from
'
vs/base/common/errorMessage
'
;
import
fs
=
require
(
'
fs
'
);
import
paths
=
require
(
'
path
'
);
...
...
@@ -129,15 +129,14 @@ export class FileWalker {
if
(
!
this
.
maxFilesize
)
{
if
(
platform
.
isMacintosh
)
{
this
.
traversal
=
Traversal
.
MacFind
;
traverse
=
this
.
macF
indTraversal
;
traverse
=
this
.
f
indTraversal
;
// Disable 'dir' for now (#11181, #11179, #11183, #11182).
// TS (2.0.2) warns about unreachable code. Using comments.
}
/* else if (false && platform.isWindows) {
}
/* else if (platform.isWindows) {
this.traversal = Traversal.WindowsDir;
traverse = this.windowsDirTraversal;
} */
else
if
(
platform
.
isLinux
)
{
this
.
traversal
=
Traversal
.
LinuxFind
;
traverse
=
this
.
linuxF
indTraversal
;
traverse
=
this
.
f
indTraversal
;
}
}
...
...
@@ -169,48 +168,38 @@ export class FileWalker {
});
}
private
macFindTraversal
(
rootFolder
:
string
,
onResult
:
(
result
:
IRawFileMatch
)
=>
void
,
done
:
(
err
?:
Error
)
=>
void
):
void
{
private
findTraversal
(
rootFolder
:
string
,
onResult
:
(
result
:
IRawFileMatch
)
=>
void
,
cb
:
(
err
?:
Error
)
=>
void
):
void
{
const
isMac
=
platform
.
isMacintosh
;
let
done
=
(
err
?:
Error
)
=>
{
done
=
()
=>
{};
cb
(
err
);
};
let
leftover
=
''
;
let
first
=
true
;
const
tree
=
this
.
initDirectoryTree
();
const
cmd
=
this
.
spawnFindCmd
(
rootFolder
,
this
.
excludePattern
);
this
.
readStdout
(
cmd
,
'
utf8
'
,
(
err
:
Error
,
stdout
?:
string
)
=>
{
this
.
collectStdout
(
cmd
,
'
utf8
'
,
(
err
:
Error
,
stdout
?:
string
,
last
?:
boolean
)
=>
{
if
(
err
)
{
done
(
err
);
return
;
}
// Mac: uses NFD unicode form on disk, but we want NFC
const
relativeFiles
=
strings
.
normalizeNFC
(
stdout
).
split
(
'
\n
./
'
);
relativeFiles
[
0
]
=
relativeFiles
[
0
].
trim
().
substr
(
2
);
const
n
=
relativeFiles
.
length
;
relativeFiles
[
n
-
1
]
=
relativeFiles
[
n
-
1
].
trim
();
if
(
!
relativeFiles
[
n
-
1
])
{
relativeFiles
.
pop
();
}
if
(
relativeFiles
.
length
&&
relativeFiles
[
0
].
indexOf
(
'
\n
'
)
!==
-
1
)
{
done
(
new
Error
(
'
Splitting up files failed
'
));
return
;
}
this
.
matchFiles
(
rootFolder
,
relativeFiles
,
onResult
);
done
();
});
}
protected
windowsDirTraversal
(
rootFolder
:
string
,
onResult
:
(
result
:
IRawFileMatch
)
=>
void
,
done
:
(
err
?:
Error
)
=>
void
):
void
{
const
cmd
=
childProcess
.
spawn
(
'
cmd
'
,
[
'
/U
'
,
'
/c
'
,
'
dir
'
,
'
/s
'
,
'
/b
'
,
'
/a-d
'
,
rootFolder
]);
this
.
readStdout
(
cmd
,
'
ucs2
'
,
(
err
:
Error
,
stdout
?:
string
)
=>
{
if
(
err
)
{
done
(
err
);
return
;
const
normalized
=
leftover
+
(
isMac
?
strings
.
normalizeNFC
(
stdout
)
:
stdout
);
const
relativeFiles
=
normalized
.
split
(
'
\n
./
'
);
if
(
first
&&
normalized
.
length
>=
2
)
{
first
=
false
;
relativeFiles
[
0
]
=
relativeFiles
[
0
].
trim
().
substr
(
2
);
}
const
relativeFiles
=
stdout
.
split
(
`\r\n
${
rootFolder
}
\
\`
);
relativeFiles[0] = relativeFiles[0].trim().substr(rootFolder.length + 1);
const n = relativeFiles.length;
relativeFiles[n - 1] = relativeFiles[n - 1].trim();
if (!relativeFiles[n - 1]) {
relativeFiles.pop();
if
(
last
)
{
const
n
=
relativeFiles
.
length
;
relativeFiles
[
n
-
1
]
=
relativeFiles
[
n
-
1
].
trim
();
if
(
!
relativeFiles
[
n
-
1
])
{
relativeFiles
.
pop
();
}
}
else
{
leftover
=
relativeFiles
.
pop
();
}
if
(
relativeFiles
.
length
&&
relativeFiles
[
0
].
indexOf
(
'
\n
'
)
!==
-
1
)
{
...
...
@@ -218,39 +207,42 @@ export class FileWalker {
return
;
}
this.matchFiles(rootFolder, relativeFiles, onResult);
done();
});
}
private linuxFindTraversal(rootFolder: string, onResult: (result: IRawFileMatch) => void, done: (err?: Error) => void): void {
const cmd = this.spawnFindCmd(rootFolder, this.excludePattern);
this.readStdout(cmd, 'utf8', (err: Error, stdout?: string) => {
if (err) {
done(err);
return;
}
const relativeFiles = stdout.split('\n./');
relativeFiles[0] = relativeFiles[0].trim().substr(2);
const n = relativeFiles.length;
relativeFiles[n - 1] = relativeFiles[n - 1].trim();
if (!relativeFiles[n - 1]) {
relativeFiles.pop();
}
this
.
addDirectoryEntries
(
tree
,
rootFolder
,
relativeFiles
,
onResult
);
if (
relativeFiles.length && relativeFiles[0].indexOf('\n') !== -1
) {
done(new Error('Splitting up files failed')
);
return
;
if
(
last
)
{
this
.
matchDirectoryTree
(
tree
,
rootFolder
,
onResult
);
done
()
;
}
this.matchFiles(rootFolder, relativeFiles, onResult);
done();
});
}
// protected windowsDirTraversal(rootFolder: string, onResult: (result: IRawFileMatch) => void, done: (err?: Error) => void): void {
// const cmd = childProcess.spawn('cmd', ['/U', '/c', 'dir', '/s', '/b', '/a-d', rootFolder]);
// this.readStdout(cmd, 'ucs2', (err: Error, stdout?: string) => {
// if (err) {
// done(err);
// return;
// }
// const relativeFiles = stdout.split(`\r\n${rootFolder}\\`);
// relativeFiles[0] = relativeFiles[0].trim().substr(rootFolder.length + 1);
// const n = relativeFiles.length;
// relativeFiles[n - 1] = relativeFiles[n - 1].trim();
// if (!relativeFiles[n - 1]) {
// relativeFiles.pop();
// }
// if (relativeFiles.length && relativeFiles[0].indexOf('\n') !== -1) {
// done(new Error('Splitting up files failed'));
// return;
// }
// this.matchFiles(rootFolder, relativeFiles, onResult);
// done();
// });
// }
/**
* Public for testing.
*/
...
...
@@ -279,13 +271,30 @@ export class FileWalker {
* Public for testing.
*/
public
readStdout
(
cmd
:
childProcess
.
ChildProcess
,
encoding
:
string
,
cb
:
(
err
:
Error
,
stdout
?:
string
)
=>
void
):
void
{
let done = (err: Error, stdout?: string) => {
done = () => {};
this.cmdForkResultTime = Date.now();
cb(err, stdout);
let
all
=
''
;
this
.
collectStdout
(
cmd
,
encoding
,
(
err
:
Error
,
stdout
?:
string
,
last
?:
boolean
)
=>
{
if
(
err
)
{
cb
(
err
);
return
;
}
all
+=
stdout
;
if
(
last
)
{
cb
(
null
,
all
);
}
});
}
private
collectStdout
(
cmd
:
childProcess
.
ChildProcess
,
encoding
:
string
,
cb
:
(
err
:
Error
,
stdout
?:
string
,
last
?:
boolean
)
=>
void
):
void
{
let
done
=
(
err
:
Error
,
stdout
?:
string
,
last
?:
boolean
)
=>
{
if
(
err
||
last
)
{
done
=
()
=>
{};
this
.
cmdForkResultTime
=
Date
.
now
();
}
cb
(
err
,
stdout
,
last
);
};
const stdout = this.collectData(cmd.stdout
);
this
.
forwardData
(
cmd
.
stdout
,
encoding
,
done
);
const
stderr
=
this
.
collectData
(
cmd
.
stderr
);
cmd
.
on
(
'
error
'
,
(
err
:
Error
)
=>
{
...
...
@@ -296,11 +305,19 @@ export class FileWalker {
if
(
code
!==
0
)
{
done
(
new
Error
(
`find failed with error code
${
code
}
:
${
this
.
decodeData
(
stderr
,
encoding
)}
`
));
}
else
{
done(null,
this.decodeData(stdout, encoding)
);
done
(
null
,
''
,
true
);
}
});
}
private
forwardData
(
stream
:
Readable
,
encoding
:
string
,
cb
:
(
err
:
Error
,
stdout
?:
string
)
=>
void
):
NodeStringDecoder
{
const
decoder
=
new
StringDecoder
(
encoding
);
stream
.
on
(
'
data
'
,
(
data
:
Buffer
)
=>
{
cb
(
null
,
decoder
.
write
(
data
));
});
return
decoder
;
}
private
collectData
(
stream
:
Readable
):
Buffer
[]
{
const
buffers
:
Buffer
[]
=
[];
stream
.
on
(
'
data
'
,
(
data
:
Buffer
)
=>
{
...
...
@@ -314,27 +331,25 @@ export class FileWalker {
return
buffers
.
map
(
buffer
=>
decoder
.
write
(
buffer
)).
join
(
''
);
}
private matchFiles(rootFolder: string, relativeFiles: string[], onResult: (result: IRawFileMatch) => void) {
this.cmdResultCount = relativeFiles.length;
private
initDirectoryTree
():
IDirectoryTree
{
const
tree
:
IDirectoryTree
=
{
rootEntries
:
[],
pathToEntries
:
Object
.
create
(
null
)
};
tree
.
pathToEntries
[
'
.
'
]
=
tree
.
rootEntries
;
return
tree
;
}
private
addDirectoryEntries
({
pathToEntries
}:
IDirectoryTree
,
base
:
string
,
relativeFiles
:
string
[],
onResult
:
(
result
:
IRawFileMatch
)
=>
void
)
{
this
.
cmdResultCount
+=
relativeFiles
.
length
;
// Support relative paths to files from a root resource (ignores excludes)
if
(
relativeFiles
.
indexOf
(
this
.
filePattern
)
!==
-
1
)
{
const
basename
=
paths
.
basename
(
this
.
filePattern
);
this.matchFile(onResult, { base:
rootFolder
, relativePath: this.filePattern, basename });
this
.
matchFile
(
onResult
,
{
base
:
base
,
relativePath
:
this
.
filePattern
,
basename
});
}
const tree = this.buildDirectoryTree(rootFolder, relativeFiles);
this.matchDirectoryTree(rootFolder, tree, onResult);
}
private buildDirectoryTree(base: string, relativeFilePaths: string[]): IDirectoryTree {
const tree: IDirectoryTree = {
rootEntries: [],
pathToEntries: Object.create(null)
};
const {pathToEntries} = tree;
pathToEntries['.'] = tree.rootEntries;
relativeFilePaths.forEach(function add(relativePath: string) {
relativeFiles
.
forEach
(
function
add
(
relativePath
:
string
)
{
const
basename
=
paths
.
basename
(
relativePath
);
const
dirname
=
paths
.
dirname
(
relativePath
);
let
entries
=
pathToEntries
[
dirname
];
...
...
@@ -348,10 +363,9 @@ export class FileWalker {
basename
});
});
return tree;
}
private matchDirectoryTree(
rootFolder: string, { rootEntries, pathToEntries }: IDirectoryTree
, onResult: (result: IRawFileMatch) => void) {
private
matchDirectoryTree
(
{
rootEntries
,
pathToEntries
}:
IDirectoryTree
,
rootFolder
:
string
,
onResult
:
(
result
:
IRawFileMatch
)
=>
void
)
{
const
self
=
this
;
const
excludePattern
=
this
.
excludePattern
;
const
filePattern
=
this
.
filePattern
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录