mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 13:00:58 +00:00
Merge branch 'master' into joh/ftp
This commit is contained in:
commit
9c3fb2ffd1
|
@ -50,6 +50,11 @@
|
|||
"scopeName": "text.git-rebase",
|
||||
"path": "./syntaxes/git-rebase.tmLanguage.json"
|
||||
}
|
||||
]
|
||||
],
|
||||
"configurationDefaults": {
|
||||
"[git-commit]": {
|
||||
"editor.rulers": [72]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,13 @@
|
|||
"foreground": "#6688cc"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "meta.embedded",
|
||||
"settings": {
|
||||
"background": "#000c18",
|
||||
"foreground": "#6688cc"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Comment",
|
||||
"scope": "comment",
|
||||
|
|
|
@ -54,6 +54,13 @@
|
|||
"foreground": "#d3af86"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "meta.embedded",
|
||||
"settings": {
|
||||
"background": "#221a0f",
|
||||
"foreground": "#d3af86"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Text",
|
||||
"scope": "variable.parameter.function",
|
||||
|
|
|
@ -51,6 +51,13 @@
|
|||
"foreground": "#c5c8c6ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "meta.embedded",
|
||||
"settings": {
|
||||
"background": "#1e1e1e",
|
||||
"foreground": "#C5C8C6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Comment",
|
||||
"scope": "comment",
|
||||
|
|
|
@ -96,6 +96,13 @@
|
|||
"foreground": "#F8F8F2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "meta.embedded",
|
||||
"settings": {
|
||||
"background": "#272822",
|
||||
"foreground": "#F8F8F2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Comment",
|
||||
"scope": "comment",
|
||||
|
|
|
@ -7,6 +7,13 @@
|
|||
"foreground": "#333333"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "meta.embedded",
|
||||
"settings": {
|
||||
"background": "#F5F5F5",
|
||||
"foreground": "#333333"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Comments",
|
||||
"scope": [
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"tokenColors": "./red.tmTheme",
|
||||
"name": "Red",
|
||||
"colors": {
|
||||
// window
|
||||
"activityBar.background": "#580000",
|
||||
|
@ -57,5 +57,342 @@
|
|||
"extensionButton.prominentBackground": "#cc3333",
|
||||
"extensionButton.prominentHoverBackground": "#cc333388"
|
||||
},
|
||||
"name": "Red"
|
||||
"tokenColors": [
|
||||
{
|
||||
"settings": {
|
||||
"background": "#390000",
|
||||
"caret": "#970000",
|
||||
"foreground": "#F8F8F8",
|
||||
"invisibles": "#c10000",
|
||||
"lineHighlight": "#0000004A",
|
||||
"selection": "#750000"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "meta.embedded",
|
||||
"settings": {
|
||||
"background": "#390000",
|
||||
"foreground": "#F8F8F8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Comment",
|
||||
"scope": "comment",
|
||||
"settings": {
|
||||
"fontStyle": "italic",
|
||||
"foreground": "#e7c0c0ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Constant",
|
||||
"scope": "constant",
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#994646ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Keyword",
|
||||
"scope": "keyword",
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#f12727ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Entity",
|
||||
"scope": "entity",
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#fec758ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Storage",
|
||||
"scope": "storage",
|
||||
"settings": {
|
||||
"fontStyle": "bold",
|
||||
"foreground": "#ff6262ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "String",
|
||||
"scope": "string",
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#cd8d8dff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Support",
|
||||
"scope": "support",
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#9df39fff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Variable",
|
||||
"scope": "variable",
|
||||
"settings": {
|
||||
"fontStyle": "italic",
|
||||
"foreground": "#fb9a4bff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Invalid",
|
||||
"scope": "invalid",
|
||||
"settings": {
|
||||
"background": "#fd6209ff",
|
||||
"foreground": "#ffffffff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Embedded Source",
|
||||
"scope": "text source",
|
||||
"settings": {
|
||||
"background": "#b0b3ba14"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Embedded Source (Bright)",
|
||||
"scope": "text.html.ruby source",
|
||||
"settings": {
|
||||
"background": "#b1b3ba21"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Entity inherited-class",
|
||||
"scope": "entity.other.inherited-class",
|
||||
"settings": {
|
||||
"fontStyle": "underline",
|
||||
"foreground": "#aa5507ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "String embedded-source",
|
||||
"scope": "string.quoted source",
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#9df39fff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "String constant",
|
||||
"scope": "string constant",
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#ffe862ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "String.regexp",
|
||||
"scope": "string.regexp",
|
||||
"settings": {
|
||||
"foreground": "#ffb454ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "String variable",
|
||||
"scope": "string variable",
|
||||
"settings": {
|
||||
"foreground": "#edef7dff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Support.function",
|
||||
"scope": "support.function",
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#ffb454ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Support.constant",
|
||||
"scope": "support.constant",
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#eb939aff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Doctype/XML Processing",
|
||||
"scope": [
|
||||
"declaration.sgml.html declaration.doctype",
|
||||
"declaration.sgml.html declaration.doctype entity",
|
||||
"declaration.sgml.html declaration.doctype string",
|
||||
"declaration.xml-processing",
|
||||
"declaration.xml-processing entity",
|
||||
"declaration.xml-processing string"
|
||||
],
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#73817dff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Meta.tag.A",
|
||||
"scope": [
|
||||
"declaration.tag",
|
||||
"declaration.tag entity",
|
||||
"meta.tag",
|
||||
"meta.tag entity"
|
||||
],
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#ec0d1eff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "css tag-name",
|
||||
"scope": "meta.selector.css entity.name.tag",
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#aa5507ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "css#id",
|
||||
"scope": "meta.selector.css entity.other.attribute-name.id",
|
||||
"settings": {
|
||||
"foreground": "#fec758ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "css.class",
|
||||
"scope": "meta.selector.css entity.other.attribute-name.class",
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#41a83eff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "css property-name:",
|
||||
"scope": "support.type.property-name.css",
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#96dd3bff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "css property-value;",
|
||||
"scope": [
|
||||
"meta.property-group support.constant.property-value.css",
|
||||
"meta.property-value support.constant.property-value.css"
|
||||
],
|
||||
"settings": {
|
||||
"fontStyle": "italic",
|
||||
"foreground": "#ffe862ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "css additional-constants",
|
||||
"scope": [
|
||||
"meta.property-value support.constant.named-color.css",
|
||||
"meta.property-value constant"
|
||||
],
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#ffe862ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "css @at-rule",
|
||||
"scope": "meta.preprocessor.at-rule keyword.control.at-rule",
|
||||
"settings": {
|
||||
"foreground": "#fd6209ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "css constructor.argument",
|
||||
"scope": "meta.constructor.argument.css",
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#ec9799ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "diff.header",
|
||||
"scope": [
|
||||
"meta.diff",
|
||||
"meta.diff.header"
|
||||
],
|
||||
"settings": {
|
||||
"background": "#0b2f20ff",
|
||||
"fontStyle": "italic",
|
||||
"foreground": "#f8f8f8ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "diff.deleted",
|
||||
"scope": "markup.deleted",
|
||||
"settings": {
|
||||
"background": "#fedcddff",
|
||||
"foreground": "#ec9799ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "diff.changed",
|
||||
"scope": "markup.changed",
|
||||
"settings": {
|
||||
"background": "#c4b14aff",
|
||||
"foreground": "#f8f8f8ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "diff.inserted",
|
||||
"scope": "markup.inserted",
|
||||
"settings": {
|
||||
"background": "#9bf199ff",
|
||||
"foreground": "#41a83eff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Markup Quote",
|
||||
"scope": "markup.quote",
|
||||
"settings": {
|
||||
"foreground": "#f12727ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Markup Lists",
|
||||
"scope": "markup.list",
|
||||
"settings": {
|
||||
"foreground": "#ff6262ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Markup Styling",
|
||||
"scope": [
|
||||
"markup.bold",
|
||||
"markup.italic"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#fb9a4bff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Markup Inline",
|
||||
"scope": "markup.inline.raw",
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#cd8d8dff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Markup Headings",
|
||||
"scope": "markup.heading",
|
||||
"settings": {
|
||||
"foreground": "#fec758ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Markup Setext Header",
|
||||
"scope": "markup.heading.setext",
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#fec758ff"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,514 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Red</string>
|
||||
<key>settings</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#390000</string>
|
||||
<key>caret</key>
|
||||
<string>#970000</string>
|
||||
<key>foreground</key>
|
||||
<string>#F8F8F8</string>
|
||||
<key>invisibles</key>
|
||||
<string>#c10000</string>
|
||||
<key>lineHighlight</key>
|
||||
<string>#0000004A</string>
|
||||
<key>selection</key>
|
||||
<string>#750000</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Comment</string>
|
||||
<key>scope</key>
|
||||
<string>comment</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#e7c0c0ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Constant</string>
|
||||
<key>scope</key>
|
||||
<string>constant</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#994646ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Keyword</string>
|
||||
<key>scope</key>
|
||||
<string>keyword</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#f12727ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Entity</string>
|
||||
<key>scope</key>
|
||||
<string>entity</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#fec758ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Storage</string>
|
||||
<key>scope</key>
|
||||
<string>storage</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>bold</string>
|
||||
<key>foreground</key>
|
||||
<string>#ff6262ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>String</string>
|
||||
<key>scope</key>
|
||||
<string>string</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#cd8d8dff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Support</string>
|
||||
<key>scope</key>
|
||||
<string>support</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#9df39fff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Variable</string>
|
||||
<key>scope</key>
|
||||
<string>variable</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#fb9a4bff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Invalid</string>
|
||||
<key>scope</key>
|
||||
<string>invalid</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#fd6209ff</string>
|
||||
<key>foreground</key>
|
||||
<string>#ffffffff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Embedded Source</string>
|
||||
<key>scope</key>
|
||||
<string>text source</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#b0b3ba14</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Embedded Source (Bright)</string>
|
||||
<key>scope</key>
|
||||
<string>text.html.ruby source</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#b1b3ba21</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Entity inherited-class</string>
|
||||
<key>scope</key>
|
||||
<string>entity.other.inherited-class</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>underline</string>
|
||||
<key>foreground</key>
|
||||
<string>#aa5507ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>String embedded-source</string>
|
||||
<key>scope</key>
|
||||
<string>string.quoted source</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#9df39fff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>String constant</string>
|
||||
<key>scope</key>
|
||||
<string>string constant</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#ffe862ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>String.regexp</string>
|
||||
<key>scope</key>
|
||||
<string>string.regexp</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#ffb454ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>String variable</string>
|
||||
<key>scope</key>
|
||||
<string>string variable</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#edef7dff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Support.function</string>
|
||||
<key>scope</key>
|
||||
<string>support.function</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#ffb454ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Support.constant</string>
|
||||
<key>scope</key>
|
||||
<string>support.constant</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#eb939aff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Doctype/XML Processing</string>
|
||||
<key>scope</key>
|
||||
<string>declaration.sgml.html declaration.doctype, declaration.sgml.html declaration.doctype entity, declaration.sgml.html declaration.doctype string, declaration.xml-processing, declaration.xml-processing entity, declaration.xml-processing string</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#73817dff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Meta.tag.A</string>
|
||||
<key>scope</key>
|
||||
<string>declaration.tag, declaration.tag entity, meta.tag, meta.tag entity</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#ec0d1eff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>css tag-name</string>
|
||||
<key>scope</key>
|
||||
<string>meta.selector.css entity.name.tag</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#aa5507ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>css#id</string>
|
||||
<key>scope</key>
|
||||
<string>meta.selector.css entity.other.attribute-name.id</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#fec758ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>css.class</string>
|
||||
<key>scope</key>
|
||||
<string>meta.selector.css entity.other.attribute-name.class</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#41a83eff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>css property-name:</string>
|
||||
<key>scope</key>
|
||||
<string>support.type.property-name.css</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#96dd3bff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>css property-value;</string>
|
||||
<key>scope</key>
|
||||
<string>meta.property-group support.constant.property-value.css, meta.property-value support.constant.property-value.css</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#ffe862ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>css additional-constants</string>
|
||||
<key>scope</key>
|
||||
<string>meta.property-value support.constant.named-color.css, meta.property-value constant</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#ffe862ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>css @at-rule</string>
|
||||
<key>scope</key>
|
||||
<string>meta.preprocessor.at-rule keyword.control.at-rule</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#fd6209ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>css constructor.argument</string>
|
||||
<key>scope</key>
|
||||
<string>meta.constructor.argument.css</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#ec9799ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>diff.header</string>
|
||||
<key>scope</key>
|
||||
<string>meta.diff, meta.diff.header</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#0b2f20ff</string>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#f8f8f8ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>diff.deleted</string>
|
||||
<key>scope</key>
|
||||
<string>markup.deleted</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#fedcddff</string>
|
||||
<key>foreground</key>
|
||||
<string>#ec9799ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>diff.changed</string>
|
||||
<key>scope</key>
|
||||
<string>markup.changed</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#c4b14aff</string>
|
||||
<key>foreground</key>
|
||||
<string>#f8f8f8ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>diff.inserted</string>
|
||||
<key>scope</key>
|
||||
<string>markup.inserted</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#9bf199ff</string>
|
||||
<key>foreground</key>
|
||||
<string>#41a83eff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup Quote</string>
|
||||
<key>scope</key>
|
||||
<string>markup.quote</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#f12727ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup Lists</string>
|
||||
<key>scope</key>
|
||||
<string>markup.list</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#ff6262ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup Styling</string>
|
||||
<key>scope</key>
|
||||
<string>markup.bold, markup.italic</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#fb9a4bff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup Inline</string>
|
||||
<key>scope</key>
|
||||
<string>markup.inline.raw</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#cd8d8dff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup Headings</string>
|
||||
<key>scope</key>
|
||||
<string>markup.heading</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#fec758ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup Setext Header</string>
|
||||
<key>scope</key>
|
||||
<string>markup.heading.setext</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#fec758ff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
|
||||
|
||||
|
||||
</array>
|
||||
<key>uuid</key>
|
||||
<string>AC0A28C5-65E6-42A6-AD05-4D01735652EE</string>
|
||||
<key>colorSpaceName</key>
|
||||
<string>sRGB</string>
|
||||
<key>semanticClass</key>
|
||||
<string>theme.dark.django</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -7,6 +7,13 @@
|
|||
"foreground": "#93A1A1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "meta.embedded",
|
||||
"settings": {
|
||||
"background": "#002B36",
|
||||
"foreground": "#93A1A1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Comment",
|
||||
"scope": "comment",
|
||||
|
|
|
@ -7,6 +7,13 @@
|
|||
"foreground": "#657B83"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "meta.embedded",
|
||||
"settings": {
|
||||
"background": "#FDF6E3",
|
||||
"foreground": "#657B83"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Comment",
|
||||
"scope": "comment",
|
||||
|
|
|
@ -60,6 +60,13 @@
|
|||
"foreground": "#FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "meta.embedded",
|
||||
"settings": {
|
||||
"background": "#002451",
|
||||
"foreground": "#FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Comment",
|
||||
"scope": "comment",
|
||||
|
|
|
@ -251,7 +251,7 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
|
|||
const detail = details[0];
|
||||
item.detail = Previewer.plain(detail.displayParts);
|
||||
|
||||
item.documentation = Previewer.plainDocumentation(detail.documentation, detail.tags);
|
||||
item.documentation = Previewer.markdownDocumentation(detail.documentation, detail.tags);
|
||||
|
||||
if (detail && this.config.useCodeSnippetsOnMethodSuggest && (item.kind === CompletionItemKind.Function || item.kind === CompletionItemKind.Method)) {
|
||||
return this.isValidFunctionCompletionContext(filepath, item.position).then(shouldCompleteFunction => {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as Proto from '../protocol';
|
||||
import { MarkdownString } from 'vscode';
|
||||
|
||||
export function plain(parts: Proto.SymbolDisplayPart[]): string {
|
||||
if (!parts) {
|
||||
|
@ -24,20 +25,15 @@ export function tagsMarkdownPreview(tags: Proto.JSDocTagInfo[]): string {
|
|||
.join(' \n\n');
|
||||
}
|
||||
|
||||
function tagsPlainPreview(tags: Proto.JSDocTagInfo[]): string {
|
||||
return (tags || [])
|
||||
.map(tag => {
|
||||
const label = `@${tag.name}`;
|
||||
if (!tag.text) {
|
||||
return label;
|
||||
}
|
||||
return label + (tag.text.match(/\r\n|\n/g) ? '\n' + tag.text : ` — ${tag.text}`);
|
||||
})
|
||||
.join('\n\ngit');
|
||||
}
|
||||
|
||||
export function plainDocumentation(documentation: Proto.SymbolDisplayPart[], tags: Proto.JSDocTagInfo[]): string {
|
||||
const processedDocumentation = plain(documentation).replace(/\n([ \t]*\n)?/gm, (x) => x.length >= 2 ? '\n\n' : ' ');
|
||||
const parts = [processedDocumentation, tagsPlainPreview(tags)];
|
||||
return parts.filter(x => x).join('\n\n');
|
||||
export function markdownDocumentation(
|
||||
documentation: Proto.SymbolDisplayPart[],
|
||||
tags: Proto.JSDocTagInfo[]
|
||||
): MarkdownString {
|
||||
const out = new MarkdownString();
|
||||
out.appendMarkdown(plain(documentation));
|
||||
const tagsPreview = tagsMarkdownPreview(tags);
|
||||
if (tagsPreview) {
|
||||
out.appendMarkdown('\n\n' + tagsPreview);
|
||||
}
|
||||
return out;
|
||||
}
|
|
@ -59,7 +59,7 @@ export default class TypeScriptSignatureHelpProvider implements SignatureHelpPro
|
|||
}
|
||||
});
|
||||
signature.label += Previewer.plain(item.suffixDisplayParts);
|
||||
signature.documentation = Previewer.plainDocumentation(item.documentation, item.tags);
|
||||
signature.documentation = Previewer.markdownDocumentation(item.documentation, item.tags);
|
||||
result.signatures.push(signature);
|
||||
});
|
||||
|
||||
|
|
2
npm-shrinkwrap.json
generated
2
npm-shrinkwrap.json
generated
|
@ -574,7 +574,7 @@
|
|||
"xterm": {
|
||||
"version": "3.0.0",
|
||||
"from": "Tyriar/xterm.js#vscode-release/1.17",
|
||||
"resolved": "git+https://github.com/Tyriar/xterm.js.git#fb7de4e8d90d20a94d3847ea857b5394a09bd771"
|
||||
"resolved": "git+https://github.com/Tyriar/xterm.js.git#c3039b4d63b5c0e4a0c993e04714ad62fd056185"
|
||||
},
|
||||
"yauzl": {
|
||||
"version": "2.8.0",
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
"gulp-replace": "^0.5.4",
|
||||
"gulp-shell": "^0.5.2",
|
||||
"gulp-sourcemaps": "^1.11.0",
|
||||
"gulp-tsb": "^2.0.4",
|
||||
"gulp-tsb": "2.0.4",
|
||||
"gulp-tslint": "^7.0.1",
|
||||
"gulp-uglify": "^3.0.0",
|
||||
"gulp-util": "^3.0.6",
|
||||
|
|
|
@ -411,8 +411,8 @@ export class IPCServer implements IChannelServer, IRoutingChannelClient, IDispos
|
|||
}
|
||||
|
||||
dispose(): void {
|
||||
this.channels = null;
|
||||
this.channelClients = null;
|
||||
this.channels = Object.create(null);
|
||||
this.channelClients = Object.create(null);
|
||||
this.onClientAdded.dispose();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ export class LaunchService implements ILaunchService {
|
|||
cli: args,
|
||||
userEnv,
|
||||
forceNewWindow: args['new-window'],
|
||||
preferNewWindow: !args['reuse-window'],
|
||||
preferNewWindow: !args['reuse-window'] && !args.wait,
|
||||
forceReuseWindow: args['reuse-window'],
|
||||
diffMode: args.diff,
|
||||
addMode: args.add
|
||||
|
|
|
@ -176,11 +176,6 @@ export class WindowsManager implements IWindowsMainService {
|
|||
state.folderPath = state.workspacePath;
|
||||
state.workspacePath = void 0;
|
||||
}
|
||||
|
||||
// TODO@Ben migration to new workspace ID
|
||||
if (state.workspace) {
|
||||
state.workspace.id = this.workspacesService.getWorkspaceId(state.workspace.configPath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -277,7 +272,6 @@ export class WindowsManager implements IWindowsMainService {
|
|||
private onBeforeQuit(): void {
|
||||
const currentWindowsState: ILegacyWindowsState = {
|
||||
openedWindows: [],
|
||||
openedFolders: [], // TODO@Ben migration so that old clients do not fail over data (prevents NPEs)
|
||||
lastPluginDevelopmentHostWindow: this.windowsState.lastPluginDevelopmentHostWindow,
|
||||
lastActiveWindow: this.lastClosedWindowState
|
||||
};
|
||||
|
|
|
@ -45,6 +45,9 @@
|
|||
|
||||
.monaco-editor .parameter-hints-widget .docs {
|
||||
padding: 0 10px 0 5px;
|
||||
}
|
||||
|
||||
.monaco-editor .parameter-hints-widget .docs .code {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ import { CharacterSet } from 'vs/editor/common/core/characterClassifier';
|
|||
import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions';
|
||||
import { ICursorSelectionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
|
||||
import { registerThemingParticipant, HIGH_CONTRAST } from 'vs/platform/theme/common/themeService';
|
||||
import { editorHoverBackground, editorHoverBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { editorHoverBackground, editorHoverBorder, textLinkForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { MarkdownRenderer } from 'vs/editor/contrib/markdown/browser/markdownRenderer';
|
||||
|
@ -507,4 +507,9 @@ registerThemingParticipant((theme, collector) => {
|
|||
if (background) {
|
||||
collector.addRule(`.monaco-editor .parameter-hints-widget { background-color: ${background}; }`);
|
||||
}
|
||||
|
||||
const link = theme.getColor(textLinkForeground);
|
||||
if (link) {
|
||||
collector.addRule(`.monaco-editor .parameter-hints-widget a { color: ${link}; }`);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -213,7 +213,6 @@
|
|||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.monaco-editor .suggest-widget .details > .monaco-scrollable-element > .body > .header > .type {
|
||||
|
@ -231,6 +230,11 @@
|
|||
padding: 4px 5px;
|
||||
}
|
||||
|
||||
.monaco-editor .suggest-widget .details > .monaco-scrollable-element > .body > .docs .code {
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.monaco-editor .suggest-widget .details > .monaco-scrollable-element > .body > p:empty {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import { alert } from 'vs/base/browser/ui/aria/aria';
|
|||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { attachListStyler } from 'vs/platform/theme/common/styler';
|
||||
import { IThemeService, ITheme, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { registerColor, editorWidgetBackground, listFocusBackground, activeContrastBorder, listHighlightForeground, editorForeground, editorWidgetBorder, focusBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { registerColor, editorWidgetBackground, listFocusBackground, activeContrastBorder, listHighlightForeground, editorForeground, editorWidgetBorder, focusBorder, textLinkForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { MarkdownRenderer } from 'vs/editor/contrib/markdown/browser/markdownRenderer';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
|
@ -1079,4 +1079,9 @@ registerThemingParticipant((theme, collector) => {
|
|||
if (foreground) {
|
||||
collector.addRule(`.monaco-editor .suggest-widget { color: ${foreground}; }`);
|
||||
}
|
||||
|
||||
const link = theme.getColor(textLinkForeground);
|
||||
if (link) {
|
||||
collector.addRule(`.monaco-editor .suggest-widget a { color: ${link}; }`);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -225,22 +225,6 @@ export class BackupMainService implements IBackupMainService {
|
|||
const hasBackups = this.hasBackupsSync(backupPath);
|
||||
const missingWorkspace = hasBackups && !fs.existsSync(workspacePath);
|
||||
|
||||
// TODO@Ben migration from old workspace ID to new
|
||||
if (hasBackups && !missingWorkspace && !isSingleFolderWorkspaceIdentifier(workspaceId) && workspaceId.id !== this.workspacesService.getWorkspaceId(workspacePath)) {
|
||||
staleBackupWorkspaces.push({ workspaceIdentifier: workspaceId, backupPath, target: workspaceOrFolder.target });
|
||||
|
||||
const identifier = { id: this.workspacesService.getWorkspaceId(workspacePath), configPath: workspacePath } as IWorkspaceIdentifier;
|
||||
this.pushBackupPathsSync(identifier, this.backups.rootWorkspaces);
|
||||
const newWorkspaceBackupPath = path.join(this.backupHome, identifier.id);
|
||||
try {
|
||||
fs.renameSync(backupPath, newWorkspaceBackupPath);
|
||||
} catch (ex) {
|
||||
this.logService.error(`Backup: Could not rename backup folder for legacy workspace: ${ex.toString()}`);
|
||||
|
||||
this.removeBackupPathSync(identifier, this.backups.rootWorkspaces);
|
||||
}
|
||||
}
|
||||
|
||||
// If the workspace/folder has no backups, make sure to delete it
|
||||
// If the workspace/folder has backups, but the target workspace is missing, convert backups to empty ones
|
||||
if (!hasBackups || missingWorkspace) {
|
||||
|
|
|
@ -204,7 +204,7 @@ export interface IEditorInput extends IDisposable {
|
|||
/**
|
||||
* Returns the display description of this input.
|
||||
*/
|
||||
getDescription(verbose?: boolean): string;
|
||||
getDescription(verbosity?: Verbosity): string;
|
||||
|
||||
/**
|
||||
* Returns the display title of this input.
|
||||
|
|
|
@ -79,6 +79,12 @@ export interface IView {
|
|||
name: string;
|
||||
}
|
||||
|
||||
export interface IColor {
|
||||
id: string;
|
||||
description: string;
|
||||
defaults: { light: string, dark: string, highContrast: string };
|
||||
}
|
||||
|
||||
export interface IExtensionContributions {
|
||||
commands?: ICommand[];
|
||||
configuration?: IConfiguration;
|
||||
|
@ -90,7 +96,9 @@ export interface IExtensionContributions {
|
|||
menus?: { [context: string]: IMenu[] };
|
||||
snippets?: ISnippet[];
|
||||
themes?: ITheme[];
|
||||
iconThemes?: ITheme[];
|
||||
views?: { [location: string]: IView[] };
|
||||
colors: IColor[];
|
||||
}
|
||||
|
||||
export interface IExtensionManifest {
|
||||
|
|
|
@ -780,6 +780,16 @@ export const SUPPORTED_ENCODINGS: { [encoding: string]: { labelLong: string; lab
|
|||
labelLong: 'Simplified Chinese (GB 2312)',
|
||||
labelShort: 'GB 2312',
|
||||
order: 45
|
||||
},
|
||||
cp865: {
|
||||
labelLong: 'Nordic DOS (CP 865)',
|
||||
labelShort: 'CP 865',
|
||||
order: 46
|
||||
},
|
||||
cp850: {
|
||||
labelLong: 'Western European DOS (CP 850)',
|
||||
labelShort: 'CP 850',
|
||||
order: 47
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -141,8 +141,7 @@ export class LifecycleService implements ILifecycleService {
|
|||
|
||||
// Windows/Linux: we quit when all windows have closed
|
||||
// Mac: we only quit when quit was requested
|
||||
// --wait: we quit when all windows are closed
|
||||
if (this.quitRequested || process.platform !== 'darwin' || this.environmentService.wait) {
|
||||
if (this.quitRequested || process.platform !== 'darwin') {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -105,7 +105,7 @@ export class ColorExtensionPoint {
|
|||
return;
|
||||
}
|
||||
let defaults = extension.defaults;
|
||||
if (typeof defaults !== 'object' || typeof defaults.light !== 'string' || typeof defaults.dark !== 'string' || typeof defaults.highContrast !== 'string') {
|
||||
if (!defaults || typeof defaults !== 'object' || typeof defaults.light !== 'string' || typeof defaults.dark !== 'string' || typeof defaults.highContrast !== 'string') {
|
||||
collector.error(nls.localize('invalid.defaults', "'configuration.colors.defaults' must be defined and must contain 'light', 'dark' and 'highContrast'"));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -19,15 +19,8 @@ import { ILogService } from 'vs/platform/log/common/log';
|
|||
import { isEqual, isEqualOrParent } from 'vs/base/common/paths';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
import { createHash } from 'crypto';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import * as json from 'vs/base/common/json';
|
||||
|
||||
// TODO@Ben migration
|
||||
export interface ILegacyStoredWorkspace {
|
||||
id: string;
|
||||
folders: string[];
|
||||
}
|
||||
|
||||
export class WorkspacesMainService implements IWorkspacesMainService {
|
||||
|
||||
public _serviceBrand: any;
|
||||
|
@ -108,13 +101,6 @@ export class WorkspacesMainService implements IWorkspacesMainService {
|
|||
throw new Error(`${path} cannot be parsed as JSON file (${error}).`);
|
||||
}
|
||||
|
||||
// TODO@Ben migration
|
||||
const legacyStoredWorkspace = (<any>storedWorkspace) as ILegacyStoredWorkspace;
|
||||
if (legacyStoredWorkspace.folders.some(folder => typeof folder === 'string')) {
|
||||
storedWorkspace.folders = legacyStoredWorkspace.folders.map(folder => ({ path: URI.parse(folder).fsPath }));
|
||||
writeFileSync(path, JSON.stringify(storedWorkspace, null, '\t'));
|
||||
}
|
||||
|
||||
// Filter out folders which do not have a path set
|
||||
if (Array.isArray(storedWorkspace.folders)) {
|
||||
storedWorkspace.folders = storedWorkspace.folders.filter(folder => !!folder.path);
|
||||
|
|
|
@ -20,7 +20,7 @@ import { RunOnceScheduler } from 'vs/base/common/async';
|
|||
import { isMacintosh } from 'vs/base/common/platform';
|
||||
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { Position, POSITIONS } from 'vs/platform/editor/common/editor';
|
||||
import { IEditorGroupService, ITabOptions, GroupArrangement, GroupOrientation } from 'vs/workbench/services/group/common/groupService';
|
||||
import { IEditorGroupService, IEditorTabOptions, GroupArrangement, GroupOrientation } from 'vs/workbench/services/group/common/groupService';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
|
@ -115,7 +115,7 @@ export class EditorGroupsControl extends Themable implements IEditorGroupsContro
|
|||
|
||||
private layoutVertically: boolean;
|
||||
|
||||
private tabOptions: ITabOptions;
|
||||
private tabOptions: IEditorTabOptions;
|
||||
|
||||
private silos: Builder[];
|
||||
private silosSize: number[];
|
||||
|
@ -225,7 +225,7 @@ export class EditorGroupsControl extends Themable implements IEditorGroupsContro
|
|||
this.extensionService.onReady().then(() => this.onExtensionsReady());
|
||||
}
|
||||
|
||||
private updateTabOptions(tabOptions: ITabOptions, refresh?: boolean): void {
|
||||
private updateTabOptions(tabOptions: IEditorTabOptions, refresh?: boolean): void {
|
||||
const tabCloseButton = this.tabOptions ? this.tabOptions.tabCloseButton : 'right';
|
||||
this.tabOptions = tabOptions;
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ import { BaseEditor, EditorDescriptor } from 'vs/workbench/browser/parts/editor/
|
|||
import { IEditorRegistry, Extensions as EditorExtensions, EditorInput, EditorOptions, ConfirmResult, IWorkbenchEditorConfiguration, IEditorDescriptor, TextEditorOptions, SideBySideEditorInput, TextCompareEditorVisible, TEXT_DIFF_EDITOR_ID } from 'vs/workbench/common/editor';
|
||||
import { EditorGroupsControl, Rochade, IEditorGroupsControl, ProgressState } from 'vs/workbench/browser/parts/editor/editorGroupsControl';
|
||||
import { WorkbenchProgressService } from 'vs/workbench/services/progress/browser/progressService';
|
||||
import { IEditorGroupService, GroupOrientation, GroupArrangement, ITabOptions, IMoveOptions } from 'vs/workbench/services/group/common/groupService';
|
||||
import { IEditorGroupService, GroupOrientation, GroupArrangement, IEditorTabOptions, IMoveOptions } from 'vs/workbench/services/group/common/groupService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IEditorPart } from 'vs/workbench/services/editor/browser/editorService';
|
||||
import { IPartService } from 'vs/workbench/services/part/common/partService';
|
||||
|
@ -91,7 +91,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService
|
|||
private editorGroupsControl: IEditorGroupsControl;
|
||||
private memento: object;
|
||||
private stacks: EditorStacksModel;
|
||||
private tabOptions: ITabOptions;
|
||||
private tabOptions: IEditorTabOptions;
|
||||
private forceHideTabs: boolean;
|
||||
private doNotFireTabOptionsChanged: boolean;
|
||||
private revealIfOpen: boolean;
|
||||
|
@ -100,7 +100,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService
|
|||
private _onEditorsMoved: Emitter<void>;
|
||||
private _onEditorOpenFail: Emitter<EditorInput>;
|
||||
private _onGroupOrientationChanged: Emitter<void>;
|
||||
private _onTabOptionsChanged: Emitter<ITabOptions>;
|
||||
private _onTabOptionsChanged: Emitter<IEditorTabOptions>;
|
||||
|
||||
private textCompareEditorVisible: IContextKey<boolean>;
|
||||
|
||||
|
@ -134,7 +134,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService
|
|||
this._onEditorsMoved = new Emitter<void>();
|
||||
this._onEditorOpenFail = new Emitter<EditorInput>();
|
||||
this._onGroupOrientationChanged = new Emitter<void>();
|
||||
this._onTabOptionsChanged = new Emitter<ITabOptions>();
|
||||
this._onTabOptionsChanged = new Emitter<IEditorTabOptions>();
|
||||
|
||||
this.visibleEditors = [];
|
||||
|
||||
|
@ -159,7 +159,8 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService
|
|||
previewEditors: editorConfig.enablePreview,
|
||||
showIcons: editorConfig.showIcons,
|
||||
showTabs: editorConfig.showTabs,
|
||||
tabCloseButton: editorConfig.tabCloseButton
|
||||
tabCloseButton: editorConfig.tabCloseButton,
|
||||
labelFormat: editorConfig.labelFormat,
|
||||
};
|
||||
|
||||
this.revealIfOpen = editorConfig.revealIfOpen;
|
||||
|
@ -170,7 +171,8 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService
|
|||
previewEditors: true,
|
||||
showIcons: false,
|
||||
showTabs: true,
|
||||
tabCloseButton: 'right'
|
||||
tabCloseButton: 'right',
|
||||
labelFormat: 'default',
|
||||
};
|
||||
|
||||
this.revealIfOpen = false;
|
||||
|
@ -221,7 +223,8 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService
|
|||
previewEditors: newPreviewEditors,
|
||||
showIcons: editorConfig.showIcons,
|
||||
tabCloseButton: editorConfig.tabCloseButton,
|
||||
showTabs: this.forceHideTabs ? false : editorConfig.showTabs
|
||||
showTabs: this.forceHideTabs ? false : editorConfig.showTabs,
|
||||
labelFormat: editorConfig.labelFormat,
|
||||
};
|
||||
|
||||
if (!this.doNotFireTabOptionsChanged && !objects.equals(oldTabOptions, this.tabOptions)) {
|
||||
|
@ -278,11 +281,11 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService
|
|||
return this._onGroupOrientationChanged.event;
|
||||
}
|
||||
|
||||
public get onTabOptionsChanged(): Event<ITabOptions> {
|
||||
public get onTabOptionsChanged(): Event<IEditorTabOptions> {
|
||||
return this._onTabOptionsChanged.event;
|
||||
}
|
||||
|
||||
public getTabOptions(): ITabOptions {
|
||||
public getTabOptions(): IEditorTabOptions {
|
||||
return this.tabOptions;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ import { IEditor as IBaseEditor, IEditorInput } from 'vs/platform/editor/common/
|
|||
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IQuickOpenService, IPickOpenEntry, IFilePickOpenEntry } from 'vs/platform/quickOpen/common/quickOpen';
|
||||
import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration';
|
||||
import { SUPPORTED_ENCODINGS, IFileService } from 'vs/platform/files/common/files';
|
||||
import { SUPPORTED_ENCODINGS, IFileService, IFilesConfiguration } from 'vs/platform/files/common/files';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
|
@ -46,6 +46,7 @@ import { ITextFileService } from 'vs/workbench/services/textfile/common/textfile
|
|||
import { getCodeEditor as getEditorWidget } from 'vs/editor/common/services/codeEditorService';
|
||||
import { ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
|
||||
import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions';
|
||||
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
|
||||
|
||||
// TODO@Sandeep layer breaker
|
||||
// tslint:disable-next-line:import-patterns
|
||||
|
@ -1058,7 +1059,7 @@ export class ChangeEncodingAction extends Action {
|
|||
actionLabel: string,
|
||||
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
|
||||
@IQuickOpenService private quickOpenService: IQuickOpenService,
|
||||
@IWorkspaceConfigurationService private configurationService: IWorkspaceConfigurationService,
|
||||
@ITextResourceConfigurationService private textResourceConfigurationService: ITextResourceConfigurationService,
|
||||
@IFileService private fileService: IFileService
|
||||
) {
|
||||
super(actionId, actionLabel);
|
||||
|
@ -1112,7 +1113,10 @@ export class ChangeEncodingAction extends Action {
|
|||
})
|
||||
.then((guessedEncoding: string) => {
|
||||
const isReopenWithEncoding = (action === reopenWithEncodingPick);
|
||||
const configuredEncoding = this.configurationService.lookup('files.encoding', { resource }).value;
|
||||
|
||||
const config = this.textResourceConfigurationService.getConfiguration(resource) as IFilesConfiguration;
|
||||
const configuredEncoding = config && config.files && config.files.encoding;
|
||||
|
||||
let directMatchIndex: number;
|
||||
let aliasMatchIndex: number;
|
||||
|
||||
|
|
|
@ -118,7 +118,15 @@ export class NoTabsTitleControl extends TitleControl {
|
|||
// Editor Label
|
||||
const resource = toResource(editor, { supportSideBySide: true });
|
||||
const name = editor.getName() || '';
|
||||
const description = isActive ? (editor.getDescription() || '') : '';
|
||||
|
||||
const labelFormat = this.editorGroupService.getTabOptions().labelFormat;
|
||||
let description: string;
|
||||
if (labelFormat === 'default' && !isActive) {
|
||||
description = ''; // hide description when group is not active and style is 'default'
|
||||
} else {
|
||||
description = editor.getDescription(this.getVerbosity(labelFormat)) || '';
|
||||
}
|
||||
|
||||
let title = editor.getTitle(Verbosity.LONG);
|
||||
if (description === title) {
|
||||
title = ''; // dont repeat what is already shown
|
||||
|
@ -134,4 +142,12 @@ export class NoTabsTitleControl extends TitleControl {
|
|||
// Update Editor Actions Toolbar
|
||||
this.updateEditorActionsToolbar();
|
||||
}
|
||||
|
||||
private getVerbosity(style: string): Verbosity {
|
||||
switch (style) {
|
||||
case 'short': return Verbosity.SHORT;
|
||||
case 'long': return Verbosity.LONG;
|
||||
default: return Verbosity.MEDIUM;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -47,11 +47,12 @@ import { IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
|
|||
|
||||
interface IEditorInputLabel {
|
||||
name: string;
|
||||
hasAmbiguousName?: boolean;
|
||||
description?: string;
|
||||
title?: string;
|
||||
}
|
||||
|
||||
type AugmentedLabel = IEditorInputLabel & { editor: IEditorInput };
|
||||
|
||||
export class TabsTitleControl extends TitleControl {
|
||||
private titleContainer: HTMLElement;
|
||||
private tabsContainer: HTMLElement;
|
||||
|
@ -264,7 +265,7 @@ export class TabsTitleControl extends TitleControl {
|
|||
|
||||
// Compute labels and protect against duplicates
|
||||
const editorsOfGroup = this.context.getEditors();
|
||||
const labels = this.getUniqueTabLabels(editorsOfGroup);
|
||||
const labels = this.getTabLabels(editorsOfGroup);
|
||||
|
||||
// Tab label and styles
|
||||
editorsOfGroup.forEach((editor, index) => {
|
||||
|
@ -276,7 +277,7 @@ export class TabsTitleControl extends TitleControl {
|
|||
|
||||
const label = labels[index];
|
||||
const name = label.name;
|
||||
const description = label.hasAmbiguousName && label.description ? label.description : '';
|
||||
const description = label.description || '';
|
||||
const title = label.title || '';
|
||||
|
||||
// Container
|
||||
|
@ -338,56 +339,108 @@ export class TabsTitleControl extends TitleControl {
|
|||
this.layout();
|
||||
}
|
||||
|
||||
private getUniqueTabLabels(editors: IEditorInput[]): IEditorInputLabel[] {
|
||||
const labels: IEditorInputLabel[] = [];
|
||||
|
||||
const mapLabelToDuplicates = new Map<string, IEditorInputLabel[]>();
|
||||
const mapLabelAndDescriptionToDuplicates = new Map<string, IEditorInputLabel[]>();
|
||||
private getTabLabels(editors: IEditorInput[]): IEditorInputLabel[] {
|
||||
const labelFormat = this.editorGroupService.getTabOptions().labelFormat;
|
||||
const { verbosity, shortenDuplicates } = this.getLabelConfigFlags(labelFormat);
|
||||
|
||||
// Build labels and descriptions for each editor
|
||||
editors.forEach(editor => {
|
||||
const name = editor.getName();
|
||||
let description = editor.getDescription();
|
||||
if (mapLabelAndDescriptionToDuplicates.has(`${name}${description}`)) {
|
||||
description = editor.getDescription(true); // try verbose description if name+description already exists
|
||||
}
|
||||
const labels = editors.map(editor => ({
|
||||
editor,
|
||||
name: editor.getName(),
|
||||
description: editor.getDescription(verbosity),
|
||||
title: editor.getTitle(Verbosity.LONG)
|
||||
}));
|
||||
|
||||
const item: IEditorInputLabel = {
|
||||
name,
|
||||
description,
|
||||
title: editor.getTitle(Verbosity.LONG)
|
||||
};
|
||||
labels.push(item);
|
||||
|
||||
getOrSet(mapLabelToDuplicates, item.name, []).push(item);
|
||||
|
||||
if (typeof description === 'string') {
|
||||
getOrSet(mapLabelAndDescriptionToDuplicates, `${item.name}${item.description}`, []).push(item);
|
||||
}
|
||||
});
|
||||
|
||||
// Mark duplicates and shorten their descriptions
|
||||
mapLabelToDuplicates.forEach(duplicates => {
|
||||
if (duplicates.length > 1) {
|
||||
duplicates = duplicates.filter(d => {
|
||||
// we could have items with equal label and description. in that case it does not make much
|
||||
// sense to produce a shortened version of the label, so we ignore those kind of items
|
||||
return typeof d.description === 'string' && mapLabelAndDescriptionToDuplicates.get(`${d.name}${d.description}`).length === 1;
|
||||
});
|
||||
|
||||
if (duplicates.length > 1) {
|
||||
const shortenedDescriptions = shorten(duplicates.map(duplicate => duplicate.description));
|
||||
duplicates.forEach((duplicate, i) => {
|
||||
duplicate.description = shortenedDescriptions[i];
|
||||
duplicate.hasAmbiguousName = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
// Shorten labels as needed
|
||||
if (shortenDuplicates) {
|
||||
this.shortenTabLabels(labels);
|
||||
}
|
||||
|
||||
return labels;
|
||||
}
|
||||
|
||||
private shortenTabLabels(labels: AugmentedLabel[]): void {
|
||||
|
||||
// Gather duplicate titles, while filtering out invalid descriptions
|
||||
const mapTitleToDuplicates = new Map<string, AugmentedLabel[]>();
|
||||
for (const label of labels) {
|
||||
if (typeof label.description === 'string' && label.description) {
|
||||
getOrSet(mapTitleToDuplicates, label.name, []).push(label);
|
||||
} else {
|
||||
label.description = '';
|
||||
}
|
||||
}
|
||||
|
||||
// Identify duplicate titles and shorten descriptions
|
||||
mapTitleToDuplicates.forEach(duplicateTitles => {
|
||||
|
||||
// Remove description if the title isn't duplicated
|
||||
if (duplicateTitles.length === 1) {
|
||||
duplicateTitles[0].description = '';
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Identify duplicate descriptions
|
||||
const mapDescriptionToDuplicates = new Map<string, AugmentedLabel[]>();
|
||||
for (const label of duplicateTitles) {
|
||||
getOrSet(mapDescriptionToDuplicates, label.description, []).push(label);
|
||||
}
|
||||
|
||||
// For editors with duplicate descriptions, check whether any long descriptions differ
|
||||
let useLongDescriptions = false;
|
||||
mapDescriptionToDuplicates.forEach((duplicateDescriptions, name) => {
|
||||
if (!useLongDescriptions && duplicateDescriptions.length > 1) {
|
||||
const [first, ...rest] = duplicateDescriptions.map(({ editor }) => editor.getDescription(Verbosity.LONG));
|
||||
useLongDescriptions = rest.some(description => description !== first);
|
||||
}
|
||||
});
|
||||
|
||||
// If so, replace all descriptions with long descriptions
|
||||
if (useLongDescriptions) {
|
||||
mapDescriptionToDuplicates.clear();
|
||||
duplicateTitles.forEach(label => {
|
||||
label.description = label.editor.getDescription(Verbosity.LONG);
|
||||
getOrSet(mapDescriptionToDuplicates, label.description, []).push(label);
|
||||
});
|
||||
}
|
||||
|
||||
// Obtain final set of descriptions
|
||||
const descriptions: string[] = [];
|
||||
mapDescriptionToDuplicates.forEach((_, description) => descriptions.push(description));
|
||||
|
||||
// Remove description if all descriptions are identical
|
||||
if (descriptions.length === 1) {
|
||||
for (const label of mapDescriptionToDuplicates.get(descriptions[0])) {
|
||||
label.description = '';
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Shorten descriptions
|
||||
const shortenedDescriptions = shorten(descriptions);
|
||||
descriptions.forEach((description, i) => {
|
||||
for (const label of mapDescriptionToDuplicates.get(description)) {
|
||||
label.description = shortenedDescriptions[i];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private getLabelConfigFlags(value: string) {
|
||||
switch (value) {
|
||||
case 'short':
|
||||
return { verbosity: Verbosity.SHORT, shortenDuplicates: false };
|
||||
case 'medium':
|
||||
return { verbosity: Verbosity.MEDIUM, shortenDuplicates: false };
|
||||
case 'long':
|
||||
return { verbosity: Verbosity.LONG, shortenDuplicates: false };
|
||||
default:
|
||||
return { verbosity: Verbosity.MEDIUM, shortenDuplicates: true };
|
||||
}
|
||||
}
|
||||
|
||||
protected doRefresh(): void {
|
||||
const group = this.context;
|
||||
const editor = group && group.activeEditor;
|
||||
|
|
|
@ -265,6 +265,17 @@ export class TitlebarPart extends Part implements ITitleService {
|
|||
}
|
||||
});
|
||||
|
||||
// Since the title area is used to drag the window, we do not want to steal focus from the
|
||||
// currently active element. So we restore focus after a timeout back to where it was.
|
||||
this.titleContainer.on([DOM.EventType.MOUSE_DOWN], () => {
|
||||
const active = document.activeElement;
|
||||
setTimeout(() => {
|
||||
if (active instanceof HTMLElement) {
|
||||
active.focus();
|
||||
}
|
||||
}, 0 /* need a timeout because we are in capture phase */);
|
||||
}, void 0, true /* use capture to know the currently active element properly */);
|
||||
|
||||
return this.titleContainer;
|
||||
}
|
||||
|
||||
|
|
|
@ -176,7 +176,7 @@ export abstract class EditorInput implements IEditorInput {
|
|||
* Returns the description of this input that can be shown to the user. Examples include showing the description of
|
||||
* the input above the editor area to the side of the name of the input.
|
||||
*/
|
||||
public getDescription(): string {
|
||||
public getDescription(verbosity?: Verbosity): string {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -806,7 +806,8 @@ export interface IWorkbenchEditorConfiguration {
|
|||
closeOnFileDelete: boolean;
|
||||
openPositioning: 'left' | 'right' | 'first' | 'last';
|
||||
revealIfOpen: boolean;
|
||||
swipeToNavigate: boolean
|
||||
swipeToNavigate: boolean,
|
||||
labelFormat: 'default' | 'short' | 'medium' | 'long';
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import Event, { Emitter } from 'vs/base/common/event';
|
|||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { telemetryURIDescriptor } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { Verbosity } from 'vs/platform/editor/common/editor';
|
||||
|
||||
/**
|
||||
* An editor input to be used for untitled text buffers.
|
||||
|
@ -36,6 +37,14 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport
|
|||
|
||||
private toUnbind: IDisposable[];
|
||||
|
||||
private shortDescription: string;
|
||||
private mediumDescription: string;
|
||||
private longDescription: string;
|
||||
|
||||
private shortTitle: string;
|
||||
private mediumTitle: string;
|
||||
private longTitle: string;
|
||||
|
||||
constructor(
|
||||
private resource: URI,
|
||||
hasAssociatedFilePath: boolean,
|
||||
|
@ -88,8 +97,47 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport
|
|||
return this.hasAssociatedFilePath ? paths.basename(this.resource.fsPath) : this.resource.fsPath;
|
||||
}
|
||||
|
||||
public getDescription(): string {
|
||||
return this.hasAssociatedFilePath ? labels.getPathLabel(paths.dirname(this.resource.fsPath), this.contextService, this.environmentService) : null;
|
||||
public getDescription(verbosity: Verbosity = Verbosity.MEDIUM): string {
|
||||
if (!this.hasAssociatedFilePath) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let description: string;
|
||||
switch (verbosity) {
|
||||
case Verbosity.SHORT:
|
||||
description = this.shortDescription ? this.shortDescription : (this.shortDescription = paths.basename(labels.getPathLabel(paths.dirname(this.resource.fsPath), void 0, this.environmentService)));
|
||||
break;
|
||||
case Verbosity.LONG:
|
||||
description = this.longDescription ? this.longDescription : (this.longDescription = labels.getPathLabel(paths.dirname(this.resource.fsPath), void 0, this.environmentService));
|
||||
break;
|
||||
case Verbosity.MEDIUM:
|
||||
default:
|
||||
description = this.mediumDescription ? this.mediumDescription : (this.mediumDescription = labels.getPathLabel(paths.dirname(this.resource.fsPath), this.contextService, this.environmentService));
|
||||
break;
|
||||
}
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
public getTitle(verbosity: Verbosity): string {
|
||||
if (!this.hasAssociatedFilePath) {
|
||||
return this.getName();
|
||||
}
|
||||
|
||||
let title: string;
|
||||
switch (verbosity) {
|
||||
case Verbosity.SHORT:
|
||||
title = this.shortTitle ? this.shortTitle : (this.shortTitle = this.getName());
|
||||
break;
|
||||
case Verbosity.MEDIUM:
|
||||
title = this.mediumTitle ? this.mediumTitle : (this.mediumTitle = labels.getPathLabel(this.resource, this.contextService, this.environmentService));
|
||||
break;
|
||||
case Verbosity.LONG:
|
||||
title = this.longTitle ? this.longTitle : (this.longTitle = labels.getPathLabel(this.resource, void 0, this.environmentService));
|
||||
break;
|
||||
}
|
||||
|
||||
return title;
|
||||
}
|
||||
|
||||
public isDirty(): boolean {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IEncodingSupport } from 'vs/workbench/common/editor';
|
||||
import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel';
|
||||
|
@ -12,7 +12,6 @@ import URI from 'vs/base/common/uri';
|
|||
import { PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRegistry';
|
||||
import { EndOfLinePreference } from 'vs/editor/common/editorCommon';
|
||||
import { IFilesConfiguration, CONTENT_CHANGE_EVENT_BUFFER_DELAY } from 'vs/platform/files/common/files';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { IMode } from 'vs/editor/common/modes';
|
||||
|
@ -20,13 +19,13 @@ import Event, { Emitter } from 'vs/base/common/event';
|
|||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { IBackupFileService, BACKUP_FILE_RESOLVE_OPTIONS } from 'vs/workbench/services/backup/common/backup';
|
||||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
|
||||
|
||||
export class UntitledEditorModel extends BaseTextEditorModel implements IEncodingSupport {
|
||||
|
||||
public static DEFAULT_CONTENT_CHANGE_BUFFER_DELAY = CONTENT_CHANGE_EVENT_BUFFER_DELAY;
|
||||
|
||||
private textModelChangeListener: IDisposable;
|
||||
private configurationChangeListener: IDisposable;
|
||||
private toDispose: IDisposable[];
|
||||
|
||||
private dirty: boolean;
|
||||
private _onDidChangeContent: Emitter<void>;
|
||||
|
@ -49,18 +48,25 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin
|
|||
@IModelService modelService: IModelService,
|
||||
@IBackupFileService private backupFileService: IBackupFileService,
|
||||
@ITextFileService private textFileService: ITextFileService,
|
||||
@IConfigurationService private configurationService: IConfigurationService
|
||||
@ITextResourceConfigurationService private configurationService: ITextResourceConfigurationService
|
||||
) {
|
||||
super(modelService, modeService);
|
||||
|
||||
this.dirty = false;
|
||||
this.versionId = 0;
|
||||
this.toDispose = [];
|
||||
|
||||
this._onDidChangeContent = new Emitter<void>();
|
||||
this.toDispose.push(this._onDidChangeContent);
|
||||
|
||||
this._onDidChangeDirty = new Emitter<void>();
|
||||
this.toDispose.push(this._onDidChangeDirty);
|
||||
|
||||
this._onDidChangeEncoding = new Emitter<void>();
|
||||
this.toDispose.push(this._onDidChangeEncoding);
|
||||
|
||||
this.contentChangeEventScheduler = new RunOnceScheduler(() => this._onDidChangeContent.fire(), UntitledEditorModel.DEFAULT_CONTENT_CHANGE_BUFFER_DELAY);
|
||||
this.toDispose.push(this.contentChangeEventScheduler);
|
||||
|
||||
this.registerListeners();
|
||||
}
|
||||
|
@ -88,11 +94,20 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin
|
|||
private registerListeners(): void {
|
||||
|
||||
// Config Changes
|
||||
this.configurationChangeListener = this.configurationService.onDidUpdateConfiguration(e => this.onConfigurationChange(this.configurationService.getConfiguration<IFilesConfiguration>()));
|
||||
this.toDispose.push(this.configurationService.onDidUpdateConfiguration(e => this.onConfigurationChange()));
|
||||
}
|
||||
|
||||
private onConfigurationChange(configuration: IFilesConfiguration): void {
|
||||
this.configuredEncoding = configuration && configuration.files && configuration.files.encoding;
|
||||
private onConfigurationChange(): void {
|
||||
const configuration = this.configurationService.getConfiguration<IFilesConfiguration>(this.resource);
|
||||
const configuredEncoding = configuration && configuration.files && configuration.files.encoding;
|
||||
|
||||
if (this.configuredEncoding !== configuredEncoding) {
|
||||
this.configuredEncoding = configuredEncoding;
|
||||
|
||||
if (!this.preferredEncoding) {
|
||||
this._onDidChangeEncoding.fire(); // do not fire event if we have a preferred encoding set
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public getVersionId(): number {
|
||||
|
@ -170,13 +185,16 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin
|
|||
this.setDirty(this.hasAssociatedFilePath || !!backupContent);
|
||||
|
||||
return this.doLoad(backupContent || this.initialValue || '').then(model => {
|
||||
const configuration = this.configurationService.getConfiguration<IFilesConfiguration>();
|
||||
const configuration = this.configurationService.getConfiguration<IFilesConfiguration>(this.resource);
|
||||
|
||||
// Encoding
|
||||
this.configuredEncoding = configuration && configuration.files && configuration.files.encoding;
|
||||
|
||||
// Listen to content changes
|
||||
this.textModelChangeListener = this.textEditorModel.onDidChangeContent(() => this.onModelContentChanged());
|
||||
this.toDispose.push(this.textEditorModel.onDidChangeContent(() => this.onModelContentChanged()));
|
||||
|
||||
// Listen to mode changes
|
||||
this.toDispose.push(this.textEditorModel.onDidChangeLanguage(() => this.onModelModeChanged()));
|
||||
|
||||
return model;
|
||||
});
|
||||
|
@ -216,23 +234,13 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin
|
|||
this.contentChangeEventScheduler.schedule();
|
||||
}
|
||||
|
||||
private onModelModeChanged(): void {
|
||||
this.onConfigurationChange(); // mode change can have impact on config
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
super.dispose();
|
||||
|
||||
if (this.textModelChangeListener) {
|
||||
this.textModelChangeListener.dispose();
|
||||
this.textModelChangeListener = null;
|
||||
}
|
||||
|
||||
if (this.configurationChangeListener) {
|
||||
this.configurationChangeListener.dispose();
|
||||
this.configurationChangeListener = null;
|
||||
}
|
||||
|
||||
this.contentChangeEventScheduler.dispose();
|
||||
|
||||
this._onDidChangeContent.dispose();
|
||||
this._onDidChangeDirty.dispose();
|
||||
this._onDidChangeEncoding.dispose();
|
||||
this.toDispose = dispose(this.toDispose);
|
||||
}
|
||||
}
|
|
@ -129,6 +129,23 @@ let workbenchProperties: { [path: string]: IJSONSchema; } = {
|
|||
'description': nls.localize('showEditorTabs', "Controls if opened editors should show in tabs or not."),
|
||||
'default': true
|
||||
},
|
||||
'workbench.editor.labelFormat': {
|
||||
'type': 'string',
|
||||
'enum': ['default', 'short', 'medium', 'long'],
|
||||
'enumDescriptions': [
|
||||
nls.localize('workbench.editor.labelFormat.default', "Show the name of the file. When tabs are enabled and two files have the same name in one group the distinguinshing sections of each file's path is added. When tabs are disabled, the path relative to workspace root is shown if the editor is active."),
|
||||
nls.localize('workbench.editor.labelFormat.short', "Show the name of the file followed by it's directory name."),
|
||||
nls.localize('workbench.editor.labelFormat.medium', "Show the name of the file followed by it's path relative to the workspace root."),
|
||||
nls.localize('workbench.editor.labelFormat.long', "Show the name of the file followed by it's absolute path.")
|
||||
],
|
||||
'default': 'default',
|
||||
'description': nls.localize({ comment: ['This is the description for a setting. Values surrounded by parenthesis are not to be translated.'], key: 'tabDescription' },
|
||||
`Controls the format of the label for an editor. Changing this setting can for example make it easier to understand the location of a file:
|
||||
- short: 'parent'
|
||||
- medium: 'workspace/src/parent'
|
||||
- long: '/home/user/workspace/src/parent'
|
||||
- default: '.../parent', when another tab shares the same title, or the relative workspace path if tabs are disabled`),
|
||||
},
|
||||
'workbench.editor.tabCloseButton': {
|
||||
'type': 'string',
|
||||
'enum': ['left', 'right', 'off'],
|
||||
|
|
|
@ -20,7 +20,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace
|
|||
import { EmptyWorkspaceServiceImpl, WorkspaceServiceImpl, WorkspaceService } from 'vs/workbench/services/configuration/node/configuration';
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import { realpath, readFile, writeFile } from 'vs/base/node/pfs';
|
||||
import { realpath } from 'vs/base/node/pfs';
|
||||
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
|
||||
import path = require('path');
|
||||
import gracefulFs = require('graceful-fs');
|
||||
|
@ -42,7 +42,6 @@ import { WorkspacesChannelClient } from 'vs/platform/workspaces/common/workspace
|
|||
import { IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { ICredentialsService } from 'vs/platform/credentials/common/credentials';
|
||||
import { CredentialsChannelClient } from 'vs/platform/credentials/node/credentialsIpc';
|
||||
import { migrateStorageToMultiRootWorkspace } from 'vs/platform/storage/common/migration';
|
||||
|
||||
import fs = require('fs');
|
||||
gracefulFs.gracefulify(fs); // enable gracefulFs
|
||||
|
@ -112,43 +111,18 @@ function openWorkbench(configuration: IWindowConfiguration): TPromise<void> {
|
|||
}
|
||||
|
||||
function createAndInitializeWorkspaceService(configuration: IWindowConfiguration, environmentService: EnvironmentService, workspacesService: IWorkspacesService): TPromise<WorkspaceService> {
|
||||
return migrateWorkspaceId(configuration).then(() => {
|
||||
return validateWorkspacePath(configuration).then(() => {
|
||||
let workspaceService: WorkspaceServiceImpl | EmptyWorkspaceServiceImpl;
|
||||
if (configuration.workspace || configuration.folderPath) {
|
||||
workspaceService = new WorkspaceServiceImpl(configuration.workspace || configuration.folderPath, environmentService, workspacesService);
|
||||
} else {
|
||||
workspaceService = new EmptyWorkspaceServiceImpl(environmentService);
|
||||
}
|
||||
return validateWorkspacePath(configuration).then(() => {
|
||||
let workspaceService: WorkspaceServiceImpl | EmptyWorkspaceServiceImpl;
|
||||
if (configuration.workspace || configuration.folderPath) {
|
||||
workspaceService = new WorkspaceServiceImpl(configuration.workspace || configuration.folderPath, environmentService, workspacesService);
|
||||
} else {
|
||||
workspaceService = new EmptyWorkspaceServiceImpl(environmentService);
|
||||
}
|
||||
|
||||
return workspaceService.initialize().then(() => workspaceService, error => new EmptyWorkspaceServiceImpl(environmentService));
|
||||
});
|
||||
return workspaceService.initialize().then(() => workspaceService, error => new EmptyWorkspaceServiceImpl(environmentService));
|
||||
});
|
||||
}
|
||||
|
||||
// TODO@Ben migration
|
||||
function migrateWorkspaceId(configuration: IWindowConfiguration): TPromise<void> {
|
||||
if (!configuration.workspace || !configuration.workspace.configPath) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
return readFile(configuration.workspace.configPath).then(data => {
|
||||
try {
|
||||
const raw = JSON.parse(data.toString());
|
||||
if (raw.id) {
|
||||
const previousWorkspaceId = raw.id;
|
||||
delete raw.id;
|
||||
|
||||
migrateStorageToMultiRootWorkspace(uri.from({ path: previousWorkspaceId, scheme: 'root' }).toString(), configuration.workspace, window.localStorage);
|
||||
|
||||
return writeFile(configuration.workspace.configPath, JSON.stringify(raw, null, '\t'));
|
||||
}
|
||||
} catch (error) { };
|
||||
|
||||
return void 0;
|
||||
}).then(() => void 0, () => void 0);
|
||||
}
|
||||
|
||||
function validateWorkspacePath(configuration: IWindowConfiguration): TPromise<void> {
|
||||
if (!configuration.folderPath) {
|
||||
return TPromise.as(null);
|
||||
|
|
|
@ -54,6 +54,7 @@ import { IContextKeyService, RawContextKey, ContextKeyExpr, IContextKey } from '
|
|||
import { Command, ICommandOptions } from 'vs/editor/common/editorCommonExtensions';
|
||||
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
|
||||
/** A context key that is set when an extension editor webview has focus. */
|
||||
export const KEYBINDING_CONTEXT_EXTENSIONEDITOR_WEBVIEW_FOCUS = new RawContextKey<boolean>('extensionEditorWebviewFocus', undefined);
|
||||
|
@ -428,7 +429,9 @@ export class ExtensionEditor extends BaseEditor {
|
|||
this.renderSettings(content, manifest, layout),
|
||||
this.renderCommands(content, manifest, layout),
|
||||
this.renderLanguages(content, manifest, layout),
|
||||
this.renderThemes(content, manifest, layout),
|
||||
this.renderColorThemes(content, manifest, layout),
|
||||
this.renderIconThemes(content, manifest, layout),
|
||||
this.renderColors(content, manifest, layout),
|
||||
this.renderJSONValidation(content, manifest, layout),
|
||||
this.renderDebuggers(content, manifest, layout),
|
||||
this.renderViews(content, manifest, layout)
|
||||
|
@ -536,6 +539,8 @@ export class ExtensionEditor extends BaseEditor {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private renderDebuggers(container: HTMLElement, manifest: IExtensionManifest, onDetailsToggle: Function): boolean {
|
||||
const contributes = manifest.contributes;
|
||||
const contrib = contributes && contributes.debuggers || [];
|
||||
|
@ -587,7 +592,7 @@ export class ExtensionEditor extends BaseEditor {
|
|||
return true;
|
||||
}
|
||||
|
||||
private renderThemes(container: HTMLElement, manifest: IExtensionManifest, onDetailsToggle: Function): boolean {
|
||||
private renderColorThemes(container: HTMLElement, manifest: IExtensionManifest, onDetailsToggle: Function): boolean {
|
||||
const contributes = manifest.contributes;
|
||||
const contrib = contributes && contributes.themes || [];
|
||||
|
||||
|
@ -596,7 +601,7 @@ export class ExtensionEditor extends BaseEditor {
|
|||
}
|
||||
|
||||
const details = $('details', { open: true, ontoggle: onDetailsToggle },
|
||||
$('summary', null, localize('themes', "Themes ({0})", contrib.length)),
|
||||
$('summary', null, localize('colorThemes', "Color Themes ({0})", contrib.length)),
|
||||
$('ul', null, ...contrib.map(theme => $('li', null, theme.label)))
|
||||
);
|
||||
|
||||
|
@ -604,6 +609,68 @@ export class ExtensionEditor extends BaseEditor {
|
|||
return true;
|
||||
}
|
||||
|
||||
private renderIconThemes(container: HTMLElement, manifest: IExtensionManifest, onDetailsToggle: Function): boolean {
|
||||
const contributes = manifest.contributes;
|
||||
const contrib = contributes && contributes.iconThemes || [];
|
||||
|
||||
if (!contrib.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const details = $('details', { open: true, ontoggle: onDetailsToggle },
|
||||
$('summary', null, localize('iconThemes', "Icon Themes ({0})", contrib.length)),
|
||||
$('ul', null, ...contrib.map(theme => $('li', null, theme.label)))
|
||||
);
|
||||
|
||||
append(container, details);
|
||||
return true;
|
||||
}
|
||||
|
||||
private renderColors(container: HTMLElement, manifest: IExtensionManifest, onDetailsToggle: Function): boolean {
|
||||
const contributes = manifest.contributes;
|
||||
const colors = contributes && contributes.colors;
|
||||
|
||||
if (!colors || !colors.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function colorPreview(colorReference: string): Node[] {
|
||||
let result: Node[] = [];
|
||||
if (colorReference && colorReference[0] === '#') {
|
||||
let color = Color.fromHex(colorReference);
|
||||
if (color) {
|
||||
result.push($('span', { class: 'colorBox', style: 'background-color: ' + Color.Format.CSS.format(color) }, ''));
|
||||
}
|
||||
}
|
||||
result.push($('code', null, colorReference));
|
||||
return result;
|
||||
}
|
||||
|
||||
const details = $('details', { open: true, ontoggle: onDetailsToggle },
|
||||
$('summary', null, localize('colors', "Colors ({0})", colors.length)),
|
||||
$('table', null,
|
||||
$('tr', null,
|
||||
$('th', null, localize('colorId', "Id")),
|
||||
$('th', null, localize('description', "Description")),
|
||||
$('th', null, localize('defaultDark', "Dark Default")),
|
||||
$('th', null, localize('defaultLight', "Light Default")),
|
||||
$('th', null, localize('defaultHC', "High Contrast Default"))
|
||||
),
|
||||
...colors.map(color => $('tr', null,
|
||||
$('td', null, $('code', null, color.id)),
|
||||
$('td', null, color.description),
|
||||
$('td', null, ...colorPreview(color.defaults.dark)),
|
||||
$('td', null, ...colorPreview(color.defaults.light)),
|
||||
$('td', null, ...colorPreview(color.defaults.highContrast))
|
||||
))
|
||||
)
|
||||
);
|
||||
|
||||
append(container, details);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private renderJSONValidation(container: HTMLElement, manifest: IExtensionManifest, onDetailsToggle: Function): boolean {
|
||||
const contributes = manifest.contributes;
|
||||
const contrib = contributes && contributes.jsonValidation || [];
|
||||
|
|
|
@ -223,6 +223,23 @@
|
|||
padding: 1px 4px;
|
||||
}
|
||||
|
||||
.extension-editor > .body > .content table .colorBox {
|
||||
box-sizing: border-box;
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
display: inline-block;
|
||||
border-width: 0.1em;
|
||||
border-style: solid;
|
||||
border-color: rgb(0, 0, 0);
|
||||
margin: 0em 0.2em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.vs-dark .extension-editor > .body > .content table .colorBox,
|
||||
.hc-black .extension-editor > .body > .content table .colorBox {
|
||||
border-color: rgb(238, 238, 238);
|
||||
}
|
||||
|
||||
.extension-editor .subcontent .monaco-tree-row .content .unknown-dependency {
|
||||
line-height: 62px;
|
||||
}
|
||||
|
|
|
@ -201,15 +201,18 @@ configurationRegistry.registerConfiguration({
|
|||
},
|
||||
'files.encoding': {
|
||||
'type': 'string',
|
||||
'overridable': true,
|
||||
'enum': Object.keys(SUPPORTED_ENCODINGS),
|
||||
'default': 'utf8',
|
||||
'description': nls.localize('encoding', "The default character set encoding to use when reading and writing files."),
|
||||
'scope': ConfigurationScope.RESOURCE
|
||||
'description': nls.localize('encoding', "The default character set encoding to use when reading and writing files. This setting can be configured per language too."),
|
||||
'scope': ConfigurationScope.RESOURCE,
|
||||
'enumDescriptions': Object.keys(SUPPORTED_ENCODINGS).map(key => SUPPORTED_ENCODINGS[key].labelLong)
|
||||
},
|
||||
'files.autoGuessEncoding': {
|
||||
'type': 'boolean',
|
||||
'overridable': true,
|
||||
'default': false,
|
||||
'description': nls.localize('autoGuessEncoding', "When enabled, will attempt to guess the character set encoding when opening files"),
|
||||
'description': nls.localize('autoGuessEncoding', "When enabled, will attempt to guess the character set encoding when opening files. This setting can be configured per language too."),
|
||||
'scope': ConfigurationScope.RESOURCE
|
||||
},
|
||||
'files.eol': {
|
||||
|
|
|
@ -32,8 +32,10 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput {
|
|||
private textModelReference: TPromise<IReference<ITextEditorModel>>;
|
||||
|
||||
private name: string;
|
||||
private description: string;
|
||||
private verboseDescription: string;
|
||||
|
||||
private shortDescription: string;
|
||||
private mediumDescription: string;
|
||||
private longDescription: string;
|
||||
|
||||
private shortTitle: string;
|
||||
private mediumTitle: string;
|
||||
|
@ -128,18 +130,22 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput {
|
|||
return this.decorateOrphanedFiles(this.name);
|
||||
}
|
||||
|
||||
public getDescription(verbose?: boolean): string {
|
||||
if (verbose) {
|
||||
if (!this.verboseDescription) {
|
||||
this.verboseDescription = labels.getPathLabel(paths.dirname(this.resource.fsPath), void 0, this.environmentService);
|
||||
}
|
||||
} else {
|
||||
if (!this.description) {
|
||||
this.description = labels.getPathLabel(paths.dirname(this.resource.fsPath), this.contextService, this.environmentService);
|
||||
}
|
||||
public getDescription(verbosity: Verbosity = Verbosity.MEDIUM): string {
|
||||
let description: string;
|
||||
switch (verbosity) {
|
||||
case Verbosity.SHORT:
|
||||
description = this.shortDescription ? this.shortDescription : (this.shortDescription = paths.basename(labels.getPathLabel(paths.dirname(this.resource.fsPath), void 0, this.environmentService)));
|
||||
break;
|
||||
case Verbosity.LONG:
|
||||
description = this.longDescription ? this.longDescription : (this.longDescription = labels.getPathLabel(paths.dirname(this.resource.fsPath), void 0, this.environmentService));
|
||||
break;
|
||||
case Verbosity.MEDIUM:
|
||||
default:
|
||||
description = this.mediumDescription ? this.mediumDescription : (this.mediumDescription = labels.getPathLabel(paths.dirname(this.resource.fsPath), this.contextService, this.environmentService));
|
||||
break;
|
||||
}
|
||||
|
||||
return verbose ? this.verboseDescription : this.description;
|
||||
return description;
|
||||
}
|
||||
|
||||
public getTitle(verbosity: Verbosity): string {
|
||||
|
@ -274,4 +280,4 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput {
|
|||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -33,6 +33,7 @@ import { QUICKOPEN_ACTION_ID, getQuickNavigateHandler } from 'vs/workbench/brows
|
|||
import { IQuickOpenRegistry, Extensions as QuickOpenExtensions, QuickOpenHandlerDescriptor } from 'vs/workbench/browser/quickopen';
|
||||
import { Scope, IActionBarRegistry, Extensions as ActionBarExtensions } from 'vs/workbench/browser/actions';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { TogglePanelAction } from 'vs/workbench/browser/parts/panel/panelActions';
|
||||
|
||||
const quickOpenRegistry = (<IQuickOpenRegistry>Registry.as(QuickOpenExtensions.Quickopen));
|
||||
|
||||
|
@ -230,6 +231,7 @@ configurationRegistry.registerConfiguration({
|
|||
NavigateLeftAction.ID,
|
||||
DeleteWordLeftTerminalAction.ID,
|
||||
DeleteWordRightTerminalAction.ID,
|
||||
TogglePanelAction.ID,
|
||||
'workbench.action.quickOpenView'
|
||||
].sort()
|
||||
},
|
||||
|
|
|
@ -412,10 +412,8 @@ export class TerminalInstance implements ITerminalInstance {
|
|||
}
|
||||
|
||||
public notifyFindWidgetFocusChanged(isFocused: boolean): void {
|
||||
// In order to support escape to close the find widget when the terminal
|
||||
// is focused terminalFocus needs to be true when either the terminal or
|
||||
// the find widget are focused.
|
||||
this._terminalFocusContextKey.set(isFocused || document.activeElement === this._xterm.textarea);
|
||||
const terminalFocused = !isFocused && (document.activeElement === this._xterm.textarea || document.activeElement === this._xterm.element);
|
||||
this._terminalFocusContextKey.set(terminalFocused);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
|
|
|
@ -20,9 +20,8 @@ const pathSeparatorClause = '\\/';
|
|||
// '":; are allowed in paths but they are often separators so ignore them
|
||||
// Also disallow \\ to prevent a catastropic backtracking case #24798
|
||||
const excludedPathCharactersClause = '[^\\0\\s!$`&*()\\[\\]+\'":;\\\\]';
|
||||
const escapedExcludedPathCharactersClause = '(\\\\s|\\\\!|\\\\$|\\\\`|\\\\&|\\\\*|(|)|\\+)';
|
||||
/** A regex that matches paths in the form /foo, ~/foo, ./foo, ../foo, foo/bar */
|
||||
const unixLocalLinkClause = '((' + pathPrefix + '|(' + excludedPathCharactersClause + '|' + escapedExcludedPathCharactersClause + ')+)?(' + pathSeparatorClause + '(' + excludedPathCharactersClause + '|' + escapedExcludedPathCharactersClause + ')+)+)';
|
||||
const unixLocalLinkClause = '((' + pathPrefix + '|(' + excludedPathCharactersClause + ')+)?(' + pathSeparatorClause + '(' + excludedPathCharactersClause + ')+)+)';
|
||||
|
||||
const winDrivePrefix = '[a-zA-Z]:';
|
||||
const winPathPrefix = '(' + winDrivePrefix + '|\\.\\.?|\\~)';
|
||||
|
|
|
@ -134,24 +134,25 @@ suite('Workbench - TerminalLinkHandler', () => {
|
|||
|
||||
const supportedLinkFormats: LinkFormatInfo[] = [
|
||||
{ urlFormat: '{0}' },
|
||||
{ urlFormat: '{0} on line {1}', line: '5' },
|
||||
{ urlFormat: '{0} on line {1}, column {2}', line: '5', column: '3' },
|
||||
{ urlFormat: '{0}:line {1}', line: '5' },
|
||||
{ urlFormat: '{0}:line {1}, column {2}', line: '5', column: '3' },
|
||||
{ urlFormat: '{0}({1})', line: '5' },
|
||||
{ urlFormat: '{0} ({1})', line: '5' },
|
||||
{ urlFormat: '{0}({1},{2})', line: '5', column: '3' },
|
||||
{ urlFormat: '{0} ({1},{2})', line: '5', column: '3' },
|
||||
{ urlFormat: '{0}:{1}', line: '5' },
|
||||
{ urlFormat: '{0}:{1}:{2}', line: '5', column: '3' },
|
||||
{ urlFormat: '{0}[{1}]', line: '5' },
|
||||
{ urlFormat: '{0} [{1}]', line: '5' },
|
||||
{ urlFormat: '{0}[{1},{2}]', line: '5', column: '3' },
|
||||
{ urlFormat: '{0} [{1},{2}]', line: '5', column: '3' }
|
||||
// { urlFormat: '{0} on line {1}', line: '5' },
|
||||
// { urlFormat: '{0} on line {1}, column {2}', line: '5', column: '3' },
|
||||
// { urlFormat: '{0}:line {1}', line: '5' },
|
||||
// { urlFormat: '{0}:line {1}, column {2}', line: '5', column: '3' },
|
||||
// { urlFormat: '{0}({1})', line: '5' },
|
||||
// { urlFormat: '{0} ({1})', line: '5' },
|
||||
// { urlFormat: '{0}({1},{2})', line: '5', column: '3' },
|
||||
// { urlFormat: '{0} ({1},{2})', line: '5', column: '3' },
|
||||
// { urlFormat: '{0}:{1}', line: '5' },
|
||||
// { urlFormat: '{0}:{1}:{2}', line: '5', column: '3' },
|
||||
// { urlFormat: '{0}[{1}]', line: '5' },
|
||||
// { urlFormat: '{0} [{1}]', line: '5' },
|
||||
// { urlFormat: '{0}[{1},{2}]', line: '5', column: '3' },
|
||||
// { urlFormat: '{0} [{1},{2}]', line: '5', column: '3' }
|
||||
];
|
||||
|
||||
linkUrls.forEach(linkUrl => {
|
||||
supportedLinkFormats.forEach(linkFormatInfo => {
|
||||
console.log('linkFormatInfo: ', linkFormatInfo);
|
||||
testLink(
|
||||
strings.format(linkFormatInfo.urlFormat, linkUrl, linkFormatInfo.line, linkFormatInfo.column),
|
||||
linkUrl,
|
||||
|
|
|
@ -19,7 +19,7 @@ import { FileService } from 'vs/workbench/services/files/node/fileService';
|
|||
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
|
||||
import { parseArgs } from 'vs/platform/environment/node/argv';
|
||||
import { RawTextSource } from 'vs/editor/common/model/textSource';
|
||||
import { TestContextService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { TestContextService, TestTextResourceConfigurationService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { Workspace } from 'vs/platform/workspace/common/workspace';
|
||||
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
|
||||
|
||||
|
@ -44,19 +44,18 @@ const fooFile = Uri.file(platform.isWindows ? 'c:\\Foo' : '/Foo');
|
|||
const barFile = Uri.file(platform.isWindows ? 'c:\\Bar' : '/Bar');
|
||||
const untitledFile = Uri.from({ scheme: 'untitled', path: 'Untitled-1' });
|
||||
const fooBackupPath = path.join(workspaceBackupPath, 'file', crypto.createHash('md5').update(fooFile.fsPath).digest('hex'));
|
||||
const fooBackupPathLegacy = path.join(workspaceBackupPath, 'file', crypto.createHash('md5').update(fooFile.fsPath.toLowerCase()).digest('hex'));
|
||||
const barBackupPath = path.join(workspaceBackupPath, 'file', crypto.createHash('md5').update(barFile.fsPath).digest('hex'));
|
||||
const untitledBackupPath = path.join(workspaceBackupPath, 'untitled', crypto.createHash('md5').update(untitledFile.fsPath).digest('hex'));
|
||||
|
||||
class TestBackupFileService extends BackupFileService {
|
||||
constructor(workspace: Uri, backupHome: string, workspacesJsonPath: string) {
|
||||
const fileService = new FileService(new TestContextService(new Workspace(workspace.fsPath, workspace.fsPath, [workspace])), new TestConfigurationService(), { disableWatcher: true });
|
||||
const fileService = new FileService(new TestContextService(new Workspace(workspace.fsPath, workspace.fsPath, [workspace])), new TestTextResourceConfigurationService(), new TestConfigurationService(), { disableWatcher: true });
|
||||
|
||||
super(workspaceBackupPath, fileService);
|
||||
}
|
||||
|
||||
public getBackupResource(resource: Uri, legacyMacWindowsFormat?: boolean): Uri {
|
||||
return super.getBackupResource(resource, legacyMacWindowsFormat);
|
||||
public getBackupResource(resource: Uri): Uri {
|
||||
return super.getBackupResource(resource);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,47 +114,6 @@ suite('BackupFileService', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('should return whether a backup resource exists - legacy support (read old lowercase format as fallback)', done => {
|
||||
if (platform.isLinux) {
|
||||
done();
|
||||
return; // only on mac and windows
|
||||
}
|
||||
|
||||
pfs.mkdirp(path.dirname(fooBackupPath)).then(() => {
|
||||
fs.writeFileSync(fooBackupPathLegacy, 'foo');
|
||||
service = new TestBackupFileService(workspaceResource, backupHome, workspacesJsonPath);
|
||||
service.loadBackupResource(fooFile).then(resource => {
|
||||
assert.ok(resource);
|
||||
assert.equal(path.basename(resource.fsPath), path.basename(fooBackupPathLegacy));
|
||||
return service.hasBackups().then(hasBackups => {
|
||||
assert.ok(hasBackups);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('should return whether a backup resource exists - legacy support #2 (both cases present, return case sensitive backup)', done => {
|
||||
if (platform.isLinux) {
|
||||
done();
|
||||
return; // only on mac and windows
|
||||
}
|
||||
|
||||
pfs.mkdirp(path.dirname(fooBackupPath)).then(() => {
|
||||
fs.writeFileSync(fooBackupPath, 'foo');
|
||||
fs.writeFileSync(fooBackupPathLegacy, 'foo');
|
||||
service = new TestBackupFileService(workspaceResource, backupHome, workspacesJsonPath);
|
||||
service.loadBackupResource(fooFile).then(resource => {
|
||||
assert.ok(resource);
|
||||
assert.equal(path.basename(resource.fsPath), path.basename(fooBackupPath));
|
||||
return service.hasBackups().then(hasBackups => {
|
||||
assert.ok(hasBackups);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('backupResource', () => {
|
||||
|
@ -200,27 +158,6 @@ suite('BackupFileService', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('text file - legacy support (dicard lowercase backup file if present)', done => {
|
||||
if (platform.isLinux) {
|
||||
done();
|
||||
return; // only on mac and windows
|
||||
}
|
||||
|
||||
pfs.mkdirp(path.dirname(fooBackupPath)).then(() => {
|
||||
fs.writeFileSync(fooBackupPathLegacy, 'foo');
|
||||
service = new TestBackupFileService(workspaceResource, backupHome, workspacesJsonPath);
|
||||
service.backupResource(fooFile, 'test').then(() => {
|
||||
assert.equal(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 2);
|
||||
service.discardResourceBackup(fooFile).then(() => {
|
||||
assert.equal(fs.existsSync(fooBackupPath), false);
|
||||
assert.equal(fs.existsSync(fooBackupPathLegacy), false);
|
||||
assert.equal(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('discardAllWorkspaceBackups', () => {
|
||||
|
|
|
@ -18,7 +18,7 @@ import { parseArgs } from 'vs/platform/environment/node/argv';
|
|||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
|
||||
import extfs = require('vs/base/node/extfs');
|
||||
import { TestTextFileService, TestEditorGroupService, TestLifecycleService, TestBackupFileService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { TestTextFileService, TestEditorGroupService, TestLifecycleService, TestBackupFileService, TestTextResourceConfigurationService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import uuid = require('vs/base/common/uuid');
|
||||
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { WorkspaceService, EmptyWorkspaceServiceImpl, WorkspaceServiceImpl } from 'vs/workbench/services/configuration/node/configuration';
|
||||
|
@ -125,7 +125,7 @@ suite('ConfigurationEditingService', () => {
|
|||
instantiationService.stub(ITelemetryService, NullTelemetryService);
|
||||
instantiationService.stub(IModeService, ModeServiceImpl);
|
||||
instantiationService.stub(IModelService, instantiationService.createInstance(ModelServiceImpl));
|
||||
instantiationService.stub(IFileService, new FileService(workspaceService, new TestConfigurationService(), { disableWatcher: true }));
|
||||
instantiationService.stub(IFileService, new FileService(workspaceService, new TestTextResourceConfigurationService(), new TestConfigurationService(), { disableWatcher: true }));
|
||||
instantiationService.stub(IUntitledEditorService, instantiationService.createInstance(UntitledEditorService));
|
||||
instantiationService.stub(ITextFileService, instantiationService.createInstance(TestTextFileService));
|
||||
instantiationService.stub(ITextModelService, <ITextModelService>instantiationService.createInstance(TextModelResolverService));
|
||||
|
|
|
@ -27,6 +27,7 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag
|
|||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
|
||||
import { shell } from 'electron';
|
||||
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
|
||||
|
||||
export class FileService implements IFileService {
|
||||
|
||||
|
@ -52,7 +53,8 @@ export class FileService implements IFileService {
|
|||
@IEditorGroupService private editorGroupService: IEditorGroupService,
|
||||
@ILifecycleService private lifecycleService: ILifecycleService,
|
||||
@IMessageService private messageService: IMessageService,
|
||||
@IStorageService private storageService: IStorageService
|
||||
@IStorageService private storageService: IStorageService,
|
||||
@ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService
|
||||
) {
|
||||
this.toUnbind = [];
|
||||
this.activeOutOfWorkspaceWatchers = new ResourceMap<uri>();
|
||||
|
@ -80,7 +82,7 @@ export class FileService implements IFileService {
|
|||
};
|
||||
|
||||
// create service
|
||||
this.raw = new NodeFileService(contextService, configurationService, fileServiceConfig);
|
||||
this.raw = new NodeFileService(contextService, textResourceConfigurationService, configurationService, fileServiceConfig);
|
||||
|
||||
// Listeners
|
||||
this.registerListeners();
|
||||
|
|
|
@ -36,6 +36,7 @@ import { FileWatcher as WindowsWatcherService } from 'vs/workbench/services/file
|
|||
import { toFileChangesEvent, normalize, IRawFileChange } from 'vs/workbench/services/files/node/watcher/common';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import { FileWatcher as NsfwWatcherService } from 'vs/workbench/services/files/node/watcher/nsfw/watcherService';
|
||||
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
|
||||
export interface IEncodingOverride {
|
||||
|
@ -93,8 +94,9 @@ export class FileService implements IFileService {
|
|||
|
||||
constructor(
|
||||
private contextService: IWorkspaceContextService,
|
||||
private textResourceConfigurationService: ITextResourceConfigurationService,
|
||||
private configurationService: IConfigurationService,
|
||||
options: IFileServiceOptions,
|
||||
options: IFileServiceOptions
|
||||
) {
|
||||
this.toDispose = [];
|
||||
this.options = options || Object.create(null);
|
||||
|
@ -638,13 +640,13 @@ export class FileService implements IFileService {
|
|||
}
|
||||
|
||||
private configuredAutoGuessEncoding(resource: uri): boolean {
|
||||
const config = this.configurationService.getConfiguration(void 0, { resource }) as IFilesConfiguration;
|
||||
const config = this.textResourceConfigurationService.getConfiguration(resource) as IFilesConfiguration;
|
||||
|
||||
return config && config.files && config.files.autoGuessEncoding === true;
|
||||
}
|
||||
|
||||
private configuredEncoding(resource: uri): string {
|
||||
const config = this.configurationService.getConfiguration(void 0, { resource }) as IFilesConfiguration;
|
||||
const config = this.textResourceConfigurationService.getConfiguration(resource) as IFilesConfiguration;
|
||||
|
||||
return config && config.files && config.files.encoding;
|
||||
}
|
||||
|
|
|
@ -19,26 +19,26 @@ import extfs = require('vs/base/node/extfs');
|
|||
import encodingLib = require('vs/base/node/encoding');
|
||||
import utils = require('vs/workbench/services/files/test/node/utils');
|
||||
import { onError } from 'vs/base/test/common/utils';
|
||||
import { TestContextService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { TestContextService, TestTextResourceConfigurationService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { Workspace } from 'vs/platform/workspace/common/workspace';
|
||||
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
|
||||
|
||||
suite('FileService', () => {
|
||||
let service: FileService;
|
||||
let parentDir = path.join(os.tmpdir(), 'vsctests', 'service');
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', 'service');
|
||||
let testDir: string;
|
||||
|
||||
setup(function (done) {
|
||||
let id = uuid.generateUuid();
|
||||
const id = uuid.generateUuid();
|
||||
testDir = path.join(parentDir, id);
|
||||
let sourceDir = require.toUrl('./fixtures/service');
|
||||
const sourceDir = require.toUrl('./fixtures/service');
|
||||
|
||||
extfs.copy(sourceDir, testDir, (error) => {
|
||||
if (error) {
|
||||
return onError(error, done);
|
||||
}
|
||||
|
||||
service = new FileService(new TestContextService(new Workspace(testDir, testDir, [uri.file(testDir)])), new TestConfigurationService(), { disableWatcher: true });
|
||||
service = new FileService(new TestContextService(new Workspace(testDir, testDir, [uri.file(testDir)])), new TestTextResourceConfigurationService(), new TestConfigurationService(), { disableWatcher: true });
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -487,7 +487,7 @@ suite('FileService', () => {
|
|||
service.resolveFile(uri.file(testDir), { resolveTo: [uri.file(path.join(testDir, 'deep'))] }).done(r => {
|
||||
assert.equal(r.children.length, 6);
|
||||
|
||||
let deep = utils.getByName(r, 'deep');
|
||||
const deep = utils.getByName(r, 'deep');
|
||||
assert.equal(deep.children.length, 4);
|
||||
|
||||
done();
|
||||
|
@ -503,7 +503,7 @@ suite('FileService', () => {
|
|||
|
||||
assert.equal(r1.children.length, 6);
|
||||
|
||||
let deep = utils.getByName(r1, 'deep');
|
||||
const deep = utils.getByName(r1, 'deep');
|
||||
assert.equal(deep.children.length, 4);
|
||||
|
||||
const r2 = res[1].stat;
|
||||
|
@ -527,7 +527,7 @@ suite('FileService', () => {
|
|||
});
|
||||
|
||||
test('updateContent', function (done: () => void) {
|
||||
let resource = uri.file(path.join(testDir, 'small.txt'));
|
||||
const resource = uri.file(path.join(testDir, 'small.txt'));
|
||||
|
||||
service.resolveContent(resource).done(c => {
|
||||
assert.equal(c.value, 'Small File');
|
||||
|
@ -543,8 +543,8 @@ suite('FileService', () => {
|
|||
});
|
||||
|
||||
test('updateContent - use encoding (UTF 16 BE)', function (done: () => void) {
|
||||
let resource = uri.file(path.join(testDir, 'small.txt'));
|
||||
let encoding = 'utf16be';
|
||||
const resource = uri.file(path.join(testDir, 'small.txt'));
|
||||
const encoding = 'utf16be';
|
||||
|
||||
service.resolveContent(resource).done(c => {
|
||||
c.encoding = encoding;
|
||||
|
@ -564,8 +564,8 @@ suite('FileService', () => {
|
|||
});
|
||||
|
||||
test('updateContent - encoding preserved (UTF 16 LE)', function (done: () => void) {
|
||||
let encoding = 'utf16le';
|
||||
let resource = uri.file(path.join(testDir, 'some_utf16le.css'));
|
||||
const encoding = 'utf16le';
|
||||
const resource = uri.file(path.join(testDir, 'some_utf16le.css'));
|
||||
|
||||
service.resolveContent(resource).done(c => {
|
||||
assert.equal(c.encoding, encoding);
|
||||
|
@ -587,7 +587,7 @@ suite('FileService', () => {
|
|||
});
|
||||
|
||||
test('resolveContent - FILE_IS_BINARY', function (done: () => void) {
|
||||
let resource = uri.file(path.join(testDir, 'binary.txt'));
|
||||
const resource = uri.file(path.join(testDir, 'binary.txt'));
|
||||
|
||||
service.resolveContent(resource, { acceptTextOnly: true }).done(null, (e: FileOperationError) => {
|
||||
assert.equal(e.fileOperationResult, FileOperationResult.FILE_IS_BINARY);
|
||||
|
@ -601,7 +601,7 @@ suite('FileService', () => {
|
|||
});
|
||||
|
||||
test('resolveContent - FILE_IS_DIRECTORY', function (done: () => void) {
|
||||
let resource = uri.file(path.join(testDir, 'deep'));
|
||||
const resource = uri.file(path.join(testDir, 'deep'));
|
||||
|
||||
service.resolveContent(resource).done(null, (e: FileOperationError) => {
|
||||
assert.equal(e.fileOperationResult, FileOperationResult.FILE_IS_DIRECTORY);
|
||||
|
@ -611,7 +611,7 @@ suite('FileService', () => {
|
|||
});
|
||||
|
||||
test('resolveContent - FILE_NOT_FOUND', function (done: () => void) {
|
||||
let resource = uri.file(path.join(testDir, '404.html'));
|
||||
const resource = uri.file(path.join(testDir, '404.html'));
|
||||
|
||||
service.resolveContent(resource).done(null, (e: FileOperationError) => {
|
||||
assert.equal(e.fileOperationResult, FileOperationResult.FILE_NOT_FOUND);
|
||||
|
@ -621,7 +621,7 @@ suite('FileService', () => {
|
|||
});
|
||||
|
||||
test('resolveContent - FILE_NOT_MODIFIED_SINCE', function (done: () => void) {
|
||||
let resource = uri.file(path.join(testDir, 'index.html'));
|
||||
const resource = uri.file(path.join(testDir, 'index.html'));
|
||||
|
||||
service.resolveContent(resource).done(c => {
|
||||
return service.resolveContent(resource, { etag: c.etag }).then(null, (e: FileOperationError) => {
|
||||
|
@ -633,7 +633,7 @@ suite('FileService', () => {
|
|||
});
|
||||
|
||||
test('resolveContent - FILE_MODIFIED_SINCE', function (done: () => void) {
|
||||
let resource = uri.file(path.join(testDir, 'index.html'));
|
||||
const resource = uri.file(path.join(testDir, 'index.html'));
|
||||
|
||||
service.resolveContent(resource).done(c => {
|
||||
fs.writeFileSync(resource.fsPath, 'Updates Incoming!');
|
||||
|
@ -647,8 +647,8 @@ suite('FileService', () => {
|
|||
});
|
||||
|
||||
test('resolveContent - encoding picked up', function (done: () => void) {
|
||||
let resource = uri.file(path.join(testDir, 'index.html'));
|
||||
let encoding = 'windows1252';
|
||||
const resource = uri.file(path.join(testDir, 'index.html'));
|
||||
const encoding = 'windows1252';
|
||||
|
||||
service.resolveContent(resource, { encoding: encoding }).done(c => {
|
||||
assert.equal(c.encoding, encoding);
|
||||
|
@ -658,7 +658,7 @@ suite('FileService', () => {
|
|||
});
|
||||
|
||||
test('resolveContent - user overrides BOM', function (done: () => void) {
|
||||
let resource = uri.file(path.join(testDir, 'some_utf16le.css'));
|
||||
const resource = uri.file(path.join(testDir, 'some_utf16le.css'));
|
||||
|
||||
service.resolveContent(resource, { encoding: 'windows1252' }).done(c => {
|
||||
assert.equal(c.encoding, 'windows1252');
|
||||
|
@ -668,7 +668,7 @@ suite('FileService', () => {
|
|||
});
|
||||
|
||||
test('resolveContent - BOM removed', function (done: () => void) {
|
||||
let resource = uri.file(path.join(testDir, 'some_utf8_bom.txt'));
|
||||
const resource = uri.file(path.join(testDir, 'some_utf8_bom.txt'));
|
||||
|
||||
service.resolveContent(resource).done(c => {
|
||||
assert.equal(encodingLib.detectEncodingByBOMFromBuffer(new Buffer(c.value), 512), null);
|
||||
|
@ -678,7 +678,7 @@ suite('FileService', () => {
|
|||
});
|
||||
|
||||
test('resolveContent - invalid encoding', function (done: () => void) {
|
||||
let resource = uri.file(path.join(testDir, 'index.html'));
|
||||
const resource = uri.file(path.join(testDir, 'index.html'));
|
||||
|
||||
service.resolveContent(resource, { encoding: 'superduper' }).done(c => {
|
||||
assert.equal(c.encoding, 'utf8');
|
||||
|
@ -688,7 +688,7 @@ suite('FileService', () => {
|
|||
});
|
||||
|
||||
test('watchFileChanges', function (done: () => void) {
|
||||
let toWatch = uri.file(path.join(testDir, 'index.html'));
|
||||
const toWatch = uri.file(path.join(testDir, 'index.html'));
|
||||
|
||||
service.watchFileChanges(toWatch);
|
||||
|
||||
|
@ -705,7 +705,7 @@ suite('FileService', () => {
|
|||
});
|
||||
|
||||
test('watchFileChanges - support atomic save', function (done: () => void) {
|
||||
let toWatch = uri.file(path.join(testDir, 'index.html'));
|
||||
const toWatch = uri.file(path.join(testDir, 'index.html'));
|
||||
|
||||
service.watchFileChanges(toWatch);
|
||||
|
||||
|
@ -729,21 +729,23 @@ suite('FileService', () => {
|
|||
test('options - encoding', function (done: () => void) {
|
||||
|
||||
// setup
|
||||
let _id = uuid.generateUuid();
|
||||
let _testDir = path.join(parentDir, _id);
|
||||
let _sourceDir = require.toUrl('./fixtures/service');
|
||||
const _id = uuid.generateUuid();
|
||||
const _testDir = path.join(parentDir, _id);
|
||||
const _sourceDir = require.toUrl('./fixtures/service');
|
||||
|
||||
extfs.copy(_sourceDir, _testDir, () => {
|
||||
let encodingOverride: IEncodingOverride[] = [];
|
||||
const encodingOverride: IEncodingOverride[] = [];
|
||||
encodingOverride.push({
|
||||
resource: uri.file(path.join(testDir, 'deep')),
|
||||
encoding: 'utf16le'
|
||||
});
|
||||
|
||||
let configurationService = new TestConfigurationService();
|
||||
const configurationService = new TestConfigurationService();
|
||||
configurationService.setUserConfiguration('files', { encoding: 'windows1252' });
|
||||
|
||||
let _service = new FileService(new TestContextService(new Workspace(_testDir, _testDir, [uri.file(_testDir)])), configurationService, {
|
||||
const textResourceConfigurationService = new TestTextResourceConfigurationService(configurationService);
|
||||
|
||||
const _service = new FileService(new TestContextService(new Workspace(_testDir, _testDir, [uri.file(_testDir)])), textResourceConfigurationService, configurationService, {
|
||||
encodingOverride,
|
||||
disableWatcher: true
|
||||
});
|
||||
|
@ -765,12 +767,12 @@ suite('FileService', () => {
|
|||
test('UTF 8 BOMs', function (done: () => void) {
|
||||
|
||||
// setup
|
||||
let _id = uuid.generateUuid();
|
||||
let _testDir = path.join(parentDir, _id);
|
||||
let _sourceDir = require.toUrl('./fixtures/service');
|
||||
let resource = uri.file(path.join(testDir, 'index.html'));
|
||||
const _id = uuid.generateUuid();
|
||||
const _testDir = path.join(parentDir, _id);
|
||||
const _sourceDir = require.toUrl('./fixtures/service');
|
||||
const resource = uri.file(path.join(testDir, 'index.html'));
|
||||
|
||||
let _service = new FileService(new TestContextService(new Workspace(_testDir, _testDir, [uri.file(_testDir)])), new TestConfigurationService(), {
|
||||
const _service = new FileService(new TestContextService(new Workspace(_testDir, _testDir, [uri.file(_testDir)])), new TestTextResourceConfigurationService(), new TestConfigurationService(), {
|
||||
disableWatcher: true
|
||||
});
|
||||
|
||||
|
|
|
@ -19,11 +19,12 @@ export type GroupOrientation = 'vertical' | 'horizontal';
|
|||
|
||||
export const IEditorGroupService = createDecorator<IEditorGroupService>('editorGroupService');
|
||||
|
||||
export interface ITabOptions {
|
||||
export interface IEditorTabOptions {
|
||||
showTabs?: boolean;
|
||||
tabCloseButton?: 'left' | 'right' | 'off';
|
||||
showIcons?: boolean;
|
||||
previewEditors?: boolean;
|
||||
labelFormat?: 'default' | 'short' | 'medium' | 'long';
|
||||
}
|
||||
|
||||
export interface IMoveOptions {
|
||||
|
@ -62,7 +63,7 @@ export interface IEditorGroupService {
|
|||
/**
|
||||
* Emitted when tab options changed.
|
||||
*/
|
||||
onTabOptionsChanged: Event<ITabOptions>;
|
||||
onTabOptionsChanged: Event<IEditorTabOptions>;
|
||||
|
||||
/**
|
||||
* Keyboard focus the editor group at the provided position.
|
||||
|
@ -130,5 +131,5 @@ export interface IEditorGroupService {
|
|||
/**
|
||||
* Returns tab options.
|
||||
*/
|
||||
getTabOptions(): ITabOptions;
|
||||
getTabOptions(): IEditorTabOptions;
|
||||
}
|
|
@ -79,9 +79,9 @@ export class TextEditorState {
|
|||
}
|
||||
}
|
||||
|
||||
interface ISerializedFileHistoryEntry {
|
||||
resource?: string;
|
||||
resourceJSON: object;
|
||||
interface ISerializedEditorHistoryEntry {
|
||||
resourceJSON?: object;
|
||||
editorInputJSON?: { typeId: string; deserialized: string; };
|
||||
}
|
||||
|
||||
interface IEditorIdentifier {
|
||||
|
@ -224,7 +224,7 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic
|
|||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
this.toUnbind.push(this.lifecycleService.onShutdown(reason => this.save()));
|
||||
this.toUnbind.push(this.lifecycleService.onShutdown(reason => this.saveHistory()));
|
||||
this.toUnbind.push(this.editorGroupService.onEditorOpenFail(editor => this.remove(editor)));
|
||||
this.toUnbind.push(this.editorGroupService.getStacksModel().onEditorClosed(event => this.onEditorClosed(event)));
|
||||
this.toUnbind.push(this.fileService.onFileChanges(e => this.onFileChanges(e)));
|
||||
|
@ -710,34 +710,58 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic
|
|||
this.loaded = true;
|
||||
}
|
||||
|
||||
private save(): void {
|
||||
private saveHistory(): void {
|
||||
if (!this.history) {
|
||||
return; // nothing to save because history was not used
|
||||
}
|
||||
|
||||
const entries: ISerializedFileHistoryEntry[] = this.history.map(input => {
|
||||
const registry = Registry.as<IEditorRegistry>(Extensions.Editors);
|
||||
|
||||
const entries: ISerializedEditorHistoryEntry[] = this.history.map(input => {
|
||||
|
||||
// Editor input: try via factory
|
||||
if (input instanceof EditorInput) {
|
||||
return void 0; // only file resource inputs are serializable currently
|
||||
const factory = registry.getEditorInputFactory(input.getTypeId());
|
||||
if (factory) {
|
||||
return { editorInputJSON: { typeId: input.getTypeId(), deserialized: factory.serialize(input) } } as ISerializedEditorHistoryEntry;
|
||||
}
|
||||
}
|
||||
|
||||
return { resourceJSON: (input as IResourceInput).resource.toJSON() };
|
||||
// File resource: via URI.toJSON()
|
||||
else {
|
||||
return { resourceJSON: (input as IResourceInput).resource.toJSON() } as ISerializedEditorHistoryEntry;
|
||||
}
|
||||
|
||||
return void 0;
|
||||
}).filter(serialized => !!serialized);
|
||||
|
||||
this.storageService.store(HistoryService.STORAGE_KEY, JSON.stringify(entries), StorageScope.WORKSPACE);
|
||||
}
|
||||
|
||||
private loadHistory(): void {
|
||||
let entries: ISerializedFileHistoryEntry[] = [];
|
||||
let entries: ISerializedEditorHistoryEntry[] = [];
|
||||
|
||||
const entriesRaw = this.storageService.get(HistoryService.STORAGE_KEY, StorageScope.WORKSPACE);
|
||||
if (entriesRaw) {
|
||||
entries = JSON.parse(entriesRaw);
|
||||
}
|
||||
|
||||
const registry = Registry.as<IEditorRegistry>(Extensions.Editors);
|
||||
|
||||
this.history = entries.map(entry => {
|
||||
const serializedFileInput = entry as ISerializedFileHistoryEntry;
|
||||
if (serializedFileInput.resource || serializedFileInput.resourceJSON) {
|
||||
return { resource: !!serializedFileInput.resourceJSON ? URI.revive(serializedFileInput.resourceJSON) : URI.parse(serializedFileInput.resource) } as IResourceInput;
|
||||
const serializedEditorHistoryEntry = entry as ISerializedEditorHistoryEntry;
|
||||
|
||||
// File resource: via URI.revive()
|
||||
if (serializedEditorHistoryEntry.resourceJSON) {
|
||||
return { resource: URI.revive(serializedEditorHistoryEntry.resourceJSON) } as IResourceInput;
|
||||
}
|
||||
|
||||
// Editor input: via factory
|
||||
if (serializedEditorHistoryEntry.editorInputJSON) {
|
||||
const factory = registry.getEditorInputFactory(serializedEditorHistoryEntry.editorInputJSON.typeId);
|
||||
if (factory) {
|
||||
return factory.deserialize(this.instantiationService, serializedEditorHistoryEntry.editorInputJSON.deserialized);
|
||||
}
|
||||
}
|
||||
|
||||
return void 0;
|
||||
|
|
|
@ -17,7 +17,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
|
|||
import { KeyCode, SimpleKeybinding, ChordKeybinding } from 'vs/base/common/keyCodes';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import extfs = require('vs/base/node/extfs');
|
||||
import { TestTextFileService, TestEditorGroupService, TestLifecycleService, TestBackupFileService, TestContextService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { TestTextFileService, TestEditorGroupService, TestLifecycleService, TestBackupFileService, TestContextService, TestTextResourceConfigurationService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { IWorkspaceContextService, Workspace } from 'vs/platform/workspace/common/workspace';
|
||||
import uuid = require('vs/base/common/uuid');
|
||||
import { ConfigurationService } from 'vs/platform/configuration/node/configurationService';
|
||||
|
@ -74,7 +74,7 @@ suite('Keybindings Editing', () => {
|
|||
instantiationService.stub(ITelemetryService, NullTelemetryService);
|
||||
instantiationService.stub(IModeService, ModeServiceImpl);
|
||||
instantiationService.stub(IModelService, instantiationService.createInstance(ModelServiceImpl));
|
||||
instantiationService.stub(IFileService, new FileService(new TestContextService(new Workspace(testDir, testDir, [uri.file(testDir)])), new TestConfigurationService(), { disableWatcher: true }));
|
||||
instantiationService.stub(IFileService, new FileService(new TestContextService(new Workspace(testDir, testDir, [uri.file(testDir)])), new TestTextResourceConfigurationService(), new TestConfigurationService(), { disableWatcher: true }));
|
||||
instantiationService.stub(IUntitledEditorService, instantiationService.createInstance(UntitledEditorService));
|
||||
instantiationService.stub(ITextFileService, instantiationService.createInstance(TestTextFileService));
|
||||
instantiationService.stub(ITextModelService, <ITextModelService>instantiationService.createInstance(TextModelResolverService));
|
||||
|
|
|
@ -215,8 +215,18 @@ export class FileWalker {
|
|||
let leftover = '';
|
||||
let first = true;
|
||||
const tree = this.initDirectoryTree();
|
||||
|
||||
const useRipgrep = this.config.useRipgrep;
|
||||
const cmd = useRipgrep ? spawnRipgrepCmd(folderQuery, this.config.includePattern, this.folderExcludePatterns.get(folderQuery.folder)).cmd : this.spawnFindCmd(folderQuery);
|
||||
let cmd: childProcess.ChildProcess;
|
||||
let noSiblingsClauses: boolean;
|
||||
if (useRipgrep) {
|
||||
const ripgrep = spawnRipgrepCmd(folderQuery, this.config.includePattern, this.folderExcludePatterns.get(folderQuery.folder));
|
||||
cmd = ripgrep.cmd;
|
||||
noSiblingsClauses = !Object.keys(ripgrep.siblingClauses).length;
|
||||
} else {
|
||||
cmd = this.spawnFindCmd(folderQuery);
|
||||
}
|
||||
|
||||
this.collectStdout(cmd, 'utf8', (err: Error, stdout?: string, last?: boolean) => {
|
||||
if (err) {
|
||||
done(err);
|
||||
|
@ -246,6 +256,19 @@ export class FileWalker {
|
|||
return;
|
||||
}
|
||||
|
||||
this.cmdResultCount += relativeFiles.length;
|
||||
|
||||
if (useRipgrep && noSiblingsClauses) {
|
||||
for (const relativePath of relativeFiles) {
|
||||
const basename = path.basename(relativePath);
|
||||
this.matchFile(onResult, { base: rootFolder, relativePath, basename });
|
||||
}
|
||||
if (last) {
|
||||
done();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Optimize siblings clauses with ripgrep here.
|
||||
this.addDirectoryEntries(tree, rootFolder, relativeFiles, onResult);
|
||||
|
||||
|
@ -382,8 +405,6 @@ export class FileWalker {
|
|||
}
|
||||
|
||||
private addDirectoryEntries({ pathToEntries }: IDirectoryTree, base: string, relativeFiles: string[], onResult: (result: IRawFileMatch) => void) {
|
||||
this.cmdResultCount += relativeFiles.length;
|
||||
|
||||
// Support relative paths to files from a root resource (ignores excludes)
|
||||
if (relativeFiles.indexOf(this.filePattern) !== -1) {
|
||||
const basename = path.basename(this.filePattern);
|
||||
|
|
|
@ -32,7 +32,7 @@ import { ILifecycleService, ShutdownEvent, ShutdownReason, StartupKind, Lifecycl
|
|||
import { EditorStacksModel } from 'vs/workbench/common/editor/editorStacksModel';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
||||
import { IEditorGroupService, GroupArrangement, GroupOrientation, ITabOptions, IMoveOptions } from 'vs/workbench/services/group/common/groupService';
|
||||
import { IEditorGroupService, GroupArrangement, GroupOrientation, IEditorTabOptions, IMoveOptions } from 'vs/workbench/services/group/common/groupService';
|
||||
import { TextFileService } from 'vs/workbench/services/textfile/common/textFileService';
|
||||
import { FileOperationEvent, IFileService, IResolveContentOptions, FileOperationError, IFileStat, IResolveFileResult, IImportResult, FileChangesEvent, IResolveFileOptions, IContent, IUpdateContentOptions, IStreamContent } from 'vs/platform/files/common/files';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
|
@ -56,6 +56,8 @@ import { generateUuid } from 'vs/base/common/uuid';
|
|||
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
|
||||
import { IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { IRecentlyOpened } from 'vs/platform/history/common/history';
|
||||
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
|
||||
import { IPosition } from 'vs/editor/common/core/position';
|
||||
|
||||
export function createFileInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput {
|
||||
return instantiationService.createInstance(FileEditorInput, resource, void 0);
|
||||
|
@ -220,7 +222,9 @@ export class TestTextFileService extends TextFileService {
|
|||
export function workbenchInstantiationService(): IInstantiationService {
|
||||
let instantiationService = new TestInstantiationService(new ServiceCollection([ILifecycleService, new TestLifecycleService()]));
|
||||
instantiationService.stub(IWorkspaceContextService, new TestContextService(TestWorkspace));
|
||||
instantiationService.stub(IConfigurationService, new TestConfigurationService());
|
||||
const configService = new TestConfigurationService();
|
||||
instantiationService.stub(IConfigurationService, configService);
|
||||
instantiationService.stub(ITextResourceConfigurationService, new TestTextResourceConfigurationService(configService));
|
||||
instantiationService.stub(IUntitledEditorService, instantiationService.createInstance(UntitledEditorService));
|
||||
instantiationService.stub(IStorageService, new TestStorageService());
|
||||
instantiationService.stub(IWorkbenchEditorService, new TestEditorService());
|
||||
|
@ -436,14 +440,14 @@ export class TestEditorGroupService implements IEditorGroupService {
|
|||
private _onEditorOpenFail: Emitter<IEditorInput>;
|
||||
private _onEditorsMoved: Emitter<void>;
|
||||
private _onGroupOrientationChanged: Emitter<void>;
|
||||
private _onTabOptionsChanged: Emitter<ITabOptions>;
|
||||
private _onTabOptionsChanged: Emitter<IEditorTabOptions>;
|
||||
|
||||
constructor(callback?: (method: string) => void) {
|
||||
this._onEditorsMoved = new Emitter<void>();
|
||||
this._onEditorsChanged = new Emitter<void>();
|
||||
this._onGroupOrientationChanged = new Emitter<void>();
|
||||
this._onEditorOpenFail = new Emitter<IEditorInput>();
|
||||
this._onTabOptionsChanged = new Emitter<ITabOptions>();
|
||||
this._onTabOptionsChanged = new Emitter<IEditorTabOptions>();
|
||||
|
||||
let services = new ServiceCollection();
|
||||
|
||||
|
@ -479,7 +483,7 @@ export class TestEditorGroupService implements IEditorGroupService {
|
|||
return this._onGroupOrientationChanged.event;
|
||||
}
|
||||
|
||||
public get onTabOptionsChanged(): Event<ITabOptions> {
|
||||
public get onTabOptionsChanged(): Event<IEditorTabOptions> {
|
||||
return this._onTabOptionsChanged.event;
|
||||
}
|
||||
|
||||
|
@ -536,7 +540,7 @@ export class TestEditorGroupService implements IEditorGroupService {
|
|||
return this.stacksModel;
|
||||
}
|
||||
|
||||
public getTabOptions(): ITabOptions {
|
||||
public getTabOptions(): IEditorTabOptions {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
@ -1162,3 +1166,21 @@ export class TestWindowsService implements IWindowsService {
|
|||
}
|
||||
}
|
||||
|
||||
export class TestTextResourceConfigurationService implements ITextResourceConfigurationService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
constructor(private configurationService = new TestConfigurationService()) {
|
||||
}
|
||||
|
||||
public onDidUpdateConfiguration() {
|
||||
return { dispose() { } };
|
||||
}
|
||||
|
||||
public getConfiguration(resource: URI, section?: string): any;
|
||||
public getConfiguration(resource: URI, position?: IPosition, section?: string): any;
|
||||
public getConfiguration(resource: any, position?: any, section?: any): any;
|
||||
public getConfiguration(resource: any, position?: any, section?: any): any {
|
||||
return this.configurationService.getConfiguration(section, { resource });
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue