Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
0d25d0a7
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,发现更多精彩内容 >>
提交
0d25d0a7
编写于
11月 22, 2019
作者:
P
Pine Wu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix #47069
上级
6b78be02
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
196 addition
and
6 deletion
+196
-6
extensions/html-language-features/client/src/htmlMain.ts
extensions/html-language-features/client/src/htmlMain.ts
+12
-0
extensions/html-language-features/client/src/matchingTag.ts
extensions/html-language-features/client/src/matchingTag.ts
+147
-0
extensions/html-language-features/package.json
extensions/html-language-features/package.json
+6
-0
extensions/html-language-features/package.nls.json
extensions/html-language-features/package.nls.json
+2
-1
extensions/html-language-features/server/package.json
extensions/html-language-features/server/package.json
+1
-1
extensions/html-language-features/server/src/htmlServerMain.ts
...sions/html-language-features/server/src/htmlServerMain.ts
+19
-0
extensions/html-language-features/server/src/modes/htmlMode.ts
...sions/html-language-features/server/src/modes/htmlMode.ts
+4
-0
extensions/html-language-features/server/src/modes/languageModes.ts
.../html-language-features/server/src/modes/languageModes.ts
+1
-0
extensions/html-language-features/server/yarn.lock
extensions/html-language-features/server/yarn.lock
+4
-4
未找到文件。
extensions/html-language-features/client/src/htmlMain.ts
浏览文件 @
0d25d0a7
...
...
@@ -14,10 +14,14 @@ import { EMPTY_ELEMENTS } from './htmlEmptyTagsShared';
import
{
activateTagClosing
}
from
'
./tagClosing
'
;
import
TelemetryReporter
from
'
vscode-extension-telemetry
'
;
import
{
getCustomDataPathsInAllWorkspaces
,
getCustomDataPathsFromAllExtensions
}
from
'
./customData
'
;
import
{
activateMatchingTagPosition
as
activateMatchingTagSelection
}
from
'
./matchingTag
'
;
namespace
TagCloseRequest
{
export
const
type
:
RequestType
<
TextDocumentPositionParams
,
string
,
any
,
any
>
=
new
RequestType
(
'
html/tag
'
);
}
namespace
MatchingTagPositionRequest
{
export
const
type
:
RequestType
<
TextDocumentPositionParams
,
Position
|
null
,
any
,
any
>
=
new
RequestType
(
'
html/matchingTagPosition
'
);
}
interface
IPackageInfo
{
name
:
string
;
...
...
@@ -84,6 +88,14 @@ export function activate(context: ExtensionContext) {
disposable
=
activateTagClosing
(
tagRequestor
,
{
html
:
true
,
handlebars
:
true
},
'
html.autoClosingTags
'
);
toDispose
.
push
(
disposable
);
const
matchingTagPositionRequestor
=
(
document
:
TextDocument
,
position
:
Position
)
=>
{
let
param
=
client
.
code2ProtocolConverter
.
asTextDocumentPositionParams
(
document
,
position
);
return
client
.
sendRequest
(
MatchingTagPositionRequest
.
type
,
param
);
};
disposable
=
activateMatchingTagSelection
(
matchingTagPositionRequestor
,
{
html
:
true
,
handlebars
:
true
},
'
html.autoSelectingMatchingTags
'
);
toDispose
.
push
(
disposable
);
disposable
=
client
.
onTelemetry
(
e
=>
{
if
(
telemetryReporter
)
{
telemetryReporter
.
sendTelemetryEvent
(
e
.
key
,
e
.
data
);
...
...
extensions/html-language-features/client/src/matchingTag.ts
0 → 100644
浏览文件 @
0d25d0a7
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
window
,
workspace
,
Disposable
,
TextDocument
,
Position
,
TextEditorSelectionChangeEvent
,
Selection
,
Range
,
WorkspaceEdit
}
from
'
vscode
'
;
export
function
activateMatchingTagPosition
(
matchingTagPositionProvider
:
(
document
:
TextDocument
,
position
:
Position
)
=>
Thenable
<
Position
|
null
>
,
supportedLanguages
:
{
[
id
:
string
]:
boolean
},
configName
:
string
):
Disposable
{
let
disposables
:
Disposable
[]
=
[];
window
.
onDidChangeTextEditorSelection
(
event
=>
onDidChangeTextEditorSelection
(
event
),
null
,
disposables
);
let
isEnabled
=
false
;
updateEnabledState
();
window
.
onDidChangeActiveTextEditor
(
updateEnabledState
,
null
,
disposables
);
function
updateEnabledState
()
{
isEnabled
=
false
;
let
editor
=
window
.
activeTextEditor
;
if
(
!
editor
)
{
return
;
}
let
document
=
editor
.
document
;
if
(
!
supportedLanguages
[
document
.
languageId
])
{
return
;
}
if
(
!
workspace
.
getConfiguration
(
undefined
,
document
.
uri
).
get
<
boolean
>
(
configName
))
{
return
;
}
isEnabled
=
true
;
}
// let prevCursorCount = 0;
let
cursorCount
=
0
;
let
inMirrorMode
=
false
;
function
onDidChangeTextEditorSelection
(
event
:
TextEditorSelectionChangeEvent
)
{
if
(
!
isEnabled
)
{
return
;
}
// prevCursorCount = cursorCount;
cursorCount
=
event
.
selections
.
length
;
if
(
cursorCount
===
1
)
{
if
(
event
.
selections
[
0
].
isEmpty
)
{
matchingTagPositionProvider
(
event
.
textEditor
.
document
,
event
.
selections
[
0
].
active
).
then
(
position
=>
{
if
(
position
&&
window
.
activeTextEditor
)
{
inMirrorMode
=
true
;
const
newCursor
=
new
Selection
(
position
.
line
,
position
.
character
,
position
.
line
,
position
.
character
);
window
.
activeTextEditor
.
selections
=
[...
window
.
activeTextEditor
.
selections
,
newCursor
];
}
});
}
}
if
(
cursorCount
===
2
&&
inMirrorMode
)
{
// Check two cases
if
(
event
.
selections
[
0
].
isEmpty
&&
event
.
selections
[
1
].
isEmpty
)
{
const
charBeforePrimarySelection
=
getCharBefore
(
event
.
textEditor
.
document
,
event
.
selections
[
0
].
anchor
);
const
charAfterPrimarySelection
=
getCharAfter
(
event
.
textEditor
.
document
,
event
.
selections
[
0
].
anchor
);
const
charBeforeSecondarySelection
=
getCharBefore
(
event
.
textEditor
.
document
,
event
.
selections
[
1
].
anchor
);
const
charAfterSecondarySelection
=
getCharAfter
(
event
.
textEditor
.
document
,
event
.
selections
[
1
].
anchor
);
// Exit mirror mode when cursor position no longer mirror
// Unless it's in the case of `<|></|>`
const
charBeforeBothPositionRoughlyEqual
=
charBeforePrimarySelection
===
charBeforeSecondarySelection
||
(
charBeforePrimarySelection
===
'
/
'
&&
charBeforeSecondarySelection
===
'
<
'
)
||
(
charBeforeSecondarySelection
===
'
/
'
&&
charBeforePrimarySelection
===
'
<
'
);
const
charAfterBothPositionRoughlyEqual
=
charAfterPrimarySelection
===
charAfterSecondarySelection
||
(
charAfterPrimarySelection
===
'
'
&&
charAfterSecondarySelection
===
'
>
'
)
||
(
charAfterSecondarySelection
===
'
'
&&
charAfterPrimarySelection
===
'
>
'
);
if
(
!
charBeforeBothPositionRoughlyEqual
||
!
charAfterBothPositionRoughlyEqual
)
{
inMirrorMode
=
false
;
window
.
activeTextEditor
!
.
selections
=
[
window
.
activeTextEditor
!
.
selections
[
0
]];
return
;
}
else
{
// Need to cleanup in the case of <div |></div |>
if
(
charBeforePrimarySelection
===
'
'
&&
charAfterPrimarySelection
===
'
>
'
&&
charBeforeSecondarySelection
===
'
'
&&
charAfterSecondarySelection
===
'
>
'
)
{
inMirrorMode
=
false
;
const
cleanupEdit
=
new
WorkspaceEdit
();
const
primaryBeforeSecondary
=
event
.
textEditor
.
document
.
offsetAt
(
event
.
selections
[
0
].
anchor
)
<
event
.
textEditor
.
document
.
offsetAt
(
event
.
selections
[
1
].
anchor
);
const
cleanupRange
=
primaryBeforeSecondary
?
new
Range
(
event
.
selections
[
1
].
anchor
.
translate
(
0
,
-
1
),
event
.
selections
[
1
].
anchor
)
:
new
Range
(
event
.
selections
[
0
].
anchor
.
translate
(
0
,
-
1
),
event
.
selections
[
0
].
anchor
);
cleanupEdit
.
replace
(
event
.
textEditor
.
document
.
uri
,
cleanupRange
,
''
);
window
.
activeTextEditor
!
.
selections
=
primaryBeforeSecondary
?
[
window
.
activeTextEditor
!
.
selections
[
0
]]
:
[
window
.
activeTextEditor
!
.
selections
[
1
]];
workspace
.
applyEdit
(
cleanupEdit
);
}
}
}
}
}
return
Disposable
.
from
(...
disposables
);
}
function
getCharBefore
(
document
:
TextDocument
,
position
:
Position
)
{
const
offset
=
document
.
offsetAt
(
position
);
if
(
offset
===
0
)
{
return
''
;
}
return
document
.
getText
(
new
Range
(
document
.
positionAt
(
offset
-
1
),
position
)
);
}
function
getCharAfter
(
document
:
TextDocument
,
position
:
Position
)
{
const
offset
=
document
.
offsetAt
(
position
);
if
(
offset
===
document
.
getText
().
length
)
{
return
''
;
}
return
document
.
getText
(
new
Range
(
position
,
document
.
positionAt
(
offset
+
1
))
);
}
\ No newline at end of file
extensions/html-language-features/package.json
浏览文件 @
0d25d0a7
...
...
@@ -161,6 +161,12 @@
"default"
:
true
,
"description"
:
"%html.autoClosingTags%"
},
"html.autoSelectingMatchingTags"
:
{
"type"
:
"boolean"
,
"scope"
:
"resource"
,
"default"
:
true
,
"description"
:
"%html.autoSelectingMatchingTags%"
},
"html.trace.server"
:
{
"type"
:
"string"
,
"scope"
:
"window"
,
...
...
extensions/html-language-features/package.nls.json
浏览文件 @
0d25d0a7
...
...
@@ -24,5 +24,6 @@
"html.trace.server.desc"
:
"Traces the communication between VS Code and the HTML language server."
,
"html.validate.scripts"
:
"Controls whether the built-in HTML language support validates embedded scripts."
,
"html.validate.styles"
:
"Controls whether the built-in HTML language support validates embedded styles."
,
"html.autoClosingTags"
:
"Enable/disable autoclosing of HTML tags."
"html.autoClosingTags"
:
"Enable/disable autoclosing of HTML tags."
,
"html.autoSelectingMatchingTags"
:
"Enable/disable auto selecting matching HTML tags."
}
extensions/html-language-features/server/package.json
浏览文件 @
0d25d0a7
...
...
@@ -10,7 +10,7 @@
"main"
:
"./out/htmlServerMain"
,
"dependencies"
:
{
"vscode-css-languageservice"
:
"^4.0.3-next.20"
,
"vscode-html-languageservice"
:
"^3.0.4-next.
9
"
,
"vscode-html-languageservice"
:
"^3.0.4-next.
10
"
,
"vscode-languageserver"
:
"^6.0.0-next.3"
,
"vscode-nls"
:
"^4.1.1"
,
"vscode-uri"
:
"^2.0.3"
...
...
extensions/html-language-features/server/src/htmlServerMain.ts
浏览文件 @
0d25d0a7
...
...
@@ -24,6 +24,9 @@ import { getDataProviders } from './customData';
namespace
TagCloseRequest
{
export
const
type
:
RequestType
<
TextDocumentPositionParams
,
string
|
null
,
any
,
any
>
=
new
RequestType
(
'
html/tag
'
);
}
namespace
MatchingTagPositionRequest
{
export
const
type
:
RequestType
<
TextDocumentPositionParams
,
Position
|
null
,
any
,
any
>
=
new
RequestType
(
'
html/matchingTagPosition
'
);
}
// Create a connection for the server
const
connection
:
IConnection
=
createConnection
();
...
...
@@ -485,5 +488,21 @@ connection.onRenameRequest((params, token) => {
},
null
,
`Error while computing rename for
${
params
.
textDocument
.
uri
}
`
,
token
);
});
connection
.
onRequest
(
MatchingTagPositionRequest
.
type
,
(
params
,
token
)
=>
{
return
runSafe
(()
=>
{
const
document
=
documents
.
get
(
params
.
textDocument
.
uri
);
if
(
document
)
{
const
pos
=
params
.
position
;
if
(
pos
.
character
>
0
)
{
const
mode
=
languageModes
.
getModeAtPosition
(
document
,
Position
.
create
(
pos
.
line
,
pos
.
character
-
1
));
if
(
mode
&&
mode
.
findMatchingTagPosition
)
{
return
mode
.
findMatchingTagPosition
(
document
,
pos
);
}
}
}
return
null
;
},
null
,
`Error while computing matching tag position for
${
params
.
textDocument
.
uri
}
`
,
token
);
});
// Listen on the connection
connection
.
listen
();
extensions/html-language-features/server/src/modes/htmlMode.ts
浏览文件 @
0d25d0a7
...
...
@@ -81,6 +81,10 @@ export function getHTMLMode(htmlLanguageService: HTMLLanguageService, workspace:
onDocumentRemoved
(
document
:
TextDocument
)
{
htmlDocuments
.
onDocumentRemoved
(
document
);
},
findMatchingTagPosition
(
document
:
TextDocument
,
position
:
Position
)
{
const
htmlDocument
=
htmlDocuments
.
get
(
document
);
return
htmlLanguageService
.
findMatchingTagPosition
(
document
,
position
,
htmlDocument
);
},
dispose
()
{
htmlDocuments
.
dispose
();
}
...
...
extensions/html-language-features/server/src/modes/languageModes.ts
浏览文件 @
0d25d0a7
...
...
@@ -48,6 +48,7 @@ export interface LanguageMode {
findDocumentColors
?:
(
document
:
TextDocument
)
=>
ColorInformation
[];
getColorPresentations
?:
(
document
:
TextDocument
,
color
:
Color
,
range
:
Range
)
=>
ColorPresentation
[];
doAutoClose
?:
(
document
:
TextDocument
,
position
:
Position
)
=>
string
|
null
;
findMatchingTagPosition
?:
(
document
:
TextDocument
,
position
:
Position
)
=>
Position
|
null
;
getFoldingRanges
?:
(
document
:
TextDocument
)
=>
FoldingRange
[];
onDocumentRemoved
(
document
:
TextDocument
):
void
;
dispose
():
void
;
...
...
extensions/html-language-features/server/yarn.lock
浏览文件 @
0d25d0a7
...
...
@@ -621,10 +621,10 @@ vscode-css-languageservice@^4.0.3-next.20:
vscode-nls "^4.1.1"
vscode-uri "^2.1.1"
vscode-html-languageservice@^3.0.4-next.
9
:
version "3.0.4-next.
9
"
resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-3.0.4-next.
9.tgz#b27f26c29f3af64fa32eabb7425749f95f64036a
"
integrity sha512-
9V9G7508ybFcn9gQpuucEZIGv8kKlBMEVD8lFFWwWS1yEonKchsxIGJZFbmSGr/n//2anfya8F8yL5ybKuWIRA
==
vscode-html-languageservice@^3.0.4-next.
10
:
version "3.0.4-next.
10
"
resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-3.0.4-next.
10.tgz#da426326833770c51712abb2c7473b9b30bf1cbc
"
integrity sha512-
8P0QBtMPJ9nDMhW8MF/z+5JGg6rK6UOa9po18KIleNuV0rDHU9CAqDyUjxW0CEfLrHYz6dQdkW12ZTClvQnNHw
==
dependencies:
vscode-languageserver-textdocument "^1.0.0-next.4"
vscode-languageserver-types "^3.15.0-next.6"
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录