Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
84c290a8
R
roslyn
项目概览
lwm1986
/
roslyn
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
84c290a8
编写于
3月 27, 2020
作者:
C
Cyrus Najmabadi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Move comment-enter off of the indentation system. it will own all its own logic.
上级
abcc1922
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
146 addition
and
135 deletion
+146
-135
src/EditorFeatures/CSharp/BlockCommentEditing/BlockCommentEditingCommandHandler.cs
.../BlockCommentEditing/BlockCommentEditingCommandHandler.cs
+131
-121
src/EditorFeatures/CSharp/BlockCommentEditing/CloseBlockCommentCommandHandler.cs
...rp/BlockCommentEditing/CloseBlockCommentCommandHandler.cs
+1
-1
src/EditorFeatures/CSharpTest/BlockCommentEditing/BlockCommentEditingTests.cs
...SharpTest/BlockCommentEditing/BlockCommentEditingTests.cs
+9
-9
src/Workspaces/CSharp/Portable/Indentation/CSharpIndentationService.Indenter.cs
...Portable/Indentation/CSharpIndentationService.Indenter.cs
+5
-4
未找到文件。
src/EditorFeatures/CSharp/BlockCommentEditing/BlockCommentEditingCommandHandler.cs
浏览文件 @
84c290a8
...
...
@@ -9,6 +9,7 @@
using
Microsoft.CodeAnalysis.CSharp
;
using
Microsoft.CodeAnalysis.Editor.Shared.Extensions
;
using
Microsoft.CodeAnalysis.Editor.Shared.Options
;
using
Microsoft.CodeAnalysis.Formatting
;
using
Microsoft.CodeAnalysis.Shared.Extensions
;
using
Microsoft.CodeAnalysis.Text
;
using
Microsoft.CodeAnalysis.Text.Shared.Extensions
;
...
...
@@ -55,186 +56,199 @@ public bool ExecuteCommand(ReturnKeyCommandArgs args, CommandExecutionContext co
private
bool
TryHandleReturnKey
(
ITextBuffer
subjectBuffer
,
ITextView
textView
)
{
if
(!
subjectBuffer
.
GetFeatureOnOffOption
(
FeatureOnOffOptions
.
AutoInsertBlockCommentStartString
))
{
return
false
;
}
var
caretPosition
=
textView
.
GetCaretPoint
(
subjectBuffer
);
if
(
caretPosition
==
null
)
{
return
false
;
}
var
exteriorText
=
GetExteriorTextFor
Nex
tLine
(
caretPosition
.
Value
);
var
exteriorText
=
GetExteriorTextFor
Curren
tLine
(
caretPosition
.
Value
);
if
(
exteriorText
==
null
)
{
return
false
;
}
using
var
transaction
=
_undoHistoryRegistry
.
GetHistory
(
textView
.
TextBuffer
).
CreateTransaction
(
EditorFeaturesResources
.
Insert_new_line
);
var
editorOperations
=
_editorOperationsFactoryService
.
GetEditorOperations
(
textView
);
editorOperations
.
InsertNewLine
();
editorOperations
.
InsertText
(
exteriorText
);
editorOperations
.
ReplaceText
(
GetReplacementSpan
(
caretPosition
.
Value
),
exteriorText
);
transaction
.
Complete
();
return
true
;
}
private
string
GetExteriorTextForNextLine
(
SnapshotPoint
caretPosition
)
private
Span
GetReplacementSpan
(
SnapshotPoint
caretPosition
)
{
var
currentLine
=
caretPosition
.
GetContainingLine
();
// We want to replace all the whitespace following the caret. This is standard <enter> behavior in VS that
// we want to mimic.
var
snapshot
=
caretPosition
.
Snapshot
;
var
start
=
caretPosition
.
Position
;
var
end
=
caretPosition
;
while
(
end
<
snapshot
.
Length
&&
char
.
IsWhiteSpace
(
end
.
GetChar
())
&&
!
SyntaxFacts
.
IsNewLine
(
end
.
GetChar
()))
end
=
end
+
1
;
return
Span
.
FromBounds
(
start
,
end
);
}
private
string
GetExteriorTextForCurrentLine
(
SnapshotPoint
caretPosition
)
{
var
currentLine
=
caretPosition
.
GetContainingLine
();
var
firstNonWhitespacePosition
=
currentLine
.
GetFirstNonWhitespacePosition
()
??
-
1
;
if
(
firstNonWhitespacePosition
==
-
1
)
{
return
null
;
}
var
currentLineS
tartsWithBlockCommentStartString
=
currentLine
.
StartsWith
(
firstNonWhitespacePosition
,
"/*"
,
ignoreCase
:
false
);
var
currentLineS
tartsWithBlockCommentEndString
=
currentLine
.
StartsWith
(
firstNonWhitespacePosition
,
"*/"
,
ignoreCase
:
false
);
var
currentLineS
tartsWithBlockCommentMiddleString
=
currentLine
.
StartsWith
(
firstNonWhitespacePosition
,
"*"
,
ignoreCase
:
false
);
var
s
tartsWithBlockCommentStartString
=
currentLine
.
StartsWith
(
firstNonWhitespacePosition
,
"/*"
,
ignoreCase
:
false
);
var
s
tartsWithBlockCommentEndString
=
currentLine
.
StartsWith
(
firstNonWhitespacePosition
,
"*/"
,
ignoreCase
:
false
);
var
s
tartsWithBlockCommentMiddleString
=
currentLine
.
StartsWith
(
firstNonWhitespacePosition
,
"*"
,
ignoreCase
:
false
);
if
(!
currentLineStartsWithBlockCommentStartString
&&
!
currentLineStartsWithBlockCommentMiddleString
)
if
(!
startsWithBlockCommentStartString
&&
!
startsWithBlockCommentMiddleString
)
{
return
null
;
}
if
(!
IsCaretInsideBlockCommentSyntax
(
caretPosition
))
{
if
(!
IsCaretInsideBlockCommentSyntax
(
caretPosition
,
out
var
document
,
out
var
blockComment
))
return
null
;
}
if
(
currentLineStartsWithBlockCommentStartString
)
{
if
(
BlockCommentEndsRightAfterCaret
(
caretPosition
))
{
// /*|*/
return
" "
;
}
else
if
(
caretPosition
==
firstNonWhitespacePosition
+
1
)
{
// /|*
return
null
;
// The newline inserted could break the syntax in a way that this handler cannot fix, let's leave it.
}
else
{
// /*|
return
" *"
+
GetPaddingOrIndentation
(
currentLine
,
caretPosition
,
firstNonWhitespacePosition
,
"/*"
);
}
}
var
textSnapshot
=
caretPosition
.
Snapshot
;
if
(
currentLineStartsWithBlockCommentEndString
)
// The whitespace indentation on the line where the block-comment starts.
var
commentIndentation
=
textSnapshot
.
GetText
(
Span
.
FromBounds
(
textSnapshot
.
GetLineFromPosition
(
blockComment
.
FullSpan
.
Start
).
Start
,
blockComment
.
FullSpan
.
Start
));
// The whitespace indentation on the current line up to the first non-whitespace char.
var
lineIndentation
=
textSnapshot
.
GetText
(
Span
.
FromBounds
(
currentLine
.
Start
,
firstNonWhitespacePosition
));
var
exteriorText
=
GetExteriorText
();
if
(
exteriorText
==
null
)
return
null
;
var
options
=
document
.
Project
.
Solution
.
Options
;
var
newLine
=
options
.
GetOption
(
FormattingOptions
.
NewLine
,
LanguageNames
.
CSharp
);
return
newLine
+
exteriorText
;
string
GetExteriorText
()
{
if
(
BlockCommentEndsRightAfterCaret
(
caretPosition
)
)
if
(
startsWithBlockCommentStartString
)
{
// /*
// |*/
return
" "
;
if
(
BlockCommentEndsRightAfterCaret
(
caretPosition
))
{
// /*|*/
return
commentIndentation
+
" "
;
}
else
if
(
caretPosition
==
firstNonWhitespacePosition
+
1
)
{
// /|*
return
null
;
// The newline inserted could break the syntax in a way that this handler cannot fix, let's leave it.
}
else
{
// /*|
// This is directly after the comment starts. Insert ' * ' to continue the comment and to put
// the user one space in. This is the idiomatic style for C#. Note: if the user is hitting
// enter after
//
// /*
// *
// *$$
//
// Then we don't add the space. In this case, they are indicating they don't want this extra
// space added.
var
padding
=
GetPaddingAfterCommentCharacter
();
return
commentIndentation
+
" *"
+
(
padding
==
""
?
" "
:
padding
);
}
}
else
if
(
caretPosition
==
firstNonWhitespacePosition
+
1
)
if
(
startsWithBlockCommentEndString
)
{
// *|/
return
"*"
;
if
(
BlockCommentEndsRightAfterCaret
(
caretPosition
))
{
// /*
// |*/
return
commentIndentation
+
" "
;
}
else
if
(
caretPosition
==
firstNonWhitespacePosition
+
1
)
{
// *|/
return
lineIndentation
+
"*"
;
}
else
{
// /*
// | */
return
commentIndentation
+
" "
;
}
}
else
if
(
startsWithBlockCommentMiddleString
)
{
// /*
// | */
return
" * "
;
if
(
BlockCommentEndsRightAfterCaret
(
caretPosition
))
{
// *|*/
return
lineIndentation
;
}
else
if
(
caretPosition
>
firstNonWhitespacePosition
)
{
// *|
return
lineIndentation
+
"*"
+
GetPaddingAfterCommentCharacter
();
}
else
{
// /*
// | *
return
commentIndentation
+
" "
;
}
}
return
null
;
}
if
(
currentLineStartsWithBlockCommentMiddleString
)
string
GetPaddingAfterCommentCharacter
(
)
{
if
(
BlockCommentEndsRightAfterCaret
(
caretPosition
))
{
// *|*/
return
""
;
}
else
if
(
caretPosition
>
firstNonWhitespacePosition
)
{
// *|
return
"*"
+
GetPaddingOrIndentation
(
currentLine
,
caretPosition
,
firstNonWhitespacePosition
,
"*"
);
}
else
{
// /*
// | *
return
" * "
;
}
}
var
currentChar
=
firstNonWhitespacePosition
;
Debug
.
Assert
(
textSnapshot
[
currentChar
]
==
'/'
||
textSnapshot
[
currentChar
]
==
'*'
);
// Skip past the first comment char.
currentChar
++;
return
null
;
// Skip past any banner of ****'s
while
(
currentChar
<
caretPosition
&&
textSnapshot
[
currentChar
]
==
'*'
)
currentChar
++;
var
start
=
currentChar
;
while
(
currentChar
<
caretPosition
&&
char
.
IsWhiteSpace
(
textSnapshot
[
currentChar
]))
currentChar
++;
return
textSnapshot
.
GetText
(
Span
.
FromBounds
(
start
,
currentChar
));
}
}
private
static
bool
BlockCommentEndsRightAfterCaret
(
SnapshotPoint
caretPosition
)
{
var
snapshot
=
caretPosition
.
Snapshot
;
return
(
(
int
)
caretPosition
+
2
<=
snapshot
.
Length
)
?
snapshot
.
GetText
(
caretPosition
,
2
)
==
"*/"
:
false
;
return
(
int
)
caretPosition
+
2
<=
snapshot
.
Length
&&
snapshot
.
GetText
(
caretPosition
,
2
)
==
"*/"
;
}
private
static
string
GetPaddingOrIndentation
(
ITextSnapshotLine
currentLine
,
int
caretPosition
,
int
firstNonWhitespacePosition
,
string
exteriorText
)
public
static
bool
IsCaretInsideBlockCommentSyntax
(
SnapshotPoint
caretPosition
,
out
Document
document
,
out
SyntaxTrivia
trivia
)
{
Debug
.
Assert
(
caretPosition
>=
firstNonWhitespacePosition
+
exteriorText
.
Length
)
;
trivia
=
default
;
var
firstNonWhitespaceOffset
=
firstNonWhitespacePosition
-
currentLine
.
Start
;
Debug
.
Assert
(
firstNonWhitespaceOffset
>
-
1
);
var
lineText
=
currentLine
.
GetText
();
if
(
lineText
.
Length
==
firstNonWhitespaceOffset
+
exteriorText
.
Length
)
{
// *|
return
" "
;
}
var
interiorText
=
lineText
.
Substring
(
firstNonWhitespaceOffset
+
exteriorText
.
Length
);
var
interiorFirstNonWhitespaceOffset
=
interiorText
.
GetFirstNonWhitespaceOffset
()
??
-
1
;
if
(
interiorFirstNonWhitespaceOffset
==
0
)
{
// /****|
return
" "
;
}
var
interiorFirstWhitespacePosition
=
firstNonWhitespacePosition
+
exteriorText
.
Length
;
if
(
interiorFirstNonWhitespaceOffset
==
-
1
||
caretPosition
<=
interiorFirstWhitespacePosition
+
interiorFirstNonWhitespaceOffset
)
{
// * |
// or
// * | 1.
// ^^
return
currentLine
.
Snapshot
.
GetText
(
interiorFirstWhitespacePosition
,
caretPosition
-
interiorFirstWhitespacePosition
);
}
else
{
// * 1. |
// ^^^
return
currentLine
.
Snapshot
.
GetText
(
interiorFirstWhitespacePosition
,
interiorFirstNonWhitespaceOffset
);
}
}
public
static
bool
IsCaretInsideBlockCommentSyntax
(
SnapshotPoint
caretPosition
)
{
var
snapshot
=
caretPosition
.
Snapshot
;
var
document
=
snapshot
.
GetOpenDocumentInCurrentContextWithChanges
();
document
=
snapshot
.
GetOpenDocumentInCurrentContextWithChanges
();
if
(
document
==
null
)
{
return
false
;
}
var
syntaxTree
=
document
.
GetSyntaxTreeSynchronously
(
CancellationToken
.
None
);
var
trivia
=
syntaxTree
.
FindTriviaAndAdjustForEndOfFile
(
caretPosition
,
CancellationToken
.
None
);
trivia
=
syntaxTree
.
FindTriviaAndAdjustForEndOfFile
(
caretPosition
,
CancellationToken
.
None
);
var
isBlockComment
=
trivia
.
IsKind
(
SyntaxKind
.
MultiLineCommentTrivia
)
||
trivia
.
IsKind
(
SyntaxKind
.
MultiLineDocumentationCommentTrivia
);
if
(
isBlockComment
)
{
var
span
=
trivia
.
FullSpan
;
if
(
span
.
Start
<
caretPosition
&&
caretPosition
<
span
.
End
)
{
return
true
;
}
// FindTriviaAndAdjustForEndOfFile always returns something if position is EOF,
// whether or not the result includes the position.
...
...
@@ -246,16 +260,12 @@ public static bool IsCaretInsideBlockCommentSyntax(SnapshotPoint caretPosition)
if
(
caretPosition
==
snapshot
.
Length
)
{
if
(
span
.
Length
<
"/**/"
.
Length
)
{
return
true
;
}
// If the block comment is not closed, SyntaxTrivia contains diagnostics
// So when the SyntaxTrivia is clean, the block comment should be closed
if
(!
trivia
.
ContainsDiagnostics
)
{
return
false
;
}
var
textBeforeCaret
=
snapshot
.
GetText
(
caretPosition
.
Position
-
2
,
2
);
return
textBeforeCaret
!=
"*/"
;
...
...
src/EditorFeatures/CSharp/BlockCommentEditing/CloseBlockCommentCommandHandler.cs
浏览文件 @
84c290a8
...
...
@@ -45,7 +45,7 @@ public bool ExecuteCommand(TypeCharCommandArgs args, CommandExecutionContext exe
line
.
IsEmptyOrWhitespace
(
0
,
line
.
Length
-
2
))
{
if
(
args
.
SubjectBuffer
.
GetFeatureOnOffOption
(
FeatureOnOffOptions
.
AutoInsertBlockCommentStartString
)
&&
BlockCommentEditingCommandHandler
.
IsCaretInsideBlockCommentSyntax
(
caret
.
Value
))
BlockCommentEditingCommandHandler
.
IsCaretInsideBlockCommentSyntax
(
caret
.
Value
,
out
_
,
out
_
))
{
args
.
SubjectBuffer
.
Replace
(
new
VisualStudio
.
Text
.
Span
(
position
-
1
,
1
),
"/"
);
return
true
;
...
...
src/EditorFeatures/CSharpTest/BlockCommentEditing/BlockCommentEditingTests.cs
浏览文件 @
84c290a8
...
...
@@ -144,7 +144,7 @@ public void InsertOnStartLine2()
"
;
var
expected
=
@"
/*
*$$*/
*
$$*/
"
;
Verify
(
code
,
expected
);
}
...
...
@@ -243,7 +243,7 @@ public void InsertOnMiddleLine0()
var
expected
=
@"
/*
*
*
$$
*$$
"
;
Verify
(
code
,
expected
);
}
...
...
@@ -342,7 +342,7 @@ public void InsertOnMiddleLine6()
var
expected
=
@"
/*
*
$$*
$$*
*/
"
;
Verify
(
code
,
expected
);
...
...
@@ -359,7 +359,7 @@ public void InsertOnMiddleLine7()
var
expected
=
@"
/*
*************
*
$$
*$$
*/
"
;
Verify
(
code
,
expected
);
...
...
@@ -376,7 +376,7 @@ public void InsertOnMiddleLine8()
var
expected
=
@"
/**
*
*
$$
*$$
*/
"
;
Verify
(
code
,
expected
);
...
...
@@ -392,7 +392,7 @@ public void InsertOnMiddleLine9()
var
expected
=
@"
/**
*
*
$$
*$$
"
;
Verify
(
code
,
expected
);
}
...
...
@@ -454,7 +454,7 @@ public void InsertOnEndLine3()
var
expected
=
@"
/*
*
$$*/
$$*/
"
;
Verify
(
code
,
expected
);
}
...
...
@@ -528,7 +528,7 @@ public void BoundCheckInsertOnStartLine1()
/*$$ "
;
var
expected
=
@"
/*
*$$"
;
*
$$"
;
Verify
(
code
,
expected
);
}
...
...
@@ -566,7 +566,7 @@ public void InsertOnStartLine2_Tab()
"
;
var
expected
=
@"
/*
*$$*/
*
$$*/
"
;
VerifyTabs
(
code
,
expected
);
}
...
...
src/Workspaces/CSharp/Portable/Indentation/CSharpIndentationService.Indenter.cs
浏览文件 @
84c290a8
...
...
@@ -4,6 +4,7 @@
using
System.Diagnostics
;
using
System.Linq
;
using
Microsoft.CodeAnalysis
;
using
Microsoft.CodeAnalysis.CSharp.Extensions
;
using
Microsoft.CodeAnalysis.CSharp.Formatting
;
using
Microsoft.CodeAnalysis.CSharp.Syntax
;
...
...
@@ -49,15 +50,15 @@ protected override IndentationResult GetDesiredIndentationWorker(Indenter indent
return
null
;
var
trivia
=
triviaOpt
.
Value
;
if
(!
trivia
.
Is
Kind
(
SyntaxKind
.
SingleLineCommentTrivia
))
if
(!
trivia
.
Is
SingleOrMultiLineComment
()
&&
!
trivia
.
IsDocComment
(
))
return
null
;
var
line
=
indenter
.
Text
.
Lines
.
GetLineFromPosition
(
trivia
.
Span
Start
);
if
(
line
.
GetFirstNonWhitespacePosition
()
!=
trivia
.
Span
Start
)
var
line
=
indenter
.
Text
.
Lines
.
GetLineFromPosition
(
trivia
.
FullSpan
.
Start
);
if
(
line
.
GetFirstNonWhitespacePosition
()
!=
trivia
.
FullSpan
.
Start
)
return
null
;
// Previous line just contained this single line comment. Align us with it.
return
new
IndentationResult
(
trivia
.
Span
Start
,
0
);
return
new
IndentationResult
(
trivia
.
FullSpan
.
Start
,
0
);
}
private
IndentationResult
?
TryGetDesiredIndentation
(
Indenter
indenter
,
SyntaxToken
?
tokenOpt
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录