Merge VS Code 1.26.1 (#2394)

* Squash merge commits for 1.26 (#1) (#2323)

* Polish tag search as per feedback (#55269)

* Polish tag search as per feedback

* Updated regex

* Allow users to opt-out of features that send online requests in the background (#55097)

* settings sweep #54690

* Minor css tweaks to enable eoverflow elipsis in more places (#55277)

* fix an issue with titlebarheight when not scaling with zoom

* Settings descriptions update #54690

* fixes #55209

* Settings editor - many padding fixes

* More space above level 2 label

* Fixing Cannot debug npm script using Yarn #55103

* Settings editor - show ellipsis when description overflows

* Settings editor - ... fix measuring around links, relayout

* Setting descriptions

* Settings editor - fix ... for some short lines, fix select container width

* Settings editor - overlay trees so scrollable shadow is full width

* Fix #54133 - missing extension settings after reload

* Settings color token description tweak

* Settings editor - disable overflow indicator temporarily, needs to be faster

* Added command to Run the selected npm script

* fixes #54452

* fixes #54929

* fixes #55248

* prefix command with extension name

* Contribute run selected to the context menu

* node-debug@1.26.6

* Allow terminal rendererType to be swapped out at runtime

Part of #53274
Fixes #55344

* Settings editor - fix not focusing search when restoring editor
setInput must be actually async. Will be fixed naturally when we aren't using winJS promises...

* Settings editor - TOC should only expand the section with a selected item

* Bump node-debug2

* Settings editor - Tree focus outlines

* Settings editor - don't blink the scrollbar when toc selection changes
And hide TOC correctly when the editor is narrow

* Settings editor - header rows should not be selectable

* fixes #54877

* change debug assignee to isi

* Settings sweep (#54690)

* workaround for #55051

* Settings sweep (#54690)

* settings sweep

#54690

* Don't try closing tags when you type > after another >

* Describe what implementation code lens does

Fixes #55370

* fix javadoc formatter setting description

* fixes #55325

* update to officical TS version

* Settings editor - Even more padding, use semibold instead of bold

* Fix #55357 - fix TOC twistie

* fixes #55288

* explorer: refresh on di change file system provider registration

fixes #53256

* Disable push to Linux repo to test standalone publisher

* New env var to notify log level to extensions #54001

* Disable snippets in extension search (when not in suggest dropdown) (#55281)

* Disable snippits in extension search (when not in suggest dropdown)

* Add monaco input contributions

* Fix bug preventing snippetSuggestions from taking effect in sub-editors

* Latest emmet helper to fix #52366

* Fix comment updates for threads within same file

* Allow extensions to log telemetry to log files #54001

* Pull latest css grammar

* files.exclude control - use same style for "add" vs "edit"

* files.exclude control - focus/keyboard behavior

* don't show menubar too early

* files.exclude - better styling

* Place cursor at end of extensions search box on autofill (#55254)

* Place cursor at end of extensions search box on autofill

* Use position instead of selection

* fix linux build issue (empty if block)

* Settings editor - fix extension category prefixes

* Settings editor - add simple ellipsis for first line that overflows, doesn't cover case when first line does not overflow but there is more text, TODO

* File/Text search provider docs

* Fixes #52655

* Include epoch (#55008)

* Fixes #53385

* Fixes #49480

*  VS Code Insiders (Users) not opening Fixes #55353

* Better handling of the case when the extension host fails to start

* Fixes #53966

*  Remove confusing Start from wordPartLeft commands ID

* vscode-xterm@3.6.0-beta12

Fixes #55488

* Initial size is set to infinity!! Fixes #55461

* Polish embeddedEditorBackground

* configuration service misses event

* Fix #55224 - fix duplicate results in multiroot workspace from splitting the diskseach query

* Select all not working in issue reporter on mac, fixes #55424

* Disable fuzzy matching for extensions autosuggest (#55498)

* Fix clipping of extensions search border in some third party themes (#55504)

* fixes #55538

* Fix bug causing an aria alert to not be shown the third time
 (and odd numbers thereafter)

* Settings editor - work around rendering glitch with webkit-line-clamp

* Settings editor - revert earlier '...' changes

* Settings editor - move enumDescription to its own div, because it disturbs -webkit-line-clamp for some reason

* Settings editor - better overflow indicator

* Don't show existing filters in autocomplete (#55495)

* Dont show existing filters in autocomplete

* Simplify

* Settings Editor: Add aria labels for input elements Fixes: #54836 (#55543)

* fixes #55223

* Update vscode-css-languageservice to 3.0.10-next.1

* Fix #55509 - settings navigation

* Fix #55519

* Fix #55520

* FIx #55524

* Fix #55556 - include wordSeparators in all search queries, so findTextInFiles can respect isWordMatch correctly

* oss updates for endgame

* Fix unit tests

* fixes #55522

* Avoid missing manifest error from bubbling up #54757

* Settings format crawl

* Search provider - Fix FileSearchProvider to return array, not progress

* Fix #55598

* Settings editor - fix NPE rendering settings with no description

* dont render inden guides in search box (#55600)

* fixes #55454

* More settings crawl

* Another change for #55598 - maxResults applies to FileSearch and TextSearch but not FileIndex

* Fix FileSearchProvider unit tests for progress change

* fixes #55561

* Settings description update for #54690

* Update setting descriptions for online services

* Minor edits

* fixes #55513

* fixes #55451

* Fix #55612 - fix findTextInFiles cancellation

* fixes #55539

* More setting description tweaks

* Setting to disable online experiments #54354

* fixes #55507

* fixes #55515

* Show online services action only in Insiders for now

* Settings editor - change toc behavior default to 'filter'

* Settings editor - nicer filter count style during search

* Fix #55617 - search viewlet icons

* Settings editor - better styling for element count indicator

* SearchProvider - fix NPE when searching extraFileResources

* Allow extends to work without json suffix

Fixes #16905

* Remove accessability options logic entirely

Follow up on #55451

* use latest version of DAP

* fixes #55490

* fixes #55122

* fixes #52332

* Avoid assumptions about git: URIs (fixes #36236)

* relative path for descriptions

* resourece: get rid of isFile context key

fixes #48275

* Register previous ids for compatibility (#53497)

* more tuning for #48275

* no need to always re-read "files explorer"

fixes #52003

* read out active composites properly

fixes #51967

* Update link colors for hc theme to meet color contrast ratio, fixes #55651

Also updated link color for `textLinkActiveForeground` to be the same as `textLinkForeground` as it wasn't properly updated

* detect 'winpty-agent.exe'; fixes #55672

* node-debug@1.26.7

* reset counter on new label

* Settings editor - fix multiple setting links in one description

* Settings editor - color code blocks in setting descriptions, fix #55532

* Settings editor - hover color in TOC

* Settings editor - fix navigation NPE

* Settings editor - fix text control width

* Settings editor - maybe fix #55684

* Fix bug causing cursor to not move on paste

* fixes #53582

* Use ctrlCmd instead of ctrl for go down from search box

* fixes #55264

* fixes #55456

* filter for spcaes before triggering search (#55611)

* Fix #55698 - don't lose filtered TOC counts when refreshing TOC

* fixes #55421

* fixes #28979

* fixes #55576

* only add check for updates to windows/linux help

* readonly files: append decoration to label

fixes #53022

* debug: do not show toolbar while initialising

fixes #55026

* Opening launch.json should not activate debug extensions

fixes #55029

* fixes #55435

* fixes #55434

* fixes #55439

* trigger menu only on altkey up

* Fix #50555 - fix settings editor memory leak

* Fix #55712 - no need to focus 'a' anymore when restoring control focus after tree render

* fixes #55335

* proper fix for readonly model

fixes #53022

* improve FoldingRangeKind spec (for #55686)

* Use class with static fields (fixes #55494)

* Fixes #53671

* fixes #54630

* [html] should disable ionic suggestions by default. Currently forces deprecated Ionic v1 suggestions in .html files while typing. Fixes #53324

* cleanup deps

* debug issues back to andre

* update electron for smoketest

* Fix #55757 - prevent settings tabs from overflowing

* Fix #53897 - revert setting menu defaults to old editor

* Add enum descriptions to `typescript.preferences.importModuleSpecifier`

* Fix #55767 - leaking style elements from settings editor

* Fix #55521 - prevent flashing when clicking in exclude control

* Update Git modified color for contrast ratio, fixes #53140

* Revert "Merge branch 'master' of github.com:Microsoft/vscode"

This reverts commit bf46b6bfbae0cab99c2863e1244a916181fa9fbc, reversing
changes made to e275a424483dfb4ed33b428c97d5e2c441d6b917.

* Revert "Revert "Merge branch 'master' of github.com:Microsoft/vscode""

This reverts commit 53949d963f39e40757557c6526332354a31d9154.

* don't ask to install an incomplete menu

* Fix NPE in terminal AccessibilityManager

Fixes #55744

* don't display fallback menu unless we've closed the last window

* fixes #55547

* Fix smoke tests for extension search box

* Update OSSREADME.json for Electron 2.0.5

* Update distro

Includes Chromium license changes

* fix #55455

* fix #55865

* fixes #55893

* Fix bug causing workspace recommendations to go away upon ignoring a recommendation (#55805)

* Fix bug causing workspace recommendations to go away upon ignoring a recommendation

* ONly show on @recommended or @recommended:workspace

* Make more consistant

* Fix #55911

* Understand json activity (#55926)

* Understand json file activity

* Refactoring

* adding composer.json

* Distro update for experiments

* use terminal.processId for auto-attach; fixes #55918

* Reject invalid URI with vscode.openFolder (for #55891)

* improve win32 setup system vs user detection

fixes #55840

fixes #55840

delay winreg import

related to #55840

show notification earlier

related to #55840

fix #55840

update inno setup message

related to #55840

* Fix #55593 - this code only operates on local paths, so use fsPath and Uri.file instead

* Bring back the old menu due to electron 2.0 issues (#55913)

* add the old menu back for native menus

* make menu labels match

* `vscode.openFolder`: treat missing URI schema gracefully (for #55891)

* delay EH reattach; fixes #55955

* Mark all json files under appSettingsHome as settings

* Use localized strings for telemetry opt-out

* Exception when saving file editor opened from remote file provider (fixes #55051)

* Remove terminal menu from stable

Fixes 56003

* VSCode Insiders crashes on open with TypeError: Cannot read property 'lastIndexOf' of undefined. Fixes #54933

* improve fix for #55891

* fix #55916

* Improve #55891

* increase EH debugging restart delay; fixes #55955

* Revert "Don't include non-resource entries in history quick pick"

This reverts commit 37209a838e9f7e9abe6dc53ed73cdf1e03b72060.

* Diff editor: horizontal scrollbar height is smaller (fixes #56062)

* improve openFolder uri fix (correctly treat backslashes)

* fixes #56116
repair ipc for native menubar keybindings

* Fix #56240 - Open the JSON settings editor instead of the UI editor

* Fix #55536

* uriDisplay: if no formatter is registered fall back to getPathlabel

fixes #56104

* VSCode hangs when opening python file. Fixes #56377

* VS Code Hangs When Opening Specific PowerShell File. Fixes #56430

* Fix #56433 - search extraFileResources even when no folders open

* Workaround #55649

* Fix in master #56371

* Fix tests #56371

* Fix in master #56317

* increase version to 1.26.1

* Fixes #56387: Handle SIGPIPE in extension host

* fixes #56185

* Fix merge issues (part 1)

* Fix build breaks (part 1)

* Build breaks (part 2)

* Build breaks (part 3)

* More build breaks (part 4)

* Fix build breaks (part 5)

* WIP

* Fix menus

* Render query result and message panels (#2363)

* Put back query editor hot exit changes

* Fix grid changes that broke profiler (#2365)

* Update APIs for saving query editor state

* Fix restore view state for profiler and edit data

* Updating custom default themes to support 4.5:1 contrast ratio

* Test updates

* Fix Extension Manager and Windows Setup

* Update license headers

* Add appveyor and travis files back

* Fix hidden modal dropdown issue
This commit is contained in:
Karl Burtram
2018-09-04 14:55:00 -07:00
committed by GitHub
parent 3763278366
commit 81329fa7fa
2638 changed files with 118456 additions and 64012 deletions
@@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/mmims/language-batchfile/commit/6235c491be4dff49cd3966b50142874d7f79580a",
"version": "https://github.com/mmims/language-batchfile/commit/4b67596631b4ecd2c89c2ec1b2e08a6623438903",
"name": "Batch File",
"scopeName": "source.batchfile",
"patterns": [
@@ -163,12 +163,6 @@
"end": "(?=$\\n|[&|><)])",
"name": "meta.expression.set.batchfile",
"patterns": [
{
"include": "#command_set_inside_arithmetic"
},
{
"include": "#command_set_group"
},
{
"begin": "\"",
"beginCaptures": {
@@ -194,6 +188,12 @@
"include": "#variables"
}
]
},
{
"include": "#command_set_inside_arithmetic"
},
{
"include": "#command_set_group"
}
]
},
@@ -266,8 +266,15 @@
"command_set_operators": {
"patterns": [
{
"match": "\\+\\=|\\-\\=|\\*\\=|/\\=|%%\\=|&\\=|\\|\\=|\\^\\=|<<\\=|>>\\=",
"name": "keyword.operator.assignment.augmented.batchfile"
"match": "([^ ]*)(\\+\\=|\\-\\=|\\*\\=|\\/\\=|%%\\=|&\\=|\\|\\=|\\^\\=|<<\\=|>>\\=)",
"captures": {
"1": {
"name": "variable.other.readwrite.batchfile"
},
"2": {
"name": "keyword.operator.assignment.augmented.batchfile"
}
}
},
{
"match": "\\+|\\-|/|\\*|%%|\\||&|\\^|<<|>>|~",
@@ -278,8 +285,15 @@
"name": "keyword.operator.logical.batchfile"
},
{
"match": "=",
"name": "keyword.operator.assignment.batchfile"
"match": "([^ ][^=]*)(=)",
"captures": {
"1": {
"name": "variable.other.readwrite.batchfile"
},
"2": {
"name": "keyword.operator.assignment.batchfile"
}
}
}
]
},
+196 -196
View File
@@ -3,10 +3,10 @@
"c": "@",
"t": "source.batchfile keyword.operator.at.batchfile",
"r": {
"dark_plus": "keyword.operator: #D4D4D4",
"light_plus": "keyword.operator: #000000",
"dark_vs": "keyword.operator: #D4D4D4",
"light_vs": "keyword.operator: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword.operator: #D4D4D4"
}
},
@@ -14,10 +14,10 @@
"c": "echo",
"t": "source.batchfile keyword.command.batchfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword: #569CD6"
}
},
@@ -25,10 +25,10 @@
"c": " ",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -36,10 +36,10 @@
"c": "off",
"t": "source.batchfile keyword.other.special-method.batchfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword: #569CD6"
}
},
@@ -47,10 +47,10 @@
"c": "setlocal",
"t": "source.batchfile keyword.command.batchfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword: #569CD6"
}
},
@@ -58,10 +58,10 @@
"c": "title",
"t": "source.batchfile keyword.command.batchfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword: #569CD6"
}
},
@@ -69,10 +69,10 @@
"c": " VSCode Dev",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -80,10 +80,10 @@
"c": "pushd",
"t": "source.batchfile keyword.command.batchfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword: #569CD6"
}
},
@@ -91,10 +91,10 @@
"c": " ",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -102,10 +102,10 @@
"c": "%",
"t": "source.batchfile punctuation.definition.variable.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -113,10 +113,10 @@
"c": "~dp0",
"t": "source.batchfile variable.parameter.batchfile",
"r": {
"dark_plus": "variable: #9CDCFE",
"light_plus": "variable: #001080",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "variable: #9CDCFE"
}
},
@@ -124,10 +124,10 @@
"c": "\\..",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -135,10 +135,10 @@
"c": "::",
"t": "source.batchfile comment.line.colon.batchfile punctuation.definition.comment.batchfile",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -146,10 +146,10 @@
"c": " Node modules",
"t": "source.batchfile comment.line.colon.batchfile",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -157,10 +157,10 @@
"c": "if",
"t": "source.batchfile keyword.control.conditional.batchfile",
"r": {
"dark_plus": "keyword.control: #C586C0",
"light_plus": "keyword.control: #AF00DB",
"dark_vs": "keyword.control: #569CD6",
"light_vs": "keyword.control: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword.control: #C586C0"
}
},
@@ -168,10 +168,10 @@
"c": " ",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -179,10 +179,10 @@
"c": "not",
"t": "source.batchfile keyword.operator.logical.batchfile",
"r": {
"dark_plus": "keyword.operator: #D4D4D4",
"light_plus": "keyword.operator: #000000",
"dark_vs": "keyword.operator: #D4D4D4",
"light_vs": "keyword.operator: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword.operator: #D4D4D4"
}
},
@@ -190,10 +190,10 @@
"c": " ",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -201,10 +201,10 @@
"c": "exist",
"t": "source.batchfile keyword.other.special-method.batchfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword: #569CD6"
}
},
@@ -212,10 +212,10 @@
"c": " node_modules ",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -223,10 +223,10 @@
"c": "call",
"t": "source.batchfile keyword.control.statement.batchfile",
"r": {
"dark_plus": "keyword.control: #C586C0",
"light_plus": "keyword.control: #AF00DB",
"dark_vs": "keyword.control: #569CD6",
"light_vs": "keyword.control: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword.control: #C586C0"
}
},
@@ -234,10 +234,10 @@
"c": " .\\scripts\\npm.bat install",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -245,10 +245,10 @@
"c": "::",
"t": "source.batchfile comment.line.colon.batchfile punctuation.definition.comment.batchfile",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -256,10 +256,10 @@
"c": " Get electron",
"t": "source.batchfile comment.line.colon.batchfile",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -267,10 +267,10 @@
"c": "node .\\node_modules\\gulp\\bin\\gulp.js electron",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -278,10 +278,10 @@
"c": "::",
"t": "source.batchfile comment.line.colon.batchfile punctuation.definition.comment.batchfile",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -289,10 +289,10 @@
"c": " Build",
"t": "source.batchfile comment.line.colon.batchfile",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -300,10 +300,10 @@
"c": "if",
"t": "source.batchfile keyword.control.conditional.batchfile",
"r": {
"dark_plus": "keyword.control: #C586C0",
"light_plus": "keyword.control: #AF00DB",
"dark_vs": "keyword.control: #569CD6",
"light_vs": "keyword.control: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword.control: #C586C0"
}
},
@@ -311,10 +311,10 @@
"c": " ",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -322,10 +322,10 @@
"c": "not",
"t": "source.batchfile keyword.operator.logical.batchfile",
"r": {
"dark_plus": "keyword.operator: #D4D4D4",
"light_plus": "keyword.operator: #000000",
"dark_vs": "keyword.operator: #D4D4D4",
"light_vs": "keyword.operator: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword.operator: #D4D4D4"
}
},
@@ -333,10 +333,10 @@
"c": " ",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -344,10 +344,10 @@
"c": "exist",
"t": "source.batchfile keyword.other.special-method.batchfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword: #569CD6"
}
},
@@ -355,10 +355,10 @@
"c": " out node .\\node_modules\\gulp\\bin\\gulp.js compile",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -366,10 +366,10 @@
"c": "::",
"t": "source.batchfile comment.line.colon.batchfile punctuation.definition.comment.batchfile",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -377,10 +377,10 @@
"c": " Configuration",
"t": "source.batchfile comment.line.colon.batchfile",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -388,10 +388,10 @@
"c": "set",
"t": "source.batchfile keyword.command.batchfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword: #569CD6"
}
},
@@ -399,10 +399,10 @@
"c": " ",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -410,10 +410,10 @@
"c": "NODE_ENV",
"t": "source.batchfile variable.other.readwrite.batchfile",
"r": {
"dark_plus": "variable: #9CDCFE",
"light_plus": "variable: #001080",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "variable: #9CDCFE"
}
},
@@ -421,10 +421,10 @@
"c": "=",
"t": "source.batchfile keyword.operator.assignment.batchfile",
"r": {
"dark_plus": "keyword.operator: #D4D4D4",
"light_plus": "keyword.operator: #000000",
"dark_vs": "keyword.operator: #D4D4D4",
"light_vs": "keyword.operator: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword.operator: #D4D4D4"
}
},
@@ -432,10 +432,10 @@
"c": "development",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -443,10 +443,10 @@
"c": "call",
"t": "source.batchfile keyword.control.statement.batchfile",
"r": {
"dark_plus": "keyword.control: #C586C0",
"light_plus": "keyword.control: #AF00DB",
"dark_vs": "keyword.control: #569CD6",
"light_vs": "keyword.control: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword.control: #C586C0"
}
},
@@ -454,10 +454,10 @@
"c": " ",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -465,10 +465,10 @@
"c": "echo",
"t": "source.batchfile keyword.command.batchfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword: #569CD6"
}
},
@@ -476,10 +476,10 @@
"c": " ",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -487,10 +487,10 @@
"c": "%%",
"t": "source.batchfile constant.character.escape.batchfile",
"r": {
"dark_plus": "constant.character.escape: #D7BA7D",
"light_plus": "constant.character.escape: #A31515",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "constant.character: #569CD6"
}
},
@@ -498,10 +498,10 @@
"c": "LINE:rem +=",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -509,10 +509,10 @@
"c": "%%",
"t": "source.batchfile constant.character.escape.batchfile",
"r": {
"dark_plus": "constant.character.escape: #D7BA7D",
"light_plus": "constant.character.escape: #A31515",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "constant.character: #569CD6"
}
},
@@ -520,10 +520,10 @@
"c": "popd",
"t": "source.batchfile keyword.command.batchfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword: #569CD6"
}
},
@@ -531,10 +531,10 @@
"c": "endlocal",
"t": "source.batchfile keyword.command.batchfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword: #569CD6"
}
}
+20 -1
View File
@@ -18,9 +18,28 @@
},
"dependencies": {
"jsonc-parser": "^1.0.0",
"vscode-nls": "^3.2.1"
"vscode-nls": "^3.2.4"
},
"contributes": {
"languages": [
{
"id": "jsonc",
"extensions": [
".code-workspace",
"language-configuration.json",
"icon-theme.json",
"color-theme.json",
".code-snippets"
],
"filenames": [
"settings.json",
"launch.json",
"tasks.json",
"keybindings.json",
"extensions.json"
]
}
],
"jsonValidation": [
{
"fileMatch": "vscode://defaultsettings/keybindings.json",
@@ -1,4 +1,4 @@
{
"displayName": "Configuration Editing",
"description": "Provides capabilities (advanced IntelliSense, auto-fixing) in configuration files like settings, launch and extension recommendation files."
"description": "Provides capabilities (advanced IntelliSense, auto-fixing) in configuration files like settings, launch, and extension recommendation files."
}
@@ -27,6 +27,12 @@ export function activate(context: vscode.ExtensionContext): void {
//extensions suggestions
context.subscriptions.push(...registerExtensionsCompletions());
// launch.json variable suggestions
context.subscriptions.push(registerVariableCompletions('**/launch.json'));
// task.json variable suggestions
context.subscriptions.push(registerVariableCompletions('**/tasks.json'));
// launch.json decorations
context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(editor => updateLaunchJsonDecorations(editor), null, context.subscriptions));
context.subscriptions.push(vscode.workspace.onDidChangeTextDocument(event => {
@@ -108,6 +114,30 @@ function registerSettingsCompletions(): vscode.Disposable {
});
}
function registerVariableCompletions(pattern: string): vscode.Disposable {
return vscode.languages.registerCompletionItemProvider({ language: 'jsonc', pattern }, {
provideCompletionItems(document, position, token) {
const location = getLocation(document.getText(), document.offsetAt(position));
if (!location.isAtPropertyKey && location.previousNode && location.previousNode.type === 'string') {
const indexOf$ = document.lineAt(position.line).text.indexOf('$');
const startPosition = indexOf$ >= 0 ? new vscode.Position(position.line, indexOf$) : position;
return [{ label: 'workspaceFolder', detail: localize('workspaceFolder', "The path of the folder opened in VS Code") }, { label: 'workspaceFolderBasename', detail: localize('workspaceFolderBasename', "The name of the folder opened in VS Code without any slashes (/)") },
{ label: 'relativeFile', detail: localize('relativeFile', "The current opened file relative to ${workspaceFolder}") }, { label: 'file', detail: localize('file', "The current opened file") }, { label: 'cwd', detail: localize('cwd', "The task runner's current working directory on startup") },
{ label: 'lineNumber', detail: localize('lineNumber', "The current selected line number in the active file") }, { label: 'selectedText', detail: localize('selectedText', "The current selected text in the active file") },
{ label: 'fileDirname', detail: localize('fileDirname', "The current opened file's dirname") }, { label: 'fileExtname', detail: localize('fileExtname', "The current opened file's extension") }, { label: 'fileBasename', detail: localize('fileBasename', "The current opened file's basename") },
{ label: 'fileBasenameNoExtension', detail: localize('fileBasenameNoExtension', "The current opened file's basename with no file extension") }].map(variable => ({
label: '${' + variable.label + '}',
range: new vscode.Range(startPosition, position),
detail: variable.detail
}));
}
return [];
}
});
}
interface IExtensionsContent {
recommendations: string[];
}
+3 -3
View File
@@ -10,6 +10,6 @@ jsonc-parser@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-1.0.0.tgz#ddcc864ae708e60a7a6dd36daea00172fa8d9272"
vscode-nls@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.1.tgz#b1f3e04e8a94a715d5a7bcbc8339c51e6d74ca51"
vscode-nls@^3.2.4:
version "3.2.4"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.4.tgz#2166b4183c8aea884d20727f5449e62be69fd398"
@@ -3,10 +3,10 @@
"c": "FROM",
"t": "source.dockerfile keyword.other.special-method.dockerfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword: #569CD6"
}
},
@@ -14,10 +14,10 @@
"c": " ubuntu",
"t": "source.dockerfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -25,10 +25,10 @@
"c": "MAINTAINER",
"t": "source.dockerfile keyword.other.special-method.dockerfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword: #569CD6"
}
},
@@ -36,10 +36,10 @@
"c": " Kimbro Staken",
"t": "source.dockerfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -47,10 +47,10 @@
"c": "RUN",
"t": "source.dockerfile keyword.other.special-method.dockerfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword: #569CD6"
}
},
@@ -58,10 +58,10 @@
"c": " apt-get install -y software-properties-common python",
"t": "source.dockerfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -69,10 +69,10 @@
"c": "RUN",
"t": "source.dockerfile keyword.other.special-method.dockerfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword: #569CD6"
}
},
@@ -80,10 +80,10 @@
"c": " add-apt-repository ppa:chris-lea/node.js",
"t": "source.dockerfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -91,10 +91,10 @@
"c": "RUN",
"t": "source.dockerfile keyword.other.special-method.dockerfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword: #569CD6"
}
},
@@ -102,10 +102,10 @@
"c": " echo ",
"t": "source.dockerfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -113,10 +113,10 @@
"c": "\"deb http://us.archive.ubuntu.com/ubuntu/ precise universe\"",
"t": "source.dockerfile string.quoted.double.dockerfile",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "string: #CE9178"
}
},
@@ -124,10 +124,10 @@
"c": " >> /etc/apt/sources.list",
"t": "source.dockerfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -135,10 +135,10 @@
"c": "RUN",
"t": "source.dockerfile keyword.other.special-method.dockerfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword: #569CD6"
}
},
@@ -146,10 +146,10 @@
"c": " apt-get update",
"t": "source.dockerfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -157,10 +157,10 @@
"c": "RUN",
"t": "source.dockerfile keyword.other.special-method.dockerfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword: #569CD6"
}
},
@@ -168,10 +168,10 @@
"c": " apt-get install -y nodejs",
"t": "source.dockerfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -179,10 +179,10 @@
"c": "#",
"t": "source.dockerfile comment.line.number-sign.dockerfile punctuation.definition.comment.dockerfile",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -190,10 +190,10 @@
"c": "RUN apt-get install -y nodejs=0.6.12~dfsg1-1ubuntu1",
"t": "source.dockerfile comment.line.number-sign.dockerfile",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -201,10 +201,10 @@
"c": "RUN",
"t": "source.dockerfile keyword.other.special-method.dockerfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword: #569CD6"
}
},
@@ -212,10 +212,10 @@
"c": " mkdir /var/www",
"t": "source.dockerfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -223,10 +223,10 @@
"c": "ADD",
"t": "source.dockerfile keyword.other.special-method.dockerfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword: #569CD6"
}
},
@@ -234,10 +234,10 @@
"c": " app.js /var/www/app.js",
"t": "source.dockerfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -245,10 +245,10 @@
"c": "CMD",
"t": "source.dockerfile keyword.other.special-method.dockerfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "keyword: #569CD6"
}
},
@@ -256,10 +256,10 @@
"c": " [",
"t": "source.dockerfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -267,10 +267,10 @@
"c": "\"/usr/bin/node\"",
"t": "source.dockerfile string.quoted.double.dockerfile",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "string: #CE9178"
}
},
@@ -278,10 +278,10 @@
"c": ", ",
"t": "source.dockerfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -289,10 +289,10 @@
"c": "\"/var/www/app.js\"",
"t": "source.dockerfile string.quoted.double.dockerfile",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "string: #CE9178"
}
},
@@ -300,10 +300,10 @@
"c": "] ",
"t": "source.dockerfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
}
+1 -1
View File
@@ -21,7 +21,7 @@
"jsonc-parser": "^1.0.0",
"markdown-it": "^8.3.1",
"parse5": "^3.0.2",
"vscode-nls": "^3.2.1"
"vscode-nls": "^3.2.4"
},
"contributes": {
"jsonValidation": [
@@ -1,4 +1,4 @@
{
"displayName": "Package File Editing",
"description": "Provides IntelliSense for VS Code extension points and linting capabilities in package.json files."
"displayName": "Extension Authoring",
"description": "Provides linting capabilities for authoring extensions."
}
@@ -3,7 +3,6 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as fs from 'fs';
import * as path from 'path';
import * as nls from 'vscode-nls';
@@ -264,13 +263,16 @@ export class ExtensionLinter {
}
private async loadPackageJson(folder: Uri) {
const file = folder.with({ path: path.posix.join(folder.path, 'package.json') });
const exists = await fileExists(file.fsPath);
if (!exists) {
if (folder.scheme === 'git') { // #36236
return undefined;
}
const file = folder.with({ path: path.posix.join(folder.path, 'package.json') });
try {
const document = await workspace.openTextDocument(file);
return parseTree(document.getText());
} catch (err) {
return undefined;
}
const document = await workspace.openTextDocument(file);
return parseTree(document.getText());
}
private packageJsonChanged(folder: Uri) {
@@ -338,20 +340,6 @@ function endsWith(haystack: string, needle: string): boolean {
}
}
function fileExists(path: string): Promise<boolean> {
return new Promise((resolve, reject) => {
fs.lstat(path, (err, stats) => {
if (!err) {
resolve(true);
} else if (err.code === 'ENOENT') {
resolve(false);
} else {
reject(err);
}
});
});
}
function parseUri(src: string) {
try {
return Uri.parse(src);
+3 -3
View File
@@ -58,6 +58,6 @@ uc.micro@^1.0.1, uc.micro@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.3.tgz#7ed50d5e0f9a9fb0a573379259f2a77458d50192"
vscode-nls@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.1.tgz#b1f3e04e8a94a715d5a7bcbc8339c51e6d74ca51"
vscode-nls@^3.2.4:
version "3.2.4"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.4.tgz#2166b4183c8aea884d20727f5449e62be69fd398"
+5
View File
@@ -1,2 +1,7 @@
# Git integration for Visual Studio Code
**Notice:** This extension is bundled with Visual Studio Code. It can be disabled but not uninstalled.
## Features
See [Git support in VS Code](https://code.visualstudio.com/docs/editor/versioncontrol#_git-support) to learn about the features of this extension.
@@ -0,0 +1,5 @@
{
"comments": {
"lineComment": "#",
}
}
+82 -7
View File
@@ -38,6 +38,11 @@
"dark": "resources/icons/dark/git.svg"
}
},
{
"command": "git.openRepository",
"title": "%command.openRepository%",
"category": "Git"
},
{
"command": "git.close",
"title": "%command.close%",
@@ -336,6 +341,10 @@
"command": "git.init",
"when": "config.git.enabled"
},
{
"command": "git.openRepository",
"when": "config.git.enabled"
},
{
"command": "git.close",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
@@ -881,7 +890,16 @@
"scope": "application"
},
"git.autoRepositoryDetection": {
"type": "boolean",
"type": [
"boolean",
"string"
],
"enum": [
true,
false,
"subFolders",
"openEditors"
],
"description": "%config.autoRepositoryDetection%",
"default": true
},
@@ -893,7 +911,8 @@
"git.autofetch": {
"type": "boolean",
"description": "%config.autofetch%",
"default": false
"default": false,
"tags": ["usesOnlineServices"]
},
"git.confirmSync": {
"type": "boolean",
@@ -907,6 +926,11 @@
"tracked",
"off"
],
"enumDescriptions": [
"%config.countBadge.all%",
"%config.countBadge.tracked%",
"%config.countBadge.off%"
],
"description": "%config.countBadge%",
"default": "all"
},
@@ -918,6 +942,12 @@
"tags",
"remote"
],
"enumDescriptions": [
"%config.checkoutType.all%",
"%config.checkoutType.local%",
"%config.checkoutType.tags%",
"%config.checkoutType.remote%"
],
"description": "%config.checkoutType%",
"default": "all"
},
@@ -943,11 +973,13 @@
},
"git.enableSmartCommit": {
"type": "boolean",
"scope": "resource",
"description": "%config.enableSmartCommit%",
"default": false
},
"git.enableCommitSigning": {
"type": "boolean",
"scope": "resource",
"description": "%config.enableCommitSigning%",
"default": false
},
@@ -958,6 +990,7 @@
},
"git.promptToSaveFilesBeforeCommit": {
"type": "boolean",
"scope": "resource",
"default": false,
"description": "%config.promptToSaveFilesBeforeCommit%"
},
@@ -966,6 +999,11 @@
"default": true,
"description": "%config.showInlineOpenFileAction%"
},
"git.showPushSuccessNotification": {
"type": "boolean",
"description": "%config.showPushSuccessNotification%",
"default": false
},
"git.inputValidation": {
"type": "string",
"enum": [
@@ -987,15 +1025,36 @@
"scope": "resource",
"default": 10,
"description": "%config.detectSubmodulesLimit%"
},
"git.alwaysSignOff": {
"type": "boolean",
"scope": "resource",
"default": false,
"description": "%config.alwaysSignOff%"
},
"git.ignoredRepositories": {
"type": "array",
"default": [],
"scope": "window",
"description": "%config.ignoredRepositories%"
}
}
},
"colors": [
{
"id": "gitDecoration.addedResourceForeground",
"description": "%colors.added%",
"defaults": {
"light": "#587c0c",
"dark": "#81b88b",
"highContrast": "#1b5225"
}
},
{
"id": "gitDecoration.modifiedResourceForeground",
"description": "%colors.modified%",
"defaults": {
"light": "#a76e12",
"light": "#895503",
"dark": "#E2C08D",
"highContrast": "#E2C08D"
}
@@ -1013,7 +1072,7 @@
"id": "gitDecoration.untrackedResourceForeground",
"description": "%colors.untracked%",
"defaults": {
"light": "#019001",
"light": "#018101",
"dark": "#73C991",
"highContrast": "#73C991"
}
@@ -1082,6 +1141,17 @@
".rej"
],
"configuration": "./languages/diff.language-configuration.json"
},
{
"id": "ignore",
"aliases": [
"Ignore",
"ignore"
],
"filenames": [
".gitignore"
],
"configuration": "./languages/ignore.language-configuration.json"
}
],
"grammars": [
@@ -1099,6 +1169,11 @@
"language": "diff",
"scopeName": "source.diff",
"path": "./syntaxes/diff.tmLanguage.json"
},
{
"language": "ignore",
"scopeName": "source.ignore",
"path": "./syntaxes/ignore.tmLanguage.json"
}
],
"configurationDefaults": {
@@ -1114,8 +1189,8 @@
"file-type": "^7.2.0",
"iconv-lite": "0.4.19",
"jschardet": "^1.6.0",
"vscode-extension-telemetry": "0.0.17",
"vscode-nls": "^3.2.1",
"vscode-extension-telemetry": "0.0.18",
"vscode-nls": "^3.2.4",
"which": "^1.3.0"
},
"devDependencies": {
@@ -1126,4 +1201,4 @@
"@types/which": "^1.0.28",
"mocha": "^3.2.0"
}
}
}
+26 -14
View File
@@ -3,6 +3,7 @@
"description": "Git SCM Integration",
"command.clone": "Clone",
"command.init": "Initialize Repository",
"command.openRepository": "Open Repository",
"command.close": "Close Repository",
"command.refresh": "Refresh",
"command.openChange": "Open Changes",
@@ -49,28 +50,39 @@
"command.stash": "Stash",
"command.stashPop": "Pop Stash...",
"command.stashPopLatest": "Pop Latest Stash",
"config.enabled": "Whether git is enabled",
"config.path": "Path to the git executable",
"config.autoRepositoryDetection": "Whether repositories should be automatically detected",
"config.autorefresh": "Whether auto refreshing is enabled",
"config.autofetch": "Whether auto fetching is enabled",
"config.enableLongCommitWarning": "Whether long commit messages should be warned about",
"config.confirmSync": "Confirm before synchronizing git repositories",
"config.countBadge": "Controls the git badge counter. `all` counts all changes. `tracked` counts only the tracked changes. `off` turns it off.",
"config.checkoutType": "Controls what type of branches are listed when running `Checkout to...`. `all` shows all refs, `local` shows only the local branches, `tags` shows only tags and `remote` shows only remote branches.",
"config.ignoreLegacyWarning": "Ignores the legacy Git warning",
"config.ignoreMissingGitWarning": "Ignores the warning when Git is missing",
"config.ignoreLimitWarning": "Ignores the warning when there are too many changes in a repository",
"config.defaultCloneDirectory": "The default location where to clone a git repository",
"config.enabled": "Whether git is enabled.",
"config.path": "Path to the git executable.",
"config.autoRepositoryDetection": "Configures when repositories should be automatically detected.",
"config.autorefresh": "Whether auto refreshing is enabled.",
"config.autofetch": "Whether auto fetching is enabled.",
"config.enableLongCommitWarning": "Whether long commit messages should be warned about.",
"config.confirmSync": "Confirm before synchronizing git repositories.",
"config.countBadge": "Controls the git badge counter.",
"config.countBadge.all": "Count all changes.",
"config.countBadge.tracked": "Count only tracked changes.",
"config.countBadge.off": "Turn off counter.",
"config.checkoutType": "Controls what type of branches are listed when running `Checkout to...`.",
"config.checkoutType.all": "Show all references.",
"config.checkoutType.local": "Show only local branches.",
"config.checkoutType.tags": "Show only tags.",
"config.checkoutType.remote": "Show only remote branches.",
"config.ignoreLegacyWarning": "Ignores the legacy Git warning.",
"config.ignoreMissingGitWarning": "Ignores the warning when Git is missing.",
"config.ignoreLimitWarning": "Ignores the warning when there are too many changes in a repository.",
"config.defaultCloneDirectory": "The default location to clone a git repository.",
"config.enableSmartCommit": "Commit all changes when there are no staged changes.",
"config.enableCommitSigning": "Enables commit signing with GPG.",
"config.discardAllScope": "Controls what changes are discarded by the `Discard all changes` command. `all` discards all changes. `tracked` discards only tracked files. `prompt` shows a prompt dialog every time the action is run.",
"config.decorations.enabled": "Controls if Git contributes colors and badges to the explorer and the open editors view.",
"config.decorations.enabled": "Controls whether Git contributes colors and badges to the explorer and the open editors view.",
"config.promptToSaveFilesBeforeCommit": "Controls whether Git should check for unsaved files before committing.",
"config.showInlineOpenFileAction": "Controls whether to show an inline Open File action in the Git changes view.",
"config.showPushSuccessNotification": "Controls whether to show a notification when a push is successful.",
"config.inputValidation": "Controls when to show commit message input validation.",
"config.detectSubmodules": "Controls whether to automatically detect git submodules.",
"colors.added": "Color for added resources.",
"config.detectSubmodulesLimit": "Controls the limit of git submodules detected.",
"config.alwaysSignOff": "Controls the signoff flag for all commits.",
"config.ignoredRepositories": "List of git repositories to ignore.",
"colors.modified": "Color for modified resources.",
"colors.deleted": "Color for deleted resources.",
"colors.untracked": "Color for untracked resources.",
@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#C5C5C5" d="M15 4v6h-2.276c.113-.318.187-.653.226-1h1.05v-5h-2v-2h-4v2.051c-.347.038-.681.112-1 .225v-3.276h5l3 3zm-7 8.949v1.051h-6v-7h2.276c.126-.354.28-.693.485-1h-3.761v9h8v-2.051c-.166.02-.329.051-.5.051l-.5-.051z"/><path fill="#75BEFF" d="M12 8.5c0-1.933-1.567-3.5-3.5-3.5s-3.5 1.567-3.5 3.5 1.567 3.5 3.5 3.5c.711 0 1.369-.215 1.922-.578l3.578 3.578 1-1-3.578-3.578c.363-.553.578-1.211.578-1.922zm-3.5 2.5c-1.381 0-2.5-1.119-2.5-2.5s1.119-2.5 2.5-2.5 2.5 1.119 2.5 2.5-1.119 2.5-2.5 2.5z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#252526;}.icon-canvas-transparent{opacity:0;}.icon-vs-bg{fill:#c5c5c5;}.icon-vs-action-blue{fill:#75beff;}</style></defs><title>Compare_16x</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M16,11H12.121l1.939,1.94a1.5,1.5,0,1,1-2.12,2.12L9.433,12.554A4.4,4.4,0,0,1,9,12.735V16H0V5H4.706A4.445,4.445,0,0,1,7,4.051V0h5.621L16,3.379Z" style="display: none;"/></g><g id="iconBg"><path class="icon-vs-bg" d="M15,3.793V10H11.735a4.4,4.4,0,0,0,.237-1H14V4.207L11.793,2H9V4.276a4.485,4.485,0,0,0-1-.225V1h4.207ZM7,12.949V14H2V7H3.276a4.493,4.493,0,0,1,.486-1H1v9H8V12.972A4.612,4.612,0,0,1,7.5,13,4.342,4.342,0,0,1,7,12.949Z"/></g><g id="colorAction"><path class="icon-vs-action-blue" d="M13.354,13.646l-3-3a.545.545,0,0,0-.071-.047A3.462,3.462,0,0,0,11,8.5,3.5,3.5,0,1,0,7.5,12a3.462,3.462,0,0,0,2.1-.717.57.57,0,0,0,.047.07l3,3a.5.5,0,1,0,.708-.707ZM7.5,11A2.5,2.5,0,1,1,10,8.5,2.5,2.5,0,0,1,7.5,11Z"/></g></svg>

Before

Width:  |  Height:  |  Size: 578 B

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#656565" d="M15 4v6h-2.276c.113-.318.187-.653.226-1h1.05v-5h-2v-2h-4v2.051c-.347.038-.681.112-1 .225v-3.276h5l3 3zm-7 8.949v1.051h-6v-7h2.276c.126-.354.28-.693.485-1h-3.761v9h8v-2.051c-.166.02-.329.051-.5.051l-.5-.051z"/><path fill="#00539C" d="M12 8.5c0-1.933-1.567-3.5-3.5-3.5s-3.5 1.567-3.5 3.5 1.567 3.5 3.5 3.5c.711 0 1.369-.215 1.922-.578l3.578 3.578 1-1-3.578-3.578c.363-.553.578-1.211.578-1.922zm-3.5 2.5c-1.381 0-2.5-1.119-2.5-2.5s1.119-2.5 2.5-2.5 2.5 1.119 2.5 2.5-1.119 2.5-2.5 2.5z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#f6f6f6;}.icon-canvas-transparent{opacity:0;}.icon-vs-bg{fill:#424242;}.icon-vs-action-blue{fill:#00539c;}</style></defs><title>Compare_16x</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M16,11H12.121l1.939,1.94a1.5,1.5,0,1,1-2.12,2.12L9.433,12.554A4.4,4.4,0,0,1,9,12.735V16H0V5H4.706A4.445,4.445,0,0,1,7,4.051V0h5.621L16,3.379Z" style="display: none;"/></g><g id="iconBg"><path class="icon-vs-bg" d="M15,3.793V10H11.735a4.4,4.4,0,0,0,.237-1H14V4.207L11.793,2H9V4.276a4.485,4.485,0,0,0-1-.225V1h4.207ZM7,12.949V14H2V7H3.276a4.493,4.493,0,0,1,.486-1H1v9H8V12.972A4.612,4.612,0,0,1,7.5,13,4.342,4.342,0,0,1,7,12.949Z"/></g><g id="colorAction"><path class="icon-vs-action-blue" d="M13.354,13.646l-3-3a.545.545,0,0,0-.071-.047A3.462,3.462,0,0,0,11,8.5,3.5,3.5,0,1,0,7.5,12a3.462,3.462,0,0,0,2.1-.717.57.57,0,0,0,.047.07l3,3a.5.5,0,1,0,.708-.707ZM7.5,11A2.5,2.5,0,1,1,10,8.5,2.5,2.5,0,0,1,7.5,11Z"/></g></svg>

Before

Width:  |  Height:  |  Size: 578 B

After

Width:  |  Height:  |  Size: 1.1 KiB

+13 -8
View File
@@ -42,19 +42,24 @@ export interface API {
export class APIImpl implements API {
constructor(private modelPromise: Promise<Model>) { }
constructor(private model: Model) { }
async getGitPath(): Promise<string> {
const model = await this.modelPromise;
return model.git.path;
return this.model.git.path;
}
async getRepositories(): Promise<Repository[]> {
const model = await this.modelPromise;
return model.repositories.map(repository => new RepositoryImpl(repository));
return this.model.repositories.map(repository => new RepositoryImpl(repository));
}
}
export function createApi(modelPromise: Promise<Model>): API {
return new APIImpl(modelPromise);
}
export class NoopAPIImpl implements API {
async getGitPath(): Promise<string> {
throw new Error('Git model not found');
}
async getRepositories(): Promise<Repository[]> {
throw new Error('Git model not found');
}
}
+7
View File
@@ -10,6 +10,7 @@ import { denodeify } from './util';
import * as path from 'path';
import * as http from 'http';
import * as os from 'os';
import * as fs from 'fs';
import * as crypto from 'crypto';
const randomBytes = denodeify<Buffer>(crypto.randomBytes);
@@ -38,6 +39,7 @@ export class Askpass implements Disposable {
private server: http.Server;
private ipcHandlePathPromise: Promise<string>;
private ipcHandlePath: string | undefined;
private enabled = true;
constructor() {
@@ -52,6 +54,7 @@ export class Askpass implements Disposable {
const buffer = await randomBytes(20);
const nonce = buffer.toString('hex');
const ipcHandlePath = getIPCHandlePath(nonce);
this.ipcHandlePath = ipcHandlePath;
try {
this.server.listen(ipcHandlePath);
@@ -110,5 +113,9 @@ export class Askpass implements Disposable {
dispose(): void {
this.server.close();
if (this.ipcHandlePath && process.platform !== 'win32') {
fs.unlinkSync(this.ipcHandlePath);
}
}
}
+114 -56
View File
@@ -10,7 +10,7 @@ import { Ref, RefType, Git, GitErrorCodes, Branch } from './git';
import { Repository, Resource, Status, CommitOptions, ResourceGroupType } from './repository';
import { Model } from './model';
import { toGitUri, fromGitUri } from './uri';
import { grep, isDescendant } from './util';
import { grep, isDescendant, pathEquals } from './util';
import { applyLineChanges, intersectDiffWithRange, toLineRanges, invertLineChange, getModifiedRange } from './staging';
import * as path from 'path';
import { lstat, Stats } from 'fs';
@@ -137,6 +137,22 @@ const ImageMimetypes = [
'image/bmp'
];
async function categorizeResourceByResolution(resources: Resource[]): Promise<{ merge: Resource[], resolved: Resource[], unresolved: Resource[] }> {
const selection = resources.filter(s => s instanceof Resource) as Resource[];
const merge = selection.filter(s => s.resourceGroupType === ResourceGroupType.Merge);
const isBothAddedOrModified = (s: Resource) => s.type === Status.BOTH_MODIFIED || s.type === Status.BOTH_ADDED;
const possibleUnresolved = merge.filter(isBothAddedOrModified);
const promises = possibleUnresolved.map(s => grep(s.resourceUri.fsPath, /^<{7}|^={7}|^>{7}/));
const unresolvedBothModified = await Promise.all<boolean>(promises);
const resolved = possibleUnresolved.filter((s, i) => !unresolvedBothModified[i]);
const unresolved = [
...merge.filter(s => !isBothAddedOrModified(s)),
...possibleUnresolved.filter((s, i) => unresolvedBothModified[i])
];
return { merge, resolved, unresolved };
}
export class CommandCenter {
private disposables: Disposable[];
@@ -236,7 +252,7 @@ export class CommandCenter {
gitRef = indexStatus ? '' : 'HEAD';
}
const { size, object } = await repository.lstree(gitRef, uri.fsPath);
const { size, object } = await repository.getObjectDetails(gitRef, uri.fsPath);
const { mimetype } = await repository.detectObjectType(object);
if (mimetype === 'text/plain') {
@@ -485,7 +501,28 @@ export class CommandCenter {
}
await this.git.init(path);
await this.model.tryOpenRepository(path);
await this.model.openRepository(path);
}
@command('git.openRepository', { repository: false })
async openRepository(path?: string): Promise<void> {
if (!path) {
const result = await window.showOpenDialog({
canSelectFiles: false,
canSelectFolders: true,
canSelectMany: false,
defaultUri: Uri.file(os.homedir()),
openLabel: localize('open repo', "Open Repository")
});
if (!result || result.length === 0) {
return;
}
path = result[0].fsPath;
}
await this.model.openRepository(path);
}
@command('git.close', { repository: true })
@@ -612,9 +649,15 @@ export class CommandCenter {
@command('git.stage')
async stage(...resourceStates: SourceControlResourceState[]): Promise<void> {
this.outputChannel.appendLine(`git.stage ${resourceStates.length}`);
resourceStates = resourceStates.filter(s => !!s);
if (resourceStates.length === 0 || (resourceStates[0] && !(resourceStates[0].resourceUri instanceof Uri))) {
const resource = this.getSCMResource();
this.outputChannel.appendLine(`git.stage.getSCMResource ${resource ? resource.resourceUri.toString() : null}`);
if (!resource) {
return;
}
@@ -623,20 +666,12 @@ export class CommandCenter {
}
const selection = resourceStates.filter(s => s instanceof Resource) as Resource[];
const merge = selection.filter(s => s.resourceGroupType === ResourceGroupType.Merge);
const bothModified = merge.filter(s => s.type === Status.BOTH_MODIFIED);
const promises = bothModified.map(s => grep(s.resourceUri.fsPath, /^<{7}|^={7}|^>{7}/));
const unresolvedBothModified = await Promise.all<boolean>(promises);
const resolvedConflicts = bothModified.filter((s, i) => !unresolvedBothModified[i]);
const unresolvedConflicts = [
...merge.filter(s => s.type !== Status.BOTH_MODIFIED),
...bothModified.filter((s, i) => unresolvedBothModified[i])
];
const { resolved, unresolved } = await categorizeResourceByResolution(selection);
if (unresolvedConflicts.length > 0) {
const message = unresolvedConflicts.length > 1
? localize('confirm stage files with merge conflicts', "Are you sure you want to stage {0} files with merge conflicts?", unresolvedConflicts.length)
: localize('confirm stage file with merge conflicts', "Are you sure you want to stage {0} with merge conflicts?", path.basename(unresolvedConflicts[0].resourceUri.fsPath));
if (unresolved.length > 0) {
const message = unresolved.length > 1
? localize('confirm stage files with merge conflicts', "Are you sure you want to stage {0} files with merge conflicts?", unresolved.length)
: localize('confirm stage file with merge conflicts', "Are you sure you want to stage {0} with merge conflicts?", path.basename(unresolved[0].resourceUri.fsPath));
const yes = localize('yes', "Yes");
const pick = await window.showWarningMessage(message, { modal: true }, yes);
@@ -647,8 +682,9 @@ export class CommandCenter {
}
const workingTree = selection.filter(s => s.resourceGroupType === ResourceGroupType.WorkingTree);
const scmResources = [...workingTree, ...resolvedConflicts, ...unresolvedConflicts];
const scmResources = [...workingTree, ...resolved, ...unresolved];
this.outputChannel.appendLine(`git.stage.scmResources ${scmResources.length}`);
if (!scmResources.length) {
return;
}
@@ -660,12 +696,12 @@ export class CommandCenter {
@command('git.stageAll', { repository: true })
async stageAll(repository: Repository): Promise<void> {
const resources = repository.mergeGroup.resourceStates.filter(s => s instanceof Resource) as Resource[];
const mergeConflicts = resources.filter(s => s.resourceGroupType === ResourceGroupType.Merge);
const { merge, unresolved } = await categorizeResourceByResolution(resources);
if (mergeConflicts.length > 0) {
const message = mergeConflicts.length > 1
? localize('confirm stage files with merge conflicts', "Are you sure you want to stage {0} files with merge conflicts?", mergeConflicts.length)
: localize('confirm stage file with merge conflicts', "Are you sure you want to stage {0} with merge conflicts?", path.basename(mergeConflicts[0].resourceUri.fsPath));
if (unresolved.length > 0) {
const message = unresolved.length > 1
? localize('confirm stage files with merge conflicts', "Are you sure you want to stage {0} files with merge conflicts?", merge.length)
: localize('confirm stage file with merge conflicts', "Are you sure you want to stage {0} with merge conflicts?", path.basename(merge[0].resourceUri.fsPath));
const yes = localize('yes', "Yes");
const pick = await window.showWarningMessage(message, { modal: true }, yes);
@@ -768,24 +804,24 @@ export class CommandCenter {
const originalUri = toGitUri(modifiedUri, '~');
const originalDocument = await workspace.openTextDocument(originalUri);
const basename = path.basename(modifiedUri.fsPath);
const message = localize('confirm revert', "Are you sure you want to revert the selected changes in {0}?", basename);
const yes = localize('revert', "Revert Changes");
const pick = await window.showWarningMessage(message, { modal: true }, yes);
if (pick !== yes) {
return;
}
const selectionsBeforeRevert = textEditor.selections;
const visibleRangesBeforeRevert = textEditor.visibleRanges;
const result = applyLineChanges(originalDocument, modifiedDocument, changes);
const edit = new WorkspaceEdit();
edit.replace(modifiedUri, new Range(new Position(0, 0), modifiedDocument.lineAt(modifiedDocument.lineCount - 1).range.end), result);
workspace.applyEdit(edit);
await modifiedDocument.save();
textEditor.selections = selectionsBeforeRevert;
textEditor.revealRange(visibleRangesBeforeRevert[0]);
}
@command('git.unstage')
async unstage(...resourceStates: SourceControlResourceState[]): Promise<void> {
resourceStates = resourceStates.filter(s => !!s);
if (resourceStates.length === 0 || (resourceStates[0] && !(resourceStates[0].resourceUri instanceof Uri))) {
const resource = this.getSCMResource();
@@ -852,6 +888,8 @@ export class CommandCenter {
@command('git.clean')
async clean(...resourceStates: SourceControlResourceState[]): Promise<void> {
resourceStates = resourceStates.filter(s => !!s);
if (resourceStates.length === 0 || (resourceStates[0] && !(resourceStates[0].resourceUri instanceof Uri))) {
const resource = this.getSCMResource();
@@ -974,7 +1012,7 @@ export class CommandCenter {
getCommitMessage: () => Promise<string | undefined>,
opts?: CommitOptions
): Promise<boolean> {
const config = workspace.getConfiguration('git');
const config = workspace.getConfiguration('git', Uri.file(repository.root));
const promptToSaveFilesBeforeCommit = config.get<boolean>('promptToSaveFilesBeforeCommit') === true;
if (promptToSaveFilesBeforeCommit) {
@@ -983,8 +1021,8 @@ export class CommandCenter {
if (unsavedTextDocuments.length > 0) {
const message = unsavedTextDocuments.length === 1
? localize('unsaved files single', "The following file is unsaved: {0}.\n\nWould you like to save it before comitting?", path.basename(unsavedTextDocuments[0].uri.fsPath))
: localize('unsaved files', "There are {0} unsaved files.\n\nWould you like to save them before comitting?", unsavedTextDocuments.length);
? localize('unsaved files single', "The following file is unsaved: {0}.\n\nWould you like to save it before committing?", path.basename(unsavedTextDocuments[0].uri.fsPath))
: localize('unsaved files', "There are {0} unsaved files.\n\nWould you like to save them before committing?", unsavedTextDocuments.length);
const saveAndCommit = localize('save and commit', "Save All & Commit");
const commit = localize('commit', "Commit Anyway");
const pick = await window.showWarningMessage(message, { modal: true }, saveAndCommit, commit);
@@ -1028,6 +1066,10 @@ export class CommandCenter {
// enable signing of commits if configurated
opts.signCommit = enableCommitSigning;
if (config.get<boolean>('alwaysSignOff')) {
opts.signoff = true;
}
if (
// no changes
(noStagedChanges && noUnstagedChanges)
@@ -1130,11 +1172,19 @@ export class CommandCenter {
const HEAD = repository.HEAD;
if (!HEAD || !HEAD.commit) {
window.showWarningMessage(localize('no more', "Can't undo because HEAD doesn't point to any commit."));
return;
}
const commit = await repository.getCommit('HEAD');
await repository.reset('HEAD~');
if (commit.parents.length > 0) {
await repository.reset('HEAD~');
} else {
await repository.deleteRef('HEAD');
await this.unstageAll(repository);
}
repository.inputBox.value = commit.message;
}
@@ -1271,16 +1321,7 @@ export class CommandCenter {
return;
}
try {
await choice.run(repository);
} catch (err) {
if (err.gitErrorCode !== GitErrorCodes.Conflict) {
throw err;
}
const message = localize('merge conflicts', "There are merge conflicts. Resolve them before committing.");
await window.showWarningMessage(message);
}
await choice.run(repository);
}
@command('git.createTag', { repository: true })
@@ -1325,7 +1366,7 @@ export class CommandCenter {
return;
}
const remotePicks = remotes.map(r => ({ label: r.name, description: r.url }));
const remotePicks = remotes.filter(r => r.fetchUrl !== undefined).map(r => ({ label: r.name, description: r.fetchUrl! }));
const placeHolder = localize('pick remote pull repo', "Pick a remote to pull the branch from");
const remotePick = await window.showQuickPick(remotePicks, { placeHolder });
@@ -1344,7 +1385,7 @@ export class CommandCenter {
const remoteCharCnt = remotePick.label.length;
repository.pullFrom(false, remotePick.label, branchPick.label.slice(remoteCharCnt + 1));
await repository.pullFrom(false, remotePick.label, branchPick.label.slice(remoteCharCnt + 1));
}
@command('git.pull', { repository: true })
@@ -1432,7 +1473,7 @@ export class CommandCenter {
}
const branchName = repository.HEAD.name;
const picks = remotes.map(r => ({ label: r.name, description: r.url }));
const picks = remotes.filter(r => r.pushUrl !== undefined).map(r => ({ label: r.name, description: r.pushUrl! }));
const placeHolder = localize('pick remote', "Pick a remote to publish the branch '{0}' to:", branchName);
const pick = await window.showQuickPick(picks, { placeHolder });
@@ -1440,7 +1481,7 @@ export class CommandCenter {
return;
}
repository.pushTo(pick.label, branchName);
await repository.pushTo(pick.label, branchName);
}
private async _sync(repository: Repository, rebase: boolean): Promise<void> {
@@ -1450,8 +1491,12 @@ export class CommandCenter {
return;
}
const remoteName = HEAD.remote || HEAD.upstream.remote;
const remote = repository.remotes.find(r => r.name === remoteName);
const isReadonly = remote && remote.isReadOnly;
const config = workspace.getConfiguration('git');
const shouldPrompt = config.get<boolean>('confirmSync') === true;
const shouldPrompt = !isReadonly && config.get<boolean>('confirmSync') === true;
if (shouldPrompt) {
const message = localize('sync is unpredictable', "This action will push and pull commits to and from '{0}/{1}'.", HEAD.upstream.remote, HEAD.upstream.name);
@@ -1522,6 +1567,8 @@ export class CommandCenter {
@command('git.ignore')
async ignore(...resourceStates: SourceControlResourceState[]): Promise<void> {
resourceStates = resourceStates.filter(s => !!s);
if (resourceStates.length === 0 || (resourceStates[0] && !(resourceStates[0].resourceUri instanceof Uri))) {
const resource = this.getSCMResource();
@@ -1647,10 +1694,11 @@ export class CommandCenter {
return result.catch(async err => {
const options: MessageOptions = {
modal: err.gitErrorCode === GitErrorCodes.DirtyWorkTree
modal: true
};
let message: string;
let type: 'error' | 'warning' = 'error';
switch (err.gitErrorCode) {
case GitErrorCodes.DirtyWorkTree:
@@ -1659,6 +1707,11 @@ export class CommandCenter {
case GitErrorCodes.PushRejected:
message = localize('cant push', "Can't push refs to remote. Try running 'Pull' first to integrate your changes.");
break;
case GitErrorCodes.Conflict:
message = localize('merge conflicts', "There are merge conflicts. Resolve them before committing.");
type = 'warning';
options.modal = false;
break;
default:
const hint = (err.stderr || err.message || String(err))
.replace(/^error: /mi, '')
@@ -1679,11 +1732,11 @@ export class CommandCenter {
return;
}
options.modal = true;
const outputChannel = this.outputChannel as OutputChannel;
const openOutputChannelChoice = localize('open git log', "Open Git Log");
const choice = await window.showErrorMessage(message, options, openOutputChannelChoice);
const choice = type === 'error'
? await window.showErrorMessage(message, options, openOutputChannelChoice)
: await window.showWarningMessage(message, options, openOutputChannelChoice);
if (choice === openOutputChannelChoice) {
outputChannel.show();
@@ -1698,7 +1751,12 @@ export class CommandCenter {
}
private getSCMResource(uri?: Uri): Resource | undefined {
uri = uri ? uri : window.activeTextEditor && window.activeTextEditor.document.uri;
uri = uri ? uri : (window.activeTextEditor && window.activeTextEditor.document.uri);
this.outputChannel.appendLine(`git.getSCMResource.uri ${uri && uri.toString()}`);
for (const r of this.model.repositories.map(r => r.root)) {
this.outputChannel.appendLine(`repo root ${r}`);
}
if (!uri) {
return undefined;
@@ -1737,7 +1795,7 @@ export class CommandCenter {
}
// Could it be a submodule?
if (resource.fsPath === repository.root) {
if (pathEquals(resource.fsPath, repository.root)) {
repository = this.model.getRepositoryForSubmodule(resource) || repository;
}
+2 -2
View File
@@ -9,7 +9,7 @@ import { workspace, Uri, Disposable, Event, EventEmitter, window } from 'vscode'
import { debounce, throttle } from './decorators';
import { fromGitUri, toGitUri } from './uri';
import { Model, ModelChangeEvent, OriginalResourceChangeEvent } from './model';
import { filterEvent, eventToPromise, isDescendant } from './util';
import { filterEvent, eventToPromise, isDescendant, pathEquals } from './util';
interface CacheRow {
uri: Uri;
@@ -130,7 +130,7 @@ export class GitContentProvider {
const { path } = fromGitUri(row.uri);
const isOpen = workspace.textDocuments
.filter(d => d.uri.scheme === 'file')
.some(d => d.uri.fsPath === path);
.some(d => pathEquals(d.uri.fsPath, path));
if (isOpen || now - row.timestamp < THREE_MINUTES) {
cache[row.uri.toString()] = row;
+154 -51
View File
@@ -13,7 +13,7 @@ import * as which from 'which';
import { EventEmitter } from 'events';
import iconv = require('iconv-lite');
import * as filetype from 'file-type';
import { assign, uniqBy, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent } from './util';
import { assign, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent } from './util';
import { CancellationToken } from 'vscode';
import { detectEncoding } from './encoding';
@@ -33,7 +33,9 @@ export interface IFileStatus {
export interface Remote {
name: string;
url: string;
fetchUrl?: string;
pushUrl?: string;
isReadOnly: boolean;
}
export interface Stash {
@@ -334,7 +336,8 @@ export const GitErrorCodes = {
NoStashFound: 'NoStashFound',
LocalChangesOverwritten: 'LocalChangesOverwritten',
NoUpstreamBranch: 'NoUpstreamBranch',
IsInSubmodule: 'IsInSubmodule'
IsInSubmodule: 'IsInSubmodule',
WrongCase: 'WrongCase',
};
function getGitErrorCode(stderr: string): string | undefined {
@@ -342,7 +345,7 @@ function getGitErrorCode(stderr: string): string | undefined {
return GitErrorCodes.RepositoryIsLocked;
} else if (/Authentication failed/.test(stderr)) {
return GitErrorCodes.AuthenticationFailed;
} else if (/Not a git repository/.test(stderr)) {
} else if (/Not a git repository/i.test(stderr)) {
return GitErrorCodes.NotAGitRepository;
} else if (/bad config file/.test(stderr)) {
return GitErrorCodes.BadConfigFile;
@@ -499,6 +502,7 @@ export class Git {
export interface Commit {
hash: string;
message: string;
parents: string[];
}
export class GitStatusParser {
@@ -629,6 +633,47 @@ export function parseGitmodules(raw: string): Submodule[] {
return result;
}
export function parseGitCommit(raw: string): Commit | null {
const match = /^([0-9a-f]{40})\n(.*)\n([^]*)$/m.exec(raw.trim());
if (!match) {
return null;
}
const parents = match[2] ? match[2].split(' ') : [];
return { hash: match[1], message: match[3], parents };
}
interface LsTreeElement {
mode: string;
type: string;
object: string;
size: string;
file: string;
}
export function parseLsTree(raw: string): LsTreeElement[] {
return raw.split('\n')
.filter(l => !!l)
.map(line => /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/.exec(line)!)
.filter(m => !!m)
.map(([, mode, type, object, size, file]) => ({ mode, type, object, size, file }));
}
interface LsFilesElement {
mode: string;
object: string;
stage: string;
file: string;
}
export function parseLsFiles(raw: string): LsFilesElement[] {
return raw.split('\n')
.filter(l => !!l)
.map(line => /^(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/.exec(line)!)
.filter(m => !!m)
.map(([, mode, object, stage, file]) => ({ mode, object, stage, file }));
}
export interface DiffOptions {
cached?: boolean;
}
@@ -697,47 +742,72 @@ export class Repository {
return Promise.reject<Buffer>('Can\'t open file from git');
}
const { exitCode, stdout } = await exec(child);
const { exitCode, stdout, stderr } = await exec(child);
if (exitCode) {
return Promise.reject<Buffer>(new GitError({
const err = new GitError({
message: 'Could not show object.',
exitCode
}));
});
if (/exists on disk, but not in/.test(stderr)) {
err.gitErrorCode = GitErrorCodes.WrongCase;
}
return Promise.reject<Buffer>(err);
}
return stdout;
}
async lstree(treeish: string, path: string): Promise<{ mode: string, object: string, size: number }> {
async getObjectDetails(treeish: string, path: string): Promise<{ mode: string, object: string, size: number }> {
if (!treeish) { // index
const { stdout } = await this.run(['ls-files', '--stage', '--', path]);
const elements = await this.lsfiles(path);
const match = /^(\d+)\s+([0-9a-f]{40})\s+(\d+)/.exec(stdout);
if (!match) {
if (elements.length === 0) {
throw new GitError({ message: 'Error running ls-files' });
}
const [, mode, object] = match;
const { mode, object } = elements[0];
const catFile = await this.run(['cat-file', '-s', object]);
const size = parseInt(catFile.stdout);
return { mode, object, size };
}
const { stdout } = await this.run(['ls-tree', '-l', treeish, '--', path]);
const elements = await this.lstree(treeish, path);
const match = /^(\d+)\s+(\w+)\s+([0-9a-f]{40})\s+(\d+)/.exec(stdout);
if (!match) {
throw new GitError({ message: 'Error running ls-tree' });
if (elements.length === 0) {
throw new GitError({ message: 'Error running ls-files' });
}
const [, mode, , object, size] = match;
const { mode, object, size } = elements[0];
return { mode, object, size: parseInt(size) };
}
async lstree(treeish: string, path: string): Promise<LsTreeElement[]> {
const { stdout } = await this.run(['ls-tree', '-l', treeish, '--', path]);
return parseLsTree(stdout);
}
async lsfiles(path: string): Promise<LsFilesElement[]> {
const { stdout } = await this.run(['ls-files', '--stage', '--', path]);
return parseLsFiles(stdout);
}
async getGitRelativePath(ref: string, relativePath: string): Promise<string> {
const relativePathLowercase = relativePath.toLowerCase();
const dirname = path.posix.dirname(relativePath) + '/';
const elements: { file: string; }[] = ref ? await this.lstree(ref, dirname) : await this.lsfiles(dirname);
const element = elements.filter(file => file.file.toLowerCase() === relativePathLowercase)[0];
if (!element) {
throw new GitError({ message: 'Git relative path not found.' });
}
return element.file;
}
async detectObjectType(object: string): Promise<{ mimetype: string, encoding?: string }> {
const child = await this.stream(['show', object]);
const buffer = await readBytes(child.stdout, 4100);
@@ -820,7 +890,7 @@ export class Repository {
let mode: string;
try {
const details = await this.lstree('HEAD', path);
const details = await this.getObjectDetails('HEAD', path);
mode = details.mode;
} catch (err) {
mode = '100644';
@@ -874,27 +944,41 @@ export class Repository {
try {
await this.run(args, { input: message || '' });
} catch (commitErr) {
if (/not possible because you have unmerged files/.test(commitErr.stderr || '')) {
commitErr.gitErrorCode = GitErrorCodes.UnmergedChanges;
throw commitErr;
}
await this.handleCommitError(commitErr);
}
}
try {
await this.run(['config', '--get-all', 'user.name']);
} catch (err) {
err.gitErrorCode = GitErrorCodes.NoUserNameConfigured;
throw err;
}
async rebaseContinue(): Promise<void> {
const args = ['rebase', '--continue'];
try {
await this.run(['config', '--get-all', 'user.email']);
} catch (err) {
err.gitErrorCode = GitErrorCodes.NoUserEmailConfigured;
throw err;
}
try {
await this.run(args);
} catch (commitErr) {
await this.handleCommitError(commitErr);
}
}
private async handleCommitError(commitErr: any): Promise<void> {
if (/not possible because you have unmerged files/.test(commitErr.stderr || '')) {
commitErr.gitErrorCode = GitErrorCodes.UnmergedChanges;
throw commitErr;
}
try {
await this.run(['config', '--get-all', 'user.name']);
} catch (err) {
err.gitErrorCode = GitErrorCodes.NoUserNameConfigured;
throw err;
}
try {
await this.run(['config', '--get-all', 'user.email']);
} catch (err) {
err.gitErrorCode = GitErrorCodes.NoUserEmailConfigured;
throw err;
}
throw commitErr;
}
async branch(name: string, checkout: boolean): Promise<void> {
@@ -912,6 +996,11 @@ export class Repository {
await this.run(args);
}
async deleteRef(ref: string): Promise<void> {
const args = ['update-ref', '-d', ref];
await this.run(args);
}
async merge(ref: string): Promise<void> {
const args = ['merge', ref];
@@ -1226,14 +1315,34 @@ export class Repository {
async getRemotes(): Promise<Remote[]> {
const result = await this.run(['remote', '--verbose']);
const regex = /^([^\s]+)\s+([^\s]+)\s/;
const rawRemotes = result.stdout.trim().split('\n')
.filter(b => !!b)
.map(line => regex.exec(line) as RegExpExecArray)
.filter(g => !!g)
.map((groups: RegExpExecArray) => ({ name: groups[1], url: groups[2] }));
const lines = result.stdout.trim().split('\n').filter(l => !!l);
const remotes: Remote[] = [];
return uniqBy(rawRemotes, remote => remote.name);
for (const line of lines) {
const parts = line.split(/\s/);
const [name, url, type] = parts;
let remote = remotes.find(r => r.name === name);
if (!remote) {
remote = { name, isReadOnly: false };
remotes.push(remote);
}
if (/fetch/i.test(type)) {
remote.fetchUrl = url;
} else if (/push/i.test(type)) {
remote.pushUrl = url;
} else {
remote.fetchUrl = url;
remote.pushUrl = url;
}
// https://github.com/Microsoft/vscode/issues/45271
remote.isReadOnly = remote.pushUrl === undefined || remote.pushUrl === 'no_push';
}
return remotes;
}
async getBranch(name: string): Promise<Branch> {
@@ -1306,14 +1415,8 @@ export class Repository {
}
async getCommit(ref: string): Promise<Commit> {
const result = await this.run(['show', '-s', '--format=%H\n%B', ref]);
const match = /^([0-9a-f]{40})\n([^]*)$/m.exec(result.stdout.trim());
if (!match) {
return Promise.reject<Commit>('bad commit format');
}
return { hash: match[1], message: match[2] };
const result = await this.run(['show', '-s', '--format=%H\n%P\n%B', ref]);
return parseGitCommit(result.stdout) || Promise.reject<Commit>('bad commit format');
}
async updateSubmodules(paths: string[]): Promise<void> {
+49 -58
View File
@@ -16,15 +16,23 @@ import { GitDecorations } from './decorationProvider';
import { Askpass } from './askpass';
import { toDisposable, filterEvent, eventToPromise } from './util';
import TelemetryReporter from 'vscode-extension-telemetry';
import { API, createApi } from './api';
import { API, NoopAPIImpl, APIImpl } from './api';
import { GitProtocolHandler } from './protocolHandler';
let telemetryReporter: TelemetryReporter;
const deactivateTasks: { (): Promise<any>; }[] = [];
async function init(context: ExtensionContext, outputChannel: OutputChannel, disposables: Disposable[]): Promise<Model> {
export async function deactivate(): Promise<any> {
for (const task of deactivateTasks) {
await task();
}
}
async function createModel(context: ExtensionContext, outputChannel: OutputChannel, telemetryReporter: TelemetryReporter, disposables: Disposable[]): Promise<Model> {
const pathHint = workspace.getConfiguration('git').get<string>('path');
const info = await findGit(pathHint, path => outputChannel.appendLine(localize('looking', "Looking for git in: {0}", path)));
const askpass = new Askpass();
disposables.push(askpass);
const env = await askpass.getEnv();
const git = new Git({ gitPath: info.path, version: info.version, env });
const model = new Model(git, context.globalState, outputChannel);
@@ -61,13 +69,30 @@ async function init(context: ExtensionContext, outputChannel: OutputChannel, dis
return model;
}
async function _activate(context: ExtensionContext, disposables: Disposable[]): Promise<Model | undefined> {
export async function activate(context: ExtensionContext): Promise<API> {
const disposables: Disposable[] = [];
context.subscriptions.push(new Disposable(() => Disposable.from(...disposables).dispose()));
const outputChannel = window.createOutputChannel('Git');
commands.registerCommand('git.showOutput', () => outputChannel.show());
disposables.push(outputChannel);
const { name, version, aiKey } = require(context.asAbsolutePath('./package.json')) as { name: string, version: string, aiKey: string };
const telemetryReporter = new TelemetryReporter(name, version, aiKey);
deactivateTasks.push(() => telemetryReporter.dispose());
const config = workspace.getConfiguration('git', null);
const enabled = config.get<boolean>('enabled');
if (!enabled) {
const onConfigChange = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git'));
const onEnabled = filterEvent(onConfigChange, () => workspace.getConfiguration('git', null).get<boolean>('enabled') === true);
await eventToPromise(onEnabled);
}
try {
return await init(context, outputChannel, disposables);
const model = await createModel(context, outputChannel, telemetryReporter, disposables);
return new APIImpl(model);
} catch (err) {
if (!/Git installation not found/.test(err.message || '')) {
throw err;
@@ -76,60 +101,30 @@ async function _activate(context: ExtensionContext, disposables: Disposable[]):
const config = workspace.getConfiguration('git');
const shouldIgnore = config.get<boolean>('ignoreMissingGitWarning') === true;
if (shouldIgnore) {
return;
if (!shouldIgnore) {
console.warn(err.message);
outputChannel.appendLine(err.message);
outputChannel.show();
const download = localize('downloadgit', "Download Git");
const neverShowAgain = localize('neverShowAgain', "Don't Show Again");
const choice = await window.showWarningMessage(
localize('notfound', "Git not found. Install it or configure it using the 'git.path' setting."),
download,
neverShowAgain
);
if (choice === download) {
commands.executeCommand('vscode.open', Uri.parse('https://git-scm.com/'));
} else if (choice === neverShowAgain) {
await config.update('ignoreMissingGitWarning', true, true);
}
}
console.warn(err.message);
outputChannel.appendLine(err.message);
outputChannel.show();
const download = localize('downloadgit', "Download Git");
const neverShowAgain = localize('neverShowAgain', "Don't Show Again");
const choice = await window.showWarningMessage(
localize('notfound', "Git not found. Install it or configure it using the 'git.path' setting."),
download,
neverShowAgain
);
if (choice === download) {
commands.executeCommand('vscode.open', Uri.parse('https://git-scm.com/'));
} else if (choice === neverShowAgain) {
await config.update('ignoreMissingGitWarning', true, true);
}
return new NoopAPIImpl();
}
}
export function activate(context: ExtensionContext): API {
const config = workspace.getConfiguration('git', null);
const enabled = config.get<boolean>('enabled');
const disposables: Disposable[] = [];
context.subscriptions.push(new Disposable(() => Disposable.from(...disposables).dispose()));
const { name, version, aiKey } = require(context.asAbsolutePath('./package.json')) as { name: string, version: string, aiKey: string };
telemetryReporter = new TelemetryReporter(name, version, aiKey);
let activatePromise: Promise<Model | undefined>;
if (enabled) {
activatePromise = _activate(context, disposables);
} else {
const onConfigChange = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git'));
const onEnabled = filterEvent(onConfigChange, () => workspace.getConfiguration('git', null).get<boolean>('enabled') === true);
activatePromise = eventToPromise(onEnabled)
.then(() => _activate(context, disposables));
}
const modelPromise = activatePromise
.then(model => model || Promise.reject<Model>('Git model not found'));
activatePromise.catch(err => console.error(err));
return createApi(modelPromise);
}
async function checkGitVersion(info: IGit): Promise<void> {
// {{SQL CARBON EDIT}}
@@ -166,7 +161,3 @@ async function checkGitVersion(info: IGit): Promise<void> {
// {{SQL CARBON EDIT}}
*/
}
export function deactivate(): Promise<any> {
return telemetryReporter ? telemetryReporter.dispose() : Promise.resolve(null);
}
+22 -8
View File
@@ -91,6 +91,13 @@ export class Model {
* for git repositories.
*/
private async scanWorkspaceFolders(): Promise<void> {
const config = workspace.getConfiguration('git');
const autoRepositoryDetection = config.get<boolean | 'subFolders' | 'openEditors'>('autoRepositoryDetection');
if (autoRepositoryDetection !== true && autoRepositoryDetection !== 'subFolders') {
return;
}
for (const folder of workspace.workspaceFolders || []) {
const root = folder.uri.fsPath;
@@ -99,7 +106,7 @@ export class Model {
children
.filter(child => child !== '.git')
.forEach(child => this.tryOpenRepository(path.join(root, child)));
.forEach(child => this.openRepository(path.join(root, child)));
} catch (err) {
// noop
}
@@ -118,7 +125,7 @@ export class Model {
@debounce(500)
private eventuallyScanPossibleGitRepositories(): void {
for (const path of this.possibleGitRepositoryPaths) {
this.tryOpenRepository(path);
this.openRepository(path);
}
this.possibleGitRepositoryPaths.clear();
@@ -139,7 +146,7 @@ export class Model {
.filter(r => !activeRepositories.has(r!.repository))
.filter(r => !(workspace.workspaceFolders || []).some(f => isDescendant(f.uri.fsPath, r!.repository.root))) as OpenRepository[];
possibleRepositoryFolders.forEach(p => this.tryOpenRepository(p.uri.fsPath));
possibleRepositoryFolders.forEach(p => this.openRepository(p.uri.fsPath));
openRepositoriesToDispose.forEach(r => r.dispose());
}
@@ -153,15 +160,15 @@ export class Model {
.filter(({ root }) => workspace.getConfiguration('git', root).get<boolean>('enabled') !== true)
.map(({ repository }) => repository);
possibleRepositoryFolders.forEach(p => this.tryOpenRepository(p.uri.fsPath));
possibleRepositoryFolders.forEach(p => this.openRepository(p.uri.fsPath));
openRepositoriesToDispose.forEach(r => r.dispose());
}
private onDidChangeVisibleTextEditors(editors: TextEditor[]): void {
const config = workspace.getConfiguration('git');
const enabled = config.get<boolean>('autoRepositoryDetection') === true;
const autoRepositoryDetection = config.get<boolean | 'subFolders' | 'openEditors'>('autoRepositoryDetection');
if (!enabled) {
if (autoRepositoryDetection !== true && autoRepositoryDetection !== 'openEditors') {
return;
}
@@ -178,12 +185,12 @@ export class Model {
return;
}
this.tryOpenRepository(path.dirname(uri.fsPath));
this.openRepository(path.dirname(uri.fsPath));
});
}
@sequentialize
async tryOpenRepository(path: string): Promise<void> {
async openRepository(path: string): Promise<void> {
if (this.getRepository(path)) {
return;
}
@@ -207,6 +214,13 @@ export class Model {
return;
}
const config = workspace.getConfiguration('git');
const ignoredRepos = new Set(config.get<Array<string>>('ignoredRepositories'));
if (ignoredRepos.has(rawRoot)) {
return;
}
const repository = new Repository(this.git.open(repositoryRoot), this.globalState);
this.open(repository);
+3 -3
View File
@@ -5,16 +5,16 @@
'use strict';
import { ProtocolHandler, Uri, window, Disposable, commands } from 'vscode';
import { UriHandler, Uri, window, Disposable, commands } from 'vscode';
import { dispose } from './util';
import * as querystring from 'querystring';
export class GitProtocolHandler implements ProtocolHandler {
export class GitProtocolHandler implements UriHandler {
private disposables: Disposable[] = [];
constructor() {
this.disposables.push(window.registerProtocolHandler(this));
this.disposables.push(window.registerUriHandler(this));
}
handleUri(uri: Uri): void {
+114 -21
View File
@@ -217,7 +217,8 @@ export class Resource implements SourceControlResourceState {
case Status.INDEX_DELETED:
case Status.DELETED:
return new ThemeColor('gitDecoration.deletedResourceForeground');
case Status.INDEX_ADDED: // todo@joh - special color?
case Status.INDEX_ADDED:
return new ThemeColor('gitDecoration.addedResourceForeground');
case Status.INDEX_RENAMED: // todo@joh - special color?
case Status.UNTRACKED:
return new ThemeColor('gitDecoration.untrackedResourceForeground');
@@ -292,13 +293,15 @@ export enum Operation {
GetCommitTemplate = 'GetCommitTemplate',
DeleteBranch = 'DeleteBranch',
RenameBranch = 'RenameBranch',
DeleteRef = 'DeleteRef',
Merge = 'Merge',
Ignore = 'Ignore',
Tag = 'Tag',
Stash = 'Stash',
CheckIgnore = 'CheckIgnore',
LSTree = 'LSTree',
SubmoduleUpdate = 'SubmoduleUpdate'
GetObjectDetails = 'GetObjectDetails',
SubmoduleUpdate = 'SubmoduleUpdate',
RebaseContinue = 'RebaseContinue',
}
function isReadOnly(operation: Operation): boolean {
@@ -306,7 +309,7 @@ function isReadOnly(operation: Operation): boolean {
case Operation.Show:
case Operation.GetCommitTemplate:
case Operation.CheckIgnore:
case Operation.LSTree:
case Operation.GetObjectDetails:
return true;
default:
return false;
@@ -317,7 +320,7 @@ function shouldShowProgress(operation: Operation): boolean {
switch (operation) {
case Operation.Fetch:
case Operation.CheckIgnore:
case Operation.LSTree:
case Operation.GetObjectDetails:
case Operation.Show:
return false;
default:
@@ -478,6 +481,22 @@ export class Repository implements Disposable {
return this._submodules;
}
private _rebaseCommit: Commit | undefined = undefined;
set rebaseCommit(rebaseCommit: Commit | undefined) {
if (this._rebaseCommit && !rebaseCommit) {
this.inputBox.value = '';
} else if (rebaseCommit && (!this._rebaseCommit || this._rebaseCommit.hash !== rebaseCommit.hash)) {
this.inputBox.value = rebaseCommit.message;
}
this._rebaseCommit = rebaseCommit;
}
get rebaseCommit(): Commit | undefined {
return this._rebaseCommit;
}
private _operations = new OperationsImpl();
get operations(): Operations { return this._operations; }
@@ -539,6 +558,16 @@ export class Repository implements Disposable {
this.disposables.push(new AutoFetcher(this, globalState));
// https://github.com/Microsoft/vscode/issues/39039
const onSuccessfulPush = filterEvent(this.onDidRunOperation, e => e.operation === Operation.Push && !e.error);
onSuccessfulPush(() => {
const gitConfig = workspace.getConfiguration('git');
if (gitConfig.get<boolean>('showPushSuccessNotification')) {
window.showInformationMessage(localize('push success', "Successfully pushed."));
}
}, null, this.disposables);
const statusBar = new StatusBarCommands(this);
this.disposables.push(statusBar);
statusBar.onDidChange(() => this._sourceControl.statusBarCommands = statusBar.commands, null, this.disposables);
@@ -552,6 +581,15 @@ export class Repository implements Disposable {
}
validateInput(text: string, position: number): SourceControlInputBoxValidation | undefined {
if (this.rebaseCommit) {
if (this.rebaseCommit.message !== text) {
return {
message: localize('commit in rebase', "It's not possible to change the commit message in the middle of a rebase. Please complete the rebase operation and use interactive rebase instead."),
type: SourceControlInputBoxValidationType.Warning
};
}
}
const config = workspace.getConfiguration('git');
const setting = config.get<'always' | 'warn' | 'off'>('inputValidation');
@@ -559,6 +597,13 @@ export class Repository implements Disposable {
return;
}
if (/^\s+$/.test(text)) {
return {
message: localize('commitMessageWhitespacesOnlyWarning', "Current commit message only contains whitespace characters"),
type: SourceControlInputBoxValidationType.Warning
};
}
let start = 0, end;
let match: RegExpExecArray | null;
const regex = /\r?\n/g;
@@ -628,13 +673,23 @@ export class Repository implements Disposable {
}
async commit(message: string, opts: CommitOptions = Object.create(null)): Promise<void> {
await this.run(Operation.Commit, async () => {
if (opts.all) {
await this.repository.add([]);
}
if (this.rebaseCommit) {
await this.run(Operation.RebaseContinue, async () => {
if (opts.all) {
await this.repository.add([]);
}
await this.repository.commit(message, opts);
});
await this.repository.rebaseContinue();
});
} else {
await this.run(Operation.Commit, async () => {
if (opts.all) {
await this.repository.add([]);
}
await this.repository.commit(message, opts);
});
}
}
async clean(resources: Uri[]): Promise<void> {
@@ -722,6 +777,10 @@ export class Repository implements Disposable {
await this.run(Operation.Reset, () => this.repository.reset(treeish, hard));
}
async deleteRef(ref: string): Promise<void> {
await this.run(Operation.DeleteRef, () => this.repository.deleteRef(ref));
}
@throttle
async fetch(): Promise<void> {
await this.run(Operation.Fetch, () => this.repository.fetch());
@@ -789,35 +848,50 @@ export class Repository implements Disposable {
}
private async _sync(head: Branch, rebase: boolean): Promise<void> {
let remote: string | undefined;
let remoteName: string | undefined;
let pullBranch: string | undefined;
let pushBranch: string | undefined;
if (head.name && head.upstream) {
remote = head.upstream.remote;
remoteName = head.upstream.remote;
pullBranch = `${head.upstream.name}`;
pushBranch = `${head.name}:${head.upstream.name}`;
}
await this.run(Operation.Sync, async () => {
await this.repository.pull(rebase, remote, pullBranch);
await this.repository.pull(rebase, remoteName, pullBranch);
const shouldPush = this.HEAD && typeof this.HEAD.ahead === 'number' ? this.HEAD.ahead > 0 : true;
const remote = this.remotes.find(r => r.name === remoteName);
if (remote && remote.isReadOnly) {
return;
}
const shouldPush = this.HEAD && (typeof this.HEAD.ahead === 'number' ? this.HEAD.ahead > 0 : true);
if (shouldPush) {
await this.repository.push(remote, pushBranch);
await this.repository.push(remoteName, pushBranch);
}
});
}
async show(ref: string, filePath: string): Promise<string> {
return this.run(Operation.Show, () => {
return await this.run(Operation.Show, async () => {
const relativePath = path.relative(this.repository.root, filePath).replace(/\\/g, '/');
const configFiles = workspace.getConfiguration('files', Uri.file(filePath));
const defaultEncoding = configFiles.get<string>('encoding');
const autoGuessEncoding = configFiles.get<boolean>('autoGuessEncoding');
return this.repository.bufferString(`${ref}:${relativePath}`, defaultEncoding, autoGuessEncoding);
try {
return await this.repository.bufferString(`${ref}:${relativePath}`, defaultEncoding, autoGuessEncoding);
} catch (err) {
if (err.gitErrorCode === GitErrorCodes.WrongCase) {
const gitRelativePath = await this.repository.getGitRelativePath(ref, relativePath);
return await this.repository.bufferString(`${ref}:${gitRelativePath}`, defaultEncoding, autoGuessEncoding);
}
throw err;
}
});
}
@@ -828,8 +902,8 @@ export class Repository implements Disposable {
});
}
lstree(ref: string, filePath: string): Promise<{ mode: string, object: string, size: number }> {
return this.run(Operation.LSTree, () => this.repository.lstree(ref, filePath));
getObjectDetails(ref: string, filePath: string): Promise<{ mode: string, object: string, size: number }> {
return this.run(Operation.GetObjectDetails, () => this.repository.getObjectDetails(ref, filePath));
}
detectObjectType(object: string): Promise<{ mimetype: string, encoding?: string }> {
@@ -1011,12 +1085,13 @@ export class Repository implements Disposable {
// noop
}
const [refs, remotes, submodules] = await Promise.all([this.repository.getRefs(), this.repository.getRemotes(), this.repository.getSubmodules()]);
const [refs, remotes, submodules, rebaseCommit] = await Promise.all([this.repository.getRefs(), this.repository.getRemotes(), this.repository.getSubmodules(), this.getRebaseCommit()]);
this._HEAD = HEAD;
this._refs = refs;
this._remotes = remotes;
this._submodules = submodules;
this.rebaseCommit = rebaseCommit;
const index: Resource[] = [];
const workingTree: Resource[] = [];
@@ -1075,6 +1150,17 @@ export class Repository implements Disposable {
this._onDidChangeStatus.fire();
}
private async getRebaseCommit(): Promise<Commit | undefined> {
const rebaseHeadPath = path.join(this.repository.root, '.git', 'REBASE_HEAD');
try {
const rebaseHead = await new Promise<string>((c, e) => fs.readFile(rebaseHeadPath, 'utf8', (err, result) => err ? e(err) : c(result)));
return await this.getCommit(rebaseHead.trim());
} catch (err) {
return undefined;
}
}
private onFSChange(uri: Uri): void {
const config = workspace.getConfiguration('git');
const autorefresh = config.get<boolean>('autorefresh');
@@ -1150,6 +1236,13 @@ export class Repository implements Disposable {
return '';
}
const remoteName = this.HEAD && this.HEAD.remote || this.HEAD.upstream.remote;
const remote = this.remotes.find(r => r.name === remoteName);
if (remote && remote.isReadOnly) {
return `${this.HEAD.behind}`;
}
return `${this.HEAD.behind}${this.HEAD.ahead}`;
}
+8 -6
View File
@@ -24,7 +24,8 @@ class CheckoutStatusBar {
}
get command(): Command | undefined {
const title = `$(git-branch) ${this.repository.headLabel}`;
const rebasing = !!this.repository.rebaseCommit;
const title = `$(git-branch) ${this.repository.headLabel}${rebasing ? ` (${localize('rebasing', 'Rebasing')})` : ''}`;
return {
command: 'git.checkout',
@@ -71,10 +72,11 @@ class SyncStatusBar {
}
private onOperationsChange(): void {
this.state = {
...this.state,
isSyncRunning: this.repository.operations.isRunning(Operation.Sync)
};
const isSyncRunning = this.repository.operations.isRunning(Operation.Sync) ||
this.repository.operations.isRunning(Operation.Push) ||
this.repository.operations.isRunning(Operation.Pull);
this.state = { ...this.state, isSyncRunning };
}
private onModelChange(): void {
@@ -173,4 +175,4 @@ export class StatusBarCommands {
this.checkoutStatusBar.dispose();
this.disposables = dispose(this.disposables);
}
}
}
+103 -1
View File
@@ -6,7 +6,7 @@
'use strict';
import 'mocha';
import { GitStatusParser, parseGitmodules } from '../git';
import { GitStatusParser, parseGitCommit, parseGitmodules, parseLsTree, parseLsFiles } from '../git';
import * as assert from 'assert';
suite('git', () => {
@@ -175,4 +175,106 @@ suite('git', () => {
]);
});
});
suite('parseGitCommit', () => {
test('single parent commit', function () {
const GIT_OUTPUT_SINGLE_PARENT = `52c293a05038d865604c2284aa8698bd087915a1
8e5a374372b8393906c7e380dbb09349c5385554
This is a commit message.`;
assert.deepEqual(parseGitCommit(GIT_OUTPUT_SINGLE_PARENT), {
hash: '52c293a05038d865604c2284aa8698bd087915a1',
message: 'This is a commit message.',
parents: ['8e5a374372b8393906c7e380dbb09349c5385554']
});
});
test('multiple parent commits', function () {
const GIT_OUTPUT_MULTIPLE_PARENTS = `52c293a05038d865604c2284aa8698bd087915a1
8e5a374372b8393906c7e380dbb09349c5385554 df27d8c75b129ab9b178b386077da2822101b217
This is a commit message.`;
assert.deepEqual(parseGitCommit(GIT_OUTPUT_MULTIPLE_PARENTS), {
hash: '52c293a05038d865604c2284aa8698bd087915a1',
message: 'This is a commit message.',
parents: ['8e5a374372b8393906c7e380dbb09349c5385554', 'df27d8c75b129ab9b178b386077da2822101b217']
});
});
test('no parent commits', function () {
const GIT_OUTPUT_NO_PARENTS = `52c293a05038d865604c2284aa8698bd087915a1
This is a commit message.`;
assert.deepEqual(parseGitCommit(GIT_OUTPUT_NO_PARENTS), {
hash: '52c293a05038d865604c2284aa8698bd087915a1',
message: 'This is a commit message.',
parents: []
});
});
});
suite('parseLsTree', function () {
test('sample', function () {
const input = `040000 tree 0274a81f8ee9ca3669295dc40f510bd2021d0043 - .vscode
100644 blob 1d487c1817262e4f20efbfa1d04c18f51b0046f6 491570 Screen Shot 2018-06-01 at 14.48.05.png
100644 blob 686c16e4f019b734655a2576ce8b98749a9ffdb9 764420 Screen Shot 2018-06-07 at 20.04.59.png
100644 blob 257cc5642cb1a054f08cc83f2d943e56fd3ebe99 4 boom.txt
100644 blob 86dc360dd25f13fa50ffdc8259e9653921f4f2b7 11 boomcaboom.txt
100644 blob a68b14060589b16d7ac75f67b905c918c03c06eb 24 file.js
100644 blob f7bcfb05af46850d780f88c069edcd57481d822d 201 file.md
100644 blob ab8b86114a051f6490f1ec5e3141b9a632fb46b5 8 hello.js
100644 blob 257cc5642cb1a054f08cc83f2d943e56fd3ebe99 4 what.js
100644 blob be859e3f412fa86513cd8bebe8189d1ea1a3e46d 24 what.txt
100644 blob 56ec42c9dc6fcf4534788f0fe34b36e09f37d085 261186 what.txt2`;
const output = parseLsTree(input);
assert.deepEqual(output, [
{ mode: '040000', type: 'tree', object: '0274a81f8ee9ca3669295dc40f510bd2021d0043', size: '-', file: '.vscode' },
{ mode: '100644', type: 'blob', object: '1d487c1817262e4f20efbfa1d04c18f51b0046f6', size: '491570', file: 'Screen Shot 2018-06-01 at 14.48.05.png' },
{ mode: '100644', type: 'blob', object: '686c16e4f019b734655a2576ce8b98749a9ffdb9', size: '764420', file: 'Screen Shot 2018-06-07 at 20.04.59.png' },
{ mode: '100644', type: 'blob', object: '257cc5642cb1a054f08cc83f2d943e56fd3ebe99', size: '4', file: 'boom.txt' },
{ mode: '100644', type: 'blob', object: '86dc360dd25f13fa50ffdc8259e9653921f4f2b7', size: '11', file: 'boomcaboom.txt' },
{ mode: '100644', type: 'blob', object: 'a68b14060589b16d7ac75f67b905c918c03c06eb', size: '24', file: 'file.js' },
{ mode: '100644', type: 'blob', object: 'f7bcfb05af46850d780f88c069edcd57481d822d', size: '201', file: 'file.md' },
{ mode: '100644', type: 'blob', object: 'ab8b86114a051f6490f1ec5e3141b9a632fb46b5', size: '8', file: 'hello.js' },
{ mode: '100644', type: 'blob', object: '257cc5642cb1a054f08cc83f2d943e56fd3ebe99', size: '4', file: 'what.js' },
{ mode: '100644', type: 'blob', object: 'be859e3f412fa86513cd8bebe8189d1ea1a3e46d', size: '24', file: 'what.txt' },
{ mode: '100644', type: 'blob', object: '56ec42c9dc6fcf4534788f0fe34b36e09f37d085', size: '261186', file: 'what.txt2' }
]);
});
});
suite('parseLsFiles', function () {
test('sample', function () {
const input = `100644 7a73a41bfdf76d6f793007240d80983a52f15f97 0 .vscode/settings.json
100644 1d487c1817262e4f20efbfa1d04c18f51b0046f6 0 Screen Shot 2018-06-01 at 14.48.05.png
100644 686c16e4f019b734655a2576ce8b98749a9ffdb9 0 Screen Shot 2018-06-07 at 20.04.59.png
100644 257cc5642cb1a054f08cc83f2d943e56fd3ebe99 0 boom.txt
100644 86dc360dd25f13fa50ffdc8259e9653921f4f2b7 0 boomcaboom.txt
100644 a68b14060589b16d7ac75f67b905c918c03c06eb 0 file.js
100644 f7bcfb05af46850d780f88c069edcd57481d822d 0 file.md
100644 ab8b86114a051f6490f1ec5e3141b9a632fb46b5 0 hello.js
100644 257cc5642cb1a054f08cc83f2d943e56fd3ebe99 0 what.js
100644 be859e3f412fa86513cd8bebe8189d1ea1a3e46d 0 what.txt
100644 56ec42c9dc6fcf4534788f0fe34b36e09f37d085 0 what.txt2`;
const output = parseLsFiles(input);
assert.deepEqual(output, [
{ mode: '100644', object: '7a73a41bfdf76d6f793007240d80983a52f15f97', stage: '0', file: '.vscode/settings.json' },
{ mode: '100644', object: '1d487c1817262e4f20efbfa1d04c18f51b0046f6', stage: '0', file: 'Screen Shot 2018-06-01 at 14.48.05.png' },
{ mode: '100644', object: '686c16e4f019b734655a2576ce8b98749a9ffdb9', stage: '0', file: 'Screen Shot 2018-06-07 at 20.04.59.png' },
{ mode: '100644', object: '257cc5642cb1a054f08cc83f2d943e56fd3ebe99', stage: '0', file: 'boom.txt' },
{ mode: '100644', object: '86dc360dd25f13fa50ffdc8259e9653921f4f2b7', stage: '0', file: 'boomcaboom.txt' },
{ mode: '100644', object: 'a68b14060589b16d7ac75f67b905c918c03c06eb', stage: '0', file: 'file.js' },
{ mode: '100644', object: 'f7bcfb05af46850d780f88c069edcd57481d822d', stage: '0', file: 'file.md' },
{ mode: '100644', object: 'ab8b86114a051f6490f1ec5e3141b9a632fb46b5', stage: '0', file: 'hello.js' },
{ mode: '100644', object: '257cc5642cb1a054f08cc83f2d943e56fd3ebe99', stage: '0', file: 'what.js' },
{ mode: '100644', object: 'be859e3f412fa86513cd8bebe8189d1ea1a3e46d', stage: '0', file: 'what.txt' },
{ mode: '100644', object: '56ec42c9dc6fcf4534788f0fe34b36e09f37d085', stage: '0', file: 'what.txt2' },
]);
});
});
});
+10
View File
@@ -324,3 +324,13 @@ export function isDescendant(parent: string, descendant: string): boolean {
return descendant.startsWith(parent);
}
export function pathEquals(a: string, b: string): boolean {
// Windows is case insensitive
if (isWindowsPath(a)) {
a = a.toLowerCase();
b = b.toLowerCase();
}
return a === b;
}
@@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/textmate/git.tmbundle/commit/d1db42c2d71948662098183a6df519fb53a7a15b",
"version": "https://github.com/textmate/git.tmbundle/commit/3f6ad2138200db14b57a090ecb2d2e733275ca3e",
"name": "Git Rebase Message",
"scopeName": "text.git-rebase",
"patterns": [
@@ -29,7 +29,23 @@
"name": "meta.commit-message.git-rebase"
}
},
"match": "^\\s*(pick|p|reword|r|edit|e|squash|s|fixup|f|exec|x|drop|d)\\s+([0-9a-f]+)\\s+(.*)$",
"match": "^\\s*(pick|p|reword|r|edit|e|squash|s|fixup|f|drop|d)\\s+([0-9a-f]+)\\s+(.*)$",
"name": "meta.commit-command.git-rebase"
},
{
"captures": {
"1": {
"name": "support.function.git-rebase"
},
"2": {
"patterns": [
{
"include": "source.shell"
}
]
}
},
"match": "^\\s*(exec|x)\\s+(.*)$",
"name": "meta.commit-command.git-rebase"
}
]
@@ -0,0 +1,10 @@
{
"name": "Ignore",
"scopeName": "source.ignore",
"patterns": [
{
"match": "^#.*",
"name": "comment.line.number-sign.ignore"
}
]
}
@@ -3,10 +3,10 @@
"c": "This is the summary line. It can't be too long.",
"t": "text.git-commit meta.scope.message.git-commit meta.scope.subject.git-commit",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -14,10 +14,10 @@
"c": "After I can write a much more detailed description without quite the same restrictions on length.",
"t": "text.git-commit meta.scope.message.git-commit",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -25,10 +25,10 @@
"c": "#",
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -36,10 +36,10 @@
"c": " Please enter the commit message for your changes. Lines starting",
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -47,10 +47,10 @@
"c": "#",
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -58,10 +58,10 @@
"c": " with '#' will be ignored, and an empty message aborts the commit.",
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -69,10 +69,10 @@
"c": "#",
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -80,10 +80,10 @@
"c": " On branch master",
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -91,10 +91,10 @@
"c": "#",
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -102,10 +102,10 @@
"c": " Your branch is up-to-date with 'origin/master'.",
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -113,10 +113,10 @@
"c": "#",
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -124,10 +124,10 @@
"c": "#",
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -135,10 +135,10 @@
"c": " Changes to be committed:",
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -146,10 +146,10 @@
"c": "#",
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -157,10 +157,10 @@
"c": "\t",
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -168,10 +168,10 @@
"c": "deleted: README.md",
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit markup.deleted.git-commit",
"r": {
"dark_plus": "markup.deleted: #CE9178",
"light_plus": "markup.deleted: #A31515",
"dark_vs": "markup.deleted: #CE9178",
"light_vs": "markup.deleted: #A31515",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.deleted: #CE9178"
}
},
@@ -179,10 +179,10 @@
"c": "#",
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -190,10 +190,10 @@
"c": "\t",
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -201,10 +201,10 @@
"c": "modified: index.less",
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit markup.changed.git-commit",
"r": {
"dark_plus": "markup.changed: #569CD6",
"light_plus": "markup.changed: #0451A5",
"dark_vs": "markup.changed: #569CD6",
"light_vs": "markup.changed: #0451A5",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.changed: #569CD6"
}
},
@@ -212,10 +212,10 @@
"c": "#",
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -223,10 +223,10 @@
"c": "\t",
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -234,10 +234,10 @@
"c": "new file: spec/COMMIT_EDITMSG",
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit markup.inserted.git-commit",
"r": {
"dark_plus": "markup.inserted: #B5CEA8",
"light_plus": "markup.inserted: #09885A",
"dark_vs": "markup.inserted: #B5CEA8",
"light_vs": "markup.inserted: #09885A",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.inserted: #B5CEA8"
}
},
@@ -245,10 +245,10 @@
"c": "#",
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
}
@@ -3,10 +3,10 @@
"c": "diff --git a/helloworld.txt b/helloworld.txt",
"t": "source.diff meta.diff.header.git",
"r": {
"dark_plus": "meta.diff.header: #569CD6",
"light_plus": "meta.diff.header: #000080",
"dark_vs": "meta.diff.header: #569CD6",
"light_vs": "meta.diff.header: #000080",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "meta.diff.header: #000080"
}
},
@@ -14,10 +14,10 @@
"c": "index e4f37c4..557db03 100644",
"t": "source.diff meta.diff.index.git",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -25,10 +25,10 @@
"c": "---",
"t": "source.diff meta.diff.header.from-file punctuation.definition.from-file.diff",
"r": {
"dark_plus": "meta.diff.header: #569CD6",
"light_plus": "meta.diff.header: #000080",
"dark_vs": "meta.diff.header: #569CD6",
"light_vs": "meta.diff.header: #000080",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "meta.diff.header: #000080"
}
},
@@ -36,10 +36,10 @@
"c": " a/helloworld.txt",
"t": "source.diff meta.diff.header.from-file",
"r": {
"dark_plus": "meta.diff.header: #569CD6",
"light_plus": "meta.diff.header: #000080",
"dark_vs": "meta.diff.header: #569CD6",
"light_vs": "meta.diff.header: #000080",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "meta.diff.header: #000080"
}
},
@@ -47,10 +47,10 @@
"c": "+++",
"t": "source.diff meta.diff.header.to-file punctuation.definition.to-file.diff",
"r": {
"dark_plus": "meta.diff.header: #569CD6",
"light_plus": "meta.diff.header: #000080",
"dark_vs": "meta.diff.header: #569CD6",
"light_vs": "meta.diff.header: #000080",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "meta.diff.header: #000080"
}
},
@@ -58,10 +58,10 @@
"c": " b/helloworld.txt",
"t": "source.diff meta.diff.header.to-file",
"r": {
"dark_plus": "meta.diff.header: #569CD6",
"light_plus": "meta.diff.header: #000080",
"dark_vs": "meta.diff.header: #569CD6",
"light_vs": "meta.diff.header: #000080",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "meta.diff.header: #000080"
}
},
@@ -69,10 +69,10 @@
"c": "@@",
"t": "source.diff meta.diff.range.unified punctuation.definition.range.diff",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -80,10 +80,10 @@
"c": " ",
"t": "source.diff meta.diff.range.unified",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -91,10 +91,10 @@
"c": "-1 +1",
"t": "source.diff meta.diff.range.unified meta.toc-list.line-number.diff",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -102,10 +102,10 @@
"c": " ",
"t": "source.diff meta.diff.range.unified",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -113,10 +113,10 @@
"c": "@@",
"t": "source.diff meta.diff.range.unified punctuation.definition.range.diff",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -124,10 +124,10 @@
"c": "-",
"t": "source.diff markup.deleted.diff punctuation.definition.deleted.diff",
"r": {
"dark_plus": "markup.deleted: #CE9178",
"light_plus": "markup.deleted: #A31515",
"dark_vs": "markup.deleted: #CE9178",
"light_vs": "markup.deleted: #A31515",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.deleted: #CE9178"
}
},
@@ -135,10 +135,10 @@
"c": "Hello world",
"t": "source.diff markup.deleted.diff",
"r": {
"dark_plus": "markup.deleted: #CE9178",
"light_plus": "markup.deleted: #A31515",
"dark_vs": "markup.deleted: #CE9178",
"light_vs": "markup.deleted: #A31515",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.deleted: #CE9178"
}
},
@@ -146,10 +146,10 @@
"c": "+",
"t": "source.diff markup.inserted.diff punctuation.definition.inserted.diff",
"r": {
"dark_plus": "markup.inserted: #B5CEA8",
"light_plus": "markup.inserted: #09885A",
"dark_vs": "markup.inserted: #B5CEA8",
"light_vs": "markup.inserted: #09885A",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.inserted: #B5CEA8"
}
},
@@ -157,10 +157,10 @@
"c": "Hello World",
"t": "source.diff markup.inserted.diff",
"r": {
"dark_plus": "markup.inserted: #B5CEA8",
"light_plus": "markup.inserted: #09885A",
"dark_vs": "markup.inserted: #B5CEA8",
"light_vs": "markup.inserted: #09885A",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.inserted: #B5CEA8"
}
}
@@ -3,10 +3,10 @@
"c": "pick",
"t": "text.git-rebase meta.commit-command.git-rebase support.function.git-rebase",
"r": {
"dark_plus": "support.function.git-rebase: #9CDCFE",
"light_plus": "support.function.git-rebase: #0451A5",
"dark_vs": "support.function.git-rebase: #9CDCFE",
"light_vs": "support.function.git-rebase: #0451A5",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "support.function.git-rebase: #D4D4D4"
}
},
@@ -14,10 +14,10 @@
"c": " ",
"t": "text.git-rebase meta.commit-command.git-rebase",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -25,10 +25,10 @@
"c": "1fc6c95",
"t": "text.git-rebase meta.commit-command.git-rebase constant.sha.git-rebase",
"r": {
"dark_plus": "constant.sha.git-rebase: #B5CEA8",
"light_plus": "constant.sha.git-rebase: #09885A",
"dark_vs": "constant.sha.git-rebase: #B5CEA8",
"light_vs": "constant.sha.git-rebase: #09885A",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "constant.sha.git-rebase: #B5CEA8"
}
},
@@ -36,10 +36,10 @@
"c": " ",
"t": "text.git-rebase meta.commit-command.git-rebase",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -47,10 +47,10 @@
"c": "Patch A",
"t": "text.git-rebase meta.commit-command.git-rebase meta.commit-message.git-rebase",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -58,10 +58,10 @@
"c": "squash",
"t": "text.git-rebase meta.commit-command.git-rebase support.function.git-rebase",
"r": {
"dark_plus": "support.function.git-rebase: #9CDCFE",
"light_plus": "support.function.git-rebase: #0451A5",
"dark_vs": "support.function.git-rebase: #9CDCFE",
"light_vs": "support.function.git-rebase: #0451A5",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "support.function.git-rebase: #D4D4D4"
}
},
@@ -69,10 +69,10 @@
"c": " ",
"t": "text.git-rebase meta.commit-command.git-rebase",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -80,10 +80,10 @@
"c": "fa39187",
"t": "text.git-rebase meta.commit-command.git-rebase constant.sha.git-rebase",
"r": {
"dark_plus": "constant.sha.git-rebase: #B5CEA8",
"light_plus": "constant.sha.git-rebase: #09885A",
"dark_vs": "constant.sha.git-rebase: #B5CEA8",
"light_vs": "constant.sha.git-rebase: #09885A",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "constant.sha.git-rebase: #B5CEA8"
}
},
@@ -91,10 +91,10 @@
"c": " ",
"t": "text.git-rebase meta.commit-command.git-rebase",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -102,10 +102,10 @@
"c": "Something to add to patch A",
"t": "text.git-rebase meta.commit-command.git-rebase meta.commit-message.git-rebase",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -113,10 +113,10 @@
"c": "pick",
"t": "text.git-rebase meta.commit-command.git-rebase support.function.git-rebase",
"r": {
"dark_plus": "support.function.git-rebase: #9CDCFE",
"light_plus": "support.function.git-rebase: #0451A5",
"dark_vs": "support.function.git-rebase: #9CDCFE",
"light_vs": "support.function.git-rebase: #0451A5",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "support.function.git-rebase: #D4D4D4"
}
},
@@ -124,10 +124,10 @@
"c": " ",
"t": "text.git-rebase meta.commit-command.git-rebase",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -135,10 +135,10 @@
"c": "7b36971",
"t": "text.git-rebase meta.commit-command.git-rebase constant.sha.git-rebase",
"r": {
"dark_plus": "constant.sha.git-rebase: #B5CEA8",
"light_plus": "constant.sha.git-rebase: #09885A",
"dark_vs": "constant.sha.git-rebase: #B5CEA8",
"light_vs": "constant.sha.git-rebase: #09885A",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "constant.sha.git-rebase: #B5CEA8"
}
},
@@ -146,10 +146,10 @@
"c": " ",
"t": "text.git-rebase meta.commit-command.git-rebase",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -157,10 +157,10 @@
"c": "Something to move before patch B",
"t": "text.git-rebase meta.commit-command.git-rebase meta.commit-message.git-rebase",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -168,10 +168,10 @@
"c": "pick",
"t": "text.git-rebase meta.commit-command.git-rebase support.function.git-rebase",
"r": {
"dark_plus": "support.function.git-rebase: #9CDCFE",
"light_plus": "support.function.git-rebase: #0451A5",
"dark_vs": "support.function.git-rebase: #9CDCFE",
"light_vs": "support.function.git-rebase: #0451A5",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "support.function.git-rebase: #D4D4D4"
}
},
@@ -179,10 +179,10 @@
"c": " ",
"t": "text.git-rebase meta.commit-command.git-rebase",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -190,10 +190,10 @@
"c": "6b2481b",
"t": "text.git-rebase meta.commit-command.git-rebase constant.sha.git-rebase",
"r": {
"dark_plus": "constant.sha.git-rebase: #B5CEA8",
"light_plus": "constant.sha.git-rebase: #09885A",
"dark_vs": "constant.sha.git-rebase: #B5CEA8",
"light_vs": "constant.sha.git-rebase: #09885A",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "constant.sha.git-rebase: #B5CEA8"
}
},
@@ -201,10 +201,10 @@
"c": " ",
"t": "text.git-rebase meta.commit-command.git-rebase",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -212,10 +212,10 @@
"c": "Patch B",
"t": "text.git-rebase meta.commit-command.git-rebase meta.commit-message.git-rebase",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -223,10 +223,10 @@
"c": "fixup",
"t": "text.git-rebase meta.commit-command.git-rebase support.function.git-rebase",
"r": {
"dark_plus": "support.function.git-rebase: #9CDCFE",
"light_plus": "support.function.git-rebase: #0451A5",
"dark_vs": "support.function.git-rebase: #9CDCFE",
"light_vs": "support.function.git-rebase: #0451A5",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "support.function.git-rebase: #D4D4D4"
}
},
@@ -234,10 +234,10 @@
"c": " ",
"t": "text.git-rebase meta.commit-command.git-rebase",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -245,10 +245,10 @@
"c": "c619268",
"t": "text.git-rebase meta.commit-command.git-rebase constant.sha.git-rebase",
"r": {
"dark_plus": "constant.sha.git-rebase: #B5CEA8",
"light_plus": "constant.sha.git-rebase: #09885A",
"dark_vs": "constant.sha.git-rebase: #B5CEA8",
"light_vs": "constant.sha.git-rebase: #09885A",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "constant.sha.git-rebase: #B5CEA8"
}
},
@@ -256,10 +256,10 @@
"c": " ",
"t": "text.git-rebase meta.commit-command.git-rebase",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -267,10 +267,10 @@
"c": "A fix for Patch B",
"t": "text.git-rebase meta.commit-command.git-rebase meta.commit-message.git-rebase",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -278,10 +278,10 @@
"c": "edit",
"t": "text.git-rebase meta.commit-command.git-rebase support.function.git-rebase",
"r": {
"dark_plus": "support.function.git-rebase: #9CDCFE",
"light_plus": "support.function.git-rebase: #0451A5",
"dark_vs": "support.function.git-rebase: #9CDCFE",
"light_vs": "support.function.git-rebase: #0451A5",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "support.function.git-rebase: #D4D4D4"
}
},
@@ -289,10 +289,10 @@
"c": " ",
"t": "text.git-rebase meta.commit-command.git-rebase",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -300,10 +300,10 @@
"c": "dd1475d",
"t": "text.git-rebase meta.commit-command.git-rebase constant.sha.git-rebase",
"r": {
"dark_plus": "constant.sha.git-rebase: #B5CEA8",
"light_plus": "constant.sha.git-rebase: #09885A",
"dark_vs": "constant.sha.git-rebase: #B5CEA8",
"light_vs": "constant.sha.git-rebase: #09885A",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "constant.sha.git-rebase: #B5CEA8"
}
},
@@ -311,10 +311,10 @@
"c": " ",
"t": "text.git-rebase meta.commit-command.git-rebase",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -322,10 +322,10 @@
"c": "Something I want to split",
"t": "text.git-rebase meta.commit-command.git-rebase meta.commit-message.git-rebase",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -333,10 +333,10 @@
"c": "reword",
"t": "text.git-rebase meta.commit-command.git-rebase support.function.git-rebase",
"r": {
"dark_plus": "support.function.git-rebase: #9CDCFE",
"light_plus": "support.function.git-rebase: #0451A5",
"dark_vs": "support.function.git-rebase: #9CDCFE",
"light_vs": "support.function.git-rebase: #0451A5",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "support.function.git-rebase: #D4D4D4"
}
},
@@ -344,10 +344,10 @@
"c": " ",
"t": "text.git-rebase meta.commit-command.git-rebase",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -355,10 +355,10 @@
"c": "4ca2acc",
"t": "text.git-rebase meta.commit-command.git-rebase constant.sha.git-rebase",
"r": {
"dark_plus": "constant.sha.git-rebase: #B5CEA8",
"light_plus": "constant.sha.git-rebase: #09885A",
"dark_vs": "constant.sha.git-rebase: #B5CEA8",
"light_vs": "constant.sha.git-rebase: #09885A",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "constant.sha.git-rebase: #B5CEA8"
}
},
@@ -366,10 +366,10 @@
"c": " ",
"t": "text.git-rebase meta.commit-command.git-rebase",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -377,10 +377,10 @@
"c": "i cant' typ goods",
"t": "text.git-rebase meta.commit-command.git-rebase meta.commit-message.git-rebase",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
@@ -388,10 +388,10 @@
"c": "#",
"t": "text.git-rebase comment.line.number-sign.git-rebase punctuation.definition.comment.git-rebase",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -399,10 +399,10 @@
"c": " Commands:",
"t": "text.git-rebase comment.line.number-sign.git-rebase",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -410,10 +410,10 @@
"c": "#",
"t": "text.git-rebase comment.line.number-sign.git-rebase punctuation.definition.comment.git-rebase",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -421,10 +421,10 @@
"c": " p, pick = use commit",
"t": "text.git-rebase comment.line.number-sign.git-rebase",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -432,10 +432,10 @@
"c": "#",
"t": "text.git-rebase comment.line.number-sign.git-rebase punctuation.definition.comment.git-rebase",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -443,10 +443,10 @@
"c": " r, reword = use commit, but edit the commit message",
"t": "text.git-rebase comment.line.number-sign.git-rebase",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -454,10 +454,10 @@
"c": "#",
"t": "text.git-rebase comment.line.number-sign.git-rebase punctuation.definition.comment.git-rebase",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -465,10 +465,10 @@
"c": " e, edit = use commit, but stop for amending",
"t": "text.git-rebase comment.line.number-sign.git-rebase",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -476,10 +476,10 @@
"c": "#",
"t": "text.git-rebase comment.line.number-sign.git-rebase punctuation.definition.comment.git-rebase",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -487,10 +487,10 @@
"c": " s, squash = use commit, but meld into previous commit",
"t": "text.git-rebase comment.line.number-sign.git-rebase",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -498,10 +498,10 @@
"c": "#",
"t": "text.git-rebase comment.line.number-sign.git-rebase punctuation.definition.comment.git-rebase",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -509,10 +509,10 @@
"c": " f, fixup = like \"squash\", but discard this commit's log message",
"t": "text.git-rebase comment.line.number-sign.git-rebase",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -520,10 +520,10 @@
"c": "#",
"t": "text.git-rebase comment.line.number-sign.git-rebase punctuation.definition.comment.git-rebase",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
},
@@ -531,10 +531,10 @@
"c": " x, exec = run command (the rest of the line) using shell",
"t": "text.git-rebase comment.line.number-sign.git-rebase",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "comment: #7CA668"
}
}
+6 -6
View File
@@ -257,15 +257,15 @@ supports-color@3.1.2:
dependencies:
has-flag "^1.0.0"
vscode-extension-telemetry@0.0.17:
version "0.0.17"
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.17.tgz#15123e7edb34e7b9724b6056f54a869bbb922cb7"
vscode-extension-telemetry@0.0.18:
version "0.0.18"
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz#602ba20d8c71453aa34533a291e7638f6e5c0327"
dependencies:
applicationinsights "1.0.1"
vscode-nls@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.1.tgz#b1f3e04e8a94a715d5a7bcbc8339c51e6d74ca51"
vscode-nls@^3.2.4:
version "3.2.4"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.4.tgz#2166b4183c8aea884d20727f5449e62be69fd398"
which@^1.3.0:
version "1.3.0"
@@ -0,0 +1,7 @@
# Language Features for JSON files
**Notice:** This extension is bundled with Visual Studio Code. It can be disabled but not uninstalled.
## Features
See [JSON in Visual Studio Code](https://code.visualstudio.com/docs/languages/json) to learn about the features of this extension.
@@ -8,12 +8,10 @@ import * as path from 'path';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
import { workspace, languages, ExtensionContext, extensions, Uri, LanguageConfiguration, TextDocument, FoldingRangeKind, FoldingRange, Disposable, FoldingContext } from 'vscode';
import { LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType, DidChangeConfigurationNotification, CancellationToken } from 'vscode-languageclient';
import { workspace, languages, ExtensionContext, extensions, Uri, LanguageConfiguration } from 'vscode';
import { LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType, DidChangeConfigurationNotification } from 'vscode-languageclient';
import TelemetryReporter from 'vscode-extension-telemetry';
import { FoldingRangeRequest, FoldingRangeRequestParam, FoldingRangeClientCapabilities, FoldingRangeKind as LSFoldingRangeKind } from 'vscode-languageserver-protocol-foldingprovider';
import { hash } from './utils/hash';
namespace VSCodeContentRequest {
@@ -97,21 +95,6 @@ export function activate(context: ExtensionContext) {
// Create the language client and start the client.
let client = new LanguageClient('json', localize('jsonserver.name', 'JSON Language Server'), serverOptions, clientOptions);
client.registerProposedFeatures();
client.registerFeature({
fillClientCapabilities(capabilities: FoldingRangeClientCapabilities): void {
let textDocumentCap = capabilities.textDocument;
if (!textDocumentCap) {
textDocumentCap = capabilities.textDocument = {};
}
textDocumentCap.foldingRange = {
dynamicRegistration: false,
rangeLimit: 5000,
lineFoldingOnly: true
};
},
initialize(capabilities, documentSelector): void {
}
});
let disposable = client.start();
toDispose.push(disposable);
@@ -141,8 +124,6 @@ export function activate(context: ExtensionContext) {
toDispose.push(workspace.onDidCloseTextDocument(d => handleContentChange(d.uri)));
client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociation(context));
toDispose.push(initFoldingProvider());
});
let languageConfiguration: LanguageConfiguration = {
@@ -154,38 +135,6 @@ export function activate(context: ExtensionContext) {
};
languages.setLanguageConfiguration('json', languageConfiguration);
languages.setLanguageConfiguration('jsonc', languageConfiguration);
function initFoldingProvider(): Disposable {
function getKind(kind: string | undefined): FoldingRangeKind | undefined {
if (kind) {
switch (kind) {
case LSFoldingRangeKind.Comment:
return FoldingRangeKind.Comment;
case LSFoldingRangeKind.Imports:
return FoldingRangeKind.Imports;
case LSFoldingRangeKind.Region:
return FoldingRangeKind.Region;
}
}
return void 0;
}
return languages.registerFoldingRangeProvider(documentSelector, {
provideFoldingRanges(document: TextDocument, context: FoldingContext, token: CancellationToken) {
const param: FoldingRangeRequestParam = {
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document)
};
return client.sendRequest(FoldingRangeRequest.type, param, token).then(ranges => {
if (Array.isArray(ranges)) {
return ranges.map(r => new FoldingRange(r.startLine, r.endLine, getKind(r.kind)));
}
return null;
}, error => {
client.logFailedRequest(FoldingRangeRequest.type, error);
return null;
});
}
});
}
}
export function deactivate(): Promise<any> {
@@ -251,11 +200,22 @@ function getSettings(): Settings {
settings.json!.schemas!.push(schemaSetting);
}
let fileMatches = setting.fileMatch;
let resultingFileMatches = schemaSetting.fileMatch!;
if (Array.isArray(fileMatches)) {
if (fileMatchPrefix) {
fileMatches = fileMatches.map(m => fileMatchPrefix + m);
for (let fileMatch of fileMatches) {
if (fileMatch[0] === '/') {
resultingFileMatches.push(fileMatchPrefix + fileMatch);
resultingFileMatches.push(fileMatchPrefix + '/*' + fileMatch);
} else {
resultingFileMatches.push(fileMatchPrefix + '/' + fileMatch);
resultingFileMatches.push(fileMatchPrefix + '/*/' + fileMatch);
}
}
} else {
resultingFileMatches.push(...fileMatches);
}
schemaSetting.fileMatch!.push(...fileMatches);
}
if (setting.schema) {
schemaSetting.schema = setting.schema;
@@ -276,10 +236,10 @@ function getSettings(): Settings {
let folderSchemas = schemaConfigInfo!.workspaceFolderValue;
if (Array.isArray(folderSchemas)) {
let folderPath = folderUri.toString();
if (folderPath[folderPath.length - 1] !== '/') {
folderPath = folderPath + '/';
if (folderPath[folderPath.length - 1] === '/') {
folderPath = folderPath.substr(0, folderPath.length - 1);
}
collectSchemaSettings(folderSchemas, folderUri.fsPath, folderPath + '*');
collectSchemaSettings(folderSchemas, folderUri.fsPath, folderPath);
}
}
}
@@ -100,10 +100,9 @@
}
},
"dependencies": {
"vscode-extension-telemetry": "0.0.17",
"vscode-languageclient": "^4.0.0",
"vscode-languageserver-protocol-foldingprovider": "^2.0.0-next.2",
"vscode-nls": "^3.2.2"
"vscode-extension-telemetry": "0.0.18",
"vscode-languageclient": "^4.4.0",
"vscode-nls": "^3.2.4"
},
"devDependencies": {
"@types/node": "7.0.43"
@@ -6,7 +6,7 @@
"json.schemas.fileMatch.desc": "An array of file patterns to match against when resolving JSON files to schemas.",
"json.schemas.fileMatch.item.desc": "A file pattern that can contain '*' to match against when resolving JSON files to schemas.",
"json.schemas.schema.desc": "The schema definition for the given URL. The schema only needs to be provided to avoid accesses to the schema URL.",
"json.format.enable.desc": "Enable/disable default JSON formatter (requires restart)",
"json.format.enable.desc": "Enable/disable default JSON formatter",
"json.tracing.desc": "Traces the communication between VS Code and the JSON language server.",
"json.colorDecorators.enable.desc": "Enables or disables color decorators",
"json.colorDecorators.enable.deprecationMessage": "The setting `json.colorDecorators.enable` has been deprecated in favor of `editor.colorDecorators`."
@@ -11,13 +11,12 @@
"vscode-json-languageserver": "./bin/vscode-json-languageserver"
},
"dependencies": {
"jsonc-parser": "^2.0.0-next.1",
"request-light": "^0.2.2",
"vscode-json-languageservice": "^3.1.2-next.2",
"vscode-languageserver": "^4.0.0",
"vscode-languageserver-protocol-foldingprovider": "^2.0.0-next.2",
"vscode-nls": "^3.2.2",
"vscode-uri": "^1.0.3"
"jsonc-parser": "^2.0.1",
"request-light": "^0.2.3",
"vscode-json-languageservice": "^3.1.4",
"vscode-languageserver": "^4.4.0",
"vscode-nls": "^3.2.4",
"vscode-uri": "^1.0.5"
},
"devDependencies": {
"@types/mocha": "2.2.33",
@@ -19,8 +19,6 @@ import { formatError, runSafe, runSafeAsync } from './utils/runner';
import { JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration } from 'vscode-json-languageservice';
import { getLanguageModelCache } from './languageModelCache';
import { FoldingRangeRequest, FoldingRangeServerCapabilities } from 'vscode-languageserver-protocol-foldingprovider';
interface ISchemaAssociations {
[pattern: string]: string[];
}
@@ -38,7 +36,7 @@ namespace SchemaContentChangeNotification {
}
// Create a connection for the server
let connection: IConnection = createConnection();
const connection: IConnection = createConnection();
process.on('unhandledRejection', (e: any) => {
console.error(formatError(`Unhandled exception`, e));
@@ -53,7 +51,7 @@ console.error = connection.console.error.bind(connection.console);
// Create a simple text document manager. The text document manager
// supports full document sync only
let documents: TextDocuments = new TextDocuments();
const documents: TextDocuments = new TextDocuments();
// Make the text document manager listen on the connection
// for open, change and close text document events
documents.listen(connection);
@@ -67,7 +65,7 @@ let foldingRangeLimit = Number.MAX_VALUE;
connection.onInitialize((params: InitializeParams): InitializeResult => {
function getClientCapability<T>(name: string, def: T) {
let keys = name.split('.');
const keys = name.split('.');
let c: any = params.capabilities;
for (let i = 0; c && i < keys.length; i++) {
if (!c.hasOwnProperty(keys[i])) {
@@ -81,29 +79,29 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
clientSnippetSupport = getClientCapability('textDocument.completion.completionItem.snippetSupport', false);
clientDynamicRegisterSupport = getClientCapability('workspace.symbol.dynamicRegistration', false);
foldingRangeLimit = getClientCapability('textDocument.foldingRange.rangeLimit', Number.MAX_VALUE);
let capabilities: ServerCapabilities & FoldingRangeServerCapabilities = {
const capabilities: ServerCapabilities = {
// Tell the client that the server works in FULL text document sync mode
textDocumentSync: documents.syncKind,
completionProvider: clientSnippetSupport ? { resolveProvider: true, triggerCharacters: ['"', ':'] } : void 0,
hoverProvider: true,
documentSymbolProvider: true,
documentRangeFormattingProvider: false,
colorProvider: true,
colorProvider: {},
foldingRangeProvider: true
};
return { capabilities };
});
let workspaceContext = {
const workspaceContext = {
resolveRelativePath: (relativePath: string, resource: string) => {
return URL.resolve(resource, relativePath);
}
};
let schemaRequestService = (uri: string): Thenable<string> => {
const schemaRequestService = (uri: string): Thenable<string> => {
if (startsWith(uri, 'file://')) {
let fsPath = URI.parse(uri).fsPath;
const fsPath = URI.parse(uri).fsPath;
return new Promise<string>((c, e) => {
fs.readFile(fsPath, 'UTF-8', (err, result) => {
err ? e('') : c(result.toString());
@@ -129,7 +127,7 @@ let schemaRequestService = (uri: string): Thenable<string> => {
}
});
}
let headers = { 'Accept-Encoding': 'gzip, deflate' };
const headers = { 'Accept-Encoding': 'gzip, deflate' };
return xhr({ url: uri, followRedirects: 5, headers }).then(response => {
return response.responseText;
}, (error: XHRResponse) => {
@@ -138,7 +136,7 @@ let schemaRequestService = (uri: string): Thenable<string> => {
};
// create the JSON language service
let languageService = getLanguageService({
const languageService = getLanguageService({
schemaRequestService,
workspaceContext,
contributions: []
@@ -176,7 +174,7 @@ connection.onDidChangeConfiguration((change) => {
// dynamically enable & disable the formatter
if (clientDynamicRegisterSupport) {
let enableFormatter = settings && settings.json && settings.json.format && settings.json.format.enable;
const enableFormatter = settings && settings.json && settings.json.format && settings.json.format.enable;
if (enableFormatter) {
if (!formatterRegistration) {
formatterRegistration = connection.client.register(DocumentRangeFormattingRequest.type, { documentSelector: [{ language: 'json' }, { language: 'jsonc' }] });
@@ -200,14 +198,14 @@ connection.onNotification(SchemaContentChangeNotification.type, uri => {
});
function updateConfiguration() {
let languageSettings = {
const languageSettings = {
validate: true,
allowComments: true,
schemas: new Array<SchemaConfiguration>()
};
if (schemaAssociations) {
for (var pattern in schemaAssociations) {
let association = schemaAssociations[pattern];
const association = schemaAssociations[pattern];
if (Array.isArray(association)) {
association.forEach(uri => {
languageSettings.schemas.push({ uri, fileMatch: [pattern] });
@@ -244,11 +242,11 @@ documents.onDidClose(event => {
connection.sendDiagnostics({ uri: event.document.uri, diagnostics: [] });
});
let pendingValidationRequests: { [uri: string]: NodeJS.Timer; } = {};
const pendingValidationRequests: { [uri: string]: NodeJS.Timer; } = {};
const validationDelayMs = 500;
function cleanPendingValidation(textDocument: TextDocument): void {
let request = pendingValidationRequests[textDocument.uri];
const request = pendingValidationRequests[textDocument.uri];
if (request) {
clearTimeout(request);
delete pendingValidationRequests[textDocument.uri];
@@ -269,13 +267,13 @@ function validateTextDocument(textDocument: TextDocument): void {
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics: [] });
return;
}
let jsonDocument = getJSONDocument(textDocument);
let version = textDocument.version;
const jsonDocument = getJSONDocument(textDocument);
const version = textDocument.version;
let documentSettings: DocumentLanguageSettings = textDocument.languageId === 'jsonc' ? { comments: 'ignore', trailingCommas: 'ignore' } : { comments: 'error', trailingCommas: 'error' };
const documentSettings: DocumentLanguageSettings = textDocument.languageId === 'jsonc' ? { comments: 'ignore', trailingCommas: 'ignore' } : { comments: 'error', trailingCommas: 'error' };
languageService.doValidation(textDocument, jsonDocument, documentSettings).then(diagnostics => {
setTimeout(() => {
let currDocument = documents.get(textDocument.uri);
const currDocument = documents.get(textDocument.uri);
if (currDocument && currDocument.version === version) {
// Send the computed diagnostics to VSCode.
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
@@ -299,7 +297,7 @@ connection.onDidChangeWatchedFiles((change) => {
}
});
let jsonDocuments = getLanguageModelCache<JSONDocument>(10, 60, document => languageService.parseJSONDocument(document));
const jsonDocuments = getLanguageModelCache<JSONDocument>(10, 60, document => languageService.parseJSONDocument(document));
documents.onDidClose(e => {
jsonDocuments.onDocumentRemoved(e.document);
});
@@ -312,10 +310,13 @@ function getJSONDocument(document: TextDocument): JSONDocument {
}
connection.onCompletion((textDocumentPosition, token) => {
return runSafeAsync(() => {
let document = documents.get(textDocumentPosition.textDocument.uri);
let jsonDocument = getJSONDocument(document);
return languageService.doComplete(document, textDocumentPosition.position, jsonDocument);
return runSafeAsync(async () => {
const document = documents.get(textDocumentPosition.textDocument.uri);
if (document) {
const jsonDocument = getJSONDocument(document);
return languageService.doComplete(document, textDocumentPosition.position, jsonDocument);
}
return null;
}, null, `Error while computing completions for ${textDocumentPosition.textDocument.uri}`, token);
});
@@ -326,53 +327,62 @@ connection.onCompletionResolve((completionItem, token) => {
});
connection.onHover((textDocumentPositionParams, token) => {
return runSafeAsync(() => {
let document = documents.get(textDocumentPositionParams.textDocument.uri);
let jsonDocument = getJSONDocument(document);
return languageService.doHover(document, textDocumentPositionParams.position, jsonDocument);
return runSafeAsync(async () => {
const document = documents.get(textDocumentPositionParams.textDocument.uri);
if (document) {
const jsonDocument = getJSONDocument(document);
return languageService.doHover(document, textDocumentPositionParams.position, jsonDocument);
}
return null;
}, null, `Error while computing hover for ${textDocumentPositionParams.textDocument.uri}`, token);
});
connection.onDocumentSymbol((documentSymbolParams, token) => {
return runSafe(() => {
let document = documents.get(documentSymbolParams.textDocument.uri);
let jsonDocument = getJSONDocument(document);
return languageService.findDocumentSymbols(document, jsonDocument);
const document = documents.get(documentSymbolParams.textDocument.uri);
if (document) {
const jsonDocument = getJSONDocument(document);
return languageService.findDocumentSymbols(document, jsonDocument);
}
return [];
}, [], `Error while computing document symbols for ${documentSymbolParams.textDocument.uri}`, token);
});
connection.onDocumentRangeFormatting((formatParams, token) => {
return runSafe(() => {
let document = documents.get(formatParams.textDocument.uri);
return languageService.format(document, formatParams.range, formatParams.options);
const document = documents.get(formatParams.textDocument.uri);
if (document) {
return languageService.format(document, formatParams.range, formatParams.options);
}
return [];
}, [], `Error while formatting range for ${formatParams.textDocument.uri}`, token);
});
connection.onDocumentColor((params, token) => {
return runSafeAsync(() => {
let document = documents.get(params.textDocument.uri);
return runSafeAsync(async () => {
const document = documents.get(params.textDocument.uri);
if (document) {
let jsonDocument = getJSONDocument(document);
const jsonDocument = getJSONDocument(document);
return languageService.findDocumentColors(document, jsonDocument);
}
return Promise.resolve([]);
return [];
}, [], `Error while computing document colors for ${params.textDocument.uri}`, token);
});
connection.onColorPresentation((params, token) => {
return runSafe(() => {
let document = documents.get(params.textDocument.uri);
const document = documents.get(params.textDocument.uri);
if (document) {
let jsonDocument = getJSONDocument(document);
const jsonDocument = getJSONDocument(document);
return languageService.getColorPresentations(document, jsonDocument, params.color, params.range);
}
return [];
}, [], `Error while computing color presentations for ${params.textDocument.uri}`, token);
});
connection.onRequest(FoldingRangeRequest.type, (params, token) => {
connection.onFoldingRanges((params, token) => {
return runSafe(() => {
let document = documents.get(params.textDocument.uri);
const document = documents.get(params.textDocument.uri);
if (document) {
return languageService.getFoldingRanges(document, { rangeLimit: foldingRangeLimit });
}
@@ -16,13 +16,7 @@ agent-base@4, agent-base@^4.1.0:
dependencies:
es6-promisify "^5.0.0"
debug@2:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
dependencies:
ms "2.0.0"
debug@^3.1.0:
debug@3.1.0, debug@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
dependencies:
@@ -38,98 +32,75 @@ es6-promisify@^5.0.0:
dependencies:
es6-promise "^4.0.3"
http-proxy-agent@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.0.0.tgz#46482a2f0523a4d6082551709f469cb3e4a85ff4"
http-proxy-agent@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405"
dependencies:
agent-base "4"
debug "2"
debug "3.1.0"
https-proxy-agent@2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.1.1.tgz#a7ce4382a1ba8266ee848578778122d491260fd9"
https-proxy-agent@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0"
dependencies:
agent-base "^4.1.0"
debug "^3.1.0"
jsonc-parser@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.0.0.tgz#62ff087a7e753875febf3c55f1fc0cd737c36b5a"
jsonc-parser@^2.0.0-next.1:
version "2.0.0-next.1"
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.0.0-next.1.tgz#445a824f765a96abfbb286d759a9b1d226b18088"
jsonc-parser@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.0.1.tgz#9d23cd2709714fff508a1a6679d82135bee1ae60"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
request-light@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.2.2.tgz#53e48af32ad1514e45221ea5ece5ce782720f712"
request-light@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.2.3.tgz#a18635ec6dd92f8705c019c42ef645f684d94f7e"
dependencies:
http-proxy-agent "2.0.0"
https-proxy-agent "2.1.1"
vscode-nls "^2.0.2"
http-proxy-agent "^2.1.0"
https-proxy-agent "^2.2.1"
vscode-nls "^3.2.2"
vscode-json-languageservice@^3.1.2-next.2:
version "3.1.2-next.2"
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.1.2-next.2.tgz#da5346e5c22edbce739f29c110eb41732d41dc2d"
vscode-json-languageservice@^3.1.4:
version "3.1.4"
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.1.4.tgz#72e84e2754ad117f9e8d36876c1a66fe16234235"
dependencies:
jsonc-parser "^2.0.0"
vscode-languageserver-types "^3.6.1"
vscode-nls "^3.2.1"
jsonc-parser "^2.0.1"
vscode-languageserver-types "^3.10.0"
vscode-nls "^3.2.4"
vscode-uri "^1.0.5"
vscode-jsonrpc@^3.6.2:
version "3.6.2"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-3.6.2.tgz#3b5eef691159a15556ecc500e9a8a0dd143470c8"
vscode-languageserver-protocol@^3.10.0:
version "3.10.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.10.0.tgz#f8dcdf987687f64a26e7c32d498fc781a0e886dc"
dependencies:
vscode-jsonrpc "^3.6.2"
vscode-languageserver-types "^3.10.0"
vscode-languageserver-types@^3.10.0:
version "3.10.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.10.0.tgz#944e5308f3b36a3f372c766f1a344e903ec9c389"
vscode-languageserver@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-4.4.0.tgz#b6e8b37a739ccb629d92f3635f0099d191c856fa"
dependencies:
vscode-languageserver-protocol "^3.10.0"
vscode-uri "^1.0.3"
vscode-jsonrpc@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-3.6.0.tgz#848d56995d5168950d84feb5d9c237ae5c6a02d4"
vscode-languageserver-protocol-foldingprovider@^2.0.0-next.2:
version "2.0.0-next.2"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol-foldingprovider/-/vscode-languageserver-protocol-foldingprovider-2.0.0-next.2.tgz#fbb9cfdf5b8c4ac451826ba6312f1f88379f35b0"
dependencies:
vscode-languageserver-protocol "^3.6.0"
vscode-languageserver-types "^3.6.0"
vscode-languageserver-protocol@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.6.0.tgz#579642cdcccf74b0cd771c33daa3239acb40d040"
dependencies:
vscode-jsonrpc "^3.6.0"
vscode-languageserver-types "^3.6.0"
vscode-languageserver-types@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.6.0.tgz#0bba63b0fa82a714394a4478f55a596ee4ed7d0a"
vscode-languageserver-types@^3.6.1:
version "3.6.1"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.6.1.tgz#4bc06a48dff653495f12f94b8b1e228988a1748d"
vscode-languageserver@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-4.0.0.tgz#8b792f0d6d10acfe363d02371ed4ce53d08af88a"
dependencies:
vscode-languageserver-protocol "^3.6.0"
vscode-uri "^1.0.1"
vscode-nls@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-2.0.2.tgz#808522380844b8ad153499af5c3b03921aea02da"
vscode-nls@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.1.tgz#b1f3e04e8a94a715d5a7bcbc8339c51e6d74ca51"
vscode-nls@^3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.2.tgz#3817eca5b985c2393de325197cf4e15eb2aa5350"
vscode-uri@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.1.tgz#11a86befeac3c4aa3ec08623651a3c81a6d0bbc8"
vscode-nls@^3.2.2, vscode-nls@^3.2.4:
version "3.2.4"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.4.tgz#2166b4183c8aea884d20727f5449e62be69fd398"
vscode-uri@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.3.tgz#631bdbf716dccab0e65291a8dc25c23232085a52"
vscode-uri@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.5.tgz#3b899a8ef71c37f3054d79bdbdda31c7bf36f20d"
+21 -28
View File
@@ -28,43 +28,36 @@ semver@^5.3.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
vscode-extension-telemetry@0.0.17:
version "0.0.17"
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.17.tgz#15123e7edb34e7b9724b6056f54a869bbb922cb7"
vscode-extension-telemetry@0.0.18:
version "0.0.18"
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz#602ba20d8c71453aa34533a291e7638f6e5c0327"
dependencies:
applicationinsights "1.0.1"
vscode-jsonrpc@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-3.6.0.tgz#848d56995d5168950d84feb5d9c237ae5c6a02d4"
vscode-jsonrpc@^3.6.2:
version "3.6.2"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-3.6.2.tgz#3b5eef691159a15556ecc500e9a8a0dd143470c8"
vscode-languageclient@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-4.0.0.tgz#635f5bfbcfa1385dae489b394857f1db8b459a7d"
vscode-languageclient@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-4.4.0.tgz#b05868f6477b6f0c9910b24daae4f3e8c4b65902"
dependencies:
vscode-languageserver-protocol "^3.6.0"
vscode-languageserver-protocol "^3.10.0"
vscode-languageserver-protocol-foldingprovider@^2.0.0-next.2:
version "2.0.0-next.2"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol-foldingprovider/-/vscode-languageserver-protocol-foldingprovider-2.0.0-next.2.tgz#fbb9cfdf5b8c4ac451826ba6312f1f88379f35b0"
vscode-languageserver-protocol@^3.10.0:
version "3.10.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.10.0.tgz#f8dcdf987687f64a26e7c32d498fc781a0e886dc"
dependencies:
vscode-languageserver-protocol "^3.6.0"
vscode-languageserver-types "^3.6.0"
vscode-jsonrpc "^3.6.2"
vscode-languageserver-types "^3.10.0"
vscode-languageserver-protocol@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.6.0.tgz#579642cdcccf74b0cd771c33daa3239acb40d040"
dependencies:
vscode-jsonrpc "^3.6.0"
vscode-languageserver-types "^3.6.0"
vscode-languageserver-types@^3.10.0:
version "3.10.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.10.0.tgz#944e5308f3b36a3f372c766f1a344e903ec9c389"
vscode-languageserver-types@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.6.0.tgz#0bba63b0fa82a714394a4478f55a596ee4ed7d0a"
vscode-nls@^3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.2.tgz#3817eca5b985c2393de325197cf4e15eb2aa5350"
vscode-nls@^3.2.4:
version "3.2.4"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.4.tgz#2166b4183c8aea884d20727f5449e62be69fd398"
zone.js@0.7.6:
version "0.7.6"
+41
View File
@@ -0,0 +1,41 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
var updateGrammar = require('../../../build/npm/update-grammar');
function adaptJSON(grammar, replacementScope) {
grammar.name = 'JSON with comments';
grammar.scopeName = `source${replacementScope}`;
var fixScopeNames = function(rule) {
if (typeof rule.name === 'string') {
rule.name = rule.name.replace(/\.json/g, replacementScope);
}
if (typeof rule.contentName === 'string') {
rule.contentName = rule.contentName.replace(/\.json/g, replacementScope);
}
for (var property in rule) {
var value = rule[property];
if (typeof value === 'object') {
fixScopeNames(value);
}
}
};
var repository = grammar.repository;
for (var key in repository) {
fixScopeNames(repository[key]);
}
}
var tsGrammarRepo = 'Microsoft/vscode-JSON.tmLanguage';
updateGrammar.update(tsGrammarRepo, 'JSON.tmLanguage', './syntaxes/JSON.tmLanguage.json');
updateGrammar.update(tsGrammarRepo, 'JSON.tmLanguage', './syntaxes/JSONC.tmLanguage.json', grammar => adaptJSON(grammar, '.json.comments'));
+7 -17
View File
@@ -8,7 +8,7 @@
"vscode": "0.10.x"
},
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js Microsoft/vscode-JSON.tmLanguage JSON.tmLanguage ./syntaxes/JSON.tmLanguage.json"
"update-grammar": "node ./build/update-grammars.js"
},
"contributes": {
"languages": [
@@ -25,7 +25,9 @@
".jscsrc",
".eslintrc",
".babelrc",
".webmanifest"
".webmanifest",
".js.map",
".css.map"
],
"filenames": [
".watchmanconfig",
@@ -43,19 +45,7 @@
"JSON with Comments"
],
"extensions": [
".code-workspace",
"language-configuration.json",
"icon-theme.json",
"color-theme.json",
".code-snippets"
],
"filenames": [
"settings.json",
"launch.json",
"tasks.json",
"keybindings.json",
"tsconfig.json",
"jsconfig.json"
".jsonc"
],
"configuration": "./language-configuration.json"
}
@@ -68,8 +58,8 @@
},
{
"language": "jsonc",
"scopeName": "source.json",
"path": "./syntaxes/JSON.tmLanguage.json"
"scopeName": "source.json.comments",
"path": "./syntaxes/JSONC.tmLanguage.json"
}
],
"jsonValidation": [
@@ -0,0 +1,213 @@
{
"information_for_contributors": [
"This file has been converted from https://github.com/Microsoft/vscode-JSON.tmLanguage/blob/master/JSON.tmLanguage",
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/Microsoft/vscode-JSON.tmLanguage/commit/9bd83f1c252b375e957203f21793316203f61f70",
"name": "JSON with comments",
"scopeName": "source.json.comments",
"patterns": [
{
"include": "#value"
}
],
"repository": {
"array": {
"begin": "\\[",
"beginCaptures": {
"0": {
"name": "punctuation.definition.array.begin.json.comments"
}
},
"end": "\\]",
"endCaptures": {
"0": {
"name": "punctuation.definition.array.end.json.comments"
}
},
"name": "meta.structure.array.json.comments",
"patterns": [
{
"include": "#value"
},
{
"match": ",",
"name": "punctuation.separator.array.json.comments"
},
{
"match": "[^\\s\\]]",
"name": "invalid.illegal.expected-array-separator.json.comments"
}
]
},
"comments": {
"patterns": [
{
"begin": "/\\*\\*(?!/)",
"captures": {
"0": {
"name": "punctuation.definition.comment.json.comments"
}
},
"end": "\\*/",
"name": "comment.block.documentation.json.comments"
},
{
"begin": "/\\*",
"captures": {
"0": {
"name": "punctuation.definition.comment.json.comments"
}
},
"end": "\\*/",
"name": "comment.block.json.comments"
},
{
"captures": {
"1": {
"name": "punctuation.definition.comment.json.comments"
}
},
"match": "(//).*$\\n?",
"name": "comment.line.double-slash.js"
}
]
},
"constant": {
"match": "\\b(?:true|false|null)\\b",
"name": "constant.language.json.comments"
},
"number": {
"match": "(?x) # turn on extended mode\n -? # an optional minus\n (?:\n 0 # a zero\n | # ...or...\n [1-9] # a 1-9 character\n \\d* # followed by zero or more digits\n )\n (?:\n (?:\n \\. # a period\n \\d+ # followed by one or more digits\n )?\n (?:\n [eE] # an e character\n [+-]? # followed by an option +/-\n \\d+ # followed by one or more digits\n )? # make exponent optional\n )? # make decimal portion optional",
"name": "constant.numeric.json.comments"
},
"object": {
"begin": "\\{",
"beginCaptures": {
"0": {
"name": "punctuation.definition.dictionary.begin.json.comments"
}
},
"end": "\\}",
"endCaptures": {
"0": {
"name": "punctuation.definition.dictionary.end.json.comments"
}
},
"name": "meta.structure.dictionary.json.comments",
"patterns": [
{
"comment": "the JSON object key",
"include": "#objectkey"
},
{
"include": "#comments"
},
{
"begin": ":",
"beginCaptures": {
"0": {
"name": "punctuation.separator.dictionary.key-value.json.comments"
}
},
"end": "(,)|(?=\\})",
"endCaptures": {
"1": {
"name": "punctuation.separator.dictionary.pair.json.comments"
}
},
"name": "meta.structure.dictionary.value.json.comments",
"patterns": [
{
"comment": "the JSON object value",
"include": "#value"
},
{
"match": "[^\\s,]",
"name": "invalid.illegal.expected-dictionary-separator.json.comments"
}
]
},
{
"match": "[^\\s\\}]",
"name": "invalid.illegal.expected-dictionary-separator.json.comments"
}
]
},
"string": {
"begin": "\"",
"beginCaptures": {
"0": {
"name": "punctuation.definition.string.begin.json.comments"
}
},
"end": "\"",
"endCaptures": {
"0": {
"name": "punctuation.definition.string.end.json.comments"
}
},
"name": "string.quoted.double.json.comments",
"patterns": [
{
"include": "#stringcontent"
}
]
},
"objectkey": {
"begin": "\"",
"beginCaptures": {
"0": {
"name": "punctuation.support.type.property-name.begin.json.comments"
}
},
"end": "\"",
"endCaptures": {
"0": {
"name": "punctuation.support.type.property-name.end.json.comments"
}
},
"name": "string.json.comments support.type.property-name.json.comments",
"patterns": [
{
"include": "#stringcontent"
}
]
},
"stringcontent": {
"patterns": [
{
"match": "(?x) # turn on extended mode\n \\\\ # a literal backslash\n (?: # ...followed by...\n [\"\\\\/bfnrt] # one of these characters\n | # ...or...\n u # a u\n [0-9a-fA-F]{4}) # and four hex digits",
"name": "constant.character.escape.json.comments"
},
{
"match": "\\\\.",
"name": "invalid.illegal.unrecognized-string-escape.json.comments"
}
]
},
"value": {
"patterns": [
{
"include": "#constant"
},
{
"include": "#number"
},
{
"include": "#string"
},
{
"include": "#array"
},
{
"include": "#object"
},
{
"include": "#comments"
}
]
}
}
}
File diff suppressed because it is too large Load Diff
@@ -36,7 +36,9 @@
"surroundingPairs": [
["(", ")"],
["[", "]"],
["`", "`"]
["`", "`"],
["_", "_"],
["*", "*"]
],
"folding": {
"offSide": true,
+3 -2
View File
@@ -19,7 +19,8 @@
".md",
".mdown",
".markdown",
".markdn"
".markdn",
".workbook"
],
"configuration": "./language-configuration.json"
}
@@ -57,7 +58,7 @@
"meta.embedded.block.dockerfile": "dockerfile",
"meta.embedded.block.go": "go",
"meta.embedded.block.groovy": "groovy",
"meta.embedded.block.jade": "jade",
"meta.embedded.block.pug": "jade",
"meta.embedded.block.javascript": "javascript",
"meta.embedded.block.json": "json",
"meta.embedded.block.less": "less",
@@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/e667795f83c83e36dc6f90bde14632a963c52e34",
"version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/4504240cdb13a4640f64fc98a0adb858226a879e",
"name": "Markdown",
"scopeName": "text.html.markdown",
"patterns": [
@@ -109,7 +109,7 @@
"include": "#fenced_code_block_groovy"
},
{
"include": "#fenced_code_block_jade"
"include": "#fenced_code_block_pug"
},
{
"include": "#fenced_code_block_js"
@@ -162,6 +162,9 @@
{
"include": "#fenced_code_block_fsharp"
},
{
"include": "#fenced_code_block_dart"
},
{
"include": "#fenced_code_block_unknown"
},
@@ -719,7 +722,7 @@
"contentName": "meta.embedded.block.dosbatch",
"patterns": [
{
"include": "source.dosbatch"
"include": "source.batchfile"
}
]
}
@@ -1055,7 +1058,7 @@
}
]
},
"fenced_code_block_jade": {
"fenced_code_block_pug": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(jade|pug)(\\s+[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
@@ -1079,10 +1082,10 @@
{
"begin": "(^|\\G)(\\s*)(.*)",
"while": "(^|\\G)(?!\\s*([`~]{3,})\\s*$)",
"contentName": "meta.embedded.block.jade",
"contentName": "meta.embedded.block.pug",
"patterns": [
{
"include": "text.jade"
"include": "text.pug"
}
]
}
@@ -1649,6 +1652,39 @@
}
]
},
"fenced_code_block_dart": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(dart)(\\s+[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
"3": {
"name": "punctuation.definition.markdown"
},
"5": {
"name": "fenced_code.block.language"
},
"6": {
"name": "fenced_code.block.language.attributes"
}
},
"endCaptures": {
"3": {
"name": "punctuation.definition.markdown"
}
},
"patterns": [
{
"begin": "(^|\\G)(\\s*)(.*)",
"while": "(^|\\G)(?!\\s*([`~]{3,})\\s*$)",
"contentName": "meta.embedded.block.dart",
"patterns": [
{
"include": "source.dart"
}
]
}
]
},
"fenced_code_block_unknown": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?=([^`~]*)?$)",
"beginCaptures": {
@@ -1958,7 +1994,7 @@
"while": "(^|\\G)([ ]{4}|\\t)"
},
"separator": {
"match": "(^|\\G)[ ]{0,3}([*-_])([ ]{0,2}\\2){2,}[ \\t]*$\\n?",
"match": "(^|\\G)[ ]{0,3}([\\*\\-\\_])([ ]{0,2}\\2){2,}[ \\t]*$\\n?",
"name": "meta.separator.markdown"
}
}
@@ -3,10 +3,10 @@
"c": "#",
"t": "text.html.markdown markup.heading.markdown heading.1.markdown punctuation.definition.heading.markdown",
"r": {
"dark_plus": "markup.heading: #569CD6",
"light_plus": "markup.heading: #800000",
"dark_vs": "markup.heading: #569CD6",
"light_vs": "markup.heading: #800000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.heading: #6796E6"
}
},
@@ -14,10 +14,10 @@
"c": " ",
"t": "text.html.markdown markup.heading.markdown heading.1.markdown",
"r": {
"dark_plus": "markup.heading: #569CD6",
"light_plus": "markup.heading: #800000",
"dark_vs": "markup.heading: #569CD6",
"light_vs": "markup.heading: #800000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.heading: #6796E6"
}
},
@@ -25,164 +25,32 @@
"c": "h",
"t": "text.html.markdown markup.heading.markdown heading.1.markdown entity.name.section.markdown",
"r": {
"dark_plus": "markup.heading: #569CD6",
"light_plus": "markup.heading: #800000",
"dark_vs": "markup.heading: #569CD6",
"light_vs": "markup.heading: #800000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.heading: #6796E6"
}
},
{
"c": "<",
"t": "text.html.markdown meta.tag.block.any.html punctuation.definition.tag.begin.html",
"c": "<pre><code>",
"t": "text.html.markdown meta.paragraph.markdown",
"r": {
"dark_plus": "punctuation.definition.tag: #808080",
"light_plus": "punctuation.definition.tag: #800000",
"dark_vs": "punctuation.definition.tag: #808080",
"light_vs": "punctuation.definition.tag: #800000",
"hc_black": "punctuation.definition.tag: #808080"
}
},
{
"c": "pre",
"t": "text.html.markdown meta.tag.block.any.html entity.name.tag.block.any.html",
"r": {
"dark_plus": "entity.name.tag: #569CD6",
"light_plus": "entity.name.tag: #800000",
"dark_vs": "entity.name.tag: #569CD6",
"light_vs": "entity.name.tag: #800000",
"hc_black": "entity.name.tag: #569CD6"
}
},
{
"c": ">",
"t": "text.html.markdown meta.tag.block.any.html punctuation.definition.tag.end.html",
"r": {
"dark_plus": "punctuation.definition.tag: #808080",
"light_plus": "punctuation.definition.tag: #800000",
"dark_vs": "punctuation.definition.tag: #808080",
"light_vs": "punctuation.definition.tag: #800000",
"hc_black": "punctuation.definition.tag: #808080"
}
},
{
"c": "<",
"t": "text.html.markdown meta.tag.inline.any.html punctuation.definition.tag.begin.html",
"r": {
"dark_plus": "punctuation.definition.tag: #808080",
"light_plus": "punctuation.definition.tag: #800000",
"dark_vs": "punctuation.definition.tag: #808080",
"light_vs": "punctuation.definition.tag: #800000",
"hc_black": "punctuation.definition.tag: #808080"
}
},
{
"c": "code",
"t": "text.html.markdown meta.tag.inline.any.html entity.name.tag.inline.any.html",
"r": {
"dark_plus": "entity.name.tag: #569CD6",
"light_plus": "entity.name.tag: #800000",
"dark_vs": "entity.name.tag: #569CD6",
"light_vs": "entity.name.tag: #800000",
"hc_black": "entity.name.tag: #569CD6"
}
},
{
"c": ">",
"t": "text.html.markdown meta.tag.inline.any.html punctuation.definition.tag.end.html",
"r": {
"dark_plus": "punctuation.definition.tag: #808080",
"light_plus": "punctuation.definition.tag: #800000",
"dark_vs": "punctuation.definition.tag: #808080",
"light_vs": "punctuation.definition.tag: #800000",
"hc_black": "punctuation.definition.tag: #808080"
}
},
{
"c": "# a",
"t": "text.html.markdown",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
{
"c": "</",
"t": "text.html.markdown meta.paragraph.markdown meta.tag.inline.any.html punctuation.definition.tag.begin.html",
"r": {
"dark_plus": "punctuation.definition.tag: #808080",
"light_plus": "punctuation.definition.tag: #800000",
"dark_vs": "punctuation.definition.tag: #808080",
"light_vs": "punctuation.definition.tag: #800000",
"hc_black": "punctuation.definition.tag: #808080"
}
},
{
"c": "code",
"t": "text.html.markdown meta.paragraph.markdown meta.tag.inline.any.html entity.name.tag.inline.any.html",
"r": {
"dark_plus": "entity.name.tag: #569CD6",
"light_plus": "entity.name.tag: #800000",
"dark_vs": "entity.name.tag: #569CD6",
"light_vs": "entity.name.tag: #800000",
"hc_black": "entity.name.tag: #569CD6"
}
},
{
"c": ">",
"t": "text.html.markdown meta.paragraph.markdown meta.tag.inline.any.html punctuation.definition.tag.end.html",
"r": {
"dark_plus": "punctuation.definition.tag: #808080",
"light_plus": "punctuation.definition.tag: #800000",
"dark_vs": "punctuation.definition.tag: #808080",
"light_vs": "punctuation.definition.tag: #800000",
"hc_black": "punctuation.definition.tag: #808080"
}
},
{
"c": "</",
"t": "text.html.markdown meta.paragraph.markdown meta.tag.block.any.html punctuation.definition.tag.begin.html",
"r": {
"dark_plus": "punctuation.definition.tag: #808080",
"light_plus": "punctuation.definition.tag: #800000",
"dark_vs": "punctuation.definition.tag: #808080",
"light_vs": "punctuation.definition.tag: #800000",
"hc_black": "punctuation.definition.tag: #808080"
}
},
{
"c": "pre",
"t": "text.html.markdown meta.paragraph.markdown meta.tag.block.any.html entity.name.tag.block.any.html",
"r": {
"dark_plus": "entity.name.tag: #569CD6",
"light_plus": "entity.name.tag: #800000",
"dark_vs": "entity.name.tag: #569CD6",
"light_vs": "entity.name.tag: #800000",
"hc_black": "entity.name.tag: #569CD6"
}
},
{
"c": ">",
"t": "text.html.markdown meta.paragraph.markdown meta.tag.block.any.html punctuation.definition.tag.end.html",
"r": {
"dark_plus": "punctuation.definition.tag: #808080",
"light_plus": "punctuation.definition.tag: #800000",
"dark_vs": "punctuation.definition.tag: #808080",
"light_vs": "punctuation.definition.tag: #800000",
"hc_black": "punctuation.definition.tag: #808080"
}
},
{
"c": "#",
"t": "text.html.markdown markup.heading.markdown heading.1.markdown punctuation.definition.heading.markdown",
"r": {
"dark_plus": "markup.heading: #569CD6",
"light_plus": "markup.heading: #800000",
"dark_vs": "markup.heading: #569CD6",
"light_vs": "markup.heading: #800000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.heading: #6796E6"
}
},
@@ -190,120 +58,43 @@
"c": " ",
"t": "text.html.markdown markup.heading.markdown heading.1.markdown",
"r": {
"dark_plus": "markup.heading: #569CD6",
"light_plus": "markup.heading: #800000",
"dark_vs": "markup.heading: #569CD6",
"light_vs": "markup.heading: #800000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.heading: #6796E6"
}
},
{
"c": "h",
"t": "text.html.markdown markup.heading.markdown heading.1.markdown entity.name.section.markdown",
"r": {
"dark_plus": "markup.heading: #569CD6",
"light_plus": "markup.heading: #800000",
"dark_vs": "markup.heading: #569CD6",
"light_vs": "markup.heading: #800000",
"hc_black": "markup.heading: #6796E6"
}
},
{
"c": "<",
"t": "text.html.markdown meta.tag.block.any.html punctuation.definition.tag.begin.html",
"r": {
"dark_plus": "punctuation.definition.tag: #808080",
"light_plus": "punctuation.definition.tag: #800000",
"dark_vs": "punctuation.definition.tag: #808080",
"light_vs": "punctuation.definition.tag: #800000",
"hc_black": "punctuation.definition.tag: #808080"
}
},
{
"c": "pre",
"t": "text.html.markdown meta.tag.block.any.html entity.name.tag.block.any.html",
"r": {
"dark_plus": "entity.name.tag: #569CD6",
"light_plus": "entity.name.tag: #800000",
"dark_vs": "entity.name.tag: #569CD6",
"light_vs": "entity.name.tag: #800000",
"hc_black": "entity.name.tag: #569CD6"
}
},
{
"c": ">",
"t": "text.html.markdown meta.tag.block.any.html punctuation.definition.tag.end.html",
"r": {
"dark_plus": "punctuation.definition.tag: #808080",
"light_plus": "punctuation.definition.tag: #800000",
"dark_vs": "punctuation.definition.tag: #808080",
"light_vs": "punctuation.definition.tag: #800000",
"hc_black": "punctuation.definition.tag: #808080"
}
},
{
"c": "# a",
"t": "text.html.markdown",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "a",
"t": "text.html.markdown markup.heading.markdown heading.1.markdown entity.name.section.markdown",
"r": {
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.heading: #6796E6"
}
},
{
"c": "</code></pre>",
"t": "text.html.markdown meta.paragraph.markdown",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
{
"c": "</",
"t": "text.html.markdown meta.paragraph.markdown meta.tag.block.any.html punctuation.definition.tag.begin.html",
"r": {
"dark_plus": "punctuation.definition.tag: #808080",
"light_plus": "punctuation.definition.tag: #800000",
"dark_vs": "punctuation.definition.tag: #808080",
"light_vs": "punctuation.definition.tag: #800000",
"hc_black": "punctuation.definition.tag: #808080"
}
},
{
"c": "pre",
"t": "text.html.markdown meta.paragraph.markdown meta.tag.block.any.html entity.name.tag.block.any.html",
"r": {
"dark_plus": "entity.name.tag: #569CD6",
"light_plus": "entity.name.tag: #800000",
"dark_vs": "entity.name.tag: #569CD6",
"light_vs": "entity.name.tag: #800000",
"hc_black": "entity.name.tag: #569CD6"
}
},
{
"c": ">",
"t": "text.html.markdown meta.paragraph.markdown meta.tag.block.any.html punctuation.definition.tag.end.html",
"r": {
"dark_plus": "punctuation.definition.tag: #808080",
"light_plus": "punctuation.definition.tag: #800000",
"dark_vs": "punctuation.definition.tag: #808080",
"light_vs": "punctuation.definition.tag: #800000",
"hc_black": "punctuation.definition.tag: #808080"
}
},
{
"c": "#",
"t": "text.html.markdown markup.heading.markdown heading.1.markdown punctuation.definition.heading.markdown",
"r": {
"dark_plus": "markup.heading: #569CD6",
"light_plus": "markup.heading: #800000",
"dark_vs": "markup.heading: #569CD6",
"light_vs": "markup.heading: #800000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.heading: #6796E6"
}
},
@@ -311,10 +102,10 @@
"c": " ",
"t": "text.html.markdown markup.heading.markdown heading.1.markdown",
"r": {
"dark_plus": "markup.heading: #569CD6",
"light_plus": "markup.heading: #800000",
"dark_vs": "markup.heading: #569CD6",
"light_vs": "markup.heading: #800000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.heading: #6796E6"
}
},
@@ -322,10 +113,98 @@
"c": "h",
"t": "text.html.markdown markup.heading.markdown heading.1.markdown entity.name.section.markdown",
"r": {
"dark_plus": "markup.heading: #569CD6",
"light_plus": "markup.heading: #800000",
"dark_vs": "markup.heading: #569CD6",
"light_vs": "markup.heading: #800000",
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.heading: #6796E6"
}
},
{
"c": "<pre>",
"t": "text.html.markdown meta.paragraph.markdown",
"r": {
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
{
"c": "#",
"t": "text.html.markdown markup.heading.markdown heading.1.markdown punctuation.definition.heading.markdown",
"r": {
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.heading: #6796E6"
}
},
{
"c": " ",
"t": "text.html.markdown markup.heading.markdown heading.1.markdown",
"r": {
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.heading: #6796E6"
}
},
{
"c": "a",
"t": "text.html.markdown markup.heading.markdown heading.1.markdown entity.name.section.markdown",
"r": {
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.heading: #6796E6"
}
},
{
"c": "a</pre>",
"t": "text.html.markdown meta.paragraph.markdown",
"r": {
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "default: #FFFFFF"
}
},
{
"c": "#",
"t": "text.html.markdown markup.heading.markdown heading.1.markdown punctuation.definition.heading.markdown",
"r": {
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.heading: #6796E6"
}
},
{
"c": " ",
"t": "text.html.markdown markup.heading.markdown heading.1.markdown",
"r": {
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.heading: #6796E6"
}
},
{
"c": "h",
"t": "text.html.markdown markup.heading.markdown heading.1.markdown entity.name.section.markdown",
"r": {
"dark_plus": null,
"light_plus": null,
"dark_vs": null,
"light_vs": null,
"hc_black": "markup.heading: #6796E6"
}
}
File diff suppressed because it is too large Load Diff
-4
View File
@@ -1,4 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
@@ -0,0 +1,7 @@
# Language Features for Markdown files
**Notice:** This extension is bundled with Visual Studio Code. It can be disabled but not uninstalled.
## Features
See [Markdown in Visual Studio Code](https://code.visualstudio.com/docs/languages/markdown) to learn about the features of this extension.
@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><style>.st0{fill:#f6f6f6}.st1{fill:none}.st2{fill:#424242}.st3{fill:#f0eff1}</style><path class="st0" d="M11.949 4C11.697 1.756 9.811 0 7.5 0A4.505 4.505 0 0 0 3 4.5c0 .6.12 1.188.35 1.735L0 9.586v.828l2 2 3-2.999V16h11V4h-4.051z" id="outline" style="display: none;"/><g id="icon_x5F_bg"><circle class="st1" cx="7.5" cy="4.5" r="2.5"/><path class="st2" d="M12 10h1v3h-1zM10 11h1v2h-1zM8 12h1v1H8zM8 9h2v1H8z"/><path class="st2" d="M11.949 5a4.431 4.431 0 0 1-.226 1H14v8H7V8.95a4.447 4.447 0 0 1-1-.227V15h9V5h-3.051z"/><path class="st2" d="M10.294 8H12V7h-.762a4.527 4.527 0 0 1-.944 1zM11 4.5a3.5 3.5 0 1 0-7 0c0 .711.215 1.369.579 1.922L1 10l1 1 3.579-3.578A3.485 3.485 0 0 0 7.5 8 3.5 3.5 0 0 0 11 4.5zm-6 0a2.5 2.5 0 1 1 5 0 2.5 2.5 0 0 1-5 0z"/></g><g id="icon_x5F_fg"><path class="st1" d="M10 11h1v2h-1zM8 12h1v1H8zM8 9h2v1H8zM12 10h1v3h-1z"/><path class="st3" d="M11.724 6a4.469 4.469 0 0 1-.485 1H12v1h-1.706c-.771.616-1.733 1-2.794 1-.169 0-.333-.031-.5-.05V14h7V6h-2.276zM8 9h2v1H8V9zm1 4H8v-1h1v1zm2 0h-1v-2h1v2zm2 0h-1v-3h1v3z"/><circle class="st3" cx="7.5" cy="4.5" r="2.5"/></g></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#f6f6f6;}.icon-canvas-transparent{opacity:0;}.icon-vs-bg{fill:#424242;}.icon-vs-action-blue{fill:#00539c;}</style></defs><title>SwitchToPreview_16x</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M16,4V16H5V9.121l-1.939,1.94A1.5,1.5,0,0,1,.939,8.939L3.446,6.433A4.4,4.4,0,0,1,3,4.5,4.488,4.488,0,0,1,11.949,4Z" style="display: none;"/></g><g id="iconBg"><path class="icon-vs-bg" d="M12,10h1v3H12Zm0-3h-.762a4.5,4.5,0,0,1-.944,1H12Zm-2,6h1V11H10Zm2-8h-.051a4.485,4.485,0,0,1-.225,1H14v8H7V8.972a4.4,4.4,0,0,1-1-.237V15h9V5ZM9,12H8v1H9Zm1-3H8v1h2Z"/></g><g id="colorAction"><path class="icon-vs-action-blue" d="M7.5,1A3.5,3.5,0,0,0,4,4.5a3.463,3.463,0,0,0,.707,2.086L1.646,9.646a.5.5,0,0,0,.708.708l3.06-3.061A3.463,3.463,0,0,0,7.5,8a3.5,3.5,0,0,0,0-7Zm0,6A2.5,2.5,0,1,1,10,4.5,2.5,2.5,0,0,1,7.5,7Z"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

@@ -1,19 +1 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.icon_x002D_vs_x002D_bg{fill:#424242;}
</style>
<g id="canvas">
</g>
<g id="outline">
</g>
<g id="iconFg">
</g>
<g id="iconBg">
<path class="icon_x002D_vs_x002D_bg" d="M9,5h5v2.4c0.4,0.2,0.7,0.4,1,0.7V2H1v12h5.6L9,11.6V5z M2,13V5h5v8H2z M11.3,12.7
c0.4,0.2,0.8,0.3,1.2,0.3c1.4,0,2.5-1.1,2.5-2.5C15,9.1,13.9,8,12.5,8C11.1,8,10,9.1,10,10.5c0,0.4,0.1,0.8,0.3,1.2L8,14l1,1
L11.3,12.7z M11,10.5C11,9.7,11.7,9,12.5,9c0.8,0,1.5,0.7,1.5,1.5c0,0.8-0.7,1.5-1.5,1.5C11.7,12,11,11.3,11,10.5z"/>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#f6f6f6;}.icon-canvas-transparent{opacity:0;}.icon-vs-bg{fill:#424242;}.icon-vs-action-blue{fill:#00539c;}</style></defs><title>PreviewInRightPanel_16x</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M16,1V15H10.121l-.56.561a1.5,1.5,0,0,1-2.122,0A1.469,1.469,0,0,1,7.1,15H0V1Z" style="display: none;"/></g><g id="iconBg"><path class="icon-vs-bg" d="M1,2V14H7.1a1.469,1.469,0,0,1,.341-.561L9,11.88V5h5V7.351a3.515,3.515,0,0,1,1,.707V2ZM7,13H2V5H7Z"/></g><g id="colorAction"><path class="icon-vs-action-blue" d="M12.5,8a2.5,2.5,0,0,0-2.084,3.877l-2.27,2.269a.5.5,0,0,0,.708.708l2.269-2.27A2.5,2.5,0,1,0,12.5,8Zm0,4A1.5,1.5,0,1,1,14,10.5,1.5,1.5,0,0,1,12.5,12Z"/></g></svg>

Before

Width:  |  Height:  |  Size: 857 B

After

Width:  |  Height:  |  Size: 890 B

@@ -1,19 +1 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{fill:#C5C5C5;}
</style>
<g id="canvas">
</g>
<g id="outline">
</g>
<g id="iconFg">
</g>
<g id="iconBg">
<path class="st0" d="M9,5h5v2.4c0.4,0.2,0.7,0.4,1,0.7V2H1v12h5.6L9,11.6V5z M2,13V5h5v8H2z M11.3,12.7c0.4,0.2,0.8,0.3,1.2,0.3
c1.4,0,2.5-1.1,2.5-2.5C15,9.1,13.9,8,12.5,8C11.1,8,10,9.1,10,10.5c0,0.4,0.1,0.8,0.3,1.2L8,14l1,1L11.3,12.7z M11,10.5
C11,9.7,11.7,9,12.5,9c0.8,0,1.5,0.7,1.5,1.5c0,0.8-0.7,1.5-1.5,1.5C11.7,12,11,11.3,11,10.5z"/>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#252526;}.icon-canvas-transparent{opacity:0;}.icon-vs-bg{fill:#c5c5c5;}.icon-vs-action-blue{fill:#75beff;}</style></defs><title>PreviewInRightPanel_16x</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M16,1V15H10.121l-.56.561a1.5,1.5,0,0,1-2.122,0A1.469,1.469,0,0,1,7.1,15H0V1Z" style="display: none;"/></g><g id="iconBg"><path class="icon-vs-bg" d="M1,2V14H7.1a1.469,1.469,0,0,1,.341-.561L9,11.88V5h5V7.351a3.515,3.515,0,0,1,1,.707V2ZM7,13H2V5H7Z"/></g><g id="colorAction"><path class="icon-vs-action-blue" d="M12.5,8a2.5,2.5,0,0,0-2.084,3.877l-2.27,2.269a.5.5,0,0,0,.708.708l2.269-2.27A2.5,2.5,0,1,0,12.5,8Zm0,4A1.5,1.5,0,1,1,14,10.5,1.5,1.5,0,0,1,12.5,12Z"/></g></svg>

Before

Width:  |  Height:  |  Size: 819 B

After

Width:  |  Height:  |  Size: 889 B

@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><style>.st0{fill:#2d2d30}.st1{fill:none}.st2{fill:#c5c5c5}.st3{fill:#2b282e}</style><path class="st0" d="M11.949 4C11.697 1.756 9.811 0 7.5 0A4.505 4.505 0 0 0 3 4.5c0 .6.12 1.188.35 1.735L0 9.586v.828l2 2 3-2.999V16h11V4h-4.051z" id="outline" style="display: none;"/><g id="icon_x5F_bg"><circle class="st1" cx="7.5" cy="4.5" r="2.5"/><path class="st2" d="M12 10h1v3h-1zM10 11h1v2h-1zM8 12h1v1H8zM8 9h2v1H8z"/><path class="st2" d="M11.949 5a4.431 4.431 0 0 1-.226 1H14v8H7V8.95a4.447 4.447 0 0 1-1-.227V15h9V5h-3.051z"/><path class="st2" d="M10.294 8H12V7h-.762a4.527 4.527 0 0 1-.944 1zM11 4.5a3.5 3.5 0 1 0-7 0c0 .711.215 1.369.579 1.922L1 10l1 1 3.579-3.578A3.485 3.485 0 0 0 7.5 8 3.5 3.5 0 0 0 11 4.5zm-6 0a2.5 2.5 0 1 1 5 0 2.5 2.5 0 0 1-5 0z"/></g><g id="icon_x5F_fg"><path class="st1" d="M10 11h1v2h-1zM8 12h1v1H8zM8 9h2v1H8zM12 10h1v3h-1z"/><path class="st3" d="M11.724 6a4.469 4.469 0 0 1-.485 1H12v1h-1.706c-.771.616-1.733 1-2.794 1-.169 0-.333-.031-.5-.05V14h7V6h-2.276zM8 9h2v1H8V9zm1 4H8v-1h1v1zm2 0h-1v-2h1v2zm2 0h-1v-3h1v3z"/><circle class="st3" cx="7.5" cy="4.5" r="2.5"/></g></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#252526;}.icon-canvas-transparent{opacity:0;}.icon-vs-bg{fill:#c5c5c5;}.icon-vs-action-blue{fill:#75beff;}</style></defs><title>SwitchToPreview_16x</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M16,4V16H5V9.121l-1.939,1.94A1.5,1.5,0,0,1,.939,8.939L3.446,6.433A4.4,4.4,0,0,1,3,4.5,4.488,4.488,0,0,1,11.949,4Z" style="display: none;"/></g><g id="iconBg"><path class="icon-vs-bg" d="M12,10h1v3H12Zm0-3h-.762a4.5,4.5,0,0,1-.944,1H12Zm-2,6h1V11H10Zm2-8h-.051a4.485,4.485,0,0,1-.225,1H14v8H7V8.972a4.4,4.4,0,0,1-1-.237V15h9V5ZM9,12H8v1H9Zm1-3H8v1h2Z"/></g><g id="colorAction"><path class="icon-vs-action-blue" d="M7.5,1A3.5,3.5,0,0,0,4,4.5a3.463,3.463,0,0,0,.707,2.086L1.646,9.646a.5.5,0,0,0,.708.708l3.06-3.061A3.463,3.463,0,0,0,7.5,8a3.5,3.5,0,0,0,0-7Zm0,6A2.5,2.5,0,1,1,10,4.5,2.5,2.5,0,0,1,7.5,7Z"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

@@ -0,0 +1,182 @@
/*
https://raw.githubusercontent.com/isagalaev/highlight.js/master/src/styles/vs2015.css
*/
/*
* Visual Studio 2015 dark style
* Author: Nicolas LLOBERA <nllobera@gmail.com>
*/
.hljs-keyword,
.hljs-literal,
.hljs-symbol,
.hljs-name {
color: #569CD6;
}
.hljs-link {
color: #569CD6;
text-decoration: underline;
}
.hljs-built_in,
.hljs-type {
color: #4EC9B0;
}
.hljs-number,
.hljs-class {
color: #B8D7A3;
}
.hljs-string,
.hljs-meta-string {
color: #D69D85;
}
.hljs-regexp,
.hljs-template-tag {
color: #9A5334;
}
.hljs-subst,
.hljs-function,
.hljs-title,
.hljs-params,
.hljs-formula {
color: #DCDCDC;
}
.hljs-comment,
.hljs-quote {
color: #57A64A;
font-style: italic;
}
.hljs-doctag {
color: #608B4E;
}
.hljs-meta,
.hljs-meta-keyword,
.hljs-tag {
color: #9B9B9B;
}
.hljs-variable,
.hljs-template-variable {
color: #BD63C5;
}
.hljs-attr,
.hljs-attribute,
.hljs-builtin-name {
color: #9CDCFE;
}
.hljs-section {
color: gold;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
/*.hljs-code {
font-family:'Monospace';
}*/
.hljs-bullet,
.hljs-selector-tag,
.hljs-selector-id,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #D7BA7D;
}
.hljs-addition {
background-color: #144212;
display: inline-block;
width: 100%;
}
.hljs-deletion {
background-color: #600;
display: inline-block;
width: 100%;
}
/*
From https://raw.githubusercontent.com/isagalaev/highlight.js/master/src/styles/vs.css
*/
/*
Visual Studio-like style based on original C# coloring by Jason Diamond <jason@diamond.name>
*/
.vscode-light .hljs-function,
.vscode-light .hljs-params {
color: inherit;
}
.vscode-light .hljs-comment,
.vscode-light .hljs-quote,
.vscode-light .hljs-variable {
color: #008000;
}
.vscode-light .hljs-keyword,
.vscode-light .hljs-selector-tag,
.vscode-light .hljs-built_in,
.vscode-light .hljs-name,
.vscode-light .hljs-tag {
color: #00f;
}
.vscode-light .hljs-string,
.vscode-light .hljs-title,
.vscode-light .hljs-section,
.vscode-light .hljs-attribute,
.vscode-light .hljs-literal,
.vscode-light .hljs-template-tag,
.vscode-light .hljs-template-variable,
.vscode-light .hljs-type,
.vscode-light .hljs-addition {
color: #a31515;
}
.vscode-light .hljs-deletion,
.vscode-light .hljs-selector-attr,
.vscode-light .hljs-selector-pseudo,
.vscode-light .hljs-meta {
color: #2b91af;
}
.vscode-light .hljs-doctag {
color: #808080;
}
.vscode-light .hljs-attr {
color: #f00;
}
.vscode-light .hljs-symbol,
.vscode-light .hljs-bullet,
.vscode-light .hljs-link {
color: #00b0e8;
}
.vscode-light .hljs-emphasis {
font-style: italic;
}
.vscode-light .hljs-strong {
font-weight: bold;
}
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
body {
@@ -98,10 +98,13 @@ img {
}
a {
color: #4080D0;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:focus,
input:focus,
select:focus,
@@ -137,11 +140,6 @@ h6 code {
line-height: auto;
}
a:hover {
color: #4080D0;
text-decoration: underline;
}
table {
border-collapse: collapse;
}
@@ -165,7 +163,8 @@ table > tbody > tr + tr > td {
blockquote {
margin: 0 7px 0 5px;
padding: 0 16px 0 10px;
border-left: 5px solid;
border-left-width: 5px;
border-left-style: solid;
}
code {
@@ -192,41 +191,20 @@ pre.hljs code > div {
/** Theming */
.vscode-light,
.vscode-light pre code {
color: rgb(30, 30, 30);
pre code {
color: var(--vscode-editor-foreground);
}
.vscode-dark,
.vscode-dark pre code {
color: #DDD;
}
.vscode-high-contrast,
.vscode-high-contrast pre code {
color: white;
}
.vscode-light code {
color: #A31515;
}
.vscode-dark code {
color: #D7BA7D;
}
.vscode-light pre:not(.hljs),
.vscode-light code > div {
.vscode-light pre {
background-color: rgba(220, 220, 220, 0.4);
}
.vscode-dark pre:not(.hljs),
.vscode-dark code > div {
.vscode-dark pre {
background-color: rgba(10, 10, 10, 0.4);
}
.vscode-high-contrast pre:not(.hljs),
.vscode-high-contrast code > div {
.vscode-high-contrast pre {
background-color: rgb(0, 0, 0);
}
@@ -253,14 +231,3 @@ pre.hljs code > div {
.vscode-dark table > tbody > tr + tr > td {
border-color: rgba(255, 255, 255, 0.18);
}
.vscode-light blockquote,
.vscode-dark blockquote {
background: rgba(127, 127, 127, 0.1);
border-color: rgba(0, 122, 204, 0.5);
}
.vscode-high-contrast blockquote {
background: transparent;
border-color: #fff;
}
File diff suppressed because one or more lines are too long
@@ -23,7 +23,7 @@
"onCommand:markdown.showLockedPreviewToSide",
"onCommand:markdown.showSource",
"onCommand:markdown.showPreviewSecuritySelector",
"onView:markdown.preview"
"onWebviewPanel:markdown.preview"
],
"contributes": {
"commands": [
@@ -115,6 +115,13 @@
"group": "navigation"
}
],
"editor/title/context": [
{
"command": "markdown.showPreview",
"when": "resourceLangId == markdown",
"group": "navigation"
}
],
"commandPalette": [
{
"command": "markdown.showPreview",
@@ -271,7 +278,7 @@
],
"markdown.previewStyles": [
"./media/markdown.css",
"./media/tomorrow.css"
"./media/highlight.css"
],
"markdown.previewScripts": [
"./media/index.js"
@@ -285,11 +292,11 @@
"build-preview": "webpack --mode development"
},
"dependencies": {
"highlight.js": "9.5.0",
"markdown-it": "^8.4.0",
"highlight.js": "9.12.0",
"markdown-it": "^8.4.1",
"markdown-it-named-headers": "0.0.4",
"vscode-extension-telemetry": "0.0.17",
"vscode-nls": "^3.2.1"
"vscode-extension-telemetry": "0.0.18",
"vscode-nls": "^3.2.4"
},
"devDependencies": {
"@types/highlight.js": "9.1.10",
@@ -297,10 +304,12 @@
"@types/markdown-it": "0.0.2",
"@types/node": "7.0.43",
"lodash.throttle": "^4.1.1",
"mocha-junit-reporter": "^1.17.0",
"mocha-multi-reporters": "^1.1.7",
"ts-loader": "^4.0.1",
"typescript": "^2.7.2",
"vscode": "^1.1.10",
"webpack": "^4.1.0",
"webpack-cli": "^2.0.10"
}
}
}
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { getElementsForSourceLine } from './scroll-sync';
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { MessagePoster } from './messaging';
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export function onceDocumentLoaded(f: () => void) {
@@ -1,13 +1,13 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ActiveLineMarker } from './activeLineMarker';
import { onceDocumentLoaded } from './events';
import { createPosterForVsCode } from './messaging';
import { getEditorLineNumberForPageOffset, scrollToRevealSourceLine } from './scroll-sync';
import { getSettings } from './settings';
import { getSettings, getData } from './settings';
import throttle = require('lodash.throttle');
declare var acquireVsCodeApi: any;
@@ -17,7 +17,10 @@ const marker = new ActiveLineMarker();
const settings = getSettings();
const vscode = acquireVsCodeApi();
vscode.postMessage({});
// Set VS Code state
const state = getData('data-state');
vscode.setState(state);
const messaging = createPosterForVsCode(vscode);
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { MessagePoster } from './messaging';
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { getSettings } from './settings';
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { CspAlerter } from './csp';
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { getSettings } from './settings';
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export interface PreviewSettings {
@@ -15,18 +15,26 @@ export interface PreviewSettings {
let cachedSettings: PreviewSettings | undefined = undefined;
export function getData(key: string): PreviewSettings {
const element = document.getElementById('vscode-markdown-preview-data');
if (element) {
const data = element.getAttribute(key);
if (data) {
return JSON.parse(data);
}
}
throw new Error(`Could not load data for ${key}`);
}
export function getSettings(): PreviewSettings {
if (cachedSettings) {
return cachedSettings;
}
const element = document.getElementById('vscode-markdown-preview-data');
if (element) {
const data = element.getAttribute('data-settings');
if (data) {
cachedSettings = JSON.parse(data);
return cachedSettings!;
}
cachedSettings = getData('data-settings');
if (cachedSettings) {
return cachedSettings;
}
throw new Error('Could not load settings');
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export function getStrings(): { [key: string]: string } {
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export { OpenDocumentLinkCommand } from './openDocumentLink';
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
@@ -46,10 +46,10 @@ export class OpenDocumentLinkCommand implements Command {
}
private async tryOpen(path: string, args: OpenDocumentLinkArgs) {
if (vscode.window.activeTextEditor && isMarkdownFile(vscode.window.activeTextEditor.document) && vscode.window.activeTextEditor.document.uri.fsPath === path) {
const resource = vscode.Uri.file(path);
if (vscode.window.activeTextEditor && isMarkdownFile(vscode.window.activeTextEditor.document) && vscode.window.activeTextEditor.document.uri.fsPath === resource.fsPath) {
return this.tryRevealLine(vscode.window.activeTextEditor, args.fragment);
} else {
const resource = vscode.Uri.file(path);
return vscode.workspace.openTextDocument(resource)
.then(vscode.window.showTextDocument)
.then(editor => this.tryRevealLine(editor, args.fragment));
@@ -63,7 +63,7 @@ export class OpenDocumentLinkCommand implements Command {
if (entry) {
return editor.revealRange(new vscode.Range(entry.line, 0, entry.line, 0), vscode.TextEditorRevealType.AtTop);
}
const lineNumberFragment = fragment.match(/^L(\d+)$/);
const lineNumberFragment = fragment.match(/^L(\d+)$/i);
if (lineNumberFragment) {
const line = +lineNumberFragment[1] - 1;
if (!isNaN(line)) {
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Command } from '../commandManager';
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
@@ -10,27 +10,6 @@ import { MarkdownPreviewManager } from '../features/previewManager';
import { TelemetryReporter } from '../telemetryReporter';
import { PreviewSettings } from '../features/preview';
function getViewColumn(sideBySide: boolean): vscode.ViewColumn | undefined {
const active = vscode.window.activeTextEditor;
if (!active) {
return vscode.ViewColumn.One;
}
if (!sideBySide) {
return active.viewColumn;
}
switch (active.viewColumn) {
case vscode.ViewColumn.One:
return vscode.ViewColumn.Two;
case vscode.ViewColumn.Two:
return vscode.ViewColumn.Three;
}
return active.viewColumn;
}
interface ShowPreviewSettings {
readonly sideBySide?: boolean;
readonly locked?: boolean;
@@ -61,7 +40,7 @@ async function showPreview(
webviewManager.preview(resource, {
resourceColumn: (vscode.window.activeTextEditor && vscode.window.activeTextEditor.viewColumn) || vscode.ViewColumn.One,
previewColumn: getViewColumn(!!previewSettings.sideBySide) || vscode.ViewColumn.Active,
previewColumn: previewSettings.sideBySide ? vscode.ViewColumn.Beside : vscode.ViewColumn.Active,
locked: !!previewSettings.locked
});
@@ -80,7 +59,7 @@ export class ShowPreviewCommand implements Command {
) { }
public execute(mainUri?: vscode.Uri, allUris?: vscode.Uri[], previewSettings?: PreviewSettings) {
for (const uri of (allUris || [mainUri])) {
for (const uri of Array.isArray(allUris) ? allUris : [mainUri]) {
showPreview(this.webviewManager, this.telemetryReporter, uri, {
sideBySide: false,
locked: previewSettings && previewSettings.locked
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Command } from '../commandManager';
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
@@ -17,16 +17,17 @@ import { MarkdownEngine } from './markdownEngine';
import { getMarkdownExtensionContributions } from './markdownExtensions';
import { ExtensionContentSecurityPolicyArbiter, PreviewSecuritySelector } from './security';
import { loadDefaultTelemetryReporter } from './telemetryReporter';
import { githubSlugifier } from './slugify';
export function activate(context: vscode.ExtensionContext) {
const telemetryReporter = loadDefaultTelemetryReporter();
context.subscriptions.push(telemetryReporter);
const contributions = getMarkdownExtensionContributions();
const contributions = getMarkdownExtensionContributions(context);
const cspArbiter = new ExtensionContentSecurityPolicyArbiter(context.globalState, context.workspaceState);
const engine = new MarkdownEngine(contributions);
const engine = new MarkdownEngine(contributions, githubSlugifier);
const logger = new Logger();
const selector: vscode.DocumentSelector = [
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
@@ -47,7 +47,7 @@ function matchAll(
}
export default class LinkProvider implements vscode.DocumentLinkProvider {
private readonly linkPattern = /(\[[^\]]*\]\(\s*?)(((((?=.*\)\)+)|(?=.*\)\]+))[^\s\)]+?)|([^\s]+?)))\)/g;
private readonly linkPattern = /(\[[^\]]*\]\(\s*)((([^\s\(\)]|\(\S*?\))+))\s*(".*?")?\)/g;
private readonly referenceLinkPattern = /(\[([^\]]+)\]\[\s*?)([^\s\]]*?)\]/g;
private readonly definitionPattern = /^([\t ]*\[([^\]]+)\]:\s*)(\S+)/gm;
@@ -1,12 +1,17 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { MarkdownEngine } from '../markdownEngine';
import { TableOfContentsProvider } from '../tableOfContentsProvider';
import { TableOfContentsProvider, SkinnyTextDocument, TocEntry } from '../tableOfContentsProvider';
interface MarkdownSymbol {
readonly level: number;
readonly parent: MarkdownSymbol | undefined;
readonly children: vscode.DocumentSymbol[];
}
export default class MDDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
@@ -14,10 +19,57 @@ export default class MDDocumentSymbolProvider implements vscode.DocumentSymbolPr
private readonly engine: MarkdownEngine
) { }
public async provideDocumentSymbols(document: vscode.TextDocument): Promise<vscode.SymbolInformation[]> {
public async provideDocumentSymbolInformation(document: SkinnyTextDocument): Promise<vscode.SymbolInformation[]> {
const toc = await new TableOfContentsProvider(this.engine, document).getToc();
return toc.map(entry => {
return new vscode.SymbolInformation('#'.repeat(entry.level) + ' ' + entry.text, vscode.SymbolKind.String, '', entry.location);
});
return toc.map(entry => this.toSymbolInformation(entry));
}
public async provideDocumentSymbols(document: SkinnyTextDocument): Promise<vscode.DocumentSymbol[]> {
const toc = await new TableOfContentsProvider(this.engine, document).getToc();
const root: MarkdownSymbol = {
level: -Infinity,
children: [],
parent: undefined
};
this.buildTree(root, toc);
return root.children;
}
private buildTree(parent: MarkdownSymbol, entries: TocEntry[]) {
if (!entries.length) {
return;
}
const entry = entries[0];
const symbol = this.toDocumentSymbol(entry);
symbol.children = [];
while (parent && entry.level <= parent.level) {
parent = parent.parent!;
}
parent.children.push(symbol);
this.buildTree({ level: entry.level, children: symbol.children, parent }, entries.slice(1));
}
private toSymbolInformation(entry: TocEntry): vscode.SymbolInformation {
return new vscode.SymbolInformation(
this.getSymbolName(entry),
vscode.SymbolKind.String,
'',
entry.location);
}
private toDocumentSymbol(entry: TocEntry) {
return new vscode.DocumentSymbol(
this.getSymbolName(entry),
'',
vscode.SymbolKind.String,
entry.location.range,
entry.location.range);
}
private getSymbolName(entry: TocEntry): string {
return '#'.repeat(entry.level) + ' ' + entry.text;
}
}
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
@@ -34,14 +34,14 @@ export class MarkdownPreview {
private isScrolling = false;
private _disposed: boolean = false;
public static async revive(
webview: vscode.WebviewPanel,
state: any,
contentProvider: MarkdownContentProvider,
previewConfigurations: MarkdownPreviewConfigurationManager,
logger: Logger,
topmostLineMonitor: MarkdownFileTopmostLineMonitor
topmostLineMonitor: MarkdownFileTopmostLineMonitor,
contributions: MarkdownContributions,
): Promise<MarkdownPreview> {
const resource = vscode.Uri.parse(state.resource);
const locked = state.locked;
@@ -54,7 +54,10 @@ export class MarkdownPreview {
contentProvider,
previewConfigurations,
logger,
topmostLineMonitor);
topmostLineMonitor,
contributions);
preview.editor.webview.options = MarkdownPreview.getWebviewOptions(resource, contributions);
if (!isNaN(line)) {
preview.line = line;
@@ -77,10 +80,8 @@ export class MarkdownPreview {
MarkdownPreview.viewType,
MarkdownPreview.getPreviewTitle(resource, locked),
previewColumn, {
enableScripts: true,
enableCommandUris: true,
enableFindWidget: true,
localResourceRoots: MarkdownPreview.getLocalResourceRoots(resource, contributions)
...MarkdownPreview.getWebviewOptions(resource, contributions)
});
return new MarkdownPreview(
@@ -90,7 +91,8 @@ export class MarkdownPreview {
contentProvider,
previewConfigurations,
logger,
topmostLineMonitor);
topmostLineMonitor,
contributions);
}
private constructor(
@@ -100,7 +102,8 @@ export class MarkdownPreview {
private readonly _contentProvider: MarkdownContentProvider,
private readonly _previewConfigurations: MarkdownPreviewConfigurationManager,
private readonly _logger: Logger,
topmostLineMonitor: MarkdownFileTopmostLineMonitor
topmostLineMonitor: MarkdownFileTopmostLineMonitor,
private readonly _contributions: MarkdownContributions,
) {
this._resource = resource;
this._locked = locked;
@@ -239,10 +242,6 @@ export class MarkdownPreview {
return this.editor.viewColumn;
}
public isWebviewOf(webview: vscode.WebviewPanel): boolean {
return this.editor === webview;
}
public matchesResource(
otherResource: vscode.Uri,
otherPosition: vscode.ViewColumn | undefined,
@@ -272,6 +271,14 @@ export class MarkdownPreview {
this.editor.title = MarkdownPreview.getPreviewTitle(this._resource, this._locked);
}
private get iconPath() {
const root = path.join(this._contributions.extensionPath, 'media');
return {
light: vscode.Uri.file(path.join(root, 'Preview.svg')),
dark: vscode.Uri.file(path.join(root, 'Preview_inverse.svg'))
};
}
private isPreviewOf(resource: vscode.Uri): boolean {
return this._resource.fsPath === resource.fsPath;
}
@@ -325,13 +332,26 @@ export class MarkdownPreview {
this.forceUpdate = false;
this.currentVersion = { resource, version: document.version };
const content = await this._contentProvider.provideTextDocumentContent(document, this._previewConfigurations, this.line);
const content = await this._contentProvider.provideTextDocumentContent(document, this._previewConfigurations, this.line, this.state);
if (this._resource === resource) {
this.editor.title = MarkdownPreview.getPreviewTitle(this._resource, this._locked);
this.editor.iconPath = this.iconPath;
this.editor.webview.options = MarkdownPreview.getWebviewOptions(resource, this._contributions);
this.editor.webview.html = content;
}
}
private static getWebviewOptions(
resource: vscode.Uri,
contributions: MarkdownContributions
): vscode.WebviewOptions {
return {
enableScripts: true,
enableCommandUris: true,
localResourceRoots: MarkdownPreview.getLocalResourceRoots(resource, contributions)
};
}
private static getLocalResourceRoots(
resource: vscode.Uri,
contributions: MarkdownContributions
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
@@ -27,7 +27,7 @@ export class MarkdownPreviewConfiguration {
private constructor(resource: vscode.Uri) {
const editorConfig = vscode.workspace.getConfiguration('editor', resource);
const markdownConfig = vscode.workspace.getConfiguration('markdown', resource);
const markdownEditorConfig = vscode.workspace.getConfiguration('[markdown]');
const markdownEditorConfig = vscode.workspace.getConfiguration('[markdown]', resource);
this.scrollBeyondLastLine = editorConfig.get<boolean>('scrollBeyondLastLine', false);
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
@@ -47,7 +47,8 @@ export class MarkdownContentProvider {
public async provideTextDocumentContent(
markdownDocument: vscode.TextDocument,
previewConfigurations: MarkdownPreviewConfigurationManager,
initialLine: number | undefined = undefined
initialLine: number | undefined = undefined,
state?: any
): Promise<string> {
const sourceUri = markdownDocument.uri;
const config = previewConfigurations.loadAndCacheConfiguration(sourceUri);
@@ -73,7 +74,10 @@ export class MarkdownContentProvider {
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
${csp}
<meta id="vscode-markdown-preview-data" data-settings="${JSON.stringify(initialData).replace(/"/g, '&quot;')}" data-strings="${JSON.stringify(previewStrings).replace(/"/g, '&quot;')}">
<meta id="vscode-markdown-preview-data"
data-settings="${JSON.stringify(initialData).replace(/"/g, '&quot;')}"
data-strings="${JSON.stringify(previewStrings).replace(/"/g, '&quot;')}"
data-state="${JSON.stringify(state || {}).replace(/"/g, '&quot;')}">
<script src="${this.extensionResourcePath('pre.js')}" nonce="${nonce}"></script>
${this.getStyles(sourceUri, nonce, config)}
<base href="${markdownDocument.uri.with({ scheme: 'vscode-resource' }).toString(true)}">
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
@@ -16,33 +16,33 @@ import { MarkdownContentProvider } from './previewContentProvider';
export class MarkdownPreviewManager implements vscode.WebviewPanelSerializer {
private static readonly markdownPreviewActiveContextKey = 'markdownPreviewFocus';
private readonly topmostLineMonitor = new MarkdownFileTopmostLineMonitor();
private readonly previewConfigurations = new MarkdownPreviewConfigurationManager();
private readonly previews: MarkdownPreview[] = [];
private activePreview: MarkdownPreview | undefined = undefined;
private readonly disposables: vscode.Disposable[] = [];
private readonly _topmostLineMonitor = new MarkdownFileTopmostLineMonitor();
private readonly _previewConfigurations = new MarkdownPreviewConfigurationManager();
private readonly _previews: MarkdownPreview[] = [];
private _activePreview: MarkdownPreview | undefined = undefined;
private readonly _disposables: vscode.Disposable[] = [];
public constructor(
private readonly contentProvider: MarkdownContentProvider,
private readonly logger: Logger,
private readonly contributions: MarkdownContributions
private readonly _contentProvider: MarkdownContentProvider,
private readonly _logger: Logger,
private readonly _contributions: MarkdownContributions
) {
this.disposables.push(vscode.window.registerWebviewPanelSerializer(MarkdownPreview.viewType, this));
this._disposables.push(vscode.window.registerWebviewPanelSerializer(MarkdownPreview.viewType, this));
}
public dispose(): void {
disposeAll(this.disposables);
disposeAll(this.previews);
disposeAll(this._disposables);
disposeAll(this._previews);
}
public refresh() {
for (const preview of this.previews) {
for (const preview of this._previews) {
preview.refresh();
}
}
public updateConfiguration() {
for (const preview of this.previews) {
for (const preview of this._previews) {
preview.updateConfiguration();
}
}
@@ -62,16 +62,16 @@ export class MarkdownPreviewManager implements vscode.WebviewPanelSerializer {
}
public get activePreviewResource() {
return this.activePreview && this.activePreview.resource;
return this._activePreview && this._activePreview.resource;
}
public toggleLock() {
const preview = this.activePreview;
const preview = this._activePreview;
if (preview) {
preview.toggleLock();
// Close any previews that are now redundant, such as having two dynamic previews in the same editor group
for (const otherPreview of this.previews) {
for (const otherPreview of this._previews) {
if (otherPreview !== preview && preview.matches(otherPreview)) {
otherPreview.dispose();
}
@@ -86,26 +86,20 @@ export class MarkdownPreviewManager implements vscode.WebviewPanelSerializer {
const preview = await MarkdownPreview.revive(
webview,
state,
this.contentProvider,
this.previewConfigurations,
this.logger,
this.topmostLineMonitor);
this._contentProvider,
this._previewConfigurations,
this._logger,
this._topmostLineMonitor,
this._contributions);
this.registerPreview(preview);
}
public async serializeWebviewPanel(
webview: vscode.WebviewPanel,
): Promise<any> {
const preview = this.previews.find(preview => preview.isWebviewOf(webview));
return preview ? preview.state : undefined;
}
private getExistingPreview(
resource: vscode.Uri,
previewSettings: PreviewSettings
): MarkdownPreview | undefined {
return this.previews.find(preview =>
return this._previews.find(preview =>
preview.matchesResource(resource, previewSettings.previewColumn, previewSettings.locked));
}
@@ -117,37 +111,46 @@ export class MarkdownPreviewManager implements vscode.WebviewPanelSerializer {
resource,
previewSettings.previewColumn,
previewSettings.locked,
this.contentProvider,
this.previewConfigurations,
this.logger,
this.topmostLineMonitor,
this.contributions);
this._contentProvider,
this._previewConfigurations,
this._logger,
this._topmostLineMonitor,
this._contributions);
this.setPreviewActiveContext(true);
this._activePreview = preview;
return this.registerPreview(preview);
}
private registerPreview(
preview: MarkdownPreview
): MarkdownPreview {
this.previews.push(preview);
this._previews.push(preview);
preview.onDispose(() => {
const existing = this.previews.indexOf(preview!);
if (existing >= 0) {
this.previews.splice(existing, 1);
const existing = this._previews.indexOf(preview);
if (existing === -1) {
return;
}
this._previews.splice(existing, 1);
if (this._activePreview === preview) {
this.setPreviewActiveContext(false);
this._activePreview = undefined;
}
});
preview.onDidChangeViewState(({ webviewPanel }) => {
disposeAll(this.previews.filter(otherPreview => preview !== otherPreview && preview!.matches(otherPreview)));
vscode.commands.executeCommand('setContext', MarkdownPreviewManager.markdownPreviewActiveContextKey,
webviewPanel.visible);
this.activePreview = webviewPanel.visible ? preview : undefined;
disposeAll(this._previews.filter(otherPreview => preview !== otherPreview && preview!.matches(otherPreview)));
this.setPreviewActiveContext(webviewPanel.active);
this._activePreview = webviewPanel.active ? preview : undefined;
});
return preview;
}
private setPreviewActiveContext(value: boolean) {
vscode.commands.executeCommand('setContext', MarkdownPreviewManager.markdownPreviewActiveContextKey, value);
}
}
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
@@ -8,19 +8,20 @@ import { disposeAll } from '../util/dispose';
import { isMarkdownFile } from '../util/file';
import { Lazy, lazy } from '../util/lazy';
import MDDocumentSymbolProvider from './documentSymbolProvider';
import { SkinnyTextDocument } from '../tableOfContentsProvider';
export interface WorkspaceMarkdownDocumentProvider {
getAllMarkdownDocuments(): Thenable<vscode.TextDocument[]>;
getAllMarkdownDocuments(): Thenable<Iterable<SkinnyTextDocument>>;
readonly onDidChangeMarkdownDocument: vscode.Event<vscode.TextDocument>;
readonly onDidCreateMarkdownDocument: vscode.Event<vscode.TextDocument>;
readonly onDidChangeMarkdownDocument: vscode.Event<SkinnyTextDocument>;
readonly onDidCreateMarkdownDocument: vscode.Event<SkinnyTextDocument>;
readonly onDidDeleteMarkdownDocument: vscode.Event<vscode.Uri>;
}
class VSCodeWorkspaceMarkdownDocumentProvider implements WorkspaceMarkdownDocumentProvider {
private readonly _onDidChangeMarkdownDocumentEmitter = new vscode.EventEmitter<vscode.TextDocument>();
private readonly _onDidCreateMarkdownDocumentEmitter = new vscode.EventEmitter<vscode.TextDocument>();
private readonly _onDidChangeMarkdownDocumentEmitter = new vscode.EventEmitter<SkinnyTextDocument>();
private readonly _onDidCreateMarkdownDocumentEmitter = new vscode.EventEmitter<SkinnyTextDocument>();
private readonly _onDidDeleteMarkdownDocumentEmitter = new vscode.EventEmitter<vscode.Uri>();
private _watcher: vscode.FileSystemWatcher | undefined;
@@ -39,9 +40,8 @@ class VSCodeWorkspaceMarkdownDocumentProvider implements WorkspaceMarkdownDocume
async getAllMarkdownDocuments() {
const resources = await vscode.workspace.findFiles('**/*.md', '**/node_modules/**');
const documents = await Promise.all(
resources.map(resource => vscode.workspace.openTextDocument(resource).then(x => x, () => undefined)));
return documents.filter(doc => doc && isMarkdownFile(doc)) as vscode.TextDocument[];
const docs = await Promise.all(resources.map(doc => this.getMarkdownDocument(doc)));
return docs.filter(doc => !!doc) as SkinnyTextDocument[];
}
public get onDidChangeMarkdownDocument() {
@@ -67,15 +67,15 @@ class VSCodeWorkspaceMarkdownDocumentProvider implements WorkspaceMarkdownDocume
this._watcher = vscode.workspace.createFileSystemWatcher('**/*.md');
this._watcher.onDidChange(async resource => {
const document = await vscode.workspace.openTextDocument(resource);
if (isMarkdownFile(document)) {
const document = await this.getMarkdownDocument(resource);
if (document) {
this._onDidChangeMarkdownDocumentEmitter.fire(document);
}
}, null, this._disposables);
this._watcher.onDidCreate(async resource => {
const document = await vscode.workspace.openTextDocument(resource);
if (isMarkdownFile(document)) {
const document = await this.getMarkdownDocument(resource);
if (document) {
this._onDidCreateMarkdownDocumentEmitter.fire(document);
}
}, null, this._disposables);
@@ -90,6 +90,11 @@ class VSCodeWorkspaceMarkdownDocumentProvider implements WorkspaceMarkdownDocume
}
}, null, this._disposables);
}
private async getMarkdownDocument(resource: vscode.Uri): Promise<SkinnyTextDocument | undefined> {
const doc = await vscode.workspace.openTextDocument(resource);
return doc && isMarkdownFile(doc) ? doc : undefined;
}
}
@@ -119,9 +124,9 @@ export default class MarkdownWorkspaceSymbolProvider implements vscode.Workspace
}
public async populateSymbolCache(): Promise<void> {
const markDownDocumentUris = await this._workspaceMarkdownDocumentProvider.getAllMarkdownDocuments();
for (const document of markDownDocumentUris) {
this._symbolCache.set(document.fileName, this.getSymbols(document));
const markdownDocumentUris = await this._workspaceMarkdownDocumentProvider.getAllMarkdownDocuments();
for (const document of markdownDocumentUris) {
this._symbolCache.set(document.uri.fsPath, this.getSymbols(document));
}
}
@@ -129,17 +134,17 @@ export default class MarkdownWorkspaceSymbolProvider implements vscode.Workspace
disposeAll(this._disposables);
}
private getSymbols(document: vscode.TextDocument): Lazy<Thenable<vscode.SymbolInformation[]>> {
private getSymbols(document: SkinnyTextDocument): Lazy<Thenable<vscode.SymbolInformation[]>> {
return lazy(async () => {
return this._symbolProvider.provideDocumentSymbols(document);
return this._symbolProvider.provideDocumentSymbolInformation(document);
});
}
private onDidChangeDocument(document: vscode.TextDocument) {
this._symbolCache.set(document.fileName, this.getSymbols(document));
private onDidChangeDocument(document: SkinnyTextDocument) {
this._symbolCache.set(document.uri.fsPath, this.getSymbols(document));
}
private onDidDeleteDocument(resource: vscode.Uri) {
this._symbolCache.delete(resource.fsPath);
}
}
}
@@ -1,9 +1,10 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { OutputChannel, window, workspace } from 'vscode';
import * as vscode from 'vscode';
import { lazy } from './util/lazy';
enum Trace {
Off,
@@ -31,7 +32,8 @@ function isString(value: any): value is string {
export class Logger {
private trace?: Trace;
private _output?: OutputChannel;
private readonly outputChannel = lazy(() => vscode.window.createOutputChannel('Markdown'));
constructor() {
this.updateConfiguration();
@@ -39,9 +41,9 @@ export class Logger {
public log(message: string, data?: any): void {
if (this.trace === Trace.Verbose) {
this.output.appendLine(`[Log - ${(new Date().toLocaleTimeString())}] ${message}`);
this.appendLine(`[Log - ${(new Date().toLocaleTimeString())}] ${message}`);
if (data) {
this.output.appendLine(Logger.data2String(data));
this.appendLine(Logger.data2String(data));
}
}
}
@@ -50,15 +52,12 @@ export class Logger {
this.trace = this.readTrace();
}
private get output(): OutputChannel {
if (!this._output) {
this._output = window.createOutputChannel('Markdown');
}
return this._output;
private appendLine(value: string) {
return this.outputChannel.value.appendLine(value);
}
private readTrace(): Trace {
return Trace.fromString(workspace.getConfiguration().get<string>('markdown.trace', 'off'));
return Trace.fromString(vscode.workspace.getConfiguration().get<string>('markdown.trace', 'off'));
}
private static data2String(data: any): string {
@@ -73,4 +72,4 @@ export class Logger {
}
return JSON.stringify(data, undefined, 2);
}
}
}
@@ -1,13 +1,13 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import * as path from 'path';
import { Slug } from './tableOfContentsProvider';
import { MarkdownIt, Token } from 'markdown-it';
import * as path from 'path';
import * as vscode from 'vscode';
import { MarkdownContributions } from './markdownExtensions';
import { Slugifier } from './slugify';
const FrontMatterRegex = /^---\s*[^]*?(-{3}|\.{3})\s*/;
@@ -19,7 +19,8 @@ export class MarkdownEngine {
private currentDocument?: vscode.Uri;
public constructor(
private readonly extensionPreviewResourceProvider: MarkdownContributions
private readonly extensionPreviewResourceProvider: MarkdownContributions,
private readonly slugifier: Slugifier,
) { }
private usePlugin(factory: (md: any) => any): void {
@@ -43,23 +44,25 @@ export class MarkdownEngine {
}
if (lang && hljs.getLanguage(lang)) {
try {
return `<pre class="hljs"><code><div>${hljs.highlight(lang, str, true).value}</div></code></pre>`;
return `<div>${hljs.highlight(lang, str, true).value}</div>`;
} catch (error) { }
}
return `<pre class="hljs"><code><div>${this.md!.utils.escapeHtml(str)}</div></code></pre>`;
return `<code><div>${this.md!.utils.escapeHtml(str)}</div></code>`;
}
}).use(mdnh, {
slugify: (header: string) => Slug.fromHeading(header).value
slugify: (header: string) => this.slugifier.fromHeading(header).value
});
for (const plugin of this.extensionPreviewResourceProvider.markdownItPlugins) {
this.usePlugin(await plugin);
}
for (const renderName of ['paragraph_open', 'heading_open', 'image', 'code_block', 'blockquote_open', 'list_item_open']) {
for (const renderName of ['paragraph_open', 'heading_open', 'image', 'code_block', 'fence', 'blockquote_open', 'list_item_open']) {
this.addLineNumberRenderer(this.md, renderName);
}
this.addFencedRenderer(this.md);
this.addLinkNormalizer(this.md);
this.addLinkValidator(this.md);
}
@@ -126,6 +129,18 @@ export class MarkdownEngine {
};
}
private addFencedRenderer(md: any): void {
const original = md.renderer.rules['fenced'];
md.renderer.rules['fenced'] = (tokens: any, idx: number, options: any, env: any, self: any) => {
const token = tokens[idx];
if (token.map && token.map.length) {
token.attrJoin('class', 'hljs');
}
return original(tokens, idx, options, env, self);
};
}
private addLinkNormalizer(md: any): void {
const normalizeLink = md.normalizeLink;
md.normalizeLink = (link: string) => {
@@ -145,13 +160,13 @@ export class MarkdownEngine {
if (fragment) {
uri = uri.with({
fragment: Slug.fromHeading(fragment).value
fragment: this.slugifier.fromHeading(fragment).value
});
}
return normalizeLink(uri.with({ scheme: 'vscode-resource' }).toString(true));
} else if (!uri.scheme && !uri.path && uri.fragment) {
return normalizeLink(uri.with({
fragment: Slug.fromHeading(uri.fragment).value
fragment: this.slugifier.fromHeading(uri.fragment).value
}).toString(true));
}
} catch (e) {
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
@@ -26,6 +26,7 @@ const resolveExtensionResources = (extension: vscode.Extension<any>, resourcePat
};
export interface MarkdownContributions {
readonly extensionPath: string;
readonly previewScripts: vscode.Uri[];
readonly previewStyles: vscode.Uri[];
readonly markdownItPlugins: Thenable<(md: any) => any>[];
@@ -40,6 +41,10 @@ class MarkdownExtensionContributions implements MarkdownContributions {
private _loaded = false;
public constructor(
public readonly extensionPath: string,
) { }
public get previewScripts(): vscode.Uri[] {
this.ensureLoaded();
return this._scripts;
@@ -111,6 +116,6 @@ class MarkdownExtensionContributions implements MarkdownContributions {
}
}
export function getMarkdownExtensionContributions(): MarkdownContributions {
return new MarkdownExtensionContributions();
export function getMarkdownExtensionContributions(context: vscode.ExtensionContext): MarkdownContributions {
return new MarkdownExtensionContributions(context.extensionPath);
}
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
@@ -0,0 +1,32 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export class Slug {
public constructor(
public readonly value: string
) { }
public equals(other: Slug): boolean {
return this.value === other.value;
}
}
export interface Slugifier {
fromHeading(heading: string): Slug;
}
export const githubSlugifier: Slugifier = new class implements Slugifier {
fromHeading(heading: string): Slug {
const slugifiedHeading = encodeURI(
heading.trim()
.toLowerCase()
.replace(/\s+/g, '-') // Replace whitespace with -
.replace(/[\]\[\!\'\#\$\%\&\'\(\)\*\+\,\.\/\:\;\<\=\>\?\@\\\^\_\{\|\}\~\`。,、;:?!…—·ˉ¨‘’“”々~‖∶"'`|〃〔〕〈〉《》「」『』.〖〗【】()[]{}]/g, '') // Remove known puctuators
.replace(/^\-+/, '') // Remove leading -
.replace(/\-+$/, '') // Remove trailing -
);
return new Slug(slugifiedHeading);
}
};
@@ -1,37 +1,11 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { MarkdownEngine } from './markdownEngine';
export class Slug {
private static specialChars: any = { 'à': 'a', 'ä': 'a', 'ã': 'a', 'á': 'a', 'â': 'a', 'æ': 'a', 'å': 'a', 'ë': 'e', 'è': 'e', 'é': 'e', 'ê': 'e', 'î': 'i', 'ï': 'i', 'ì': 'i', 'í': 'i', 'ò': 'o', 'ó': 'o', 'ö': 'o', 'ô': 'o', 'ø': 'o', 'ù': 'o', 'ú': 'u', 'ü': 'u', 'û': 'u', 'ñ': 'n', 'ç': 'c', 'ß': 's', 'ÿ': 'y', 'œ': 'o', 'ŕ': 'r', 'ś': 's', 'ń': 'n', 'ṕ': 'p', 'ẃ': 'w', 'ǵ': 'g', 'ǹ': 'n', 'ḿ': 'm', 'ǘ': 'u', 'ẍ': 'x', 'ź': 'z', 'ḧ': 'h', '·': '-', '/': '-', '_': '-', ',': '-', ':': '-', ';': '-', 'З': '3', 'з': '3' };
public static fromHeading(heading: string): Slug {
const slugifiedHeading = encodeURI(heading.trim()
.toLowerCase()
.replace(/./g, c => Slug.specialChars[c] || c)
.replace(/[\]\[\!\'\#\$\%\&\'\(\)\*\+\,\.\/\:\;\<\=\>\?\@\\\^\_\{\|\}\~\`]/g, '')
.replace(/\s+/g, '-') // Replace whitespace with -
.replace(/[^\w\-]+/g, '') // Remove remaining non-word chars
.replace(/^\-+/, '') // Remove leading -
.replace(/\-+$/, '') // Remove trailing -
);
return new Slug(slugifiedHeading);
}
private constructor(
public readonly value: string
) { }
public equals(other: Slug): boolean {
return this.value === other.value;
}
}
import { Slug, githubSlugifier } from './slugify';
export interface TocEntry {
readonly slug: Slug;
@@ -41,12 +15,18 @@ export interface TocEntry {
readonly location: vscode.Location;
}
export interface SkinnyTextDocument {
readonly uri: vscode.Uri;
getText(): string;
lineAt(line: number): vscode.TextLine;
}
export class TableOfContentsProvider {
private toc?: TocEntry[];
public constructor(
private engine: MarkdownEngine,
private document: vscode.TextDocument
private document: SkinnyTextDocument
) { }
public async getToc(): Promise<TocEntry[]> {
@@ -62,11 +42,11 @@ export class TableOfContentsProvider {
public async lookup(fragment: string): Promise<TocEntry | undefined> {
const toc = await this.getToc();
const slug = Slug.fromHeading(fragment);
const slug = githubSlugifier.fromHeading(fragment);
return toc.find(entry => entry.slug.equals(slug));
}
private async buildToc(document: vscode.TextDocument): Promise<TocEntry[]> {
private async buildToc(document: SkinnyTextDocument): Promise<TocEntry[]> {
const toc: TocEntry[] = [];
const tokens = await this.engine.parse(document.uri, document.getText());
@@ -74,7 +54,7 @@ export class TableOfContentsProvider {
const lineNumber = heading.map[0];
const line = document.lineAt(lineNumber);
toc.push({
slug: Slug.fromHeading(line.text),
slug: githubSlugifier.fromHeading(line.text),
text: TableOfContentsProvider.getHeaderText(line.text),
level: TableOfContentsProvider.getHeaderLevel(heading.markup),
line: lineNumber,
@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { default as VSCodeTelemetryReporter } from 'vscode-extension-telemetry';
@@ -0,0 +1,108 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import 'mocha';
import * as vscode from 'vscode';
import LinkProvider from '../features/documentLinkProvider';
import { InMemoryDocument } from './inMemoryDocument';
const testFileName = vscode.Uri.parse('test.md');
const noopToken = new class implements vscode.CancellationToken {
private _onCancellationRequestedEmitter = new vscode.EventEmitter<void>();
public onCancellationRequested = this._onCancellationRequestedEmitter.event;
get isCancellationRequested() { return false; }
};
function getLinksForFile(fileContents: string) {
const doc = new InMemoryDocument(testFileName, fileContents);
const provider = new LinkProvider();
return provider.provideDocumentLinks(doc, noopToken);
}
function assertRangeEqual(expected: vscode.Range, actual: vscode.Range) {
assert.strictEqual(expected.start.line, actual.start.line);
assert.strictEqual(expected.start.character, actual.start.character);
assert.strictEqual(expected.end.line, actual.end.line);
assert.strictEqual(expected.end.character, actual.end.character);
}
suite('markdown.DocumentLinkProvider', () => {
test('Should not return anything for empty document', () => {
const links = getLinksForFile('');
assert.strictEqual(links.length, 0);
});
test('Should not return anything for simple document without links', () => {
const links = getLinksForFile('# a\nfdasfdfsafsa');
assert.strictEqual(links.length, 0);
});
test('Should detect basic http links', () => {
const links = getLinksForFile('a [b](https://example.com) c');
assert.strictEqual(links.length, 1);
const [link] = links;
assertRangeEqual(link.range, new vscode.Range(0, 6, 0, 25));
});
test('Should detect basic workspace links', () => {
{
const links = getLinksForFile('a [b](./file) c');
assert.strictEqual(links.length, 1);
const [link] = links;
assertRangeEqual(link.range, new vscode.Range(0, 6, 0, 12));
}
{
const links = getLinksForFile('a [b](file.png) c');
assert.strictEqual(links.length, 1);
const [link] = links;
assertRangeEqual(link.range, new vscode.Range(0, 6, 0, 14));
}
});
test('Should detect links with title', () => {
const links = getLinksForFile('a [b](https://example.com "abc") c');
assert.strictEqual(links.length, 1);
const [link] = links;
assertRangeEqual(link.range, new vscode.Range(0, 6, 0, 25));
});
test('Should handle links with balanced parens', () => {
{
const links = getLinksForFile('a [b](https://example.com/a()c) c');
assert.strictEqual(links.length, 1);
const [link] = links;
assertRangeEqual(link.range, new vscode.Range(0, 6, 0, 30));
}
{
const links = getLinksForFile('a [b](https://example.com/a(b)c) c');
assert.strictEqual(links.length, 1);
const [link] = links;
assertRangeEqual(link.range, new vscode.Range(0, 6, 0, 31));
}
{
// #49011
const links = getLinksForFile('[A link](http://ThisUrlhasParens/A_link(in_parens))');
assert.strictEqual(links.length, 1);
const [link] = links;
assertRangeEqual(link.range, new vscode.Range(0, 9, 0, 50));
}
});
test('Should handle two links without space', () => {
const links = getLinksForFile('a ([test](test)[test2](test2)) c');
assert.strictEqual(links.length, 2);
const [link1, link2] = links;
assertRangeEqual(link1.range, new vscode.Range(0, 10, 0, 14));
assertRangeEqual(link2.range, new vscode.Range(0, 23, 0, 28));
});
});

Some files were not shown because too many files have changed in this diff Show More