Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
d0daae36
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,发现更多精彩内容 >>
提交
d0daae36
编写于
3月 13, 2018
作者:
P
Peng Lyu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
re #45690. Find in chunks.
上级
2678fffd
变更
5
显示空白变更内容
内联
并排
Showing
5 changed file
with
179 addition
and
6 deletion
+179
-6
src/vs/editor/common/model.ts
src/vs/editor/common/model.ts
+2
-0
src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts
.../editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts
+141
-1
src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.ts
...r/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.ts
+6
-1
src/vs/editor/common/model/textModel.ts
src/vs/editor/common/model/textModel.ts
+17
-1
src/vs/editor/common/model/textModelSearch.ts
src/vs/editor/common/model/textModelSearch.ts
+13
-3
未找到文件。
src/vs/editor/common/model.ts
浏览文件 @
d0daae36
...
...
@@ -15,6 +15,7 @@ import { Selection } from 'vs/editor/common/core/selection';
import
{
ModelRawContentChangedEvent
,
IModelContentChangedEvent
,
IModelDecorationsChangedEvent
,
IModelLanguageChangedEvent
,
IModelOptionsChangedEvent
,
IModelLanguageConfigurationChangedEvent
,
IModelTokensChangedEvent
,
IModelContentChange
}
from
'
vs/editor/common/model/textModelEvents
'
;
import
{
ThemeColor
}
from
'
vs/platform/theme/common/themeService
'
;
import
{
ITextSnapshot
}
from
'
vs/platform/files/common/files
'
;
import
{
SearchData
}
from
'
vs/editor/common/model/textModelSearch
'
;
/**
* Vertical Lane in the overview ruler of the editor.
...
...
@@ -1100,6 +1101,7 @@ export interface ITextBuffer {
setEOL
(
newEOL
:
'
\r\n
'
|
'
\n
'
):
void
;
applyEdits
(
rawOperations
:
IIdentifiedSingleEditOperation
[],
recordTrimAutoWhitespace
:
boolean
):
ApplyEditsResult
;
findMatchesLineByLine
?(
searchRange
:
Range
,
searchData
:
SearchData
,
captureMatches
:
boolean
,
limitResultCount
:
number
):
FindMatch
[];
}
/**
...
...
src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts
浏览文件 @
d0daae36
...
...
@@ -9,6 +9,8 @@ import { CharCode } from 'vs/base/common/charCode';
import
{
Range
}
from
'
vs/editor/common/core/range
'
;
import
{
ITextSnapshot
}
from
'
vs/platform/files/common/files
'
;
import
{
leftest
,
righttest
,
updateTreeMetadata
,
rbDelete
,
fixInsert
,
NodeColor
,
SENTINEL
,
TreeNode
}
from
'
vs/editor/common/model/pieceTreeTextBuffer/rbTreeBase
'
;
import
{
SearchData
,
isValidMatch
,
Searcher
,
createFindMatch
}
from
'
vs/editor/common/model/textModelSearch
'
;
import
{
FindMatch
}
from
'
vs/editor/common/model
'
;
// const lfRegex = new RegExp(/\r\n|\r|\n/g);
...
...
@@ -535,6 +537,138 @@ export class PieceTreeBase {
return
this
.
getOffsetAt
(
lineNumber
+
1
,
1
)
-
this
.
getOffsetAt
(
lineNumber
,
1
)
-
this
.
_EOLLength
;
}
public
findMatchesInNode
(
node
:
TreeNode
,
searcher
:
Searcher
,
startLineNumber
:
number
,
startCursor
:
BufferCursor
,
endCursor
:
BufferCursor
,
searchData
:
SearchData
,
captureMatches
:
boolean
,
limitResultCount
:
number
,
resultLen
:
number
,
result
:
FindMatch
[])
{
let
buffer
=
this
.
_buffers
[
node
.
piece
.
bufferIndex
];
let
startOffsetInBuffer
=
this
.
offsetInBuffer
(
node
.
piece
.
bufferIndex
,
node
.
piece
.
start
);
let
start
=
this
.
offsetInBuffer
(
node
.
piece
.
bufferIndex
,
startCursor
);
let
end
=
this
.
offsetInBuffer
(
node
.
piece
.
bufferIndex
,
endCursor
);
let
m
:
RegExpExecArray
;
// Reset regex to search from the beginning
searcher
.
reset
(
start
);
let
ret
:
BufferCursor
=
{
line
:
0
,
column
:
0
};
do
{
m
=
searcher
.
next
(
buffer
.
buffer
);
if
(
m
)
{
if
(
m
.
index
>=
end
)
{
return
resultLen
;
}
this
.
positionInBuffer
(
node
,
m
.
index
-
startOffsetInBuffer
,
ret
);
let
lineFeedCnt
=
this
.
getLineFeedCnt
(
node
.
piece
.
bufferIndex
,
startCursor
,
ret
);
result
[
resultLen
++
]
=
createFindMatch
(
new
Range
(
startLineNumber
+
lineFeedCnt
,
ret
.
column
+
1
,
startLineNumber
+
lineFeedCnt
,
ret
.
column
+
1
+
m
[
0
].
length
),
m
,
captureMatches
);
if
(
m
.
index
+
m
[
0
].
length
>=
end
)
{
return
resultLen
;
}
if
(
resultLen
>=
limitResultCount
)
{
return
resultLen
;
}
}
}
while
(
m
);
return
resultLen
;
}
public
findMatchesLineByLine
(
searchRange
:
Range
,
searchData
:
SearchData
,
captureMatches
:
boolean
,
limitResultCount
:
number
):
FindMatch
[]
{
const
result
:
FindMatch
[]
=
[];
let
resultLen
=
0
;
const
searcher
=
new
Searcher
(
searchData
.
wordSeparators
,
searchData
.
regex
);
let
startPostion
=
this
.
nodeAt2
(
searchRange
.
startLineNumber
,
searchRange
.
startColumn
);
let
endPosition
=
this
.
nodeAt2
(
searchRange
.
endLineNumber
,
searchRange
.
endColumn
);
let
start
=
this
.
positionInBuffer
(
startPostion
.
node
,
startPostion
.
remainder
);
let
end
=
this
.
positionInBuffer
(
endPosition
.
node
,
endPosition
.
remainder
);
if
(
startPostion
.
node
===
endPosition
.
node
)
{
this
.
findMatchesInNode
(
startPostion
.
node
,
searcher
,
searchRange
.
startLineNumber
,
start
,
end
,
searchData
,
captureMatches
,
limitResultCount
,
resultLen
,
result
);
return
result
;
}
let
startLineNumber
=
searchRange
.
startLineNumber
;
let
currentNode
=
startPostion
.
node
;
while
(
currentNode
!==
endPosition
.
node
)
{
let
lineBreakCnt
=
this
.
getLineFeedCnt
(
currentNode
.
piece
.
bufferIndex
,
start
,
currentNode
.
piece
.
end
);
if
(
lineBreakCnt
>=
1
)
{
// last line break position
let
lineStarts
=
this
.
_buffers
[
currentNode
.
piece
.
bufferIndex
].
lineStarts
;
let
nextLineStartOffset
=
lineStarts
[
start
.
line
+
lineBreakCnt
];
resultLen
=
this
.
findMatchesInNode
(
currentNode
,
searcher
,
startLineNumber
,
start
,
this
.
positionInBuffer
(
currentNode
,
nextLineStartOffset
),
searchData
,
captureMatches
,
limitResultCount
,
resultLen
,
result
);
if
(
resultLen
>=
limitResultCount
)
{
return
result
;
}
startLineNumber
+=
lineBreakCnt
;
}
// search for the remaining content
if
(
startLineNumber
===
searchRange
.
endLineNumber
)
{
const
text
=
this
.
getLineContent
(
startLineNumber
).
substring
(
0
,
searchRange
.
endColumn
-
1
);
resultLen
=
this
.
_findMatchesInLine
(
searchData
,
searcher
,
text
,
searchRange
.
endLineNumber
,
0
,
resultLen
,
result
,
captureMatches
,
limitResultCount
);
return
result
;
}
resultLen
=
this
.
_findMatchesInLine
(
searchData
,
searcher
,
this
.
getLineContent
(
startLineNumber
),
startLineNumber
,
0
,
resultLen
,
result
,
captureMatches
,
limitResultCount
);
if
(
resultLen
>=
limitResultCount
)
{
return
result
;
}
startLineNumber
++
;
startPostion
=
this
.
nodeAt2
(
startLineNumber
,
1
);
currentNode
=
startPostion
.
node
;
start
=
this
.
positionInBuffer
(
startPostion
.
node
,
startPostion
.
remainder
);
}
if
(
startLineNumber
===
searchRange
.
endLineNumber
)
{
const
text
=
this
.
getLineContent
(
startLineNumber
).
substring
(
0
,
searchRange
.
endColumn
-
1
);
resultLen
=
this
.
_findMatchesInLine
(
searchData
,
searcher
,
text
,
searchRange
.
endLineNumber
,
0
,
resultLen
,
result
,
captureMatches
,
limitResultCount
);
return
result
;
}
resultLen
=
this
.
findMatchesInNode
(
endPosition
.
node
,
searcher
,
startLineNumber
,
start
,
end
,
searchData
,
captureMatches
,
limitResultCount
,
resultLen
,
result
);
return
result
;
}
private
_findMatchesInLine
(
searchData
:
SearchData
,
searcher
:
Searcher
,
text
:
string
,
lineNumber
:
number
,
deltaOffset
:
number
,
resultLen
:
number
,
result
:
FindMatch
[],
captureMatches
:
boolean
,
limitResultCount
:
number
):
number
{
const
wordSeparators
=
searchData
.
wordSeparators
;
if
(
!
captureMatches
&&
searchData
.
simpleSearch
)
{
const
searchString
=
searchData
.
simpleSearch
;
const
searchStringLen
=
searchString
.
length
;
const
textLength
=
text
.
length
;
let
lastMatchIndex
=
-
searchStringLen
;
while
((
lastMatchIndex
=
text
.
indexOf
(
searchString
,
lastMatchIndex
+
searchStringLen
))
!==
-
1
)
{
if
(
!
wordSeparators
||
isValidMatch
(
wordSeparators
,
text
,
textLength
,
lastMatchIndex
,
searchStringLen
))
{
result
[
resultLen
++
]
=
new
FindMatch
(
new
Range
(
lineNumber
,
lastMatchIndex
+
1
+
deltaOffset
,
lineNumber
,
lastMatchIndex
+
1
+
searchStringLen
+
deltaOffset
),
null
);
if
(
resultLen
>=
limitResultCount
)
{
return
resultLen
;
}
}
}
return
resultLen
;
}
let
m
:
RegExpExecArray
;
// Reset regex to search from the beginning
searcher
.
reset
(
0
);
do
{
m
=
searcher
.
next
(
text
);
if
(
m
)
{
result
[
resultLen
++
]
=
createFindMatch
(
new
Range
(
lineNumber
,
m
.
index
+
1
+
deltaOffset
,
lineNumber
,
m
.
index
+
1
+
m
[
0
].
length
+
deltaOffset
),
m
,
captureMatches
);
if
(
resultLen
>=
limitResultCount
)
{
return
resultLen
;
}
}
}
while
(
m
);
return
resultLen
;
}
// #endregion
// #region Piece Table
...
...
@@ -744,7 +878,7 @@ export class PieceTreeBase {
this
.
validateCRLFWithPrevNode
(
newNode
);
}
positionInBuffer
(
node
:
TreeNode
,
remainder
:
number
):
BufferCursor
{
positionInBuffer
(
node
:
TreeNode
,
remainder
:
number
,
ret
?:
BufferCursor
):
BufferCursor
{
let
piece
=
node
.
piece
;
let
bufferIndex
=
node
.
piece
.
bufferIndex
;
let
lineStarts
=
this
.
_buffers
[
bufferIndex
].
lineStarts
;
...
...
@@ -780,6 +914,12 @@ export class PieceTreeBase {
}
}
if
(
ret
)
{
ret
.
line
=
mid
;
ret
.
column
=
offset
-
midStart
;
return
null
;
}
return
{
line
:
mid
,
column
:
offset
-
midStart
...
...
src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.ts
浏览文件 @
d0daae36
...
...
@@ -9,8 +9,9 @@ import { Position } from 'vs/editor/common/core/position';
import
*
as
strings
from
'
vs/base/common/strings
'
;
import
{
IValidatedEditOperation
}
from
'
vs/editor/common/model/linesTextBuffer/linesTextBuffer
'
;
import
{
PieceTreeBase
,
StringBuffer
}
from
'
vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase
'
;
import
{
IIdentifiedSingleEditOperation
,
EndOfLinePreference
,
ITextBuffer
,
ApplyEditsResult
,
IInternalModelContentChange
}
from
'
vs/editor/common/model
'
;
import
{
IIdentifiedSingleEditOperation
,
EndOfLinePreference
,
ITextBuffer
,
ApplyEditsResult
,
IInternalModelContentChange
,
FindMatch
}
from
'
vs/editor/common/model
'
;
import
{
ITextSnapshot
}
from
'
vs/platform/files/common/files
'
;
import
{
SearchData
}
from
'
vs/editor/common/model/textModelSearch
'
;
export
class
PieceTreeTextBuffer
implements
ITextBuffer
{
private
_pieceTree
:
PieceTreeBase
;
...
...
@@ -410,6 +411,10 @@ export class PieceTreeTextBuffer implements ITextBuffer {
return
contentChanges
;
}
findMatchesLineByLine
(
searchRange
:
Range
,
searchData
:
SearchData
,
captureMatches
:
boolean
,
limitResultCount
:
number
):
FindMatch
[]
{
return
this
.
_pieceTree
.
findMatchesLineByLine
(
searchRange
,
searchData
,
captureMatches
,
limitResultCount
);
}
// #endregion
// #region helper
...
...
src/vs/editor/common/model/textModel.ts
浏览文件 @
d0daae36
...
...
@@ -30,7 +30,7 @@ import { getWordAtText } from 'vs/editor/common/model/wordHelper';
import
{
ModelLinesTokens
,
ModelTokensChangedEventBuilder
}
from
'
vs/editor/common/model/textModelTokens
'
;
import
{
guessIndentation
}
from
'
vs/editor/common/model/indentationGuesser
'
;
import
{
EDITOR_MODEL_DEFAULTS
}
from
'
vs/editor/common/config/editorOptions
'
;
import
{
TextModelSearch
,
SearchParams
}
from
'
vs/editor/common/model/textModelSearch
'
;
import
{
TextModelSearch
,
SearchParams
,
SearchData
}
from
'
vs/editor/common/model/textModelSearch
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
IStringStream
,
ITextSnapshot
}
from
'
vs/platform/files/common/files
'
;
import
{
LinesTextBufferBuilder
}
from
'
vs/editor/common/model/linesTextBuffer/linesTextBufferBuilder
'
;
...
...
@@ -983,6 +983,10 @@ export class TextModel extends Disposable implements model.ITextModel {
return
new
Range
(
1
,
1
,
lineCount
,
this
.
getLineMaxColumn
(
lineCount
));
}
private
findMatchesLineByLine
(
searchRange
:
Range
,
searchData
:
SearchData
,
captureMatches
:
boolean
,
limitResultCount
:
number
):
model
.
FindMatch
[]
{
return
this
.
_buffer
.
findMatchesLineByLine
(
searchRange
,
searchData
,
captureMatches
,
limitResultCount
);
}
public
findMatches
(
searchString
:
string
,
rawSearchScope
:
any
,
isRegex
:
boolean
,
matchCase
:
boolean
,
wordSeparators
:
string
,
captureMatches
:
boolean
,
limitResultCount
:
number
=
LIMIT_FIND_COUNT
):
model
.
FindMatch
[]
{
this
.
_assertNotDisposed
();
...
...
@@ -993,6 +997,18 @@ export class TextModel extends Disposable implements model.ITextModel {
searchRange
=
this
.
getFullModelRange
();
}
if
(
!
isRegex
&&
searchString
.
indexOf
(
'
\n
'
)
<
0
&&
OPTIONS
.
TEXT_BUFFER_IMPLEMENTATION
===
TextBufferType
.
PieceTree
)
{
// not regex, not multi line
const
searchParams
=
new
SearchParams
(
searchString
,
isRegex
,
matchCase
,
wordSeparators
);
const
searchData
=
searchParams
.
parseSearchRequest
();
if
(
!
searchData
)
{
return
[];
}
return
this
.
findMatchesLineByLine
(
searchRange
,
searchData
,
captureMatches
,
limitResultCount
);
}
return
TextModelSearch
.
findMatches
(
this
,
new
SearchParams
(
searchString
,
isRegex
,
matchCase
,
wordSeparators
),
searchRange
,
captureMatches
,
limitResultCount
);
}
...
...
src/vs/editor/common/model/textModelSearch.ts
浏览文件 @
d0daae36
...
...
@@ -116,7 +116,7 @@ export class SearchData {
}
}
function
createFindMatch
(
range
:
Range
,
rawMatches
:
RegExpExecArray
,
captureMatches
:
boolean
):
FindMatch
{
export
function
createFindMatch
(
range
:
Range
,
rawMatches
:
RegExpExecArray
,
captureMatches
:
boolean
):
FindMatch
{
if
(
!
captureMatches
)
{
return
new
FindMatch
(
range
,
null
);
}
...
...
@@ -434,6 +434,11 @@ function leftIsWordBounday(wordSeparators: WordCharacterClassifier, text: string
return
true
;
}
if
(
charBefore
===
CharCode
.
CarriageReturn
||
charBefore
===
CharCode
.
LineFeed
)
{
// The character before the match is line break or carriage return.
return
true
;
}
if
(
matchLength
>
0
)
{
const
firstCharInMatch
=
text
.
charCodeAt
(
matchStartIndex
);
if
(
wordSeparators
.
get
(
firstCharInMatch
)
!==
WordCharacterClass
.
Regular
)
{
...
...
@@ -457,6 +462,11 @@ function rightIsWordBounday(wordSeparators: WordCharacterClassifier, text: strin
return
true
;
}
if
(
charAfter
===
CharCode
.
CarriageReturn
||
charAfter
===
CharCode
.
LineFeed
)
{
// The character after the match is line break or carriage return.
return
true
;
}
if
(
matchLength
>
0
)
{
const
lastCharInMatch
=
text
.
charCodeAt
(
matchStartIndex
+
matchLength
-
1
);
if
(
wordSeparators
.
get
(
lastCharInMatch
)
!==
WordCharacterClass
.
Regular
)
{
...
...
@@ -468,14 +478,14 @@ function rightIsWordBounday(wordSeparators: WordCharacterClassifier, text: strin
return
false
;
}
function
isValidMatch
(
wordSeparators
:
WordCharacterClassifier
,
text
:
string
,
textLength
:
number
,
matchStartIndex
:
number
,
matchLength
:
number
):
boolean
{
export
function
isValidMatch
(
wordSeparators
:
WordCharacterClassifier
,
text
:
string
,
textLength
:
number
,
matchStartIndex
:
number
,
matchLength
:
number
):
boolean
{
return
(
leftIsWordBounday
(
wordSeparators
,
text
,
textLength
,
matchStartIndex
,
matchLength
)
&&
rightIsWordBounday
(
wordSeparators
,
text
,
textLength
,
matchStartIndex
,
matchLength
)
);
}
class
Searcher
{
export
class
Searcher
{
private
_wordSeparators
:
WordCharacterClassifier
;
private
_searchRegex
:
RegExp
;
private
_prevMatchStartIndex
:
number
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录