Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
b1fbe705
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,发现更多精彩内容 >>
提交
b1fbe705
编写于
11月 04, 2016
作者:
A
Alex Dima
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Introduce cursorCommon
上级
0584e71c
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
293 addition
and
344 deletion
+293
-344
src/vs/editor/common/commands/shiftCommand.ts
src/vs/editor/common/commands/shiftCommand.ts
+6
-6
src/vs/editor/common/commonCodeEditor.ts
src/vs/editor/common/commonCodeEditor.ts
+2
-2
src/vs/editor/common/controller/cursor.ts
src/vs/editor/common/controller/cursor.ts
+3
-2
src/vs/editor/common/controller/cursorColumnSelection.ts
src/vs/editor/common/controller/cursorColumnSelection.ts
+6
-6
src/vs/editor/common/controller/cursorCommon.ts
src/vs/editor/common/controller/cursorCommon.ts
+182
-0
src/vs/editor/common/controller/cursorDeleteOperations.ts
src/vs/editor/common/controller/cursorDeleteOperations.ts
+10
-10
src/vs/editor/common/controller/cursorMoveHelper.ts
src/vs/editor/common/controller/cursorMoveHelper.ts
+4
-196
src/vs/editor/common/controller/cursorMoveOperations.ts
src/vs/editor/common/controller/cursorMoveOperations.ts
+21
-21
src/vs/editor/common/controller/cursorTypeOperations.ts
src/vs/editor/common/controller/cursorTypeOperations.ts
+8
-8
src/vs/editor/common/controller/cursorWordOperations.ts
src/vs/editor/common/controller/cursorWordOperations.ts
+9
-9
src/vs/editor/common/controller/oneCursor.ts
src/vs/editor/common/controller/oneCursor.ts
+10
-9
src/vs/editor/test/common/controller/cursorMoveHelper.test.ts
...vs/editor/test/common/controller/cursorMoveHelper.test.ts
+32
-75
未找到文件。
src/vs/editor/common/commands/shiftCommand.ts
浏览文件 @
b1fbe705
...
...
@@ -5,7 +5,7 @@
'
use strict
'
;
import
*
as
strings
from
'
vs/base/common/strings
'
;
import
{
Cursor
MoveHelper
}
from
'
vs/editor/common/controller/cursorMoveHelper
'
;
import
{
Cursor
Columns
}
from
'
vs/editor/common/controller/cursorCommon
'
;
import
{
Range
}
from
'
vs/editor/common/core/range
'
;
import
{
Selection
}
from
'
vs/editor/common/core/selection
'
;
import
{
ICommand
,
ICursorStateComputerData
,
IEditOperationBuilder
,
ITokenizedModel
}
from
'
vs/editor/common/editorCommon
'
;
...
...
@@ -22,9 +22,9 @@ export class ShiftCommand implements ICommand {
public
static
unshiftIndentCount
(
line
:
string
,
column
:
number
,
tabSize
:
number
):
number
{
// Determine the visible column where the content starts
let
contentStartVisibleColumn
=
Cursor
MoveHelper
.
visibleColumnFromColumn2
(
line
,
column
,
tabSize
);
let
contentStartVisibleColumn
=
Cursor
Columns
.
visibleColumnFromColumn
(
line
,
column
,
tabSize
);
let
desiredTabStop
=
Cursor
MoveHelper
.
prevTabColumn
(
contentStartVisibleColumn
,
tabSize
);
let
desiredTabStop
=
Cursor
Columns
.
prevTabStop
(
contentStartVisibleColumn
,
tabSize
);
// The `desiredTabStop` is a multiple of `tabSize` => determine the number of indents
return
desiredTabStop
/
tabSize
;
...
...
@@ -32,9 +32,9 @@ export class ShiftCommand implements ICommand {
public
static
shiftIndentCount
(
line
:
string
,
column
:
number
,
tabSize
:
number
):
number
{
// Determine the visible column where the content starts
let
contentStartVisibleColumn
=
Cursor
MoveHelper
.
visibleColumnFromColumn2
(
line
,
column
,
tabSize
);
let
contentStartVisibleColumn
=
Cursor
Columns
.
visibleColumnFromColumn
(
line
,
column
,
tabSize
);
let
desiredTabStop
=
Cursor
MoveHelper
.
nextTabColumn
(
contentStartVisibleColumn
,
tabSize
);
let
desiredTabStop
=
Cursor
Columns
.
nextTabStop
(
contentStartVisibleColumn
,
tabSize
);
// The `desiredTabStop` is a multiple of `tabSize` => determine the number of indents
return
desiredTabStop
/
tabSize
;
...
...
@@ -97,7 +97,7 @@ export class ShiftCommand implements ICommand {
}
if
(
lineNumber
>
1
)
{
let
contentStartVisibleColumn
=
Cursor
MoveHelper
.
visibleColumnFromColumn2
(
lineText
,
indentationEndIndex
+
1
,
tabSize
);
let
contentStartVisibleColumn
=
Cursor
Columns
.
visibleColumnFromColumn
(
lineText
,
indentationEndIndex
+
1
,
tabSize
);
if
(
contentStartVisibleColumn
%
tabSize
!==
0
)
{
// The current line is "miss-aligned", so let's see if this is expected...
// This can only happen when it has trailing commas in the indent
...
...
src/vs/editor/common/commonCodeEditor.ts
浏览文件 @
b1fbe705
...
...
@@ -15,7 +15,7 @@ import { ContextKeyExpr, IContextKey, IContextKeyServiceTarget, IContextKeyServi
import
{
CommonEditorConfiguration
}
from
'
vs/editor/common/config/commonEditorConfig
'
;
import
{
DefaultConfig
}
from
'
vs/editor/common/config/defaultConfig
'
;
import
{
Cursor
}
from
'
vs/editor/common/controller/cursor
'
;
import
{
Cursor
MoveHelper
}
from
'
vs/editor/common/controller/cursorMoveHelper
'
;
import
{
Cursor
Columns
}
from
'
vs/editor/common/controller/cursorCommon
'
;
import
{
IViewModelHelper
}
from
'
vs/editor/common/controller/oneCursor
'
;
import
{
EditorState
}
from
'
vs/editor/common/core/editorState
'
;
import
{
Position
}
from
'
vs/editor/common/core/position
'
;
...
...
@@ -229,7 +229,7 @@ export abstract class CommonCodeEditor extends EventEmitter implements editorCom
let
position
=
this
.
model
.
validatePosition
(
rawPosition
);
let
tabSize
=
this
.
model
.
getOptions
().
tabSize
;
return
Cursor
MoveHelper
.
visibleColumnFromColumn
(
this
.
model
,
position
.
lineNumber
,
position
.
column
,
tabSize
)
+
1
;
return
Cursor
Columns
.
visibleColumnFromColumn
(
this
.
model
.
getLineContent
(
position
.
lineNumber
)
,
position
.
column
,
tabSize
)
+
1
;
}
public
getPosition
():
Position
{
...
...
src/vs/editor/common/controller/cursor.ts
浏览文件 @
b1fbe705
...
...
@@ -16,7 +16,8 @@ import { Position } from 'vs/editor/common/core/position';
import
{
Range
}
from
'
vs/editor/common/core/range
'
;
import
{
Selection
,
SelectionDirection
}
from
'
vs/editor/common/core/selection
'
;
import
*
as
editorCommon
from
'
vs/editor/common/editorCommon
'
;
import
{
IColumnSelectResult
,
CursorMove
}
from
'
vs/editor/common/controller/cursorMoveHelper
'
;
import
{
IColumnSelectResult
}
from
'
vs/editor/common/controller/cursorMoveHelper
'
;
import
{
CursorColumns
}
from
'
vs/editor/common/controller/cursorCommon
'
;
import
{
LanguageConfigurationRegistry
}
from
'
vs/editor/common/modes/languageConfigurationRegistry
'
;
import
{
WordNavigationType
}
from
'
vs/editor/common/controller/cursorWordOperations
'
;
...
...
@@ -1127,7 +1128,7 @@ export class Cursor extends EventEmitter {
if
(
!
this
.
_columnSelectToVisualColumn
)
{
let
primaryCursor
=
this
.
cursors
.
getAll
()[
0
];
let
primaryPos
=
primaryCursor
.
viewState
.
position
;
return
Cursor
Move
.
visibleColumnFromColumn2
(
primaryCursor
.
config
,
primaryCursor
.
viewModel
,
primaryPos
);
return
Cursor
Columns
.
visibleColumnFromColumn2
(
primaryCursor
.
config
,
primaryCursor
.
viewModel
,
primaryPos
);
}
return
this
.
_columnSelectToVisualColumn
;
}
...
...
src/vs/editor/common/controller/cursorColumnSelection.ts
浏览文件 @
b1fbe705
...
...
@@ -6,7 +6,7 @@
import
{
Selection
}
from
'
vs/editor/common/core/selection
'
;
import
{
Position
}
from
'
vs/editor/common/core/position
'
;
import
{
Cursor
Move
,
CursorMoveConfiguration
,
ICursorMoveHelperModel
}
from
'
vs/editor/common/controller/cursorMoveHelper
'
;
import
{
Cursor
Columns
,
CursorConfiguration
,
ICursorSimpleModel
}
from
'
vs/editor/common/controller/cursorCommon
'
;
export
interface
IViewColumnSelectResult
{
viewSelections
:
Selection
[];
...
...
@@ -14,7 +14,7 @@ export interface IViewColumnSelectResult {
}
export
class
ColumnSelection
{
public
static
columnSelect
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
fromLineNumber
:
number
,
fromVisibleColumn
:
number
,
toLineNumber
:
number
,
toVisibleColumn
:
number
):
IViewColumnSelectResult
{
public
static
columnSelect
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
fromLineNumber
:
number
,
fromVisibleColumn
:
number
,
toLineNumber
:
number
,
toVisibleColumn
:
number
):
IViewColumnSelectResult
{
let
lineCount
=
Math
.
abs
(
toLineNumber
-
fromLineNumber
)
+
1
;
let
reversed
=
(
fromLineNumber
>
toLineNumber
);
let
isRTL
=
(
fromVisibleColumn
>
toVisibleColumn
);
...
...
@@ -27,10 +27,10 @@ export class ColumnSelection {
for
(
let
i
=
0
;
i
<
lineCount
;
i
++
)
{
let
lineNumber
=
fromLineNumber
+
(
reversed
?
-
i
:
i
);
let
startColumn
=
Cursor
Move
.
columnFromVisibleColumn2
(
config
,
model
,
lineNumber
,
fromVisibleColumn
);
let
endColumn
=
Cursor
Move
.
columnFromVisibleColumn2
(
config
,
model
,
lineNumber
,
toVisibleColumn
);
let
visibleStartColumn
=
Cursor
Move
.
visibleColumnFromColumn2
(
config
,
model
,
new
Position
(
lineNumber
,
startColumn
));
let
visibleEndColumn
=
Cursor
Move
.
visibleColumnFromColumn2
(
config
,
model
,
new
Position
(
lineNumber
,
endColumn
));
let
startColumn
=
Cursor
Columns
.
columnFromVisibleColumn2
(
config
,
model
,
lineNumber
,
fromVisibleColumn
);
let
endColumn
=
Cursor
Columns
.
columnFromVisibleColumn2
(
config
,
model
,
lineNumber
,
toVisibleColumn
);
let
visibleStartColumn
=
Cursor
Columns
.
visibleColumnFromColumn2
(
config
,
model
,
new
Position
(
lineNumber
,
startColumn
));
let
visibleEndColumn
=
Cursor
Columns
.
visibleColumnFromColumn2
(
config
,
model
,
new
Position
(
lineNumber
,
endColumn
));
// console.log(`lineNumber: ${lineNumber}: visibleStartColumn: ${visibleStartColumn}, visibleEndColumn: ${visibleEndColumn}`);
...
...
src/vs/editor/common/controller/cursorCommon.ts
0 → 100644
浏览文件 @
b1fbe705
/*---------------------------------------------------------------------------------------------
* 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
{
Position
}
from
'
vs/editor/common/core/position
'
;
import
{
CharCode
}
from
'
vs/base/common/charCode
'
;
import
*
as
strings
from
'
vs/base/common/strings
'
;
import
{
IModeConfiguration
}
from
'
vs/editor/common/controller/oneCursor
'
;
import
{
IConfigurationChangedEvent
,
TextModelResolvedOptions
,
IConfiguration
}
from
'
vs/editor/common/editorCommon
'
;
import
{
TextModel
}
from
'
vs/editor/common/model/textModel
'
;
export
interface
CharacterMap
{
[
char
:
string
]:
string
;
}
export
class
CursorConfiguration
{
_cursorMoveConfigurationBrand
:
void
;
public
readonly
tabSize
:
number
;
public
readonly
insertSpaces
:
boolean
;
public
readonly
oneIndent
:
string
;
public
readonly
pageSize
:
number
;
public
readonly
useTabStops
:
boolean
;
public
readonly
wordSeparators
:
string
;
public
readonly
autoClosingBrackets
:
boolean
;
public
readonly
autoClosingPairsOpen
:
CharacterMap
;
public
static
shouldRecreate
(
e
:
IConfigurationChangedEvent
):
boolean
{
return
(
e
.
layoutInfo
||
e
.
wordSeparators
||
e
.
autoClosingBrackets
||
e
.
useTabStops
);
}
constructor
(
oneIndent
:
string
,
modelOptions
:
TextModelResolvedOptions
,
configuration
:
IConfiguration
,
modeConfiguration
:
IModeConfiguration
)
{
let
c
=
configuration
.
editor
;
this
.
tabSize
=
modelOptions
.
tabSize
;
this
.
insertSpaces
=
modelOptions
.
insertSpaces
;
this
.
oneIndent
=
oneIndent
;
this
.
pageSize
=
Math
.
floor
(
c
.
layoutInfo
.
height
/
c
.
fontInfo
.
lineHeight
)
-
2
;
this
.
useTabStops
=
c
.
useTabStops
;
this
.
wordSeparators
=
c
.
wordSeparators
;
this
.
autoClosingBrackets
=
c
.
autoClosingBrackets
;
this
.
autoClosingPairsOpen
=
modeConfiguration
.
autoClosingPairsOpen
;
}
public
normalizeIndentation
(
str
:
string
):
string
{
return
TextModel
.
normalizeIndentation
(
str
,
this
.
tabSize
,
this
.
insertSpaces
);
}
}
export
interface
ICursorSimpleModel
{
getLineCount
():
number
;
getLineContent
(
lineNumber
:
number
):
string
;
getLineMinColumn
(
lineNumber
:
number
):
number
;
getLineMaxColumn
(
lineNumber
:
number
):
number
;
getLineFirstNonWhitespaceColumn
(
lineNumber
:
number
):
number
;
getLineLastNonWhitespaceColumn
(
lineNumber
:
number
):
number
;
}
/**
* Common operations that work and make sense both on the model and on the view model.
*/
export
class
CursorColumns
{
public
static
isLowSurrogate
(
model
:
ICursorSimpleModel
,
lineNumber
:
number
,
charOffset
:
number
):
boolean
{
let
lineContent
=
model
.
getLineContent
(
lineNumber
);
if
(
charOffset
<
0
||
charOffset
>=
lineContent
.
length
)
{
return
false
;
}
return
strings
.
isLowSurrogate
(
lineContent
.
charCodeAt
(
charOffset
));
}
public
static
isHighSurrogate
(
model
:
ICursorSimpleModel
,
lineNumber
:
number
,
charOffset
:
number
):
boolean
{
let
lineContent
=
model
.
getLineContent
(
lineNumber
);
if
(
charOffset
<
0
||
charOffset
>=
lineContent
.
length
)
{
return
false
;
}
return
strings
.
isHighSurrogate
(
lineContent
.
charCodeAt
(
charOffset
));
}
public
static
isInsideSurrogatePair
(
model
:
ICursorSimpleModel
,
lineNumber
:
number
,
column
:
number
):
boolean
{
return
this
.
isHighSurrogate
(
model
,
lineNumber
,
column
-
2
);
}
public
static
visibleColumnFromColumn
(
lineContent
:
string
,
column
:
number
,
tabSize
:
number
):
number
{
let
endOffset
=
lineContent
.
length
;
if
(
endOffset
>
column
-
1
)
{
endOffset
=
column
-
1
;
}
let
result
=
0
;
for
(
let
i
=
0
;
i
<
endOffset
;
i
++
)
{
let
charCode
=
lineContent
.
charCodeAt
(
i
);
if
(
charCode
===
CharCode
.
Tab
)
{
result
=
this
.
nextTabStop
(
result
,
tabSize
);
}
else
{
result
=
result
+
1
;
}
}
return
result
;
}
public
static
visibleColumnFromColumn2
(
config
:
CursorConfiguration
,
model
:
ICursorSimpleModel
,
position
:
Position
):
number
{
return
this
.
visibleColumnFromColumn
(
model
.
getLineContent
(
position
.
lineNumber
),
position
.
column
,
config
.
tabSize
);
}
public
static
columnFromVisibleColumn
(
lineContent
:
string
,
visibleColumn
:
number
,
tabSize
:
number
):
number
{
if
(
visibleColumn
<=
0
)
{
return
1
;
}
const
lineLength
=
lineContent
.
length
;
let
beforeVisibleColumn
=
0
;
for
(
let
i
=
0
;
i
<
lineLength
;
i
++
)
{
let
charCode
=
lineContent
.
charCodeAt
(
i
);
let
afterVisibleColumn
:
number
;
if
(
charCode
===
CharCode
.
Tab
)
{
afterVisibleColumn
=
this
.
nextTabStop
(
beforeVisibleColumn
,
tabSize
);
}
else
{
afterVisibleColumn
=
beforeVisibleColumn
+
1
;
}
if
(
afterVisibleColumn
>=
visibleColumn
)
{
let
prevDelta
=
visibleColumn
-
beforeVisibleColumn
;
let
afterDelta
=
afterVisibleColumn
-
visibleColumn
;
if
(
afterDelta
<
prevDelta
)
{
return
i
+
2
;
}
else
{
return
i
+
1
;
}
}
beforeVisibleColumn
=
afterVisibleColumn
;
}
// walked the entire string
return
lineLength
+
1
;
}
public
static
columnFromVisibleColumn2
(
config
:
CursorConfiguration
,
model
:
ICursorSimpleModel
,
lineNumber
:
number
,
visibleColumn
:
number
):
number
{
let
result
=
this
.
columnFromVisibleColumn
(
model
.
getLineContent
(
lineNumber
),
visibleColumn
,
config
.
tabSize
);
let
minColumn
=
model
.
getLineMinColumn
(
lineNumber
);
if
(
result
<
minColumn
)
{
return
minColumn
;
}
let
maxColumn
=
model
.
getLineMaxColumn
(
lineNumber
);
if
(
result
>
maxColumn
)
{
return
maxColumn
;
}
return
result
;
}
/**
* ATTENTION: This works with 0-based columns (as oposed to the regular 1-based columns)
*/
public
static
nextTabStop
(
visibleColumn
:
number
,
tabSize
:
number
):
number
{
return
visibleColumn
+
tabSize
-
visibleColumn
%
tabSize
;
}
/**
* ATTENTION: This works with 0-based columns (as oposed to the regular 1-based columns)
*/
public
static
prevTabStop
(
column
:
number
,
tabSize
:
number
):
number
{
return
column
-
1
-
(
column
-
1
)
%
tabSize
;
}
}
src/vs/editor/common/controller/cursorDeleteOperations.ts
浏览文件 @
b1fbe705
...
...
@@ -5,7 +5,7 @@
'
use strict
'
;
import
{
ReplaceCommand
}
from
'
vs/editor/common/commands/replaceCommand
'
;
import
{
Cursor
MoveHelper
,
CursorMove
,
CursorMoveConfiguration
,
ICursorMoveHelperModel
}
from
'
vs/editor/common/controller/cursorMoveHelper
'
;
import
{
Cursor
Columns
,
CursorConfiguration
,
ICursorSimpleModel
}
from
'
vs/editor/common/controller/cursorCommon
'
;
import
{
Range
}
from
'
vs/editor/common/core/range
'
;
import
{
ICommand
,
CursorChangeReason
}
from
'
vs/editor/common/editorCommon
'
;
import
{
MoveOperations
}
from
'
vs/editor/common/controller/cursorMoveOperations
'
;
...
...
@@ -61,7 +61,7 @@ export class EditOperationResult {
export
class
DeleteOperations
{
public
static
deleteRight
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
cursor
:
CursorModelState
):
EditOperationResult
{
public
static
deleteRight
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
cursor
:
CursorModelState
):
EditOperationResult
{
let
deleteSelection
:
Range
=
cursor
.
selection
;
...
...
@@ -92,7 +92,7 @@ export class DeleteOperations {
});
}
public
static
deleteAllRight
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
cursor
:
CursorModelState
):
EditOperationResult
{
public
static
deleteAllRight
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
cursor
:
CursorModelState
):
EditOperationResult
{
let
selection
=
cursor
.
selection
;
if
(
selection
.
isEmpty
())
{
...
...
@@ -115,7 +115,7 @@ export class DeleteOperations {
return
this
.
deleteRight
(
config
,
model
,
cursor
);
}
public
static
autoClosingPairDelete
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
cursor
:
CursorModelState
):
EditOperationResult
{
public
static
autoClosingPairDelete
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
cursor
:
CursorModelState
):
EditOperationResult
{
if
(
!
config
.
autoClosingBrackets
)
{
return
null
;
}
...
...
@@ -150,7 +150,7 @@ export class DeleteOperations {
return
new
EditOperationResult
(
new
ReplaceCommand
(
deleteSelection
,
''
));
}
public
static
deleteLeft
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
cursor
:
CursorModelState
):
EditOperationResult
{
public
static
deleteLeft
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
cursor
:
CursorModelState
):
EditOperationResult
{
let
r
=
this
.
autoClosingPairDelete
(
config
,
model
,
cursor
);
if
(
r
)
{
// This was a case for an auto-closing pair delete
...
...
@@ -173,9 +173,9 @@ export class DeleteOperations {
);
if
(
position
.
column
<=
lastIndentationColumn
)
{
let
fromVisibleColumn
=
Cursor
Move
.
visibleColumnFromColumn2
(
config
,
model
,
position
);
let
toVisibleColumn
=
Cursor
MoveHelper
.
prevTabColumn
(
fromVisibleColumn
,
config
.
tabSize
);
let
toColumn
=
Cursor
Move
.
columnFromVisibleColumn2
(
config
,
model
,
position
.
lineNumber
,
toVisibleColumn
);
let
fromVisibleColumn
=
Cursor
Columns
.
visibleColumnFromColumn2
(
config
,
model
,
position
);
let
toVisibleColumn
=
Cursor
Columns
.
prevTabStop
(
fromVisibleColumn
,
config
.
tabSize
);
let
toColumn
=
Cursor
Columns
.
columnFromVisibleColumn2
(
config
,
model
,
position
.
lineNumber
,
toVisibleColumn
);
deleteSelection
=
new
Range
(
position
.
lineNumber
,
toColumn
,
position
.
lineNumber
,
position
.
column
);
}
else
{
deleteSelection
=
new
Range
(
position
.
lineNumber
,
position
.
column
-
1
,
position
.
lineNumber
,
position
.
column
);
...
...
@@ -207,7 +207,7 @@ export class DeleteOperations {
});
}
public
static
deleteAllLeft
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
cursor
:
CursorModelState
):
EditOperationResult
{
public
static
deleteAllLeft
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
cursor
:
CursorModelState
):
EditOperationResult
{
let
r
=
this
.
autoClosingPairDelete
(
config
,
model
,
cursor
);
if
(
r
)
{
// This was a case for an auto-closing pair delete
...
...
@@ -235,7 +235,7 @@ export class DeleteOperations {
return
this
.
deleteLeft
(
config
,
model
,
cursor
);
}
public
static
cut
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
cursor
:
CursorModelState
,
enableEmptySelectionClipboard
:
boolean
):
EditOperationResult
{
public
static
cut
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
cursor
:
CursorModelState
,
enableEmptySelectionClipboard
:
boolean
):
EditOperationResult
{
let
selection
=
cursor
.
selection
;
if
(
selection
.
isEmpty
())
{
...
...
src/vs/editor/common/controller/cursorMoveHelper.ts
浏览文件 @
b1fbe705
...
...
@@ -5,178 +5,8 @@
'
use strict
'
;
import
{
Selection
}
from
'
vs/editor/common/core/selection
'
;
import
{
Position
}
from
'
vs/editor/common/core/position
'
;
import
{
CharCode
}
from
'
vs/base/common/charCode
'
;
import
{
IViewColumnSelectResult
}
from
'
vs/editor/common/controller/cursorColumnSelection
'
;
import
*
as
strings
from
'
vs/base/common/strings
'
;
import
{
IModeConfiguration
}
from
'
vs/editor/common/controller/oneCursor
'
;
import
{
IConfigurationChangedEvent
,
TextModelResolvedOptions
,
IConfiguration
}
from
'
vs/editor/common/editorCommon
'
;
import
{
TextModel
}
from
'
vs/editor/common/model/textModel
'
;
export
interface
CharacterMap
{
[
char
:
string
]:
string
;
}
export
class
CursorMoveConfiguration
{
_cursorMoveConfigurationBrand
:
void
;
public
readonly
tabSize
:
number
;
public
readonly
insertSpaces
:
boolean
;
public
readonly
oneIndent
:
string
;
public
readonly
pageSize
:
number
;
public
readonly
useTabStops
:
boolean
;
public
readonly
wordSeparators
:
string
;
public
readonly
autoClosingBrackets
:
boolean
;
public
readonly
autoClosingPairsOpen
:
CharacterMap
;
public
static
shouldRecreate
(
e
:
IConfigurationChangedEvent
):
boolean
{
return
(
e
.
layoutInfo
||
e
.
wordSeparators
||
e
.
autoClosingBrackets
||
e
.
useTabStops
);
}
constructor
(
oneIndent
:
string
,
modelOptions
:
TextModelResolvedOptions
,
configuration
:
IConfiguration
,
modeConfiguration
:
IModeConfiguration
)
{
let
c
=
configuration
.
editor
;
this
.
tabSize
=
modelOptions
.
tabSize
;
this
.
insertSpaces
=
modelOptions
.
insertSpaces
;
this
.
oneIndent
=
oneIndent
;
this
.
pageSize
=
Math
.
floor
(
c
.
layoutInfo
.
height
/
c
.
fontInfo
.
lineHeight
)
-
2
;
this
.
useTabStops
=
c
.
useTabStops
;
this
.
wordSeparators
=
c
.
wordSeparators
;
this
.
autoClosingBrackets
=
c
.
autoClosingBrackets
;
this
.
autoClosingPairsOpen
=
modeConfiguration
.
autoClosingPairsOpen
;
}
public
normalizeIndentation
(
str
:
string
):
string
{
return
TextModel
.
normalizeIndentation
(
str
,
this
.
tabSize
,
this
.
insertSpaces
);
}
}
export
interface
ICursorMoveHelperModel
{
getLineCount
():
number
;
getLineContent
(
lineNumber
:
number
):
string
;
getLineMinColumn
(
lineNumber
:
number
):
number
;
getLineMaxColumn
(
lineNumber
:
number
):
number
;
getLineFirstNonWhitespaceColumn
(
lineNumber
:
number
):
number
;
getLineLastNonWhitespaceColumn
(
lineNumber
:
number
):
number
;
}
/**
* Common operations that work and make sense both on the model and on the view model.
*/
export
class
CursorMove
{
public
static
isLowSurrogate
(
model
:
ICursorMoveHelperModel
,
lineNumber
:
number
,
charOffset
:
number
):
boolean
{
let
lineContent
=
model
.
getLineContent
(
lineNumber
);
if
(
charOffset
<
0
||
charOffset
>=
lineContent
.
length
)
{
return
false
;
}
return
strings
.
isLowSurrogate
(
lineContent
.
charCodeAt
(
charOffset
));
}
public
static
isHighSurrogate
(
model
:
ICursorMoveHelperModel
,
lineNumber
:
number
,
charOffset
:
number
):
boolean
{
let
lineContent
=
model
.
getLineContent
(
lineNumber
);
if
(
charOffset
<
0
||
charOffset
>=
lineContent
.
length
)
{
return
false
;
}
return
strings
.
isHighSurrogate
(
lineContent
.
charCodeAt
(
charOffset
));
}
public
static
isInsideSurrogatePair
(
model
:
ICursorMoveHelperModel
,
lineNumber
:
number
,
column
:
number
):
boolean
{
return
this
.
isHighSurrogate
(
model
,
lineNumber
,
column
-
2
);
}
public
static
visibleColumnFromColumn
(
lineContent
:
string
,
column
:
number
,
tabSize
:
number
):
number
{
let
endOffset
=
lineContent
.
length
;
if
(
endOffset
>
column
-
1
)
{
endOffset
=
column
-
1
;
}
let
result
=
0
;
for
(
let
i
=
0
;
i
<
endOffset
;
i
++
)
{
let
charCode
=
lineContent
.
charCodeAt
(
i
);
if
(
charCode
===
CharCode
.
Tab
)
{
result
=
this
.
nextTabStop
(
result
,
tabSize
);
}
else
{
result
=
result
+
1
;
}
}
return
result
;
}
public
static
visibleColumnFromColumn2
(
config
:
CursorMoveConfiguration
,
model
:
ICursorMoveHelperModel
,
position
:
Position
):
number
{
return
this
.
visibleColumnFromColumn
(
model
.
getLineContent
(
position
.
lineNumber
),
position
.
column
,
config
.
tabSize
);
}
public
static
columnFromVisibleColumn
(
lineContent
:
string
,
visibleColumn
:
number
,
tabSize
:
number
):
number
{
if
(
visibleColumn
<=
0
)
{
return
1
;
}
const
lineLength
=
lineContent
.
length
;
let
beforeVisibleColumn
=
0
;
for
(
let
i
=
0
;
i
<
lineLength
;
i
++
)
{
let
charCode
=
lineContent
.
charCodeAt
(
i
);
let
afterVisibleColumn
:
number
;
if
(
charCode
===
CharCode
.
Tab
)
{
afterVisibleColumn
=
this
.
nextTabStop
(
beforeVisibleColumn
,
tabSize
);
}
else
{
afterVisibleColumn
=
beforeVisibleColumn
+
1
;
}
if
(
afterVisibleColumn
>=
visibleColumn
)
{
let
prevDelta
=
visibleColumn
-
beforeVisibleColumn
;
let
afterDelta
=
afterVisibleColumn
-
visibleColumn
;
if
(
afterDelta
<
prevDelta
)
{
return
i
+
2
;
}
else
{
return
i
+
1
;
}
}
beforeVisibleColumn
=
afterVisibleColumn
;
}
// walked the entire string
return
lineLength
+
1
;
}
public
static
columnFromVisibleColumn2
(
config
:
CursorMoveConfiguration
,
model
:
ICursorMoveHelperModel
,
lineNumber
:
number
,
visibleColumn
:
number
):
number
{
let
result
=
this
.
columnFromVisibleColumn
(
model
.
getLineContent
(
lineNumber
),
visibleColumn
,
config
.
tabSize
);
let
minColumn
=
model
.
getLineMinColumn
(
lineNumber
);
if
(
result
<
minColumn
)
{
return
minColumn
;
}
let
maxColumn
=
model
.
getLineMaxColumn
(
lineNumber
);
if
(
result
>
maxColumn
)
{
return
maxColumn
;
}
return
result
;
}
/**
* ATTENTION: This works with 0-based columns (as oposed to the regular 1-based columns)
*/
public
static
nextTabStop
(
visibleColumn
:
number
,
tabSize
:
number
):
number
{
return
visibleColumn
+
tabSize
-
visibleColumn
%
tabSize
;
}
}
import
{
ICursorSimpleModel
}
from
'
vs/editor/common/controller/cursorCommon
'
;
export
interface
IColumnSelectResult
extends
IViewColumnSelectResult
{
selections
:
Selection
[];
...
...
@@ -184,10 +14,9 @@ export interface IColumnSelectResult extends IViewColumnSelectResult {
toVisualColumn
:
number
;
}
export
class
CursorMoveHelper
{
public
static
getColumnAtBeginningOfLine
(
model
:
ICursor
MoveHelper
Model
,
lineNumber
:
number
,
column
:
number
):
number
{
public
static
getColumnAtBeginningOfLine
(
model
:
ICursor
Simple
Model
,
lineNumber
:
number
,
column
:
number
):
number
{
var
firstNonBlankColumn
=
model
.
getLineFirstNonWhitespaceColumn
(
lineNumber
)
||
1
;
var
minColumn
=
model
.
getLineMinColumn
(
lineNumber
);
...
...
@@ -200,7 +29,7 @@ export class CursorMoveHelper {
return
column
;
}
public
static
getColumnAtEndOfLine
(
model
:
ICursor
MoveHelper
Model
,
lineNumber
:
number
,
column
:
number
):
number
{
public
static
getColumnAtEndOfLine
(
model
:
ICursor
Simple
Model
,
lineNumber
:
number
,
column
:
number
):
number
{
var
maxColumn
=
model
.
getLineMaxColumn
(
lineNumber
);
var
lastNonBlankColumn
=
model
.
getLineLastNonWhitespaceColumn
(
lineNumber
)
||
maxColumn
;
...
...
@@ -213,25 +42,4 @@ export class CursorMoveHelper {
return
column
;
}
public
static
visibleColumnFromColumn
(
model
:
ICursorMoveHelperModel
,
lineNumber
:
number
,
column
:
number
,
tabSize
:
number
):
number
{
return
CursorMoveHelper
.
visibleColumnFromColumn2
(
model
.
getLineContent
(
lineNumber
),
column
,
tabSize
);
}
public
static
visibleColumnFromColumn2
(
line
:
string
,
column
:
number
,
tabSize
:
number
):
number
{
return
CursorMove
.
visibleColumnFromColumn
(
line
,
column
,
tabSize
);
}
/**
* ATTENTION: This works with 0-based columns (as oposed to the regular 1-based columns)
*/
public
static
nextTabColumn
(
column
:
number
,
tabSize
:
number
):
number
{
return
CursorMove
.
nextTabStop
(
column
,
tabSize
);
}
/**
* ATTENTION: This works with 0-based columns (as oposed to the regular 1-based columns)
*/
public
static
prevTabColumn
(
column
:
number
,
tabSize
:
number
):
number
{
return
column
-
1
-
(
column
-
1
)
%
tabSize
;
}
}
\ No newline at end of file
}
src/vs/editor/common/controller/cursorMoveOperations.ts
浏览文件 @
b1fbe705
...
...
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
{
Cursor
Move
,
CursorMoveConfiguration
,
ICursorMoveHelperModel
}
from
'
vs/editor/common/controller/cursorMoveHelper
'
;
import
{
Cursor
Columns
,
CursorConfiguration
,
ICursorSimpleModel
}
from
'
vs/editor/common/controller/cursorCommon
'
;
import
{
CursorChangeReason
}
from
'
vs/editor/common/editorCommon
'
;
import
{
CursorModelState
}
from
'
vs/editor/common/controller/oneCursor
'
;
...
...
@@ -51,10 +51,10 @@ export class MoveOperationResult {
export
class
MoveOperations
{
public
static
left
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
lineNumber
:
number
,
column
:
number
):
CursorMoveResult
{
public
static
left
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
lineNumber
:
number
,
column
:
number
):
CursorMoveResult
{
if
(
column
>
model
.
getLineMinColumn
(
lineNumber
))
{
if
(
Cursor
Move
.
isLowSurrogate
(
model
,
lineNumber
,
column
-
2
))
{
if
(
Cursor
Columns
.
isLowSurrogate
(
model
,
lineNumber
,
column
-
2
))
{
// character before column is a low surrogate
column
=
column
-
2
;
}
else
{
...
...
@@ -68,7 +68,7 @@ export class MoveOperations {
return
new
CursorMoveResult
(
lineNumber
,
column
,
0
);
}
public
static
moveLeft
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
cursor
:
CursorModelState
,
inSelectionMode
:
boolean
,
noOfColumns
:
number
):
MoveOperationResult
{
public
static
moveLeft
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
cursor
:
CursorModelState
,
inSelectionMode
:
boolean
,
noOfColumns
:
number
):
MoveOperationResult
{
let
lineNumber
:
number
,
column
:
number
;
...
...
@@ -85,10 +85,10 @@ export class MoveOperations {
return
new
MoveOperationResult
(
inSelectionMode
,
lineNumber
,
column
,
0
,
true
,
CursorChangeReason
.
Explicit
);
}
public
static
right
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
lineNumber
:
number
,
column
:
number
):
CursorMoveResult
{
public
static
right
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
lineNumber
:
number
,
column
:
number
):
CursorMoveResult
{
if
(
column
<
model
.
getLineMaxColumn
(
lineNumber
))
{
if
(
Cursor
Move
.
isHighSurrogate
(
model
,
lineNumber
,
column
-
1
))
{
if
(
Cursor
Columns
.
isHighSurrogate
(
model
,
lineNumber
,
column
-
1
))
{
// character after column is a high surrogate
column
=
column
+
2
;
}
else
{
...
...
@@ -102,7 +102,7 @@ export class MoveOperations {
return
new
CursorMoveResult
(
lineNumber
,
column
,
0
);
}
public
static
moveRight
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
cursor
:
CursorModelState
,
inSelectionMode
:
boolean
,
noOfColumns
:
number
):
MoveOperationResult
{
public
static
moveRight
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
cursor
:
CursorModelState
,
inSelectionMode
:
boolean
,
noOfColumns
:
number
):
MoveOperationResult
{
let
lineNumber
:
number
,
column
:
number
;
...
...
@@ -119,8 +119,8 @@ export class MoveOperations {
return
new
MoveOperationResult
(
inSelectionMode
,
lineNumber
,
column
,
0
,
true
,
CursorChangeReason
.
Explicit
);
}
public
static
down
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
lineNumber
:
number
,
column
:
number
,
leftoverVisibleColumns
:
number
,
count
:
number
,
allowMoveOnLastLine
:
boolean
):
CursorMoveResult
{
const
currentVisibleColumn
=
Cursor
Move
.
visibleColumnFromColumn
(
model
.
getLineContent
(
lineNumber
),
column
,
config
.
tabSize
)
+
leftoverVisibleColumns
;
public
static
down
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
lineNumber
:
number
,
column
:
number
,
leftoverVisibleColumns
:
number
,
count
:
number
,
allowMoveOnLastLine
:
boolean
):
CursorMoveResult
{
const
currentVisibleColumn
=
Cursor
Columns
.
visibleColumnFromColumn
(
model
.
getLineContent
(
lineNumber
),
column
,
config
.
tabSize
)
+
leftoverVisibleColumns
;
lineNumber
=
lineNumber
+
count
;
var
lineCount
=
model
.
getLineCount
();
...
...
@@ -130,23 +130,23 @@ export class MoveOperations {
column
=
model
.
getLineMaxColumn
(
lineNumber
);
}
else
{
column
=
Math
.
min
(
model
.
getLineMaxColumn
(
lineNumber
),
column
);
if
(
Cursor
Move
.
isInsideSurrogatePair
(
model
,
lineNumber
,
column
))
{
if
(
Cursor
Columns
.
isInsideSurrogatePair
(
model
,
lineNumber
,
column
))
{
column
=
column
-
1
;
}
}
}
else
{
column
=
Cursor
Move
.
columnFromVisibleColumn2
(
config
,
model
,
lineNumber
,
currentVisibleColumn
);
if
(
Cursor
Move
.
isInsideSurrogatePair
(
model
,
lineNumber
,
column
))
{
column
=
Cursor
Columns
.
columnFromVisibleColumn2
(
config
,
model
,
lineNumber
,
currentVisibleColumn
);
if
(
Cursor
Columns
.
isInsideSurrogatePair
(
model
,
lineNumber
,
column
))
{
column
=
column
-
1
;
}
}
leftoverVisibleColumns
=
currentVisibleColumn
-
Cursor
Move
.
visibleColumnFromColumn
(
model
.
getLineContent
(
lineNumber
),
column
,
config
.
tabSize
);
leftoverVisibleColumns
=
currentVisibleColumn
-
Cursor
Columns
.
visibleColumnFromColumn
(
model
.
getLineContent
(
lineNumber
),
column
,
config
.
tabSize
);
return
new
CursorMoveResult
(
lineNumber
,
column
,
leftoverVisibleColumns
);
}
public
static
moveDown
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
cursor
:
CursorModelState
,
inSelectionMode
:
boolean
,
linesCount
:
number
):
MoveOperationResult
{
public
static
moveDown
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
cursor
:
CursorModelState
,
inSelectionMode
:
boolean
,
linesCount
:
number
):
MoveOperationResult
{
let
lineNumber
:
number
,
column
:
number
;
...
...
@@ -164,8 +164,8 @@ export class MoveOperations {
return
new
MoveOperationResult
(
inSelectionMode
,
r
.
lineNumber
,
r
.
column
,
r
.
leftoverVisibleColumns
,
true
,
CursorChangeReason
.
Explicit
);
}
public
static
up
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
lineNumber
:
number
,
column
:
number
,
leftoverVisibleColumns
:
number
,
count
:
number
,
allowMoveOnFirstLine
:
boolean
):
CursorMoveResult
{
const
currentVisibleColumn
=
Cursor
Move
.
visibleColumnFromColumn
(
model
.
getLineContent
(
lineNumber
),
column
,
config
.
tabSize
)
+
leftoverVisibleColumns
;
public
static
up
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
lineNumber
:
number
,
column
:
number
,
leftoverVisibleColumns
:
number
,
count
:
number
,
allowMoveOnFirstLine
:
boolean
):
CursorMoveResult
{
const
currentVisibleColumn
=
Cursor
Columns
.
visibleColumnFromColumn
(
model
.
getLineContent
(
lineNumber
),
column
,
config
.
tabSize
)
+
leftoverVisibleColumns
;
lineNumber
=
lineNumber
-
count
;
if
(
lineNumber
<
1
)
{
...
...
@@ -174,23 +174,23 @@ export class MoveOperations {
column
=
model
.
getLineMinColumn
(
lineNumber
);
}
else
{
column
=
Math
.
min
(
model
.
getLineMaxColumn
(
lineNumber
),
column
);
if
(
Cursor
Move
.
isInsideSurrogatePair
(
model
,
lineNumber
,
column
))
{
if
(
Cursor
Columns
.
isInsideSurrogatePair
(
model
,
lineNumber
,
column
))
{
column
=
column
-
1
;
}
}
}
else
{
column
=
Cursor
Move
.
columnFromVisibleColumn2
(
config
,
model
,
lineNumber
,
currentVisibleColumn
);
if
(
Cursor
Move
.
isInsideSurrogatePair
(
model
,
lineNumber
,
column
))
{
column
=
Cursor
Columns
.
columnFromVisibleColumn2
(
config
,
model
,
lineNumber
,
currentVisibleColumn
);
if
(
Cursor
Columns
.
isInsideSurrogatePair
(
model
,
lineNumber
,
column
))
{
column
=
column
-
1
;
}
}
leftoverVisibleColumns
=
currentVisibleColumn
-
Cursor
Move
.
visibleColumnFromColumn
(
model
.
getLineContent
(
lineNumber
),
column
,
config
.
tabSize
);
leftoverVisibleColumns
=
currentVisibleColumn
-
Cursor
Columns
.
visibleColumnFromColumn
(
model
.
getLineContent
(
lineNumber
),
column
,
config
.
tabSize
);
return
new
CursorMoveResult
(
lineNumber
,
column
,
leftoverVisibleColumns
);
}
public
static
moveUp
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
cursor
:
CursorModelState
,
inSelectionMode
:
boolean
,
linesCount
:
number
):
MoveOperationResult
{
public
static
moveUp
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
cursor
:
CursorModelState
,
inSelectionMode
:
boolean
,
linesCount
:
number
):
MoveOperationResult
{
let
lineNumber
:
number
,
column
:
number
;
...
...
src/vs/editor/common/controller/cursorTypeOperations.ts
浏览文件 @
b1fbe705
...
...
@@ -5,7 +5,7 @@
'
use strict
'
;
import
{
ReplaceCommand
}
from
'
vs/editor/common/commands/replaceCommand
'
;
import
{
Cursor
Move
,
CursorMoveConfiguration
,
ICursorMoveHelperModel
}
from
'
vs/editor/common/controller/cursorMoveHelper
'
;
import
{
Cursor
Columns
,
CursorConfiguration
,
ICursorSimpleModel
}
from
'
vs/editor/common/controller/cursorCommon
'
;
import
{
Range
}
from
'
vs/editor/common/core/range
'
;
import
{
CursorChangeReason
}
from
'
vs/editor/common/editorCommon
'
;
import
{
CursorModelState
}
from
'
vs/editor/common/controller/oneCursor
'
;
...
...
@@ -19,7 +19,7 @@ import { IndentAction } from 'vs/editor/common/modes/languageConfiguration';
export
class
TypeOperations
{
public
static
indent
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
cursor
:
CursorModelState
):
EditOperationResult
{
public
static
indent
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
cursor
:
CursorModelState
):
EditOperationResult
{
return
new
EditOperationResult
(
new
ShiftCommand
(
cursor
.
selection
,
{
isUnshift
:
false
,
...
...
@@ -33,7 +33,7 @@ export class TypeOperations {
);
}
public
static
outdent
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
cursor
:
CursorModelState
):
EditOperationResult
{
public
static
outdent
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
cursor
:
CursorModelState
):
EditOperationResult
{
return
new
EditOperationResult
(
new
ShiftCommand
(
cursor
.
selection
,
{
isUnshift
:
true
,
...
...
@@ -47,7 +47,7 @@ export class TypeOperations {
);
}
public
static
paste
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
cursor
:
CursorModelState
,
text
:
string
,
pasteOnNewLine
:
boolean
):
EditOperationResult
{
public
static
paste
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
cursor
:
CursorModelState
,
text
:
string
,
pasteOnNewLine
:
boolean
):
EditOperationResult
{
let
position
=
cursor
.
position
;
let
selection
=
cursor
.
selection
;
...
...
@@ -79,7 +79,7 @@ export class TypeOperations {
});
}
private
static
_goodIndentForLine
(
config
:
Cursor
Move
Configuration
,
model
:
ITokenizedModel
,
lineNumber
:
number
):
string
{
private
static
_goodIndentForLine
(
config
:
CursorConfiguration
,
model
:
ITokenizedModel
,
lineNumber
:
number
):
string
{
let
lastLineNumber
=
lineNumber
-
1
;
for
(
lastLineNumber
=
lineNumber
-
1
;
lastLineNumber
>=
1
;
lastLineNumber
--
)
{
...
...
@@ -117,12 +117,12 @@ export class TypeOperations {
return
result
;
}
private
static
_replaceJumpToNextIndent
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
selection
:
Selection
):
ReplaceCommand
{
private
static
_replaceJumpToNextIndent
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
selection
:
Selection
):
ReplaceCommand
{
let
typeText
=
''
;
let
position
=
selection
.
getStartPosition
();
if
(
config
.
insertSpaces
)
{
let
visibleColumnFromColumn
=
Cursor
Move
.
visibleColumnFromColumn2
(
config
,
model
,
position
);
let
visibleColumnFromColumn
=
Cursor
Columns
.
visibleColumnFromColumn2
(
config
,
model
,
position
);
let
tabSize
=
config
.
tabSize
;
let
spacesCnt
=
tabSize
-
(
visibleColumnFromColumn
%
tabSize
);
for
(
let
i
=
0
;
i
<
spacesCnt
;
i
++
)
{
...
...
@@ -135,7 +135,7 @@ export class TypeOperations {
return
new
ReplaceCommand
(
selection
,
typeText
);
}
public
static
tab
(
config
:
Cursor
Move
Configuration
,
model
:
ITokenizedModel
,
cursor
:
CursorModelState
):
EditOperationResult
{
public
static
tab
(
config
:
CursorConfiguration
,
model
:
ITokenizedModel
,
cursor
:
CursorModelState
):
EditOperationResult
{
let
selection
=
cursor
.
selection
;
if
(
selection
.
isEmpty
())
{
...
...
src/vs/editor/common/controller/cursorWordOperations.ts
浏览文件 @
b1fbe705
...
...
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
{
Cursor
MoveConfiguration
,
ICursorMoveHelperModel
}
from
'
vs/editor/common/controller/cursorMoveHelper
'
;
import
{
Cursor
Configuration
,
ICursorSimpleModel
}
from
'
vs/editor/common/controller/cursorCommon
'
;
import
{
Position
}
from
'
vs/editor/common/core/position
'
;
import
{
CharCode
}
from
'
vs/base/common/charCode
'
;
import
{
CharacterClassifier
}
from
'
vs/editor/common/core/characterClassifier
'
;
...
...
@@ -84,7 +84,7 @@ export class WordOperations {
return
{
start
:
start
,
end
:
end
,
wordType
:
wordType
};
}
public
static
findPreviousWordOnLine
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
position
:
Position
):
IFindWordResult
{
public
static
findPreviousWordOnLine
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
position
:
Position
):
IFindWordResult
{
let
wordSeparators
=
getMapForWordSeparators
(
config
.
wordSeparators
);
let
lineContent
=
model
.
getLineContent
(
position
.
lineNumber
);
return
this
.
_findPreviousWordOnLine
(
lineContent
,
wordSeparators
,
position
);
...
...
@@ -139,7 +139,7 @@ export class WordOperations {
return
len
;
}
public
static
findNextWordOnLine
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
position
:
Position
):
IFindWordResult
{
public
static
findNextWordOnLine
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
position
:
Position
):
IFindWordResult
{
let
wordSeparators
=
getMapForWordSeparators
(
config
.
wordSeparators
);
let
lineContent
=
model
.
getLineContent
(
position
.
lineNumber
);
return
this
.
_findNextWordOnLine
(
lineContent
,
wordSeparators
,
position
);
...
...
@@ -195,7 +195,7 @@ export class WordOperations {
return
0
;
}
public
static
moveWordLeft
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
cursor
:
CursorModelState
,
inSelectionMode
:
boolean
,
wordNavigationType
:
WordNavigationType
):
MoveOperationResult
{
public
static
moveWordLeft
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
cursor
:
CursorModelState
,
inSelectionMode
:
boolean
,
wordNavigationType
:
WordNavigationType
):
MoveOperationResult
{
let
position
=
cursor
.
position
;
let
lineNumber
=
position
.
lineNumber
;
let
column
=
position
.
column
;
...
...
@@ -229,7 +229,7 @@ export class WordOperations {
return
new
MoveOperationResult
(
inSelectionMode
,
lineNumber
,
column
,
0
,
true
,
CursorChangeReason
.
Explicit
);
}
public
static
moveWordRight
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
cursor
:
CursorModelState
,
inSelectionMode
:
boolean
,
wordNavigationType
:
WordNavigationType
):
MoveOperationResult
{
public
static
moveWordRight
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
cursor
:
CursorModelState
,
inSelectionMode
:
boolean
,
wordNavigationType
:
WordNavigationType
):
MoveOperationResult
{
let
position
=
cursor
.
position
;
let
lineNumber
=
position
.
lineNumber
;
let
column
=
position
.
column
;
...
...
@@ -263,7 +263,7 @@ export class WordOperations {
return
new
MoveOperationResult
(
inSelectionMode
,
lineNumber
,
column
,
0
,
true
,
CursorChangeReason
.
Explicit
);
}
private
static
_deleteWordLeftWhitespace
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
cursor
:
CursorModelState
):
EditOperationResult
{
private
static
_deleteWordLeftWhitespace
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
cursor
:
CursorModelState
):
EditOperationResult
{
let
position
=
cursor
.
position
;
let
lineContent
=
model
.
getLineContent
(
position
.
lineNumber
);
let
startIndex
=
position
.
column
-
2
;
...
...
@@ -275,7 +275,7 @@ export class WordOperations {
return
null
;
}
public
static
deleteWordLeft
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
cursor
:
CursorModelState
,
whitespaceHeuristics
:
boolean
,
wordNavigationType
:
WordNavigationType
):
EditOperationResult
{
public
static
deleteWordLeft
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
cursor
:
CursorModelState
,
whitespaceHeuristics
:
boolean
,
wordNavigationType
:
WordNavigationType
):
EditOperationResult
{
let
r
=
DeleteOperations
.
autoClosingPairDelete
(
config
,
model
,
cursor
);
if
(
r
)
{
// This was a case for an auto-closing pair delete
...
...
@@ -341,7 +341,7 @@ export class WordOperations {
return
len
;
}
private
static
_deleteWordRightWhitespace
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
cursor
:
CursorModelState
):
EditOperationResult
{
private
static
_deleteWordRightWhitespace
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
cursor
:
CursorModelState
):
EditOperationResult
{
let
position
=
cursor
.
position
;
let
lineContent
=
model
.
getLineContent
(
position
.
lineNumber
);
let
startIndex
=
position
.
column
-
1
;
...
...
@@ -354,7 +354,7 @@ export class WordOperations {
return
null
;
}
public
static
deleteWordRight
(
config
:
Cursor
MoveConfiguration
,
model
:
ICursorMoveHelper
Model
,
cursor
:
CursorModelState
,
whitespaceHeuristics
:
boolean
,
wordNavigationType
:
WordNavigationType
):
EditOperationResult
{
public
static
deleteWordRight
(
config
:
Cursor
Configuration
,
model
:
ICursorSimple
Model
,
cursor
:
CursorModelState
,
whitespaceHeuristics
:
boolean
,
wordNavigationType
:
WordNavigationType
):
EditOperationResult
{
let
selection
=
cursor
.
selection
;
...
...
src/vs/editor/common/controller/oneCursor.ts
浏览文件 @
b1fbe705
...
...
@@ -9,7 +9,8 @@ import * as strings from 'vs/base/common/strings';
import
{
ReplaceCommand
,
ReplaceCommandWithOffsetCursorState
,
ReplaceCommandWithoutChangingPosition
}
from
'
vs/editor/common/commands/replaceCommand
'
;
import
{
ShiftCommand
}
from
'
vs/editor/common/commands/shiftCommand
'
;
import
{
SurroundSelectionCommand
}
from
'
vs/editor/common/commands/surroundSelectionCommand
'
;
import
{
CursorMoveHelper
,
CursorMove
,
CursorMoveConfiguration
,
ICursorMoveHelperModel
,
IColumnSelectResult
}
from
'
vs/editor/common/controller/cursorMoveHelper
'
;
import
{
CursorMoveHelper
,
IColumnSelectResult
}
from
'
vs/editor/common/controller/cursorMoveHelper
'
;
import
{
CursorColumns
,
CursorConfiguration
,
ICursorSimpleModel
}
from
'
vs/editor/common/controller/cursorCommon
'
;
import
{
Position
}
from
'
vs/editor/common/core/position
'
;
import
{
Range
}
from
'
vs/editor/common/core/range
'
;
import
{
Selection
,
SelectionDirection
}
from
'
vs/editor/common/core/selection
'
;
...
...
@@ -67,7 +68,7 @@ export interface CursorMoveArguments extends editorCommon.CursorMoveArguments {
export
interface
IViewModelHelper
{
viewModel
:
ICursor
MoveHelper
Model
;
viewModel
:
ICursor
Simple
Model
;
getCurrentCompletelyVisibleViewLinesRangeInViewport
():
Range
;
getCurrentCompletelyVisibleModelLinesRangeInViewport
():
Range
;
...
...
@@ -212,7 +213,7 @@ export class CursorModelState {
export
interface
IOneCursor
{
readonly
modelState
:
CursorModelState
;
readonly
viewState
:
CursorModelState
;
readonly
config
:
Cursor
Move
Configuration
;
readonly
config
:
CursorConfiguration
;
}
export
class
OneCursor
implements
IOneCursor
{
...
...
@@ -220,7 +221,7 @@ export class OneCursor implements IOneCursor {
// --- contextual state
private
readonly
editorId
:
number
;
public
readonly
model
:
editorCommon
.
IModel
;
public
readonly
viewModel
:
ICursor
MoveHelper
Model
;
public
readonly
viewModel
:
ICursor
Simple
Model
;
private
readonly
configuration
:
editorCommon
.
IConfiguration
;
private
readonly
viewModelHelper
:
IViewModelHelper
;
...
...
@@ -228,7 +229,7 @@ export class OneCursor implements IOneCursor {
private
readonly
_configChangeListener
:
IDisposable
;
public
modeConfiguration
:
IModeConfiguration
;
public
config
:
Cursor
Move
Configuration
;
public
config
:
CursorConfiguration
;
public
modelState
:
CursorModelState
;
public
viewState
:
CursorModelState
;
...
...
@@ -259,7 +260,7 @@ export class OneCursor implements IOneCursor {
this
.
_modelOptionsListener
=
model
.
onDidChangeOptions
(()
=>
this
.
_recreateCursorConfig
());
this
.
_configChangeListener
=
this
.
configuration
.
onDidChange
((
e
)
=>
{
if
(
Cursor
Move
Configuration
.
shouldRecreate
(
e
))
{
if
(
CursorConfiguration
.
shouldRecreate
(
e
))
{
this
.
_recreateCursorConfig
();
}
});
...
...
@@ -281,7 +282,7 @@ export class OneCursor implements IOneCursor {
}
private
_recreateCursorConfig
():
void
{
this
.
config
=
new
Cursor
Move
Configuration
(
this
.
config
=
new
CursorConfiguration
(
this
.
model
.
getOneIndent
(),
this
.
model
.
getOptions
(),
this
.
configuration
,
...
...
@@ -787,7 +788,7 @@ export class OneCursorOp {
private
static
_columnSelectOp
(
cursor
:
OneCursor
,
toViewLineNumber
:
number
,
toViewVisualColumn
:
number
):
IColumnSelectResult
{
let
viewStartSelection
=
cursor
.
viewState
.
selection
;
let
fromVisibleColumn
=
Cursor
Move
.
visibleColumnFromColumn2
(
cursor
.
config
,
cursor
.
viewModel
,
new
Position
(
viewStartSelection
.
selectionStartLineNumber
,
viewStartSelection
.
selectionStartColumn
));
let
fromVisibleColumn
=
Cursor
Columns
.
visibleColumnFromColumn2
(
cursor
.
config
,
cursor
.
viewModel
,
new
Position
(
viewStartSelection
.
selectionStartLineNumber
,
viewStartSelection
.
selectionStartColumn
));
return
cursor
.
columnSelect
(
viewStartSelection
.
selectionStartLineNumber
,
fromVisibleColumn
,
toViewLineNumber
,
toViewVisualColumn
);
}
...
...
@@ -819,7 +820,7 @@ export class OneCursorOp {
let
maxViewLineNumber
=
Math
.
max
(
cursor
.
viewState
.
position
.
lineNumber
,
toViewLineNumber
);
for
(
let
lineNumber
=
minViewLineNumber
;
lineNumber
<=
maxViewLineNumber
;
lineNumber
++
)
{
let
lineMaxViewColumn
=
cursor
.
getViewLineMaxColumn
(
lineNumber
);
let
lineMaxVisualViewColumn
=
Cursor
Move
.
visibleColumnFromColumn2
(
cursor
.
config
,
cursor
.
viewModel
,
new
Position
(
lineNumber
,
lineMaxViewColumn
));
let
lineMaxVisualViewColumn
=
Cursor
Columns
.
visibleColumnFromColumn2
(
cursor
.
config
,
cursor
.
viewModel
,
new
Position
(
lineNumber
,
lineMaxViewColumn
));
maxVisualViewColumn
=
Math
.
max
(
maxVisualViewColumn
,
lineMaxVisualViewColumn
);
}
...
...
src/vs/editor/test/common/controller/cursorMoveHelper.test.ts
浏览文件 @
b1fbe705
...
...
@@ -5,89 +5,46 @@
'
use strict
'
;
import
*
as
assert
from
'
assert
'
;
import
*
as
strings
from
'
vs/base/common/strings
'
;
import
{
CursorMoveHelper
,
CursorMove
,
ICursorMoveHelperModel
,
CursorMoveConfiguration
}
from
'
vs/editor/common/controller/cursorMoveHelper
'
;
import
{
CursorColumns
}
from
'
vs/editor/common/controller/cursorCommon
'
;
suite
(
'
CursorMove
'
,
()
=>
{
test
(
'
nextTabStop
'
,
()
=>
{
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
0
,
4
),
4
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
1
,
4
),
4
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
2
,
4
),
4
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
3
,
4
),
4
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
4
,
4
),
8
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
5
,
4
),
8
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
6
,
4
),
8
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
7
,
4
),
8
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
8
,
4
),
12
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
0
,
2
),
2
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
1
,
2
),
2
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
2
,
2
),
4
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
3
,
2
),
4
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
4
,
2
),
6
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
5
,
2
),
6
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
6
,
2
),
8
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
7
,
2
),
8
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
8
,
2
),
10
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
0
,
1
),
1
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
1
,
1
),
2
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
2
,
1
),
3
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
3
,
1
),
4
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
4
,
1
),
5
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
5
,
1
),
6
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
6
,
1
),
7
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
7
,
1
),
8
);
assert
.
equal
(
Cursor
MoveHelper
.
nextTabColumn
(
8
,
1
),
9
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
0
,
4
),
4
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
1
,
4
),
4
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
2
,
4
),
4
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
3
,
4
),
4
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
4
,
4
),
8
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
5
,
4
),
8
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
6
,
4
),
8
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
7
,
4
),
8
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
8
,
4
),
12
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
0
,
2
),
2
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
1
,
2
),
2
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
2
,
2
),
4
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
3
,
2
),
4
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
4
,
2
),
6
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
5
,
2
),
6
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
6
,
2
),
8
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
7
,
2
),
8
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
8
,
2
),
10
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
0
,
1
),
1
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
1
,
1
),
2
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
2
,
1
),
3
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
3
,
1
),
4
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
4
,
1
),
5
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
5
,
1
),
6
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
6
,
1
),
7
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
7
,
1
),
8
);
assert
.
equal
(
Cursor
Columns
.
nextTabStop
(
8
,
1
),
9
);
});
class
OneLineModel
implements
ICursorMoveHelperModel
{
private
_line
:
string
;
constructor
(
line
:
string
)
{
this
.
_line
=
line
;
}
getLineCount
():
number
{
return
1
;
}
getLineContent
(
lineNumber
:
number
):
string
{
return
this
.
_line
;
}
getLineMinColumn
(
lineNumber
:
number
):
number
{
return
1
;
}
getLineMaxColumn
(
lineNumber
:
number
):
number
{
return
this
.
_line
.
length
+
1
;
}
getLineFirstNonWhitespaceColumn
(
lineNumber
:
number
):
number
{
let
result
=
strings
.
firstNonWhitespaceIndex
(
this
.
_line
);
if
(
result
===
-
1
)
{
return
0
;
}
return
result
+
1
;
}
getLineLastNonWhitespaceColumn
(
lineNumber
:
number
):
number
{
let
result
=
strings
.
lastNonWhitespaceIndex
(
this
.
_line
);
if
(
result
===
-
1
)
{
return
0
;
}
return
result
+
2
;
}
}
test
(
'
visibleColumnFromColumn
'
,
()
=>
{
function
testVisibleColumnFromColumn
(
text
:
string
,
tabSize
:
number
,
column
:
number
,
expected
:
number
):
void
{
let
model
=
new
OneLineModel
(
text
);
assert
.
equal
(
CursorMoveHelper
.
visibleColumnFromColumn
(
model
,
1
,
column
,
tabSize
),
expected
);
assert
.
equal
(
CursorColumns
.
visibleColumnFromColumn
(
text
,
column
,
tabSize
),
expected
);
}
testVisibleColumnFromColumn
(
'
\t\t
var x = 3;
'
,
4
,
1
,
0
);
...
...
@@ -146,7 +103,7 @@ suite('CursorMove', () => {
test
(
'
columnFromVisibleColumn
'
,
()
=>
{
function
testColumnFromVisibleColumn
(
text
:
string
,
tabSize
:
number
,
visibleColumn
:
number
,
expected
:
number
):
void
{
assert
.
equal
(
Cursor
Move
.
columnFromVisibleColumn
(
text
,
visibleColumn
,
tabSize
),
expected
);
assert
.
equal
(
Cursor
Columns
.
columnFromVisibleColumn
(
text
,
visibleColumn
,
tabSize
),
expected
);
}
// testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 0, 1);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录