├── .eslintignore ├── .eslintrc.json ├── .gitignore ├── .vscode ├── extensions.json ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── gulpfile.js ├── images ├── favorites.svg ├── favorites │ ├── favorite-add-dark.svg │ ├── favorite-add-light.svg │ ├── favorite-item-dark.svg │ ├── favorite-item-light.svg │ ├── new-group-dark.svg │ ├── new-group-light.svg │ ├── open-diff-dark.svg │ └── open-diff-light.svg ├── history │ ├── history-clear-dark.svg │ ├── history-clear-light.svg │ ├── history-file-dark.svg │ ├── history-file-light.svg │ ├── history-folder-dark.svg │ ├── history-folder-light.svg │ ├── history-item-dark.svg │ └── history-item-light.svg ├── icon.png ├── panels │ ├── toggle-case-sensitive-dark.svg │ ├── toggle-case-sensitive-disabled-dark.svg │ ├── toggle-case-sensitive-disabled-light.svg │ ├── toggle-case-sensitive-light.svg │ ├── toggle-eol-dark.svg │ ├── toggle-eol-disabled-dark.svg │ ├── toggle-eol-disabled-light.svg │ ├── toggle-eol-light.svg │ ├── toggle-whitespace-dark.svg │ ├── toggle-whitespace-disabled-dark.svg │ ├── toggle-whitespace-disabled-light.svg │ └── toggle-whitespace-light.svg └── previews │ ├── preview-favorites.png │ ├── preview-projects.png │ ├── preview-search.png │ ├── preview-select.png │ ├── preview-start.png │ ├── preview-stats.png │ └── preview.png ├── package-lock.json ├── package.json ├── plugins ├── check-lint-rules │ ├── index.js │ └── package.json ├── eslint-plugin-l13 │ ├── .gitignore │ ├── LICENSE │ ├── docs │ │ └── rules │ │ │ └── padded-blocks-extended.md │ ├── lib │ │ ├── index.js │ │ └── rules │ │ │ └── padded-blocks-extended.js │ ├── package.json │ └── tests │ │ └── lib │ │ ├── index.js │ │ └── rules │ │ └── padded-blocks-extended.js ├── gulp-file2json │ ├── index.js │ └── package.json └── gulp-tasks │ ├── index.js │ └── package.json ├── src ├── @l13 │ ├── arrays.ts │ ├── formats.test.ts │ ├── formats.ts │ └── units │ │ └── files.ts ├── @types │ ├── basics.ts │ ├── diffs.ts │ ├── formats.ts │ ├── json.ts │ ├── messages.ts │ ├── platforms.ts │ └── tests.ts ├── services │ ├── @l13 │ │ ├── buffers.test.ts │ │ ├── buffers.ts │ │ ├── format.test.ts │ │ ├── formats.ts │ │ ├── fse.test.ts │ │ ├── fse.ts │ │ ├── jsonc.test.ts │ │ ├── jsonc.ts │ │ ├── platforms.test.ts │ │ └── platforms.ts │ ├── @types │ │ ├── compare.ts │ │ ├── copy.ts │ │ ├── delete.ts │ │ ├── events.ts │ │ ├── favorites.ts │ │ ├── fse.ts │ │ ├── history.ts │ │ ├── packages.ts │ │ ├── panel.ts │ │ ├── projects.ts │ │ └── states.ts │ ├── actions │ │ ├── DiffCompare.ts │ │ ├── DiffCopy.ts │ │ ├── DiffDelete.ts │ │ ├── DiffOpen.ts │ │ └── symlinks │ │ │ └── SymlinkContentProvider.ts │ ├── commands │ │ ├── common.ts │ │ ├── developer.ts │ │ ├── explorer.ts │ │ ├── favorites.ts │ │ ├── history.ts │ │ ├── output.ts │ │ ├── panel.ts │ │ ├── projects.ts │ │ ├── settings.ts │ │ ├── shortcuts.ts │ │ └── symlinks.ts │ ├── common │ │ ├── commands.ts │ │ ├── dialogs.ts │ │ ├── extensions.ts │ │ ├── files.ts │ │ ├── paths.ts │ │ ├── settings.ts │ │ └── states.ts │ ├── dialogs │ │ ├── FavoriteGroupsDialog.ts │ │ ├── FavoritesDialog.ts │ │ └── HistoryDialog.ts │ ├── main.ts │ ├── output │ │ ├── DiffOutput.ts │ │ ├── DiffResult.ts │ │ ├── DiffStats.ts │ │ ├── DiffStatusBar.ts │ │ └── stats │ │ │ ├── DetailStats.ts │ │ │ └── FolderStats.ts │ ├── panel │ │ ├── DiffMessage.ts │ │ ├── DiffPanel.ts │ │ ├── events.ts │ │ └── events │ │ │ ├── compare.ts │ │ │ ├── context.ts │ │ │ ├── copy.ts │ │ │ ├── deletes.ts │ │ │ ├── dialogs.ts │ │ │ ├── favorites.ts │ │ │ ├── menu.ts │ │ │ ├── open.ts │ │ │ ├── panelstates.ts │ │ │ └── updates.ts │ ├── sidebar │ │ ├── FavoritesProvider.ts │ │ ├── HistoryProvider.ts │ │ └── trees │ │ │ ├── FavoriteGroupTreeItem.ts │ │ │ ├── FavoriteTreeItem.ts │ │ │ └── HistoryTreeItem.ts │ └── states │ │ ├── FavoriteGroupsState.ts │ │ ├── FavoritesState.ts │ │ ├── HistoryState.ts │ │ └── MenuState.ts ├── test │ └── index.ts ├── types.ts └── views │ ├── @l13 │ ├── component │ │ ├── component.abstract.ts │ │ ├── view-model-service.abstract.ts │ │ └── view-model.abstract.ts │ ├── core.ts │ ├── events │ │ ├── event-dispatcher.class.ts │ │ └── event.class.ts │ ├── messages │ │ └── message.class.ts │ └── os │ │ ├── languages.ts │ │ └── platforms.ts │ ├── @types │ ├── components.ts │ ├── events.ts │ ├── inits.ts │ ├── intro.ts │ ├── keyboards.ts │ ├── list.ts │ ├── search.ts │ ├── states.ts │ └── views.ts │ ├── common.ts │ ├── components │ ├── icons.ts │ ├── l13-diff-actions │ │ ├── l13-diff-actions.component.ts │ │ ├── l13-diff-actions.html │ │ ├── l13-diff-actions.scss │ │ ├── l13-diff-actions.service.ts │ │ └── l13-diff-actions.viewmodel.ts │ ├── l13-diff-compare │ │ ├── l13-diff-compare.component.ts │ │ ├── l13-diff-compare.html │ │ ├── l13-diff-compare.scss │ │ ├── l13-diff-compare.service.ts │ │ └── l13-diff-compare.viewmodel.ts │ ├── l13-diff-context │ │ ├── l13-diff-context.component.ts │ │ ├── l13-diff-context.html │ │ ├── l13-diff-context.scss │ │ ├── l13-diff-context.service.ts │ │ └── l13-diff-context.viewmodel.ts │ ├── l13-diff-input │ │ ├── l13-diff-input.component.ts │ │ ├── l13-diff-input.html │ │ ├── l13-diff-input.scss │ │ ├── l13-diff-input.service.ts │ │ └── l13-diff-input.viewmodel.ts │ ├── l13-diff-intro │ │ ├── l13-diff-intro.component.ts │ │ ├── l13-diff-intro.html │ │ ├── l13-diff-intro.scss │ │ ├── l13-diff-intro.service.ts │ │ └── l13-diff-intro.viewmodel.ts │ ├── l13-diff-list │ │ ├── events │ │ │ ├── context-menu.ts │ │ │ └── drag-n-drop.ts │ │ ├── l13-diff-list.component.ts │ │ ├── l13-diff-list.html │ │ ├── l13-diff-list.interface.ts │ │ ├── l13-diff-list.scss │ │ ├── l13-diff-list.service.ts │ │ └── l13-diff-list.viewmodel.ts │ ├── l13-diff-menu │ │ ├── l13-diff-menu.component.ts │ │ ├── l13-diff-menu.html │ │ ├── l13-diff-menu.scss │ │ ├── l13-diff-menu.service.ts │ │ └── l13-diff-menu.viewmodel.ts │ ├── l13-diff-navigator │ │ ├── l13-diff-navigator.component.ts │ │ ├── l13-diff-navigator.html │ │ ├── l13-diff-navigator.scss │ │ ├── l13-diff-navigator.service.ts │ │ └── l13-diff-navigator.viewmodel.ts │ ├── l13-diff-panel │ │ ├── l13-diff-panel.component.ts │ │ ├── l13-diff-panel.html │ │ ├── l13-diff-panel.scss │ │ ├── l13-diff-panel.service.ts │ │ └── l13-diff-panel.viewmodel.ts │ ├── l13-diff-search │ │ ├── l13-diff-search.component.ts │ │ ├── l13-diff-search.html │ │ ├── l13-diff-search.pipe.ts │ │ ├── l13-diff-search.scss │ │ ├── l13-diff-search.service.ts │ │ └── l13-diff-search.viewmodel.ts │ ├── l13-diff-swap │ │ ├── l13-diff-swap.component.ts │ │ ├── l13-diff-swap.html │ │ ├── l13-diff-swap.scss │ │ ├── l13-diff-swap.service.ts │ │ └── l13-diff-swap.viewmodel.ts │ ├── l13-diff-views │ │ ├── l13-diff-views.component.ts │ │ ├── l13-diff-views.html │ │ ├── l13-diff-views.pipe.ts │ │ ├── l13-diff-views.scss │ │ ├── l13-diff-views.service.ts │ │ └── l13-diff-views.viewmodel.ts │ ├── l13-diff │ │ ├── commands.ts │ │ ├── commands │ │ │ ├── actions.ts │ │ │ ├── compare.ts │ │ │ ├── favorites.ts │ │ │ ├── input.ts │ │ │ ├── list.ts │ │ │ ├── menu.ts │ │ │ ├── search.ts │ │ │ ├── swap.ts │ │ │ └── views.ts │ │ ├── events.ts │ │ ├── events │ │ │ ├── actions.ts │ │ │ ├── compare.ts │ │ │ ├── diff.ts │ │ │ ├── input.ts │ │ │ ├── list.ts │ │ │ ├── navigator.ts │ │ │ ├── search.ts │ │ │ ├── swap.ts │ │ │ └── window.ts │ │ ├── l13-diff.component.ts │ │ ├── l13-diff.html │ │ ├── l13-diff.scss │ │ ├── l13-diff.service.ts │ │ └── l13-diff.viewmodel.ts │ ├── styles.ts │ └── templates.ts │ ├── icons │ ├── components │ │ ├── case-sensitive.svg │ │ ├── checked.svg │ │ ├── close.svg │ │ ├── copy-file.svg │ │ ├── copy-left.svg │ │ ├── copy-right.svg │ │ ├── delete-file.svg │ │ ├── folder.svg │ │ ├── list-error.svg │ │ ├── list-file.svg │ │ ├── list-folder.svg │ │ ├── list-symlink.svg │ │ ├── list-unknown.svg │ │ ├── open-file.svg │ │ ├── regexp.svg │ │ ├── reveal-file.svg │ │ ├── search-conflict.svg │ │ ├── search-other.svg │ │ ├── select-all.svg │ │ ├── select-deleted.svg │ │ ├── select-modified.svg │ │ ├── select-untracked.svg │ │ ├── show-deleted.svg │ │ ├── show-ignored.svg │ │ ├── show-modified.svg │ │ ├── show-unchanged.svg │ │ ├── show-untracked.svg │ │ └── swap.svg │ └── panel │ │ ├── icon-dark.svg │ │ └── icon-light.svg │ ├── main.ts │ ├── settings.ts │ ├── style.scss │ └── vscode.d.ts ├── tasks ├── icons.js ├── scripts.js ├── styles.js ├── templates.js └── tests.js └── tsconfig.json /.eslintignore: -------------------------------------------------------------------------------- 1 | .cache/ 2 | .vscode/ 3 | images/ 4 | media/ 5 | out/ 6 | plugins/ 7 | tasks/ 8 | test/ 9 | gulpfile.js -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | media 2 | out 3 | node_modules 4 | .cache 5 | .vscode-test/ 6 | *.vsix 7 | test/ 8 | !src/test/ -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "dbaeumer.vscode-eslint" 6 | ] 7 | } -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Run Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "runtimeExecutable": "${execPath}", 13 | "args": [ 14 | "--extensionDevelopmentPath=${workspaceFolder}" 15 | ], 16 | "outFiles": [ 17 | "${workspaceFolder}/out/**/*.js" 18 | ], 19 | // "preLaunchTask": "npm: watch" 20 | }, 21 | { 22 | "name": "Extension Tests", 23 | "type": "extensionHost", 24 | "request": "launch", 25 | "runtimeExecutable": "${execPath}", 26 | "args": [ 27 | "--extensionDevelopmentPath=${workspaceFolder}", 28 | "--extensionTestsPath=${workspaceFolder}/out/test" 29 | ], 30 | "outFiles": [ 31 | "${workspaceFolder}/out/test/**/*.js" 32 | ], 33 | // "preLaunchTask": "npm: watch" 34 | } 35 | ] 36 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "out": true // set this to false to include "out" folder in search results 8 | }, 9 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts 10 | "typescript.tsc.autoDetect": "off", 11 | "l13Diff.exclude": [ 12 | ".cache", 13 | "**/.DS_Store", 14 | "**/.git", 15 | "**/.hg", 16 | "**/.svn", 17 | "**/.vscode", 18 | "**/CVS", 19 | "diff", 20 | "media", 21 | "**/node_modules", 22 | "out", 23 | "package-lock.json" 24 | ] 25 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "gulp", 8 | "task": "build & watch", 9 | "problemMatcher": [] 10 | }, 11 | { 12 | "type": "gulp", 13 | "task": "build", 14 | "problemMatcher": [] 15 | }, 16 | { 17 | "type": "gulp", 18 | "task": "watch", 19 | "problemMatcher": [] 20 | }, 21 | { 22 | "type": "gulp", 23 | "task": "clean", 24 | "problemMatcher": [] 25 | }, 26 | { 27 | "type": "npm", 28 | "script": "compile", 29 | "problemMatcher": [] 30 | }, 31 | { 32 | "type": "gulp", 33 | "task": "icons:fix", 34 | "problemMatcher": [] 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .cache/** 2 | .vscode/** 3 | .vscode-test/** 4 | plugins/** 5 | src/** 6 | tasks/** 7 | test/** 8 | .eslintignore 9 | .eslintrc.json 10 | .gitignore 11 | gulpfile.js 12 | tsconfig.json 13 | **/*.map 14 | **/*.ts -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 - 2025 L13|RARY 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | 21 | Except as contained in this notice, the name(s) of the above copyright holders 22 | shall not be used in advertising or otherwise to promote the sale, use or other 23 | dealings in this Software without prior written authorization. -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | const del = require('del'); 4 | 5 | const { GulpTasks } = require('./plugins/gulp-tasks'); 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | const tasks = new GulpTasks({ paths: 'tasks/**/*.@(js|json)' }); 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | tasks.build([clean, 'icons', 'styles', 'templates', 'scripts', 'tests']); 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | 18 | 19 | // Functions __________________________________________________________________ 20 | 21 | function clean () { 22 | 23 | return del(['.cache', 'media', 'out', 'test']); 24 | 25 | } -------------------------------------------------------------------------------- /images/favorites.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/favorites/favorite-add-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/favorites/favorite-add-light.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/favorites/favorite-item-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/favorites/favorite-item-light.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/favorites/new-group-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/favorites/new-group-light.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/favorites/open-diff-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/favorites/open-diff-light.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/history/history-clear-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/history/history-clear-light.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/history/history-file-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/history/history-file-light.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/history/history-folder-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/history/history-folder-light.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/history/history-item-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/history/history-item-light.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/L13/vscode-diff/11353f797ed878a31c837a4dc668966f46729d19/images/icon.png -------------------------------------------------------------------------------- /images/panels/toggle-eol-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/panels/toggle-eol-disabled-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/panels/toggle-eol-disabled-light.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/panels/toggle-eol-light.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/panels/toggle-whitespace-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/panels/toggle-whitespace-disabled-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/panels/toggle-whitespace-disabled-light.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/panels/toggle-whitespace-light.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/previews/preview-favorites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/L13/vscode-diff/11353f797ed878a31c837a4dc668966f46729d19/images/previews/preview-favorites.png -------------------------------------------------------------------------------- /images/previews/preview-projects.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/L13/vscode-diff/11353f797ed878a31c837a4dc668966f46729d19/images/previews/preview-projects.png -------------------------------------------------------------------------------- /images/previews/preview-search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/L13/vscode-diff/11353f797ed878a31c837a4dc668966f46729d19/images/previews/preview-search.png -------------------------------------------------------------------------------- /images/previews/preview-select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/L13/vscode-diff/11353f797ed878a31c837a4dc668966f46729d19/images/previews/preview-select.png -------------------------------------------------------------------------------- /images/previews/preview-start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/L13/vscode-diff/11353f797ed878a31c837a4dc668966f46729d19/images/previews/preview-start.png -------------------------------------------------------------------------------- /images/previews/preview-stats.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/L13/vscode-diff/11353f797ed878a31c837a4dc668966f46729d19/images/previews/preview-stats.png -------------------------------------------------------------------------------- /images/previews/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/L13/vscode-diff/11353f797ed878a31c837a4dc668966f46729d19/images/previews/preview.png -------------------------------------------------------------------------------- /plugins/check-lint-rules/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "check-lint-rules", 3 | "version": "0.13.0", 4 | "description": "Check local and extended ESLint and TSLint rules against each other", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "L13RARY", 10 | "license": "SEE LICENSE IN LICENSE.md" 11 | } -------------------------------------------------------------------------------- /plugins/eslint-plugin-l13/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /plugins/eslint-plugin-l13/lib/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rules: { 3 | 'padded-blocks-extended': require('./rules/padded-blocks-extended'), 4 | } 5 | }; -------------------------------------------------------------------------------- /plugins/eslint-plugin-l13/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-plugin-l13", 3 | "main": "lib/index.js", 4 | "version": "0.13.0", 5 | "scripts": { 6 | "test": "node tests/lib" 7 | }, 8 | "devDependencies": { 9 | "eslint": "^7.24.0" 10 | }, 11 | "license": "SEE LICENCE", 12 | "engines": { 13 | "node": "^10.12.0 || >=12.0.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /plugins/eslint-plugin-l13/tests/lib/index.js: -------------------------------------------------------------------------------- 1 | require('./rules/padded-blocks-extended'); -------------------------------------------------------------------------------- /plugins/gulp-file2json/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gulp-file2json", 3 | "version": "0.13.0", 4 | "description": "Wraps multiple file contents as a JSON map.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "L13RARY", 10 | "license": "SEE LICENSE IN LICENSE.md" 11 | } -------------------------------------------------------------------------------- /plugins/gulp-tasks/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gulp-tasks", 3 | "version": "0.13.0", 4 | "description": "Manage gulp tasks more simple.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "L13RARY", 10 | "license": "SEE LICENSE IN LICENSE.md" 11 | } -------------------------------------------------------------------------------- /src/@l13/arrays.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export function remove (values: any[], value: any) { 16 | 17 | const index = values.indexOf(value); 18 | 19 | if (index !== -1) values.splice(index, 1); 20 | 21 | } 22 | 23 | export function sortCaseInsensitive (a: string, b: string) { 24 | 25 | a = a.toUpperCase(); 26 | b = b.toUpperCase(); 27 | 28 | return a < b ? -1 : a > b ? 1 : 0; 29 | 30 | } 31 | 32 | // Functions __________________________________________________________________ 33 | 34 | -------------------------------------------------------------------------------- /src/@l13/formats.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { Plural } from '../types'; 4 | 5 | import { pluralBytes } from './units/files'; 6 | 7 | const { floor, log, pow } = Math; 8 | 9 | // Variables __________________________________________________________________ 10 | 11 | const byteUnits = [pluralBytes.size, 'KB', 'MB', 'GB', 'TB', 'PB']; 12 | const KB = 1024; 13 | const logKB = log(KB); 14 | 15 | // Initialize _________________________________________________________________ 16 | 17 | 18 | 19 | // Exports ____________________________________________________________________ 20 | 21 | export function formatAmount (value: number, units: Plural) { 22 | 23 | return `${value} ${units[value] || units.size}`; 24 | 25 | } 26 | 27 | export function formatFileSize (size: number) { 28 | 29 | const bytes = formatAmount(size, pluralBytes); 30 | 31 | if (size < KB) return bytes; 32 | 33 | let i = floor(log(size) / logKB); 34 | 35 | if (!byteUnits[i]) i = byteUnits.length - 1; 36 | 37 | return `${parseFloat((size / pow(KB, i)).toFixed(2))} ${byteUnits[i]} (${bytes})`; 38 | 39 | } 40 | 41 | export function formatDate (date: Date) { 42 | 43 | // eslint-disable-next-line max-len 44 | return `${date.getFullYear()}-${formatDigit(date.getMonth() + 1)}-${formatDigit(date.getDate())} ${date.getHours()}:${formatDigit(date.getMinutes())}:${formatDigit(date.getSeconds())}`; 45 | 46 | } 47 | 48 | export function formatList (values: string[]) { 49 | 50 | const length = values.length; 51 | 52 | return length > 2 ? `${values.slice(0, -1).join(', ')} and ${values[length - 1]}` : values.join(' and '); 53 | 54 | } 55 | 56 | // Functions __________________________________________________________________ 57 | 58 | function formatDigit (digit: number) { 59 | 60 | return `${digit}`.padStart(2, '0'); 61 | 62 | } -------------------------------------------------------------------------------- /src/@l13/units/files.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { Plural } from '../../types'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export const pluralFiles: Plural = { size: 'files', 1: 'file' }; 16 | export const pluralFolders: Plural = { size: 'folders', 1: 'folder' }; 17 | export const pluralSymlinks: Plural = { size: 'symlinks', 1: 'symlink' }; 18 | export const pluralErrors: Plural = { size: 'errors', 1: 'error' }; 19 | export const pluralOthers: Plural = { size: 'others', 1: 'other' }; 20 | 21 | export const pluralEntries: Plural = { size: 'entries', 1: 'entry' }; 22 | 23 | export const pluralBytes: Plural = { size: 'Bytes', 1: 'Byte' }; 24 | 25 | // Functions __________________________________________________________________ 26 | 27 | -------------------------------------------------------------------------------- /src/@types/basics.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export type Dictionary = { 16 | [key: string]: T, 17 | }; 18 | 19 | // Functions __________________________________________________________________ 20 | 21 | -------------------------------------------------------------------------------- /src/@types/diffs.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import * as fs from 'fs'; 4 | 5 | import { MODIFIED } from '../services/@l13/buffers'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export type DiffFileTypes = 'error' | 'file' | 'folder' | 'symlink' | 'unknown'; 18 | 19 | export type Diff = { 20 | id: string, 21 | status: DiffStatus, 22 | type: DiffFileTypes | 'mixed', 23 | ignoredEOL: MODIFIED, 24 | ignoredBOM: MODIFIED, 25 | ignoredWhitespace: MODIFIED, 26 | fileA: null | DiffFile, 27 | fileB: null | DiffFile, 28 | }; 29 | 30 | export type DiffFile = { 31 | root: string, 32 | relative: string, 33 | fsPath: string, 34 | stat?: fs.Stats, 35 | path: string, 36 | name: string, 37 | basename: string, 38 | dirname: string, 39 | extname: string, 40 | ignore: boolean, 41 | type: DiffFileTypes, 42 | }; 43 | 44 | export type DiffSettings = { 45 | abortOnError: boolean, 46 | excludes: string[], 47 | ignoreContents: boolean, 48 | ignoreEndOfLine: boolean, 49 | ignoreTrimWhitespace: boolean, 50 | ignoreByteOrderMark: boolean, 51 | maxFileSize: number, 52 | useCaseSensitive: boolean, 53 | }; 54 | 55 | export type DiffStatus = 'conflicting' | 'deleted' | 'ignored' | 'modified' | 'unchanged' | 'untracked'; 56 | 57 | // Functions __________________________________________________________________ 58 | 59 | -------------------------------------------------------------------------------- /src/@types/formats.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export type Plural = { 16 | size: string, 17 | [index: number]: string, 18 | }; 19 | 20 | // Functions __________________________________________________________________ 21 | 22 | -------------------------------------------------------------------------------- /src/@types/json.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export type JSONPrimitive = string | number | boolean | null; 16 | 17 | export type JSONObject = { [key: string]: JSONValue }; 18 | 19 | export type JSONArray = JSONValue[]; 20 | 21 | export type JSONValue = JSONPrimitive | JSONObject | JSONArray; 22 | 23 | // Functions __________________________________________________________________ 24 | 25 | -------------------------------------------------------------------------------- /src/@types/platforms.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export type Platform = 'Linux' | 'macOS' | 'Windows'; 16 | 17 | // Functions __________________________________________________________________ 18 | 19 | -------------------------------------------------------------------------------- /src/@types/tests.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export type Test = { 16 | desc: string, 17 | expect: any, 18 | toBe?: any, 19 | }; 20 | 21 | // Functions __________________________________________________________________ 22 | 23 | -------------------------------------------------------------------------------- /src/services/@l13/formats.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { basename, normalize, sep } from 'path'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export function formatNameAndDesc (pathA: string, pathB: string): [string, string] { 16 | 17 | const namesA: string[] = normalize(pathA).split(sep); 18 | const namesB: string[] = normalize(pathB).split(sep); 19 | 20 | const desc: string[] = []; 21 | 22 | // Remove last entry if path has a slash/backslash at the end 23 | if (!namesA[namesA.length - 1]) namesA.pop(); 24 | if (!namesB[namesB.length - 1]) namesB.pop(); 25 | 26 | while (namesA.length > 1 && namesB.length > 1 && namesA[0] === namesB[0]) { 27 | desc.push(namesA.shift()); 28 | namesB.shift(); 29 | } 30 | 31 | // Fix for absolute and network paths if folders are part of the root 32 | if (desc.length && desc.join('') === '') { 33 | desc.forEach((value, index) => { 34 | 35 | namesA.splice(index, 0, value); 36 | namesB.splice(index, 0, value); 37 | 38 | }); 39 | desc.splice(0, desc.length); 40 | } 41 | 42 | if (pathA === sep) namesA.push(''); 43 | if (pathB === sep) namesB.push(''); 44 | 45 | return [`${namesA.join(sep)} ↔ ${namesB.join(sep)}`, desc.join(sep)]; 46 | 47 | } 48 | 49 | export function formatName (pathA: string, pathB: string) { 50 | 51 | return `${basename(pathA)} ↔ ${basename(pathB)}`; 52 | 53 | } 54 | export function formatError (error: Error) { 55 | 56 | return `${error.message}\n${error.stack}`; 57 | 58 | } 59 | 60 | // Functions __________________________________________________________________ 61 | 62 | -------------------------------------------------------------------------------- /src/services/@l13/jsonc.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | const _parse = JSON.parse; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | const findComments = /"(?:[^"\r\n\\]*(?:\\.)*)*"|(\/\*(?:.|[\r\n])*?\*\/|\/\/[^\r\n]*)/g; 8 | const findTrailingCommas = /"(?:[^"\r\n\\]*(?:\\.)*)*"|,\s*?([\]}])/g; 9 | 10 | // Initialize _________________________________________________________________ 11 | 12 | 13 | 14 | // Exports ____________________________________________________________________ 15 | 16 | export function parse (jsonc: string, reviver?: (this: any, key: string, value: any) => any) { 17 | 18 | const json = jsonc 19 | .replace(findComments, (match, comment) => comment ? '' : match) 20 | .replace(findTrailingCommas, (match, close) => close || match); 21 | 22 | return _parse(json, reviver); 23 | 24 | } 25 | 26 | // Functions __________________________________________________________________ 27 | 28 | -------------------------------------------------------------------------------- /src/services/@l13/platforms.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { Platform } from '../../@types/platforms'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export const platform: Platform = detectPlatform(); 16 | 17 | export let isMacOs = platform === 'macOS'; 18 | 19 | export let isWindows = platform === 'Windows'; 20 | 21 | export let isLinux = platform === 'Linux'; 22 | 23 | export function setPlatform (value: Platform) { // Just for testing 24 | 25 | isMacOs = value === 'macOS'; 26 | isWindows = value === 'Windows'; 27 | isLinux = value === 'Linux'; 28 | 29 | } 30 | 31 | export function restoreDefaultPlatform () { // Just for testing 32 | 33 | setPlatform(platform); 34 | 35 | } 36 | 37 | // Functions __________________________________________________________________ 38 | 39 | function detectPlatform () { 40 | 41 | if (process.platform === 'darwin') return 'macOS'; 42 | if (process.platform === 'win32') return 'Windows'; 43 | 44 | return 'Linux'; 45 | 46 | } -------------------------------------------------------------------------------- /src/services/@types/compare.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { DiffSettings } from '../../@types/diffs'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export type DiffError = { 16 | diffSettings?: DiffSettings, 17 | error: string | Error, 18 | pathA: string, 19 | pathB: string, 20 | }; 21 | 22 | // Functions __________________________________________________________________ 23 | 24 | -------------------------------------------------------------------------------- /src/services/@types/copy.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export type CopyFilesJob = { 16 | error: null | Error, 17 | tasks: number, 18 | done: (error?: Error) => void, 19 | }; 20 | 21 | // Functions __________________________________________________________________ 22 | 23 | -------------------------------------------------------------------------------- /src/services/@types/delete.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export type DeleteDialog = { 16 | text: string, 17 | textSingle?: string, 18 | buttonAll: string, 19 | buttonLeft?: string, 20 | buttonRight?: string, 21 | buttonOk?: string, 22 | }; 23 | 24 | // Functions __________________________________________________________________ 25 | 26 | -------------------------------------------------------------------------------- /src/services/@types/events.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { DiffFile } from '../../@types/diffs'; 4 | import type { DiffCopyMessage, DiffInitMessage, DiffMultiCopyMessage } from '../../@types/messages'; 5 | 6 | // Variables __________________________________________________________________ 7 | 8 | 9 | 10 | // Initialize _________________________________________________________________ 11 | 12 | 13 | 14 | // Exports ____________________________________________________________________ 15 | 16 | export type CopyFileEvent = { 17 | from: DiffFile, 18 | to: DiffFile, 19 | }; 20 | 21 | export type CopyFilesEvent = { 22 | data: DiffCopyMessage, 23 | from: 'A' | 'B', 24 | to: 'A' | 'B', 25 | }; 26 | 27 | export type MultiCopyEvent = { 28 | data: DiffMultiCopyMessage, 29 | from: 'left' | 'right', 30 | }; 31 | 32 | export type StartEvent = { 33 | data: DiffInitMessage, 34 | pathA: string, 35 | pathB: string 36 | }; 37 | 38 | // Functions __________________________________________________________________ 39 | 40 | -------------------------------------------------------------------------------- /src/services/@types/favorites.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { FavoriteGroupTreeItem } from '../sidebar/trees/FavoriteGroupTreeItem'; 4 | import type { FavoriteTreeItem } from '../sidebar/trees/FavoriteTreeItem'; 5 | 6 | // Variables __________________________________________________________________ 7 | 8 | 9 | 10 | // Initialize _________________________________________________________________ 11 | 12 | 13 | 14 | // Exports ____________________________________________________________________ 15 | 16 | export type FavoriteTreeItems = FavoriteTreeItem | FavoriteGroupTreeItem; 17 | 18 | export type Favorite = { 19 | label: string, 20 | fileA: string, 21 | fileB: string, 22 | groupId?: number, 23 | }; 24 | 25 | export type FavoriteImport = { 26 | label: string, 27 | pathA: string, 28 | pathB: string, 29 | groupId?: number, 30 | }; 31 | 32 | export type ValidFavoriteImport = { 33 | label: string, 34 | [key: string]: unknown, 35 | }; 36 | 37 | export type FavoriteGroup = { 38 | label: string, 39 | id: number, 40 | collapsed: boolean, 41 | }; 42 | 43 | export type InitialState = 'collapsed' | 'expanded' | 'remember'; 44 | 45 | export type FavoritesStates = { 46 | favorites: Favorite[], 47 | favoriteGroups: FavoriteGroup[], 48 | }; 49 | 50 | export type RefreshFavoritesStates = { 51 | favorites?: Favorite[], 52 | favoriteGroups?: FavoriteGroup[], 53 | }; 54 | 55 | // Functions __________________________________________________________________ 56 | 57 | -------------------------------------------------------------------------------- /src/services/@types/fse.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { Dictionary, DiffFile } from '../../types'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export type WalkTreeOptions = { 16 | abortOnError: boolean, 17 | excludes?: string[], 18 | useCaseSensitive?: boolean, 19 | maxFileSize?: number, 20 | }; 21 | 22 | export type StatsMap = Dictionary; 23 | 24 | export type WalkTreeJob = { 25 | error: null | Error, 26 | abort: boolean, 27 | ignore: null | RegExp, 28 | tasks: number, 29 | result: StatsMap, 30 | maxSize: number, 31 | done: (error?: Error) => void, 32 | }; 33 | 34 | // Functions __________________________________________________________________ 35 | 36 | -------------------------------------------------------------------------------- /src/services/@types/history.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export type Comparison = { 16 | fileA: string, 17 | fileB: string, 18 | label: string, 19 | desc: string, 20 | type: 'file' | 'folder' | 'symlink', 21 | }; 22 | 23 | export type HistoryStates = { 24 | comparisons: Comparison[], 25 | }; 26 | 27 | export type RefreshHistoryStates = { 28 | comparisons?: Comparison[], 29 | }; 30 | 31 | // Functions __________________________________________________________________ 32 | 33 | -------------------------------------------------------------------------------- /src/services/@types/packages.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export type PackageLanguage = { 16 | extensions: string[], 17 | filenames: string[], 18 | }; 19 | 20 | // Functions __________________________________________________________________ 21 | 22 | -------------------------------------------------------------------------------- /src/services/@types/panel.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { Dictionary } from '../../types'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export type ContextStates = Dictionary; 16 | 17 | export type Uri = { 18 | fsPath: string, 19 | }; 20 | 21 | // Functions __________________________________________________________________ 22 | 23 | -------------------------------------------------------------------------------- /src/services/@types/projects.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { TreeItem } from 'vscode'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export type WorkspaceTypes = 'git' | 'subfolder' | 'vscode' | 'workspace'; 16 | 17 | export type ProjectTypes = 'folder' | 'folders' | WorkspaceTypes; 18 | 19 | export type Project = { 20 | path: string, 21 | label: string, 22 | type: ProjectTypes, 23 | color?: number, 24 | deleted?: boolean, 25 | }; 26 | 27 | export interface ProjectTreeItem extends TreeItem { 28 | 29 | command: { 30 | arguments: any[], 31 | command: string, 32 | title: string, 33 | }; 34 | 35 | readonly project: Project; 36 | 37 | } 38 | 39 | // Functions __________________________________________________________________ 40 | 41 | -------------------------------------------------------------------------------- /src/services/@types/states.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export type StateInfo = { 16 | lastModified: number, 17 | }; 18 | 19 | // Functions __________________________________________________________________ 20 | 21 | -------------------------------------------------------------------------------- /src/services/actions/symlinks/SymlinkContentProvider.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import * as fs from 'fs'; 4 | import * as vscode from 'vscode'; 5 | 6 | // Variables __________________________________________________________________ 7 | 8 | const findTimestamp = /\?ts=\d+$/; 9 | 10 | // Initialize _________________________________________________________________ 11 | 12 | 13 | 14 | // Exports ____________________________________________________________________ 15 | 16 | export class SymlinkContentProvider implements vscode.TextDocumentContentProvider { 17 | 18 | public static SCHEME = 'l13diffsymlink'; 19 | 20 | public provideTextDocumentContent (uri: vscode.Uri, cancel: vscode.CancellationToken): Promise { 21 | 22 | if (cancel.isCancellationRequested) return Promise.resolve(''); 23 | 24 | return new Promise((resolve, reject) => { 25 | 26 | fs.readlink(uri.fsPath.replace(findTimestamp, ''), (error, content) => { 27 | 28 | if (error) reject(error); 29 | else resolve(content); 30 | 31 | }); 32 | 33 | }); 34 | 35 | } 36 | 37 | public static parse (pathname: string) { 38 | 39 | return vscode.Uri.parse(`${SymlinkContentProvider.SCHEME}:${pathname}?ts=${+new Date()}`, true); 40 | 41 | } 42 | 43 | } 44 | 45 | // Functions __________________________________________________________________ 46 | 47 | -------------------------------------------------------------------------------- /src/services/commands/common.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import * as vscode from 'vscode'; 4 | 5 | import * as states from '../common/states'; 6 | 7 | import { FavoritesProvider } from '../sidebar/FavoritesProvider'; 8 | import { HistoryProvider } from '../sidebar/HistoryProvider'; 9 | 10 | import { FavoriteGroupsState } from '../states/FavoriteGroupsState'; 11 | import { FavoritesState } from '../states/FavoritesState'; 12 | import { HistoryState } from '../states/HistoryState'; 13 | 14 | // Variables __________________________________________________________________ 15 | 16 | 17 | 18 | // Initialize _________________________________________________________________ 19 | 20 | 21 | 22 | // Exports ____________________________________________________________________ 23 | 24 | export function activate (context: vscode.ExtensionContext) { 25 | 26 | const favoritesState = FavoritesState.create(context); 27 | const favoriteGroupsState = FavoriteGroupsState.create(context); 28 | const historyState = HistoryState.create(context); 29 | 30 | let previousLastModified = states.getStateInfo(context).lastModified; 31 | 32 | context.subscriptions.push(vscode.window.onDidChangeWindowState(({ focused }) => { 33 | 34 | if (focused) { // Update data if changes in another workspace have been done 35 | const currentLastModified = states.getStateInfo(context).lastModified; 36 | if (previousLastModified !== currentLastModified) { 37 | previousLastModified = currentLastModified; 38 | FavoritesProvider.current?.refresh({ 39 | favorites: favoritesState.get(), 40 | favoriteGroups: favoriteGroupsState.get(), 41 | }); 42 | HistoryProvider.current?.refresh({ 43 | comparisons: historyState.get(), 44 | }); 45 | } 46 | } 47 | 48 | })); 49 | 50 | } 51 | 52 | // Functions __________________________________________________________________ 53 | 54 | -------------------------------------------------------------------------------- /src/services/commands/explorer.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import * as vscode from 'vscode'; 4 | 5 | import type { ProjectTreeItem } from '../../types'; 6 | 7 | import * as commands from '../common/commands'; 8 | 9 | // Variables __________________________________________________________________ 10 | 11 | 12 | 13 | // Initialize _________________________________________________________________ 14 | 15 | 16 | 17 | // Exports ____________________________________________________________________ 18 | 19 | export function activate (context: vscode.ExtensionContext) { 20 | 21 | let folderUri: vscode.Uri = null; 22 | 23 | commands.register(context, { 24 | 25 | 'l13Diff.action.explorer.selectForCompare': (uri: vscode.Uri) => { 26 | 27 | if (!folderUri) vscode.commands.executeCommand('setContext', 'l13DiffSelectedFolder', true); 28 | 29 | folderUri = uri; 30 | 31 | }, 32 | 33 | 'l13Diff.action.explorer.compareWithSelected': (uri: vscode.Uri) => { 34 | 35 | vscode.commands.executeCommand('l13Diff.action.panel.openAndCompare', folderUri, uri); 36 | 37 | }, 38 | 39 | 'l13Diff.action.explorer.compareSelected': (uri: vscode.Uri, uris: vscode.Uri[]) => { 40 | 41 | vscode.commands.executeCommand('l13Diff.action.panel.openAndCompare', uris[0], uris[1]); 42 | 43 | }, 44 | 45 | 'l13Diff.action.projects.selectForCompare': ({ project }: ProjectTreeItem) => { 46 | 47 | if (!folderUri) vscode.commands.executeCommand('setContext', 'l13DiffSelectedFolder', true); 48 | 49 | folderUri = vscode.Uri.file(project.path); 50 | 51 | }, 52 | 53 | 'l13Diff.action.projects.compareWithSelected': ({ project }: ProjectTreeItem) => { 54 | 55 | vscode.commands.executeCommand('l13Diff.action.panel.openAndCompare', folderUri, vscode.Uri.file(project.path)); 56 | 57 | }, 58 | 59 | }); 60 | 61 | } 62 | 63 | // Functions __________________________________________________________________ 64 | 65 | -------------------------------------------------------------------------------- /src/services/commands/output.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import * as vscode from 'vscode'; 4 | 5 | import * as commands from '../common/commands'; 6 | 7 | import { DiffOutput } from '../output/DiffOutput'; 8 | 9 | // Variables __________________________________________________________________ 10 | 11 | 12 | 13 | // Initialize _________________________________________________________________ 14 | 15 | 16 | 17 | // Exports ____________________________________________________________________ 18 | 19 | export function activate (context: vscode.ExtensionContext) { 20 | 21 | commands.register(context, { 22 | 'l13Diff.action.output.show': () => DiffOutput.currentOutput?.show(), 23 | }); 24 | 25 | } 26 | 27 | // Functions __________________________________________________________________ 28 | 29 | -------------------------------------------------------------------------------- /src/services/commands/projects.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import * as vscode from 'vscode'; 4 | 5 | import type { ProjectTreeItem } from '../../types'; 6 | 7 | import * as commands from '../common/commands'; 8 | 9 | import { DiffPanel } from '../panel/DiffPanel'; 10 | 11 | // Variables __________________________________________________________________ 12 | 13 | 14 | 15 | // Initialize _________________________________________________________________ 16 | 17 | 18 | 19 | // Exports ____________________________________________________________________ 20 | 21 | export function activate (context: vscode.ExtensionContext) { 22 | 23 | commands.register(context, { 24 | 25 | 'l13Diff.action.projects.compareWithWorkspace': async ({ project }: ProjectTreeItem) => { 26 | 27 | const workspaces = workspaceFoldersQuickPickItems(); 28 | 29 | if (workspaces.length > 1) { 30 | const value = await vscode.window.showQuickPick(workspaces); 31 | if (value) DiffPanel.createOrShow(context, [{ fsPath: value.description }, { fsPath: project.path }], true); 32 | } else if (workspaces.length === 1) { 33 | DiffPanel.createOrShow(context, [{ fsPath: workspaces[0].description }, { fsPath: project.path }], true); 34 | } else vscode.window.showErrorMessage('No workspace available!'); 35 | 36 | }, 37 | 38 | 'l13Diff.action.projects.open': ({ project }: ProjectTreeItem) => { 39 | 40 | DiffPanel.createOrShow(context, [{ fsPath: project.path }, { fsPath: '' }]); 41 | 42 | }, 43 | 44 | }); 45 | 46 | } 47 | 48 | // Functions __________________________________________________________________ 49 | 50 | function workspaceFoldersQuickPickItems (): Array<{ label: string, description: string }> { 51 | 52 | const workspaceFolders = vscode.workspace.workspaceFolders; 53 | 54 | return workspaceFolders ? workspaceFolders.map((folder) => ({ label: folder.name, description: folder.uri.fsPath })) : []; 55 | 56 | } -------------------------------------------------------------------------------- /src/services/commands/symlinks.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import * as vscode from 'vscode'; 4 | 5 | import { SymlinkContentProvider } from '../actions/symlinks/SymlinkContentProvider'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export function activate (context: vscode.ExtensionContext) { 18 | 19 | const contentProvider = new SymlinkContentProvider(); 20 | 21 | context.subscriptions.push(vscode.workspace.registerTextDocumentContentProvider(SymlinkContentProvider.SCHEME, contentProvider)); 22 | 23 | } 24 | 25 | // Functions __________________________________________________________________ 26 | 27 | -------------------------------------------------------------------------------- /src/services/common/commands.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import * as vscode from 'vscode'; 4 | 5 | import type { Dictionary } from '../../types'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export function register (context: vscode.ExtensionContext, commands: Dictionary<(...args: any) => void>) { 18 | 19 | for (const [command, callback] of Object.entries(commands)) { 20 | context.subscriptions.push(vscode.commands.registerCommand(command, callback)); 21 | } 22 | 23 | } 24 | 25 | // Functions __________________________________________________________________ 26 | 27 | -------------------------------------------------------------------------------- /src/services/common/dialogs.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import * as vscode from 'vscode'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export async function openFile (options: { filters?: { [name: string]: string[] } } = {}) { 16 | 17 | const uris = await vscode.window.showOpenDialog({ 18 | canSelectFiles: true, 19 | canSelectFolders: false, 20 | canSelectMany: false, 21 | ...options, 22 | }); 23 | 24 | return uris ? uris[0].fsPath : null; 25 | 26 | } 27 | 28 | export async function openFolder () { 29 | 30 | const uris = await vscode.window.showOpenDialog({ 31 | canSelectFiles: false, 32 | canSelectFolders: true, 33 | canSelectMany: false, 34 | }); 35 | 36 | return uris ? uris[0].fsPath : null; 37 | 38 | } 39 | 40 | export async function confirm (text: string, ...buttons: string[]) { 41 | 42 | return await vscode.window.showInformationMessage(text, { modal: true }, ...buttons); 43 | 44 | } 45 | 46 | // Functions __________________________________________________________________ 47 | 48 | -------------------------------------------------------------------------------- /src/services/common/files.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import * as vscode from 'vscode'; 4 | 5 | import { lstatSync } from '../@l13/fse'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export function reveal (pathname: string) { 18 | 19 | if (lstatSync(pathname)) { 20 | vscode.commands.executeCommand('revealFileInOS', vscode.Uri.file(pathname)); 21 | } else vscode.window.showErrorMessage(`Path "${pathname}" doesn't exist!`); 22 | 23 | } 24 | 25 | // Functions __________________________________________________________________ 26 | 27 | -------------------------------------------------------------------------------- /src/services/common/paths.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import * as vscode from 'vscode'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | // eslint-disable-next-line no-useless-escape 8 | const findPlaceholder = /^\$\{workspaceFolder(?:\:((?:\\\}|[^\}])*))?\}/; 9 | const findEscapedEndingBrace = /\\\}/g; 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export function workspacePaths (workspaceFolders: readonly vscode.WorkspaceFolder[] | undefined) { 18 | 19 | return (workspaceFolders || []).map((item: vscode.WorkspaceFolder) => item.uri.fsPath); 20 | 21 | } 22 | 23 | export function parsePredefinedVariable (pathname: string, ignoreErrors = false) { 24 | 25 | return pathname.replace(findPlaceholder, function (match, name: string) { 26 | 27 | const workspaceFolders = vscode.workspace.workspaceFolders; 28 | 29 | if (!workspaceFolders) { 30 | if (!ignoreErrors) vscode.window.showErrorMessage('No workspace folder available!'); 31 | return match; 32 | } 33 | 34 | if (!name) return workspaceFolders[0].uri.fsPath; 35 | 36 | name = name.replace(findEscapedEndingBrace, '}'); 37 | 38 | for (const workspaceFolder of workspaceFolders) { 39 | if (workspaceFolder.name === name) return workspaceFolder.uri.fsPath; 40 | } 41 | 42 | if (!ignoreErrors) vscode.window.showErrorMessage(`No workspace folder with name "${name}" available!`); 43 | 44 | return match; 45 | 46 | }); 47 | 48 | } 49 | 50 | // Functions __________________________________________________________________ 51 | 52 | -------------------------------------------------------------------------------- /src/services/dialogs/HistoryDialog.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { Comparison } from '../../types'; 4 | 5 | import * as dialogs from '../common/dialogs'; 6 | 7 | import type { HistoryState } from '../states/HistoryState'; 8 | import type { MenuState } from '../states/MenuState'; 9 | 10 | // Variables __________________________________________________________________ 11 | 12 | 13 | 14 | // Initialize _________________________________________________________________ 15 | 16 | 17 | 18 | // Exports ____________________________________________________________________ 19 | 20 | export class HistoryDialog { 21 | 22 | private static current: HistoryDialog = null; 23 | 24 | public static create (historyState: HistoryState, menuState: MenuState) { 25 | 26 | return HistoryDialog.current || (HistoryDialog.current = new HistoryDialog(historyState, menuState)); 27 | 28 | } 29 | 30 | private constructor (private readonly historyState: HistoryState, private readonly menuState: MenuState) {} 31 | 32 | public async remove (comparison: Comparison) { 33 | 34 | const text = `Delete comparison '${`${comparison.label}${comparison.desc ? ` (${comparison.desc})` : ''}`}'?`; 35 | 36 | if (await dialogs.confirm(text, 'Delete')) { 37 | this.historyState.remove(comparison); 38 | } 39 | 40 | } 41 | 42 | public async clear () { 43 | 44 | if (await dialogs.confirm('Delete the complete history?', 'Delete')) { 45 | this.menuState.clear(); 46 | this.historyState.clear(); 47 | } 48 | 49 | } 50 | 51 | } 52 | 53 | // Functions __________________________________________________________________ 54 | 55 | -------------------------------------------------------------------------------- /src/services/main.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import * as vscode from 'vscode'; 4 | 5 | import * as common from './commands/common'; 6 | import * as developer from './commands/developer'; 7 | import * as explorer from './commands/explorer'; 8 | import * as favorites from './commands/favorites'; 9 | import * as history from './commands/history'; 10 | import * as output from './commands/output'; 11 | import * as panel from './commands/panel'; 12 | import * as projects from './commands/projects'; 13 | import * as settings from './commands/settings'; 14 | import * as shortcuts from './commands/shortcuts'; 15 | import * as symlinks from './commands/symlinks'; 16 | 17 | // Variables __________________________________________________________________ 18 | 19 | 20 | 21 | // Initialize _________________________________________________________________ 22 | 23 | 24 | 25 | // Exports ____________________________________________________________________ 26 | 27 | export function activate (context: vscode.ExtensionContext) { 28 | 29 | common.activate(context); 30 | explorer.activate(context); 31 | favorites.activate(context); 32 | history.activate(context); 33 | output.activate(context); 34 | panel.activate(context); 35 | projects.activate(context); 36 | settings.activate(context); 37 | shortcuts.activate(context); 38 | symlinks.activate(context); 39 | 40 | if (context.extensionMode === vscode.ExtensionMode.Development) developer.activate(context); 41 | 42 | } 43 | 44 | export function deactivate () { 45 | 46 | // 47 | 48 | } 49 | 50 | // Functions __________________________________________________________________ 51 | 52 | -------------------------------------------------------------------------------- /src/services/output/DiffResult.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { Diff, DiffSettings } from '../../types'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export class DiffResult { 16 | 17 | public diffs: Diff[] = []; 18 | 19 | public constructor (public pathA: string, public pathB: string, public settings: DiffSettings) { 20 | 21 | 22 | 23 | } 24 | 25 | } 26 | 27 | // Functions __________________________________________________________________ 28 | 29 | -------------------------------------------------------------------------------- /src/services/output/stats/DetailStats.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export class DetailStats { 16 | 17 | public total = 0; 18 | public entries = 0; 19 | public files = 0; 20 | public folders = 0; 21 | public symlinks = 0; 22 | public errors = 0; 23 | public others = 0; 24 | public size = 0; 25 | public ignoredBOM = 0; 26 | public ignoredEOL = 0; 27 | public ignoredWhitespace = 0; 28 | 29 | } 30 | 31 | // Functions __________________________________________________________________ 32 | 33 | -------------------------------------------------------------------------------- /src/services/output/stats/FolderStats.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export class FolderStats { 16 | 17 | public pathname = ''; 18 | public entries = 0; 19 | public files = 0; 20 | public folders = 0; 21 | public symlinks = 0; 22 | public errors = 0; 23 | public others = 0; 24 | public size = 0; 25 | 26 | } 27 | 28 | // Functions __________________________________________________________________ 29 | 30 | -------------------------------------------------------------------------------- /src/services/panel/events.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export * as compare from './events/compare'; 16 | export * as context from './events/context'; 17 | export * as copy from './events/copy'; 18 | export * as deletes from './events/deletes'; 19 | export * as dialogs from './events/dialogs'; 20 | export * as favorites from './events/favorites'; 21 | export * as menu from './events/menu'; 22 | export * as open from './events/open'; 23 | export * as panelstates from './events/panelstates'; 24 | export * as updates from './events/updates'; 25 | 26 | // Functions __________________________________________________________________ 27 | 28 | -------------------------------------------------------------------------------- /src/services/panel/events/context.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { DiffPanel } from '../DiffPanel'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export function init (currentDiffPanel: DiffPanel) { 16 | 17 | currentDiffPanel.msg.on('context', ({ name, value }) => { 18 | 19 | currentDiffPanel.setContext(name, value); 20 | 21 | }); 22 | 23 | } 24 | 25 | // Functions __________________________________________________________________ 26 | 27 | -------------------------------------------------------------------------------- /src/services/panel/events/deletes.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { DiffFile } from '../../../types'; 4 | 5 | import type { DiffResult } from '../../output/DiffResult'; 6 | 7 | import type { DiffPanel } from '../DiffPanel'; 8 | 9 | // Variables __________________________________________________________________ 10 | 11 | 12 | 13 | // Initialize _________________________________________________________________ 14 | 15 | 16 | 17 | // Exports ____________________________________________________________________ 18 | 19 | export function init (currentDiffPanel: DiffPanel) { 20 | 21 | currentDiffPanel.msg.on('delete:both', (data: DiffResult) => { 22 | 23 | currentDiffPanel.delete.showDeleteFilesDialog(data); 24 | 25 | }); 26 | 27 | currentDiffPanel.msg.on('delete:left', (data: DiffResult) => { 28 | 29 | currentDiffPanel.delete.showDeleteFileDialog(data, 'left'); 30 | 31 | }); 32 | 33 | currentDiffPanel.msg.on('delete:right', (data: DiffResult) => { 34 | 35 | currentDiffPanel.delete.showDeleteFileDialog(data, 'right'); 36 | 37 | }); 38 | 39 | currentDiffPanel.delete.onDidCancel(() => { 40 | 41 | currentDiffPanel.msg.send('cancel'); 42 | 43 | }, null, currentDiffPanel.disposables); 44 | 45 | currentDiffPanel.delete.onDidDeleteFile((file: DiffFile) => { 46 | 47 | currentDiffPanel.output.log(`Deleted ${file.type} "${file.path}"`); 48 | 49 | }, null, currentDiffPanel.disposables); 50 | 51 | currentDiffPanel.delete.onDidDeleteFiles((data: DiffResult) => { 52 | 53 | currentDiffPanel.msg.send('delete:files', data); 54 | currentDiffPanel.sendOthers('update:multi', data); 55 | 56 | }, null, currentDiffPanel.disposables); 57 | 58 | } 59 | 60 | // Functions __________________________________________________________________ 61 | 62 | -------------------------------------------------------------------------------- /src/services/panel/events/dialogs.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import * as dialogs from '../../common/dialogs'; 4 | 5 | import type { DiffPanel } from '../DiffPanel'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export function init (currentDiffPanel: DiffPanel) { 18 | 19 | currentDiffPanel.msg.on('dialog:file', async () => { 20 | 21 | const fsPath = await dialogs.openFile(); 22 | 23 | currentDiffPanel.msg.send('dialog:file', { fsPath }); 24 | 25 | }); 26 | 27 | currentDiffPanel.msg.on('dialog:folder', async () => { 28 | 29 | const fsPath = await dialogs.openFolder(); 30 | 31 | currentDiffPanel.msg.send('dialog:folder', { fsPath }); 32 | 33 | }); 34 | 35 | } 36 | 37 | // Functions __________________________________________________________________ 38 | 39 | -------------------------------------------------------------------------------- /src/services/panel/events/favorites.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { DiffFavoriteMessage } from '../../../types'; 4 | 5 | import { FavoritesDialog } from '../../dialogs/FavoritesDialog'; 6 | 7 | import { FavoritesState } from '../../states/FavoritesState'; 8 | 9 | import type { DiffPanel } from '../DiffPanel'; 10 | 11 | // Variables __________________________________________________________________ 12 | 13 | 14 | 15 | // Initialize _________________________________________________________________ 16 | 17 | 18 | 19 | // Exports ____________________________________________________________________ 20 | 21 | export function init (currentDiffPanel: DiffPanel) { 22 | 23 | const favoritesState = FavoritesState.create(currentDiffPanel.context); 24 | const favoritesDialog = FavoritesDialog.create(favoritesState); 25 | 26 | currentDiffPanel.msg.on('save:favorite', (data: DiffFavoriteMessage) => { 27 | 28 | favoritesDialog.add(data.pathA, data.pathB); 29 | 30 | }); 31 | 32 | } 33 | 34 | // Functions __________________________________________________________________ 35 | 36 | -------------------------------------------------------------------------------- /src/services/panel/events/menu.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import * as vscode from 'vscode'; 4 | 5 | import type { DiffMenuMessage } from '../../../types'; 6 | 7 | import { workspacePaths } from '../../common/paths'; 8 | 9 | import { MenuState } from '../../states/MenuState'; 10 | 11 | import type { DiffPanel } from '../DiffPanel'; 12 | 13 | // Variables __________________________________________________________________ 14 | 15 | 16 | 17 | // Initialize _________________________________________________________________ 18 | 19 | 20 | 21 | // Exports ____________________________________________________________________ 22 | 23 | export function init (currentDiffPanel: DiffPanel) { 24 | 25 | const menuState = MenuState.create(currentDiffPanel.context); 26 | 27 | currentDiffPanel.msg.on('update:menu', () => { 28 | 29 | currentDiffPanel.msg.send('update:menu', { 30 | history: menuState.get(), 31 | workspaces: workspacePaths(vscode.workspace.workspaceFolders), 32 | }); 33 | 34 | }); 35 | 36 | } 37 | 38 | // Functions __________________________________________________________________ 39 | 40 | -------------------------------------------------------------------------------- /src/services/panel/events/open.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { DiffGoToMessage, DiffOpenMessage, DiffPreviewMessage } from '../../../types'; 4 | 5 | import { DiffOpen } from '../../actions/DiffOpen'; 6 | 7 | import * as files from '../../common/files'; 8 | import * as settings from '../../common/settings'; 9 | 10 | import type { DiffPanel } from '../DiffPanel'; 11 | 12 | // Variables __________________________________________________________________ 13 | 14 | 15 | 16 | // Initialize _________________________________________________________________ 17 | 18 | 19 | 20 | // Exports ____________________________________________________________________ 21 | 22 | export function init (currentDiffPanel: DiffPanel) { 23 | 24 | currentDiffPanel.msg.on('open:diff', async ({ diffs, openToSide }: DiffOpenMessage) => { 25 | 26 | openToSide = settings.get('openToSide', false) || openToSide; 27 | 28 | for (let i = 0; i < diffs.length; i++) await DiffOpen.open(diffs[i], i === 0 && openToSide); 29 | 30 | }); 31 | 32 | currentDiffPanel.msg.on('preview:diff', async ({ diff }: DiffPreviewMessage) => { 33 | 34 | await DiffOpen.open(diff, true, true); 35 | 36 | }); 37 | 38 | currentDiffPanel.msg.on('goto:file', async ({ files: diffFiles, openToSide }: DiffGoToMessage) => { 39 | 40 | openToSide = settings.get('openToSide', false) || openToSide; 41 | 42 | for (let i = 0; i < diffFiles.length; i++) await DiffOpen.openFile(diffFiles[i], i === 0 && openToSide, false); 43 | 44 | }); 45 | 46 | currentDiffPanel.msg.on('reveal:file', (fsPath: string) => files.reveal(fsPath)); 47 | 48 | } 49 | 50 | // Functions __________________________________________________________________ 51 | 52 | -------------------------------------------------------------------------------- /src/services/panel/events/panelstates.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { DiffPanelStateMessage } from '../../../types'; 4 | 5 | import type { DiffPanel } from '../DiffPanel'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export function init (currentDiffPanel: DiffPanel) { 18 | 19 | currentDiffPanel.msg.on('save:panelstate', (data: DiffPanelStateMessage) => { 20 | 21 | currentDiffPanel.savePanelState(data); 22 | 23 | }); 24 | 25 | } 26 | 27 | // Functions __________________________________________________________________ 28 | 29 | -------------------------------------------------------------------------------- /src/services/panel/events/updates.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { Diff, DiffResultMessage } from '../../../types'; 4 | 5 | import type { DiffResult } from '../../output/DiffResult'; 6 | 7 | import type { DiffPanel } from '../DiffPanel'; 8 | 9 | // Variables __________________________________________________________________ 10 | 11 | 12 | 13 | // Initialize _________________________________________________________________ 14 | 15 | 16 | 17 | // Exports ____________________________________________________________________ 18 | 19 | export function init (currentDiffPanel: DiffPanel) { 20 | 21 | currentDiffPanel.msg.on('update:diffs', (data: DiffResultMessage) => { 22 | 23 | currentDiffPanel.compare.updateDiffs(data); 24 | 25 | }); 26 | 27 | currentDiffPanel.compare.onDidUpdateDiff((diff: Diff) => { 28 | 29 | currentDiffPanel.output.log(`Compared "${formatPath(diff)}" again. Status is now "${diff.status}"`); 30 | 31 | }, null, currentDiffPanel.disposables); 32 | 33 | currentDiffPanel.compare.onDidUpdateAllDiffs((diffResult: DiffResult) => { 34 | 35 | currentDiffPanel.msg.send('update:diffs', diffResult); 36 | 37 | }, null, currentDiffPanel.disposables); 38 | 39 | } 40 | 41 | // Functions __________________________________________________________________ 42 | 43 | function formatPath (diff: Diff) { 44 | 45 | const relativeA = diff.fileA.relative; 46 | const relativeB = diff.fileB.relative; 47 | 48 | return relativeA === relativeB ? relativeA : `${relativeA}" and "${relativeB}`; 49 | 50 | } -------------------------------------------------------------------------------- /src/services/sidebar/trees/FavoriteGroupTreeItem.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { TreeItemCollapsibleState, TreeItem } from 'vscode'; 4 | 5 | import type { FavoriteGroup } from '../../../types'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export class FavoriteGroupTreeItem extends TreeItem { 18 | 19 | public contextValue = 'favoriteGroup'; 20 | 21 | public constructor (public readonly favoriteGroup: FavoriteGroup) { 22 | 23 | super(favoriteGroup.label, favoriteGroup.collapsed ? TreeItemCollapsibleState.Collapsed : TreeItemCollapsibleState.Expanded); 24 | 25 | this.id = `${favoriteGroup.id}`; 26 | 27 | } 28 | 29 | } 30 | 31 | // Functions __________________________________________________________________ 32 | 33 | -------------------------------------------------------------------------------- /src/services/sidebar/trees/FavoriteTreeItem.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { join, resolve } from 'path'; 4 | import * as vscode from 'vscode'; 5 | 6 | import type { Favorite } from '../../../types'; 7 | 8 | // Variables __________________________________________________________________ 9 | 10 | const basePath = resolve(__dirname, '..', 'images', 'favorites'); 11 | const iconPath = { 12 | light: join(basePath, 'favorite-item-light.svg'), 13 | dark: join(basePath, 'favorite-item-dark.svg'), 14 | }; 15 | 16 | // Initialize _________________________________________________________________ 17 | 18 | 19 | 20 | // Exports ____________________________________________________________________ 21 | 22 | export class FavoriteTreeItem extends vscode.TreeItem { 23 | 24 | public command = { 25 | arguments: [this], 26 | command: 'l13Diff.action.favorite.compare', 27 | title: 'Compare', 28 | }; 29 | 30 | public iconPath = iconPath; 31 | 32 | public contextValue = 'favorite'; 33 | 34 | public constructor (public readonly favorite: Favorite) { 35 | 36 | super(favorite.label); 37 | 38 | if (favorite.groupId !== undefined) this.contextValue = `sub${this.contextValue}`; 39 | 40 | this.tooltip = `${this.favorite.fileA} ↔ ${this.favorite.fileB}`; 41 | 42 | } 43 | 44 | } 45 | 46 | // Functions __________________________________________________________________ 47 | 48 | -------------------------------------------------------------------------------- /src/services/sidebar/trees/HistoryTreeItem.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { join, resolve } from 'path'; 4 | import * as vscode from 'vscode'; 5 | 6 | import type { Comparison } from '../../../types'; 7 | 8 | // Variables __________________________________________________________________ 9 | 10 | const basePath = resolve(__dirname, '..', 'images', 'history'); 11 | 12 | // Initialize _________________________________________________________________ 13 | 14 | 15 | 16 | // Exports ____________________________________________________________________ 17 | 18 | export class HistoryTreeItem extends vscode.TreeItem { 19 | 20 | public command = { 21 | arguments: [this], 22 | command: 'l13Diff.action.history.compare', 23 | title: 'Compare', 24 | }; 25 | 26 | public contextValue = 'history'; 27 | 28 | public constructor (public readonly comparison: Comparison) { 29 | 30 | super(comparison.label); 31 | 32 | let type = 'item'; 33 | 34 | if (comparison.type) { 35 | type = comparison.type; 36 | this.contextValue += `-${type}`; 37 | } 38 | 39 | this.iconPath = { 40 | light: join(basePath, `history-${type}-light.svg`), 41 | dark: join(basePath, `history-${type}-dark.svg`), 42 | }; 43 | 44 | this.description = `${this.comparison.desc || ''}`; 45 | this.tooltip = `${this.comparison.fileA} ↔ ${this.comparison.fileB}`; 46 | 47 | } 48 | 49 | } 50 | 51 | // Functions __________________________________________________________________ 52 | 53 | -------------------------------------------------------------------------------- /src/services/states/MenuState.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import * as vscode from 'vscode'; 4 | 5 | import * as settings from '../common/settings'; 6 | import * as states from '../common/states'; 7 | 8 | // Variables __________________________________________________________________ 9 | 10 | 11 | 12 | // Initialize _________________________________________________________________ 13 | 14 | 15 | 16 | // Exports ____________________________________________________________________ 17 | 18 | export class MenuState { 19 | 20 | private static current: MenuState = null; 21 | 22 | public static create (context: vscode.ExtensionContext) { 23 | 24 | return MenuState.current || (MenuState.current = new MenuState(context)); 25 | 26 | } 27 | 28 | private constructor (private readonly context: vscode.ExtensionContext) {} 29 | 30 | private _onDidChangeHistory: vscode.EventEmitter = new vscode.EventEmitter(); 31 | public readonly onDidChangeHistory: vscode.Event = this._onDidChangeHistory.event; 32 | 33 | public get () { 34 | 35 | return states.getHistory(this.context); 36 | 37 | } 38 | 39 | private save (history: string[]) { 40 | 41 | states.updateHistory(this.context, history); 42 | 43 | } 44 | 45 | public saveRecentlyUsed (pathA: string, pathB: string) { 46 | 47 | let history = states.getHistory(this.context); 48 | 49 | history = history.filter((path) => path !== pathA && path !== pathB); 50 | history.unshift(pathA, pathB); 51 | 52 | history = history.slice(0, settings.maxRecentlyUsed()); 53 | 54 | this.save(history); 55 | this._onDidChangeHistory.fire(history); 56 | 57 | } 58 | 59 | public clear () { 60 | 61 | this.save([]); 62 | this._onDidChangeHistory.fire([]); 63 | 64 | } 65 | 66 | } 67 | 68 | // Functions __________________________________________________________________ 69 | 70 | -------------------------------------------------------------------------------- /src/test/index.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import * as path from 'path'; 4 | import * as glob from 'glob'; 5 | import Mocha from 'mocha'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | const mocha = new Mocha({ 10 | ui: 'bdd', 11 | color: true, 12 | }); 13 | 14 | const files = glob.sync('**/*.test.js', { 15 | cwd: __dirname, 16 | }); 17 | 18 | // Initialize _________________________________________________________________ 19 | 20 | files.forEach((file) => mocha.addFile(path.resolve(__dirname, file))); 21 | 22 | mocha.run(() => { 23 | 24 | // 25 | 26 | }); 27 | 28 | // Exports ____________________________________________________________________ 29 | 30 | 31 | 32 | // Functions __________________________________________________________________ 33 | 34 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export * from './@types/basics'; 16 | export * from './@types/diffs'; 17 | export * from './@types/formats'; 18 | export * from './@types/json'; 19 | export * from './@types/messages'; 20 | export * from './@types/tests'; 21 | 22 | export * from './services/@types/compare'; 23 | export * from './services/@types/copy'; 24 | export * from './services/@types/delete'; 25 | export * from './services/@types/events'; 26 | export * from './services/@types/favorites'; 27 | export * from './services/@types/fse'; 28 | export * from './services/@types/history'; 29 | export * from './services/@types/packages'; 30 | export * from './services/@types/panel'; 31 | export * from './services/@types/projects'; 32 | export * from './services/@types/states'; 33 | 34 | export * from './views/@types/components'; 35 | export * from './views/@types/events'; 36 | export * from './views/@types/intro'; 37 | export * from './views/@types/inits'; 38 | export * from './views/@types/keyboards'; 39 | export * from './views/@types/list'; 40 | export * from './views/@types/search'; 41 | export * from './views/@types/states'; 42 | export * from './views/@types/views'; 43 | 44 | // Functions __________________________________________________________________ 45 | 46 | -------------------------------------------------------------------------------- /src/views/@l13/component/view-model-service.abstract.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { ViewModelConstructor } from '../../@types/components'; 4 | 5 | import type { ViewModel } from './view-model.abstract'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | const viewmodels = new Map, { counter: number, vms: Map }>(); 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export abstract class ViewModelService { 18 | 19 | public abstract name: string; 20 | 21 | public abstract vmc: ViewModelConstructor; 22 | 23 | public model (vmId: string): T { 24 | 25 | let collection = viewmodels.get(this.vmc); 26 | 27 | if (!collection) { 28 | collection = { counter: 1, vms: new Map() }; 29 | viewmodels.set(this.vmc, collection); 30 | } 31 | 32 | let viewmodel = collection.vms.get(vmId); 33 | 34 | if (viewmodel) return viewmodel; 35 | 36 | viewmodel = new this.vmc(); 37 | viewmodel.id = vmId || `${this.name}-${collection.counter++}`; 38 | 39 | collection.vms.set(vmId, viewmodel); 40 | 41 | return viewmodel; 42 | 43 | } 44 | 45 | public static requestUpdate (vmc?: new () => ViewModel) { 46 | 47 | if (vmc) { 48 | const collection = viewmodels.get(vmc); 49 | if (collection) { 50 | for (const vm of collection.vms.values()) vm.requestUpdate(); 51 | } 52 | } else { 53 | for (const collection of viewmodels.values()) { 54 | for (const vm of collection.vms.values()) vm.requestUpdate(); 55 | } 56 | } 57 | 58 | } 59 | 60 | } 61 | 62 | // Functions __________________________________________________________________ 63 | 64 | -------------------------------------------------------------------------------- /src/views/@l13/core.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export * from './component/component.abstract'; 16 | export * from './component/view-model-service.abstract'; 17 | export * from './component/view-model.abstract'; 18 | 19 | export * from './events/event-dispatcher.class'; 20 | export * from './events/event.class'; 21 | 22 | export * from './messages/message.class'; 23 | 24 | export * from './os/languages'; 25 | export * from './os/platforms'; 26 | 27 | // Functions __________________________________________________________________ 28 | 29 | -------------------------------------------------------------------------------- /src/views/@l13/events/event.class.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | const IS_STOPPED = Symbol.for('isStopped'); 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export class Event { 16 | 17 | public type: string; 18 | 19 | private [IS_STOPPED] = false; 20 | 21 | public constructor (options: { type: string }) { 22 | 23 | this.type = options.type; 24 | 25 | } 26 | 27 | public get isStopped () { 28 | 29 | return this[IS_STOPPED]; 30 | 31 | } 32 | 33 | public stopPropagation () { 34 | 35 | this[IS_STOPPED] = true; 36 | 37 | } 38 | 39 | } 40 | 41 | // Functions __________________________________________________________________ 42 | 43 | -------------------------------------------------------------------------------- /src/views/@l13/messages/message.class.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { Dictionary, MessageListener } from '../../../types'; 4 | 5 | import { remove } from '../../../@l13/arrays'; 6 | 7 | import { vscode } from '../../common'; 8 | 9 | // Variables __________________________________________________________________ 10 | 11 | const LISTENERS = Symbol.for('listeners'); 12 | 13 | // Initialize _________________________________________________________________ 14 | 15 | 16 | 17 | // Exports ____________________________________________________________________ 18 | 19 | export class Message { 20 | 21 | private [LISTENERS]: Dictionary = Object.create(null); 22 | 23 | public constructor (private readonly root: typeof vscode) { 24 | 25 | window.addEventListener('message', (event) => { 26 | 27 | const message = event.data; 28 | const command = message.command; 29 | const data = message.data; 30 | const listeners = this[LISTENERS][command]; 31 | 32 | if (listeners) listeners.forEach((listener) => listener(data)); 33 | 34 | }); 35 | 36 | } 37 | 38 | public on (name: string, listener: MessageListener) { 39 | 40 | const listeners: EventListener[] = this[LISTENERS][name] || (this[LISTENERS][name] = []); 41 | 42 | listeners[listeners.length] = listener; 43 | 44 | } 45 | 46 | public send (command: string, data: T = null) { 47 | 48 | this.root.postMessage({ command, data }); 49 | 50 | } 51 | 52 | public removeMessageListener (name: string, listener?: MessageListener) { 53 | 54 | if (!listener) return delete this[LISTENERS][name]; 55 | 56 | const listeners: null | MessageListener[] = this[LISTENERS][name] || null; 57 | 58 | if (listeners) { 59 | remove(listeners, listener); 60 | if (!listeners.length) delete this[LISTENERS][name]; 61 | } 62 | 63 | } 64 | 65 | } 66 | 67 | // Functions __________________________________________________________________ 68 | 69 | -------------------------------------------------------------------------------- /src/views/@l13/os/languages.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | // eslint-disable-next-line no-useless-escape 8 | const findLanguageClassName = /^language\-/; 9 | 10 | // Initialize _________________________________________________________________ 11 | 12 | 13 | 14 | // Exports ____________________________________________________________________ 15 | 16 | export let language = 'en'; 17 | 18 | export function detectLanguage () { 19 | 20 | document.body.classList.forEach((classname) => { 21 | 22 | if (findLanguageClassName.test(classname)) language = classname.replace(findLanguageClassName, ''); 23 | 24 | }); 25 | 26 | } 27 | 28 | // Functions __________________________________________________________________ 29 | 30 | -------------------------------------------------------------------------------- /src/views/@l13/os/platforms.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { Platform } from '../../../@types/platforms'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export let isMacOs = false; 16 | 17 | export let isWindows = false; 18 | 19 | export let isLinux = false; 20 | 21 | export function detectPlatform () { 22 | 23 | const body = document.body; 24 | 25 | isMacOs = !!body.classList.contains('platform-mac'); 26 | isWindows = !!body.classList.contains('platform-win'); 27 | isLinux = !!body.classList.contains('platform-linux'); 28 | 29 | } 30 | 31 | // Only for testing platform features 32 | 33 | export function changePlatform () { 34 | 35 | let platform: Platform; 36 | 37 | if (isMacOs) { 38 | isMacOs = false; 39 | isWindows = true; 40 | platform = 'Windows'; 41 | } else if (isWindows) { 42 | isWindows = false; 43 | isLinux = true; 44 | platform = 'Linux'; 45 | } else { 46 | isLinux = false; 47 | isMacOs = true; 48 | platform = 'macOS'; 49 | } 50 | 51 | // eslint-disable-next-line no-console 52 | console.log(`Changed platform to '${platform}'`); 53 | 54 | } 55 | 56 | // Functions __________________________________________________________________ 57 | 58 | -------------------------------------------------------------------------------- /src/views/@types/components.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { Dictionary } from '../../types'; 4 | 5 | import type { ViewModel } from '../@l13/component/view-model.abstract'; 6 | import type { ViewModelService } from '../@l13/core'; 7 | 8 | // Variables __________________________________________________________________ 9 | 10 | 11 | 12 | // Initialize _________________________________________________________________ 13 | 14 | 15 | 16 | // Exports ____________________________________________________________________ 17 | 18 | export type ComponentOptions = { 19 | name: string, 20 | service: ViewModelServiceConstructor>, 21 | styles?: string[], 22 | template?: string, 23 | }; 24 | 25 | // eslint-disable-next-line @typescript-eslint/ban-types 26 | export type ViewModelConstructor = new (options?: Dictionary) => T; 27 | 28 | export type ViewModelServiceConstructor> = new () => T; 29 | 30 | // Functions __________________________________________________________________ 31 | 32 | -------------------------------------------------------------------------------- /src/views/@types/events.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { Event } from '../@l13/events/event.class'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export type EventListener = (event?: Event, ...args: any[]) => void; 16 | 17 | // Functions __________________________________________________________________ 18 | 19 | -------------------------------------------------------------------------------- /src/views/@types/intro.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export type DisplayShortcut = { 16 | description: string, 17 | key: string, 18 | mac?: string, 19 | win?: string, 20 | }; 21 | 22 | // Functions __________________________________________________________________ 23 | 24 | -------------------------------------------------------------------------------- /src/views/@types/keyboards.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export type Keybinding = { 16 | title?: string, 17 | key: string, 18 | mac?: string, 19 | win?: string, 20 | }; 21 | 22 | // Functions __________________________________________________________________ 23 | 24 | -------------------------------------------------------------------------------- /src/views/@types/list.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { DiffStatus } from '../../types'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export type ListItemInfo = { 16 | selected: boolean, 17 | status: DiffStatus, 18 | offsetHeight: number, 19 | }; 20 | 21 | // Functions __________________________________________________________________ 22 | 23 | -------------------------------------------------------------------------------- /src/views/@types/search.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { Diff } from '../../types'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export type SearchCache = { 16 | searchterm: string, 17 | useRegExp: boolean, 18 | useCaseSensitive: boolean, 19 | useFiles: boolean, 20 | useFolders: boolean, 21 | useSymlinks: boolean, 22 | useConflicts: boolean, 23 | useOthers: boolean, 24 | regexp: RegExp, 25 | items: Diff[], 26 | filteredItems: Diff[], 27 | }; 28 | 29 | // Functions __________________________________________________________________ 30 | 31 | -------------------------------------------------------------------------------- /src/views/@types/states.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export type SearchState = { 16 | searchterm: string, 17 | useRegExp: boolean, 18 | useCaseSensitive: boolean, 19 | useFiles: boolean, 20 | useFolders: boolean, 21 | useSymlinks: boolean, 22 | useConflicts: boolean, 23 | useOthers: boolean, 24 | }; 25 | 26 | export type ViewsState = { 27 | unchangedChecked: boolean, 28 | deletedChecked: boolean, 29 | modifiedChecked: boolean, 30 | untrackedChecked: boolean, 31 | ignoredChecked: boolean, 32 | }; 33 | 34 | // Functions __________________________________________________________________ 35 | 36 | -------------------------------------------------------------------------------- /src/views/@types/views.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { Diff } from '../../types'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export type ViewsCache = { 16 | unchangedChecked: boolean, 17 | deletedChecked: boolean, 18 | modifiedChecked: boolean, 19 | untrackedChecked: boolean, 20 | ignoredChecked: boolean, 21 | items: Diff[], 22 | filteredItems: Diff[], 23 | }; 24 | 25 | // Functions __________________________________________________________________ 26 | 27 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-actions/l13-diff-actions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-actions/l13-diff-actions.service.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { ViewModelService } from '../../@l13/component/view-model-service.abstract'; 4 | 5 | import type { ViewModelConstructor } from '../../@types/components'; 6 | 7 | import { L13DiffActionsViewModel } from './l13-diff-actions.viewmodel'; 8 | 9 | // Variables __________________________________________________________________ 10 | 11 | 12 | 13 | // Initialize _________________________________________________________________ 14 | 15 | 16 | 17 | // Exports ____________________________________________________________________ 18 | 19 | export class L13DiffActionsViewModelService extends ViewModelService { 20 | 21 | public name = 'l13-diff-actions'; 22 | 23 | public vmc: ViewModelConstructor = L13DiffActionsViewModel; 24 | 25 | } 26 | 27 | // Functions __________________________________________________________________ 28 | 29 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-actions/l13-diff-actions.viewmodel.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { ViewModel } from '../../@l13/component/view-model.abstract'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export class L13DiffActionsViewModel extends ViewModel { 16 | 17 | public selectDisabled = true; 18 | 19 | public copyDisabled = true; 20 | 21 | public disable () { 22 | 23 | this.selectDisabled = true; 24 | this.copyDisabled = true; 25 | this.requestUpdate(); 26 | 27 | } 28 | 29 | public enable () { 30 | 31 | this.selectDisabled = false; 32 | this.copyDisabled = false; 33 | this.requestUpdate(); 34 | 35 | } 36 | 37 | public disableCopy () { 38 | 39 | this.copyDisabled = true; 40 | this.requestUpdate(); 41 | 42 | } 43 | 44 | public enableCopy () { 45 | 46 | this.copyDisabled = false; 47 | this.requestUpdate(); 48 | 49 | } 50 | 51 | } 52 | 53 | // Functions __________________________________________________________________ 54 | 55 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-compare/l13-diff-compare.component.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { L13Component, L13Element, L13Query } from '../../@l13/core'; 4 | 5 | import { disableContextMenu, setLabel } from '../../common'; 6 | 7 | import styles from '../styles'; 8 | import templates from '../templates'; 9 | 10 | import { L13DiffCompareViewModelService } from './l13-diff-compare.service'; 11 | import type { L13DiffCompareViewModel } from './l13-diff-compare.viewmodel'; 12 | 13 | // Variables __________________________________________________________________ 14 | 15 | 16 | 17 | // Initialize _________________________________________________________________ 18 | 19 | 20 | 21 | // Exports ____________________________________________________________________ 22 | 23 | @L13Component({ 24 | name: 'l13-diff-compare', 25 | service: L13DiffCompareViewModelService, 26 | styles: [styles['l13-diff-compare/l13-diff-compare.css']], 27 | template: templates['l13-diff-compare/l13-diff-compare.html'], 28 | }) 29 | export class L13DiffCompareComponent extends L13Element { 30 | 31 | @L13Query('button') 32 | private button: HTMLButtonElement; 33 | 34 | public constructor () { 35 | 36 | super(); 37 | 38 | setLabel(this.button, 'Compare'); 39 | 40 | this.button.addEventListener('click', ({ altKey }) => this.dispatchCustomEvent('compare', { altKey })); 41 | 42 | disableContextMenu(this); 43 | 44 | } 45 | 46 | } 47 | 48 | // Functions __________________________________________________________________ 49 | 50 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-compare/l13-diff-compare.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-compare/l13-diff-compare.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | display: block; 3 | padding: 3px 10px 0 0; 4 | text-align: right; 5 | user-select: none; 6 | } 7 | 8 | button { 9 | background: var(--vscode-button-background); 10 | border: none; 11 | box-sizing: border-box; 12 | color: var(--vscode-button-foreground); 13 | cursor: pointer; 14 | font-size: 0.8125rem; 15 | outline: var(--l13-button-outline, none); 16 | padding: 2px 14px 3px 14px; 17 | position: relative; 18 | z-index: 1; 19 | 20 | &:hover { 21 | background: var(--vscode-button-hoverBackground); 22 | } 23 | 24 | &:focus { 25 | outline: solid 1px var(--vscode-focusBorder, transparent); 26 | outline-offset: 1px; 27 | } 28 | 29 | &[disabled] { 30 | opacity: 0.3; 31 | cursor: default; 32 | 33 | &:hover { 34 | background: var(--vscode-button-background) !important; 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/views/components/l13-diff-compare/l13-diff-compare.service.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { ViewModelService } from '../../@l13/component/view-model-service.abstract'; 4 | 5 | import type { ViewModelConstructor } from '../../@types/components'; 6 | 7 | import { L13DiffCompareViewModel } from './l13-diff-compare.viewmodel'; 8 | 9 | // Variables __________________________________________________________________ 10 | 11 | 12 | 13 | // Initialize _________________________________________________________________ 14 | 15 | 16 | 17 | // Exports ____________________________________________________________________ 18 | 19 | export class L13DiffCompareViewModelService extends ViewModelService { 20 | 21 | public name = 'l13-diff-compare'; 22 | 23 | public vmc: ViewModelConstructor = L13DiffCompareViewModel; 24 | 25 | } 26 | 27 | // Functions __________________________________________________________________ 28 | 29 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-compare/l13-diff-compare.viewmodel.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { ViewModel } from '../../@l13/component/view-model.abstract'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export class L13DiffCompareViewModel extends ViewModel { 16 | 17 | public disabled = false; 18 | 19 | public disable () { 20 | 21 | this.disabled = true; 22 | this.requestUpdate(); 23 | 24 | } 25 | 26 | public enable () { 27 | 28 | this.disabled = false; 29 | this.requestUpdate(); 30 | 31 | } 32 | 33 | } 34 | 35 | // Functions __________________________________________________________________ 36 | 37 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-context/l13-diff-context.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-context/l13-diff-context.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | box-sizing: border-box; 3 | line-height: 1px; 4 | padding: 1px 0 0 0; 5 | vertical-align: sub; 6 | white-space: nowrap; 7 | 8 | button { 9 | background: transparent; 10 | border: none; 11 | border-radius: 5px; 12 | cursor: pointer; 13 | display: inline-block; 14 | height: 22px; 15 | margin: -3px 0 0 0; 16 | position: relative; 17 | width: 22px; 18 | z-index: 1; 19 | 20 | &:not([disabled]):hover { 21 | background-color: var(--l13-button-hover-background); 22 | } 23 | 24 | &:not([disabled]).-active { 25 | background-color: var(--l13-button-active-background); 26 | 27 | &::before { 28 | background-color: var(--l13-icon-activeBackground); 29 | } 30 | } 31 | 32 | &:disabled { 33 | cursor: default; 34 | opacity: .3; 35 | } 36 | 37 | &:focus { 38 | outline: solid 1px var(--vscode-focusBorder, transparent); 39 | } 40 | 41 | &::before { 42 | background-color: var(--l13-icon-background); 43 | content: ''; 44 | display: block; 45 | height: 100%; 46 | left: 0; 47 | -webkit-mask-position: 50% 50%; 48 | mask-position: 50% 50%; 49 | -webkit-mask-repeat: no-repeat; 50 | mask-repeat: no-repeat; 51 | position: absolute; 52 | top: 0; 53 | transition: background-color 0.1s; 54 | width: 100%; 55 | } 56 | 57 | &#copy { 58 | 59 | &::before { 60 | -webkit-mask-image: url('copy-file.svg'); 61 | mask-image: url('copy-file.svg'); 62 | } 63 | } 64 | 65 | &#goto { 66 | 67 | &::before { 68 | -webkit-mask-image: url('open-file.svg'); 69 | mask-image: url('open-file.svg'); 70 | } 71 | } 72 | 73 | &#delete { 74 | 75 | &::before { 76 | -webkit-mask-image: url('delete-file.svg'); 77 | mask-image: url('delete-file.svg'); 78 | } 79 | } 80 | 81 | &#reveal { 82 | 83 | &::before { 84 | -webkit-mask-image: url('reveal-file.svg'); 85 | mask-image: url('reveal-file.svg'); 86 | } 87 | } 88 | } 89 | } -------------------------------------------------------------------------------- /src/views/components/l13-diff-context/l13-diff-context.service.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { ViewModelService } from '../../@l13/component/view-model-service.abstract'; 4 | 5 | import type { ViewModelConstructor } from '../../@types/components'; 6 | 7 | import { L13DiffContextViewModel } from './l13-diff-context.viewmodel'; 8 | 9 | // Variables __________________________________________________________________ 10 | 11 | 12 | 13 | // Initialize _________________________________________________________________ 14 | 15 | 16 | 17 | // Exports ____________________________________________________________________ 18 | 19 | export class L13DiffContextViewModelService extends ViewModelService { 20 | 21 | public name = 'l13-diff-context'; 22 | 23 | public vmc: ViewModelConstructor = L13DiffContextViewModel; 24 | 25 | } 26 | 27 | // Functions __________________________________________________________________ 28 | 29 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-input/l13-diff-input.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-input/l13-diff-input.service.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { ViewModelService } from '../../@l13/component/view-model-service.abstract'; 4 | 5 | import type { ViewModelConstructor } from '../../@types/components'; 6 | 7 | import { L13DiffInputViewModel } from './l13-diff-input.viewmodel'; 8 | 9 | // Variables __________________________________________________________________ 10 | 11 | 12 | 13 | // Initialize _________________________________________________________________ 14 | 15 | 16 | 17 | // Exports ____________________________________________________________________ 18 | 19 | export class L13DiffInputViewModelService extends ViewModelService { 20 | 21 | public name = 'l13-diff-input'; 22 | 23 | public vmc: ViewModelConstructor = L13DiffInputViewModel; 24 | 25 | } 26 | 27 | // Functions __________________________________________________________________ 28 | 29 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-input/l13-diff-input.viewmodel.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { DiffDialogMessage } from '../../../types'; 4 | 5 | import { ViewModel } from '../../@l13/component/view-model.abstract'; 6 | 7 | import { msg } from '../../common'; 8 | 9 | // Variables __________________________________________________________________ 10 | 11 | const VALUE = Symbol.for('value'); 12 | 13 | // Initialize _________________________________________________________________ 14 | 15 | 16 | 17 | // Exports ____________________________________________________________________ 18 | 19 | export class L13DiffInputViewModel extends ViewModel { 20 | 21 | public disabled = false; 22 | 23 | public disable () { 24 | 25 | this.disabled = true; 26 | this.requestUpdate(); 27 | 28 | } 29 | 30 | public enable () { 31 | 32 | this.disabled = false; 33 | this.requestUpdate(); 34 | 35 | } 36 | 37 | private [VALUE] = ''; 38 | 39 | public get value () { 40 | 41 | return this[VALUE]; 42 | 43 | } 44 | 45 | public set value (val) { 46 | 47 | this[VALUE] = val; 48 | this.requestUpdate(); 49 | 50 | } 51 | 52 | private eventName: string = null; 53 | 54 | private dialogListener = (data: DiffDialogMessage) => { 55 | 56 | 57 | if (data.fsPath) this.value = data.fsPath; 58 | 59 | msg.removeMessageListener(this.eventName, this.dialogListener); 60 | 61 | this.eventName = null; 62 | 63 | }; 64 | 65 | public pick (file = false) { 66 | 67 | this.eventName = `dialog:${file ? 'file' : 'folder'}`; 68 | 69 | msg.on(this.eventName, this.dialogListener); 70 | msg.send(this.eventName); 71 | 72 | } 73 | 74 | } 75 | 76 | // Functions __________________________________________________________________ 77 | 78 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-intro/l13-diff-intro.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-intro/l13-diff-intro.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | background: var(--l13-intro-backgroundUrl) no-repeat; 3 | background-size: 260px 260px; 4 | background-position: 50% 0; 5 | padding: 270px 0 0 0; 6 | display: block; 7 | min-width: 260px; 8 | text-align: center; 9 | user-select: none; 10 | } 11 | 12 | l13-diff-shortcuts { 13 | display: inline-table; 14 | } 15 | 16 | dl { 17 | color: var(--l13-intro-color); 18 | cursor: default; 19 | display: table-row; 20 | opacity: 0.8; 21 | } 22 | 23 | dt { 24 | color: var(--l13-intro-color); 25 | display: table-cell; 26 | letter-spacing: .04em; 27 | padding: 0 5px 1em 0; 28 | text-align: right; 29 | } 30 | 31 | dd { 32 | display: table-cell; 33 | padding: 0 0 1em 5px; 34 | text-align: left; 35 | } 36 | 37 | div.-keybinding { 38 | align-items: center; 39 | display: flex; 40 | line-height: 10px; 41 | } 42 | 43 | span.-key { 44 | background-color: var(--l13-intro-keyBackgroundColor); 45 | border: 1px solid var(--l13-intro-keyBorderColor); 46 | border-bottom-color: var(--l13-intro-shadow); 47 | border-radius: 3px; 48 | box-shadow: inset 0 -1px 0 var(--l13-intro-shadow); 49 | color: var(--l13-intro-keyColor); 50 | display: inline-block; 51 | font-size: 11px; 52 | line-height: 10px; 53 | margin: 0 2px; 54 | padding: 3px 5px; 55 | vertical-align: middle; 56 | } -------------------------------------------------------------------------------- /src/views/components/l13-diff-intro/l13-diff-intro.service.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { ViewModelService } from '../../@l13/component/view-model-service.abstract'; 4 | 5 | import type { ViewModelConstructor } from '../../@types/components'; 6 | 7 | import { L13DiffIntroViewModel } from './l13-diff-intro.viewmodel'; 8 | 9 | // Variables __________________________________________________________________ 10 | 11 | 12 | 13 | // Initialize _________________________________________________________________ 14 | 15 | 16 | 17 | // Exports ____________________________________________________________________ 18 | 19 | export class L13DiffIntroViewModelService extends ViewModelService { 20 | 21 | public name = 'l13-diff-intro'; 22 | 23 | public vmc: ViewModelConstructor = L13DiffIntroViewModel; 24 | 25 | } 26 | 27 | // Functions __________________________________________________________________ 28 | 29 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-intro/l13-diff-intro.viewmodel.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { ViewModel } from '../../@l13/component/view-model.abstract'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export class L13DiffIntroViewModel extends ViewModel { 16 | 17 | public disabled = false; 18 | 19 | public disable () { 20 | 21 | this.disabled = true; 22 | this.requestUpdate(); 23 | 24 | } 25 | 26 | public enable () { 27 | 28 | this.disabled = false; 29 | this.requestUpdate(); 30 | 31 | } 32 | 33 | } 34 | 35 | // Functions __________________________________________________________________ 36 | 37 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-list/l13-diff-list.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-list/l13-diff-list.interface.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { ViewModel } from '../../@l13/component/view-model.abstract'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export interface L13DiffListPipe { 16 | 17 | vm: ViewModel; 18 | 19 | transform: (items: T[]) => T[]; 20 | 21 | } 22 | 23 | // Functions __________________________________________________________________ 24 | 25 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-list/l13-diff-list.service.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { ViewModelService } from '../../@l13/component/view-model-service.abstract'; 4 | 5 | import type { ViewModelConstructor } from '../../@types/components'; 6 | 7 | import { L13DiffListViewModel } from './l13-diff-list.viewmodel'; 8 | 9 | // Variables __________________________________________________________________ 10 | 11 | 12 | 13 | // Initialize _________________________________________________________________ 14 | 15 | 16 | 17 | // Exports ____________________________________________________________________ 18 | 19 | export class L13DiffListViewModelService extends ViewModelService { 20 | 21 | public name = 'l13-diff-list'; 22 | 23 | public vmc: ViewModelConstructor = L13DiffListViewModel; 24 | 25 | } 26 | 27 | // Functions __________________________________________________________________ 28 | 29 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-menu/l13-diff-menu.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-menu/l13-diff-menu.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | background: var(--vscode-editorWidget-background); 3 | box-shadow: 0px 5px 8px var(--vscode-widget-shadow, transparent); 4 | box-sizing: border-box; 5 | display: block; 6 | 7 | > l13-diff-menu-lists { 8 | 9 | > ul { 10 | border-top: solid 1px var(--vscode-pickerGroup-border); 11 | list-style-type: none; 12 | margin: 0 0 0 0; 13 | // outline: solid 1px var(--vscode-pickerGroup-border, transparent); 14 | // outline-offset: -1px; 15 | padding: 0 0 0 0; 16 | 17 | &:first-child { 18 | border: none; 19 | } 20 | 21 | > li { 22 | color: var(--vscode-foreground); 23 | cursor: pointer; 24 | display: flex; 25 | justify-content: space-between; 26 | margin: 0 0 0 0; 27 | padding: 4px 10px 5px 10px; 28 | user-select: none; 29 | 30 | &.-active, 31 | &.-selected { 32 | background: var(--vscode-list-focusBackground); 33 | color: var(--vscode-list-focusForeground); 34 | } 35 | 36 | &:hover { 37 | background: var(--vscode-list-hoverBackground); 38 | color: var(--vscode-list-hoverForeground); 39 | } 40 | 41 | div.-path { 42 | overflow: hidden; 43 | text-overflow: ellipsis; 44 | white-space: nowrap; 45 | } 46 | 47 | div.-info { 48 | color: var(--vscode-pickerGroup-foreground); 49 | padding-left: 10px; 50 | text-align: right; 51 | white-space: nowrap; 52 | } 53 | } 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /src/views/components/l13-diff-menu/l13-diff-menu.service.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { ViewModelService } from '../../@l13/component/view-model-service.abstract'; 4 | 5 | import type { ViewModelConstructor } from '../../@types/components'; 6 | 7 | import { L13DiffMenuViewModel } from './l13-diff-menu.viewmodel'; 8 | 9 | // Variables __________________________________________________________________ 10 | 11 | 12 | 13 | // Initialize _________________________________________________________________ 14 | 15 | 16 | 17 | // Exports ____________________________________________________________________ 18 | 19 | export class L13DiffMenuViewModelService extends ViewModelService { 20 | 21 | public name = 'l13-diff-menu'; 22 | 23 | public vmc: ViewModelConstructor = L13DiffMenuViewModel; 24 | 25 | } 26 | 27 | // Functions __________________________________________________________________ 28 | 29 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-menu/l13-diff-menu.viewmodel.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { DiffMenuMessage } from '../../../types'; 4 | 5 | import { ViewModel } from '../../@l13/component/view-model.abstract'; 6 | 7 | import { msg } from '../../common'; 8 | 9 | // Variables __________________________________________________________________ 10 | 11 | 12 | 13 | // Initialize _________________________________________________________________ 14 | 15 | 16 | 17 | // Exports ____________________________________________________________________ 18 | 19 | export class L13DiffMenuViewModel extends ViewModel { 20 | 21 | public history: string[] = []; 22 | 23 | public workspaces: string[] = []; 24 | 25 | public update () { 26 | 27 | return new Promise((resolve) => { 28 | 29 | msg.on('update:menu', (data: DiffMenuMessage) => { 30 | 31 | this.updateHistory(data.history); 32 | this.updateWorkspaces(data.workspaces); 33 | // eslint-disable-next-line @typescript-eslint/unbound-method 34 | msg.removeMessageListener('update:menu', this.update); 35 | resolve(undefined); 36 | 37 | }); 38 | 39 | msg.send('update:menu'); 40 | 41 | }); 42 | 43 | } 44 | 45 | private updateHistory (history: string[]) { 46 | 47 | if (history) { 48 | if (`${history}` !== `${this.history}`) { 49 | this.history = history; 50 | this.requestUpdate(); 51 | } 52 | } else this.history = []; 53 | 54 | } 55 | 56 | private updateWorkspaces (workspaces: string[]) { 57 | 58 | if (workspaces) { 59 | if (`${workspaces}` !== `${this.workspaces}`) { 60 | this.workspaces = workspaces; 61 | this.requestUpdate(); 62 | } 63 | } else this.workspaces = []; 64 | 65 | } 66 | 67 | } 68 | 69 | // Functions __________________________________________________________________ 70 | 71 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-navigator/l13-diff-navigator.html: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /src/views/components/l13-diff-navigator/l13-diff-navigator.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | display: block; 3 | position: relative; 4 | transform: translate3d(0, 0, 0); 5 | user-select: none; 6 | } 7 | 8 | #slider { 9 | background-color: var(--vscode-scrollbarSlider-background); 10 | box-sizing: border-box; 11 | height: 10; 12 | position: absolute; 13 | right: 0; 14 | top: 0; 15 | transform: translate3d(0, 0, 0); 16 | width: 30px; 17 | z-index: 1; 18 | 19 | &:hover { 20 | background-color: var(--vscode-scrollbarSlider-hoverBackground); 21 | } 22 | 23 | &:active { 24 | background-color: var(--vscode-scrollbarSlider-activeBackground); 25 | } 26 | } 27 | 28 | #ruler { 29 | display: block; 30 | position: absolute; 31 | right: 30px; 32 | top: 0; 33 | z-index: 0; 34 | } 35 | 36 | #map { 37 | display: block; 38 | opacity: 0.7; 39 | position: absolute; 40 | right: 0; 41 | top: 0; 42 | z-index: 0; 43 | } -------------------------------------------------------------------------------- /src/views/components/l13-diff-navigator/l13-diff-navigator.service.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { ViewModelService } from '../../@l13/component/view-model-service.abstract'; 4 | 5 | import type { ViewModelConstructor } from '../../@types/components'; 6 | 7 | import { L13DiffNavigatorViewModel } from './l13-diff-navigator.viewmodel'; 8 | 9 | // Variables __________________________________________________________________ 10 | 11 | 12 | 13 | // Initialize _________________________________________________________________ 14 | 15 | 16 | 17 | // Exports ____________________________________________________________________ 18 | 19 | export class L13DiffNavigatorViewModelService extends ViewModelService { 20 | 21 | public name = 'l13-diff-navigator'; 22 | 23 | public vmc: ViewModelConstructor = L13DiffNavigatorViewModel; 24 | 25 | } 26 | 27 | // Functions __________________________________________________________________ 28 | 29 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-navigator/l13-diff-navigator.viewmodel.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { ViewModel } from '../../@l13/component/view-model.abstract'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export class L13DiffNavigatorViewModel extends ViewModel { 16 | 17 | 18 | 19 | } 20 | 21 | // Functions __________________________________________________________________ 22 | 23 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-panel/l13-diff-panel.component.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { L13Component, L13Element } from '../../@l13/core'; 4 | 5 | import styles from '../styles'; 6 | import templates from '../templates'; 7 | 8 | import { L13DiffPanelViewModelService } from './l13-diff-panel.service'; 9 | import type { L13DiffPanelViewModel } from './l13-diff-panel.viewmodel'; 10 | 11 | // Variables __________________________________________________________________ 12 | 13 | 14 | 15 | // Initialize _________________________________________________________________ 16 | 17 | 18 | 19 | // Exports ____________________________________________________________________ 20 | 21 | @L13Component({ 22 | name: 'l13-diff-panel', 23 | service: L13DiffPanelViewModelService, 24 | styles: [styles['l13-diff-panel/l13-diff-panel.css']], 25 | template: templates['l13-diff-panel/l13-diff-panel.html'], 26 | }) 27 | export class L13DiffPanelComponent extends L13Element { 28 | 29 | 30 | 31 | } 32 | 33 | // Functions __________________________________________________________________ 34 | 35 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-panel/l13-diff-panel.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-panel/l13-diff-panel.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | background: var(--vscode-sideBar-background); 3 | color: var(--vscode-foreground); 4 | display: block; 5 | position: relative; 6 | width: 100%; 7 | } 8 | 9 | l13-diff-loading { 10 | bottom: 0; 11 | display: block; 12 | height: 2px; 13 | left: 0; 14 | overflow: hidden; 15 | position: absolute; 16 | right: 0; 17 | width: 100%; 18 | z-index: 4; 19 | 20 | &::after { 21 | animation: loading 4s linear infinite; 22 | background: linear-gradient(90deg, transparent 0%, var(--vscode-progressBar-background) 20%, var(--vscode-progressBar-background) 80%, transparent 100%) no-repeat; 23 | bottom: 0; 24 | content: ''; 25 | height: 2px; 26 | position: absolute; 27 | left: 0; 28 | width: 5%; 29 | } 30 | } 31 | 32 | @keyframes loading { 33 | 0% { 34 | left: 0; 35 | width: 3%; 36 | } 37 | 50% { 38 | width: 8%; 39 | } 40 | 100% { 41 | left: 100%; 42 | width: 3%; 43 | } 44 | } -------------------------------------------------------------------------------- /src/views/components/l13-diff-panel/l13-diff-panel.service.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { ViewModelService } from '../../@l13/component/view-model-service.abstract'; 4 | 5 | import type { ViewModelConstructor } from '../../@types/components'; 6 | 7 | import { L13DiffPanelViewModel } from './l13-diff-panel.viewmodel'; 8 | 9 | // Variables __________________________________________________________________ 10 | 11 | 12 | 13 | // Initialize _________________________________________________________________ 14 | 15 | 16 | 17 | // Exports ____________________________________________________________________ 18 | 19 | export class L13DiffPanelViewModelService extends ViewModelService { 20 | 21 | public name = 'l13-diff-panel'; 22 | 23 | public vmc: ViewModelConstructor = L13DiffPanelViewModel; 24 | 25 | } 26 | 27 | // Functions __________________________________________________________________ 28 | 29 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-panel/l13-diff-panel.viewmodel.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { ViewModel } from '../../@l13/component/view-model.abstract'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | const LOADING = Symbol.for('loading'); 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export class L13DiffPanelViewModel extends ViewModel { 16 | 17 | private [LOADING] = false; 18 | 19 | public get loading () { 20 | 21 | return this[LOADING]; 22 | 23 | } 24 | 25 | public set loading (value: boolean) { 26 | 27 | this[LOADING] = value; 28 | this.requestUpdate(); 29 | 30 | } 31 | 32 | } 33 | 34 | // Functions __________________________________________________________________ 35 | 36 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-search/l13-diff-search.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 | 6 |
{{ error }}
7 |
8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-search/l13-diff-search.service.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { ViewModelService } from '../../@l13/component/view-model-service.abstract'; 4 | 5 | import type { ViewModelConstructor } from '../../@types/components'; 6 | 7 | import { L13DiffSearchViewModel } from './l13-diff-search.viewmodel'; 8 | 9 | // Variables __________________________________________________________________ 10 | 11 | 12 | 13 | // Initialize _________________________________________________________________ 14 | 15 | 16 | 17 | // Exports ____________________________________________________________________ 18 | 19 | export class L13DiffSearchViewModelService extends ViewModelService { 20 | 21 | public name = 'l13-diff-search'; 22 | 23 | public vmc: ViewModelConstructor = L13DiffSearchViewModel; 24 | 25 | } 26 | 27 | // Functions __________________________________________________________________ 28 | 29 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-swap/l13-diff-swap.component.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { L13Component, L13Element, L13Query } from '../../@l13/core'; 4 | 5 | import { addButtonActiveStyleEvents, disableContextMenu, parseIcons, setLabel } from '../../common'; 6 | 7 | import styles from '../styles'; 8 | import templates from '../templates'; 9 | 10 | import { L13DiffSwapViewModelService } from './l13-diff-swap.service'; 11 | import type { L13DiffSwapViewModel } from './l13-diff-swap.viewmodel'; 12 | 13 | // Variables __________________________________________________________________ 14 | 15 | 16 | 17 | // Initialize _________________________________________________________________ 18 | 19 | 20 | 21 | // Exports ____________________________________________________________________ 22 | 23 | @L13Component({ 24 | name: 'l13-diff-swap', 25 | service: L13DiffSwapViewModelService, 26 | styles: [parseIcons(styles['l13-diff-swap/l13-diff-swap.css'])], 27 | template: templates['l13-diff-swap/l13-diff-swap.html'], 28 | }) 29 | export class L13DiffSwapComponent extends L13Element { 30 | 31 | @L13Query('button') 32 | public button: HTMLButtonElement; 33 | 34 | public constructor () { 35 | 36 | super(); 37 | 38 | setLabel(this.button, 'Swap Paths'); 39 | 40 | this.button.addEventListener('click', (event) => this.dispatchCustomEvent('swap', event)); 41 | 42 | addButtonActiveStyleEvents(this.button); 43 | disableContextMenu(this); 44 | 45 | } 46 | 47 | } 48 | 49 | // Functions __________________________________________________________________ 50 | 51 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-swap/l13-diff-swap.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-swap/l13-diff-swap.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | display: block; 3 | user-select: none; 4 | 5 | > button { 6 | background: transparent; 7 | border: 0; 8 | border-radius: 5px; 9 | cursor: pointer; 10 | height: 22px; 11 | margin: 2px 0 0 0; 12 | padding: 0 0 0 0; 13 | position: relative; 14 | width: 22px; 15 | 16 | &::before { 17 | background: var(--l13-icon-background); 18 | content: ''; 19 | height: 100%; 20 | left: 0; 21 | -webkit-mask-image: url('swap.svg'); 22 | mask-image: url('swap.svg'); 23 | -webkit-mask-position: 50% 50%; 24 | mask-position: 50% 50%; 25 | -webkit-mask-repeat: no-repeat; 26 | mask-repeat: no-repeat; 27 | position: absolute; 28 | top: 0; 29 | width: 100%; 30 | } 31 | 32 | &:focus { 33 | outline: solid 1px var(--vscode-focusBorder, transparent); 34 | } 35 | 36 | &:not([disabled]):hover { 37 | background-color: var(--l13-button-hover-background); 38 | outline: var(--l13-list-hover-outline, none); 39 | } 40 | 41 | &:not([disabled]).-active { 42 | background-color: var(--l13-button-active-background); 43 | } 44 | 45 | &[disabled] { 46 | cursor: default; 47 | opacity: 0.3; 48 | 49 | &:hover { 50 | 51 | &::before { 52 | background: var(--l13-icon-background) !important; 53 | } 54 | } 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /src/views/components/l13-diff-swap/l13-diff-swap.service.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { ViewModelService } from '../../@l13/component/view-model-service.abstract'; 4 | 5 | import type { ViewModelConstructor } from '../../@types/components'; 6 | 7 | import { L13DiffSwapViewModel } from './l13-diff-swap.viewmodel'; 8 | 9 | // Variables __________________________________________________________________ 10 | 11 | 12 | 13 | // Initialize _________________________________________________________________ 14 | 15 | 16 | 17 | // Exports ____________________________________________________________________ 18 | 19 | export class L13DiffSwapViewModelService extends ViewModelService { 20 | 21 | public name = 'l13-diff-swap'; 22 | 23 | public vmc: ViewModelConstructor = L13DiffSwapViewModel; 24 | 25 | } 26 | 27 | // Functions __________________________________________________________________ 28 | 29 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-swap/l13-diff-swap.viewmodel.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { ViewModel } from '../../@l13/component/view-model.abstract'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export class L13DiffSwapViewModel extends ViewModel { 16 | 17 | public disabled = false; 18 | 19 | public disable () { 20 | 21 | this.disabled = true; 22 | this.requestUpdate(); 23 | 24 | } 25 | 26 | public enable () { 27 | 28 | this.disabled = false; 29 | this.requestUpdate(); 30 | 31 | } 32 | 33 | } 34 | 35 | // Functions __________________________________________________________________ 36 | 37 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-views/l13-diff-views.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-views/l13-diff-views.service.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { ViewModelService } from '../../@l13/component/view-model-service.abstract'; 4 | import { ViewModelConstructor } from '../../@types/components'; 5 | 6 | import { L13DiffViewsViewModel } from './l13-diff-views.viewmodel'; 7 | 8 | // Variables __________________________________________________________________ 9 | 10 | 11 | 12 | // Initialize _________________________________________________________________ 13 | 14 | 15 | 16 | // Exports ____________________________________________________________________ 17 | 18 | export class L13DiffViewsViewModelService extends ViewModelService { 19 | 20 | public name = 'l13-diff-views'; 21 | 22 | public vmc: ViewModelConstructor = L13DiffViewsViewModel; 23 | 24 | } 25 | 26 | // Functions __________________________________________________________________ 27 | 28 | -------------------------------------------------------------------------------- /src/views/components/l13-diff-views/l13-diff-views.viewmodel.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { ViewsState } from '../../../types'; 4 | 5 | import { ViewModel } from '../../@l13/component/view-model.abstract'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export class L13DiffViewsViewModel extends ViewModel { 18 | 19 | public disabled = false; 20 | 21 | public disable () { 22 | 23 | this.disabled = true; 24 | this.requestUpdate(); 25 | 26 | } 27 | 28 | public enable () { 29 | 30 | this.disabled = false; 31 | this.requestUpdate(); 32 | 33 | } 34 | 35 | public unchangedChecked = false; 36 | 37 | public deletedChecked = true; 38 | 39 | public modifiedChecked = true; 40 | 41 | public untrackedChecked = true; 42 | 43 | public ignoredChecked = false; 44 | 45 | public getState (): ViewsState { 46 | 47 | return { 48 | unchangedChecked: this.unchangedChecked, 49 | deletedChecked: this.deletedChecked, 50 | modifiedChecked: this.modifiedChecked, 51 | untrackedChecked: this.untrackedChecked, 52 | ignoredChecked: this.ignoredChecked, 53 | }; 54 | 55 | } 56 | 57 | public setState (state: ViewsState) { 58 | 59 | this.unchangedChecked = state.unchangedChecked; 60 | this.deletedChecked = state.deletedChecked; 61 | this.modifiedChecked = state.modifiedChecked; 62 | this.untrackedChecked = state.untrackedChecked; 63 | this.ignoredChecked = state.ignoredChecked; 64 | 65 | this.requestUpdate(); 66 | 67 | } 68 | 69 | } 70 | 71 | // Functions __________________________________________________________________ 72 | 73 | -------------------------------------------------------------------------------- /src/views/components/l13-diff/commands.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import * as actions from './commands/actions'; 4 | import * as compare from './commands/compare'; 5 | import * as favorites from './commands/favorites'; 6 | import * as input from './commands/input'; 7 | import * as list from './commands/list'; 8 | import * as menu from './commands/menu'; 9 | import * as search from './commands/search'; 10 | import * as swap from './commands/swap'; 11 | import * as views from './commands/views'; 12 | 13 | // Variables __________________________________________________________________ 14 | 15 | 16 | 17 | // Initialize _________________________________________________________________ 18 | 19 | 20 | 21 | // Exports ____________________________________________________________________ 22 | 23 | export { 24 | actions, 25 | compare, 26 | favorites, 27 | input, 28 | list, 29 | menu, 30 | search, 31 | swap, 32 | views, 33 | }; 34 | 35 | // Functions __________________________________________________________________ 36 | 37 | -------------------------------------------------------------------------------- /src/views/components/l13-diff/commands/actions.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { ActionsCommandsInit } from '../../../../types'; 4 | 5 | import { msg } from '../../../common'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export function init ({ list }: ActionsCommandsInit) { 18 | 19 | msg.on('l13Diff.action.actions.copyToLeftFolder', () => list.copy('right')); 20 | msg.on('l13Diff.action.actions.copyToRightFolder', () => list.copy('left')); 21 | 22 | msg.on('l13Diff.action.actions.selectAllEntries', () => { 23 | 24 | list.selectAll(); 25 | list.focus(); 26 | 27 | }); 28 | 29 | msg.on('l13Diff.action.actions.selectCreatedEntries', () => list.selectByStatus('untracked')); 30 | msg.on('l13Diff.action.actions.selectDeletedEntries', () => list.selectByStatus('deleted')); 31 | msg.on('l13Diff.action.actions.selectModifiedEntries', () => list.selectByStatus('modified')); 32 | 33 | } 34 | 35 | // Functions __________________________________________________________________ 36 | 37 | -------------------------------------------------------------------------------- /src/views/components/l13-diff/commands/compare.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { CompareCommandsInit } from '../../../../types'; 4 | 5 | import { msg } from '../../../common'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export function init ({ diff, left, right, search }: CompareCommandsInit) { 18 | 19 | msg.on('l13Diff.action.panel.compare', () => { 20 | 21 | if (!left.focused && !right.focused && !search.focused) diff.initCompare(); 22 | 23 | }); 24 | 25 | msg.on('l13Diff.action.panel.compareAll', () => { 26 | 27 | if (!left.focused && !right.focused && !search.focused) msg.send('compare:multi'); 28 | 29 | }); 30 | 31 | } 32 | 33 | // Functions __________________________________________________________________ 34 | 35 | -------------------------------------------------------------------------------- /src/views/components/l13-diff/commands/favorites.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { DiffFavoriteMessage, FavoritesCommandsInit } from '../../../../types'; 4 | 5 | import { msg } from '../../../common'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export function init ({ leftVM, rightVM }: FavoritesCommandsInit) { 18 | 19 | msg.on('l13Diff.action.panel.addToFavorites', () => { 20 | 21 | msg.send('save:favorite', { 22 | pathA: leftVM.value, 23 | pathB: rightVM.value, 24 | }); 25 | 26 | }); 27 | 28 | } 29 | 30 | // Functions __________________________________________________________________ 31 | 32 | -------------------------------------------------------------------------------- /src/views/components/l13-diff/commands/input.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { InputCommandsInit } from '../../../../types'; 4 | 5 | import { msg } from '../../../common'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export function init ({ leftVM, rightVM }: InputCommandsInit) { 18 | 19 | msg.on('l13Diff.action.input.pickLeftFolder', () => leftVM.pick()); 20 | 21 | msg.on('l13Diff.action.input.pickLeftFile', () => leftVM.pick(true)); 22 | 23 | msg.on('l13Diff.action.input.pickRightFolder', () => rightVM.pick()); 24 | 25 | msg.on('l13Diff.action.input.pickRightFile', () => rightVM.pick(true)); 26 | 27 | } 28 | 29 | // Functions __________________________________________________________________ 30 | 31 | -------------------------------------------------------------------------------- /src/views/components/l13-diff/commands/list.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { ListCommandsInit } from '../../../../types'; 4 | 5 | import { msg } from '../../../common'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export function init ({ diff, list, search }: ListCommandsInit) { 18 | 19 | msg.on('l13Diff.action.list.delete', () => { 20 | 21 | if (list.disabled) return; 22 | 23 | diff.disable(); 24 | list.delete(); 25 | 26 | }); 27 | 28 | msg.on('l13Diff.action.list.unselect', () => { 29 | 30 | if (!search.focused) list.unselect(); 31 | 32 | }); 33 | 34 | } 35 | 36 | // Functions __________________________________________________________________ 37 | 38 | -------------------------------------------------------------------------------- /src/views/components/l13-diff/commands/menu.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { MenuCommandsInit } from '../../../../types'; 4 | 5 | import { msg } from '../../../common'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export function init ({ menu }: MenuCommandsInit) { 18 | 19 | msg.on('l13Diff.action.menu.close', () => { 20 | 21 | if (menu && menu.parentNode) menu.remove(); 22 | 23 | }); 24 | 25 | } 26 | 27 | // Functions __________________________________________________________________ 28 | 29 | -------------------------------------------------------------------------------- /src/views/components/l13-diff/commands/swap.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { SwapCommandsInit } from '../../../../types'; 4 | 5 | import { msg } from '../../../common'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export function init ({ diff }: SwapCommandsInit) { 18 | 19 | msg.on('l13Diff.action.inputs.swap', () => diff.swapInputs()); 20 | 21 | msg.on('l13Diff.action.inputs.swapAll', () => diff.swapInputs(true)); 22 | 23 | } 24 | 25 | // Functions __________________________________________________________________ 26 | 27 | -------------------------------------------------------------------------------- /src/views/components/l13-diff/commands/views.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { ViewsCommandsInit } from '../../../../types'; 4 | 5 | import { msg } from '../../../common'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export function init ({ viewsVM }: ViewsCommandsInit) { 18 | 19 | msg.on('l13Diff.action.views.toggleShowAllCreated', () => { 20 | 21 | viewsVM.untrackedChecked = !viewsVM.untrackedChecked; 22 | viewsVM.requestUpdate(); 23 | 24 | }); 25 | 26 | msg.on('l13Diff.action.views.toggleShowAllDeleted', () => { 27 | 28 | viewsVM.deletedChecked = !viewsVM.deletedChecked; 29 | viewsVM.requestUpdate(); 30 | 31 | }); 32 | 33 | msg.on('l13Diff.action.views.toggleShowAllIgnored', () => { 34 | 35 | viewsVM.ignoredChecked = !viewsVM.ignoredChecked; 36 | viewsVM.requestUpdate(); 37 | 38 | }); 39 | 40 | msg.on('l13Diff.action.views.toggleShowAllModified', () => { 41 | 42 | viewsVM.modifiedChecked = !viewsVM.modifiedChecked; 43 | viewsVM.requestUpdate(); 44 | 45 | }); 46 | 47 | msg.on('l13Diff.action.views.toggleShowAllUnchanged', () => { 48 | 49 | viewsVM.unchangedChecked = !viewsVM.unchangedChecked; 50 | viewsVM.requestUpdate(); 51 | 52 | }); 53 | 54 | } 55 | 56 | // Functions __________________________________________________________________ 57 | 58 | -------------------------------------------------------------------------------- /src/views/components/l13-diff/events.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import * as actions from './events/actions'; 4 | import * as compare from './events/compare'; 5 | import * as diff from './events/diff'; 6 | import * as input from './events/input'; 7 | import * as list from './events/list'; 8 | import * as navigator from './events/navigator'; 9 | import * as search from './events/search'; 10 | import * as swap from './events/swap'; 11 | import * as window from './events/window'; 12 | 13 | // Variables __________________________________________________________________ 14 | 15 | 16 | 17 | // Initialize _________________________________________________________________ 18 | 19 | 20 | 21 | // Exports ____________________________________________________________________ 22 | 23 | export { 24 | actions, 25 | compare, 26 | diff, 27 | input, 28 | list, 29 | navigator, 30 | search, 31 | swap, 32 | window, 33 | }; 34 | 35 | // Functions __________________________________________________________________ 36 | 37 | -------------------------------------------------------------------------------- /src/views/components/l13-diff/events/actions.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { ActionsEventsInit } from '../../../../types'; 4 | 5 | import { isMetaKey } from '../../../common'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export function init ({ diff, actions, list }: ActionsEventsInit) { 18 | 19 | actions.addEventListener('select', (event) => { 20 | 21 | const { metaKey, ctrlKey, status } = (event).detail; 22 | 23 | if (status) list.selectByStatus(status, isMetaKey(ctrlKey, metaKey)); 24 | else list.selectAll(); 25 | 26 | }); 27 | 28 | actions.addEventListener('copy', (event) => { 29 | 30 | const detail = (event).detail; 31 | 32 | diff.disable(); 33 | 34 | if (detail.altKey) list.multiCopy(detail.from); 35 | else list.copy(detail.from); 36 | 37 | }); 38 | 39 | } 40 | 41 | // Functions __________________________________________________________________ 42 | 43 | -------------------------------------------------------------------------------- /src/views/components/l13-diff/events/compare.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { CompareEventsInit } from '../../../../types'; 4 | 5 | import { msg } from '../../../common'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export function init ({ diff, compare }: CompareEventsInit) { 18 | 19 | compare.addEventListener('compare', (event) => { 20 | 21 | if (((event).detail).altKey) msg.send('compare:multi'); 22 | else diff.initCompare(); 23 | 24 | }); 25 | 26 | msg.on('compare:multi', () => diff.initCompare()); 27 | 28 | } 29 | 30 | // Functions __________________________________________________________________ 31 | 32 | -------------------------------------------------------------------------------- /src/views/components/l13-diff/events/diff.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { DiffEventsInit, DiffInitViewMessage, DiffUpdatePathsMessage } from '../../../../types'; 4 | 5 | import { msg } from '../../../common'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export function init ({ diff, leftVM, rightVM, panelVM, listVM }: DiffEventsInit) { 18 | 19 | msg.on('cancel', () => diff.enable()); 20 | 21 | msg.on('update:paths', (data: DiffUpdatePathsMessage) => { 22 | 23 | if (panelVM.loading || listVM.hasUpdateRequest()) return; 24 | 25 | if (data.uris.length) { 26 | leftVM.value = data.uris[0]?.fsPath || ''; 27 | rightVM.value = data.uris[1]?.fsPath || ''; 28 | if (data.compare) diff.initCompare(); 29 | } 30 | 31 | }); 32 | 33 | msg.on('init:view', (data: DiffInitViewMessage) => { 34 | 35 | msg.removeMessageListener('init:view'); 36 | 37 | diff.initPanelStates(data.panel); 38 | 39 | if (data.uris.length) { 40 | leftVM.value = data.uris[0]?.fsPath || ''; 41 | rightVM.value = data.uris[1]?.fsPath || ''; 42 | } else { 43 | leftVM.value = data.workspaces[0] || ''; 44 | rightVM.value = data.workspaces[1] || ''; 45 | } 46 | 47 | if (data.compare) diff.initCompare(); 48 | 49 | }); 50 | 51 | msg.send('init:view'); 52 | 53 | } 54 | 55 | // Functions __________________________________________________________________ 56 | 57 | -------------------------------------------------------------------------------- /src/views/components/l13-diff/events/input.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { InputEventsInit } from '../../../../types'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export function init ({ diff, left, right, menu }: InputEventsInit) { 16 | 17 | left.menu = menu; 18 | right.menu = menu; 19 | 20 | left.addEventListener('compare', () => diff.initCompare()); 21 | right.addEventListener('compare', () => diff.initCompare()); 22 | 23 | } 24 | 25 | // Functions __________________________________________________________________ 26 | 27 | -------------------------------------------------------------------------------- /src/views/components/l13-diff/events/list.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { ListEventsInit } from '../../../../types'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export function init ({ diff, list, listVM, navigator, actionsVM, result, intro }: ListEventsInit) { 16 | 17 | listVM.on('cancel', () => diff.enable()); 18 | listVM.on('compared', () => diff.enable()); 19 | listVM.on('copied', () => diff.enable()); 20 | listVM.on('deleted', () => diff.enable()); 21 | 22 | listVM.on('multicopy', () => diff.disable()); 23 | 24 | listVM.on('filtered', () => { 25 | 26 | result.style.display = listVM.items.length && !listVM.filteredItems.length ? 'block' : 'none'; 27 | intro.style.display = listVM.items.length ? 'none' : 'block'; 28 | 29 | }); 30 | 31 | list.addEventListener('copy', () => diff.disable()); 32 | list.addEventListener('delete', () => diff.disable()); 33 | 34 | list.addEventListener('selected', () => { 35 | 36 | actionsVM.enableCopy(); 37 | diff.updateNavigator(false, true); 38 | 39 | }); 40 | 41 | list.addEventListener('unselected', () => { 42 | 43 | actionsVM.disableCopy(); 44 | navigator.clearSelection(); 45 | 46 | }); 47 | 48 | list.addEventListener('scroll', (event) => { 49 | 50 | event.stopImmediatePropagation(); 51 | 52 | diff.updateScrollbarPosition(); 53 | list.showVisibleListViewItems(); 54 | 55 | }); 56 | 57 | list.addEventListener('filtered', () => diff.updateNavigator(true, false)); 58 | 59 | } 60 | 61 | // Functions __________________________________________________________________ 62 | 63 | -------------------------------------------------------------------------------- /src/views/components/l13-diff/events/navigator.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { NavigatorEventsInit } from '../../../../types'; 4 | 5 | import { isMacOs } from '../../../@l13/core'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | const { floor } = Math; 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | export function init ({ navigator, list }: NavigatorEventsInit) { 18 | 19 | navigator.addEventListener('mousemovescroll', (event: any) => { 20 | 21 | const scrollbarY = event.detail.y; 22 | const scrollbarHeight = event.detail.height; 23 | const canvasHeight = navigator.canvasMap.offsetHeight; 24 | const listScrollHeight = list.scrollHeight; 25 | 26 | if (scrollbarY + scrollbarHeight === canvasHeight) { 27 | list.scrollTop = listScrollHeight; 28 | } else { 29 | list.scrollTop = floor(scrollbarY / canvasHeight * listScrollHeight); 30 | } 31 | 32 | }); 33 | 34 | navigator.addEventListener('mousedownscroll', () => list.classList.add('-active')); 35 | navigator.addEventListener('mouseupscroll', () => list.classList.remove('-active')); 36 | 37 | if (isMacOs) { 38 | navigator.addEventListener('wheel', (event: WheelEvent) => { 39 | 40 | if (list.scrollHeight > list.clientHeight) list.scrollTop += event.deltaY; 41 | 42 | }); 43 | } 44 | 45 | } 46 | 47 | // Functions __________________________________________________________________ 48 | 49 | -------------------------------------------------------------------------------- /src/views/components/l13-diff/events/search.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { SearchEventsInit } from '../../../../types'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export function init ({ diff, list, navigator, search }: SearchEventsInit) { 16 | 17 | search.addEventListener('close', () => { 18 | 19 | search.classList.add('-moveout'); 20 | 21 | }); 22 | 23 | search.addEventListener('animationend', async () => { 24 | 25 | if (search.classList.contains('-moveout')) { 26 | list.classList.remove('-widgets'); 27 | navigator.classList.remove('-widgets'); 28 | search.classList.remove('-moveout'); 29 | search.viewmodel.disable(); 30 | search.remove(); 31 | list.focus(); 32 | } else { 33 | list.classList.add('-widgets'); 34 | navigator.classList.add('-widgets'); 35 | search.classList.remove('-movein'); 36 | await search.viewmodel.enable(); 37 | search.focus(); 38 | } 39 | 40 | diff.updateNavigator(); 41 | 42 | }); 43 | 44 | } 45 | 46 | // Functions __________________________________________________________________ 47 | 48 | -------------------------------------------------------------------------------- /src/views/components/l13-diff/events/swap.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { SwapEventsInit } from '../../../../types'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export function init ({ diff, swap }: SwapEventsInit) { 16 | 17 | swap.addEventListener('swap', ({ detail }: any) => diff.swapInputs(detail.altKey)); 18 | 19 | } 20 | 21 | // Functions __________________________________________________________________ 22 | 23 | -------------------------------------------------------------------------------- /src/views/components/l13-diff/events/window.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { WindowEventsInit } from '../../../../types'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export function init ({ diff, list, left, right, search }: WindowEventsInit) { 16 | 17 | document.addEventListener('mouseup', ({ target }) => { 18 | 19 | if (list.disabled) return; 20 | 21 | if (target === document.body || target === document.documentElement) list.unselect(); 22 | 23 | }); 24 | 25 | window.addEventListener('theme', () => diff.updateNavigator()); 26 | 27 | window.addEventListener('resize', () => { 28 | 29 | list.showVisibleListViewItems(true); 30 | diff.updateNavigator(); 31 | 32 | }); 33 | 34 | window.addEventListener('focus', () => { 35 | 36 | if (list.content.firstElementChild && !left.focused && !right.focused && !search.focused) { 37 | setTimeout(() => { 38 | 39 | if (!left.focused && !right.focused && !search.focused) list.focus(); 40 | 41 | }, 0); 42 | } 43 | 44 | }); 45 | 46 | } 47 | 48 | // Functions __________________________________________________________________ 49 | 50 | -------------------------------------------------------------------------------- /src/views/components/l13-diff/l13-diff.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | No items are matching the current filter settings. -------------------------------------------------------------------------------- /src/views/components/l13-diff/l13-diff.service.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { ViewModelService } from '../../@l13/component/view-model-service.abstract'; 4 | import type { ViewModelConstructor } from '../../@types/components'; 5 | 6 | import { L13DiffViewModel } from './l13-diff.viewmodel'; 7 | 8 | // Variables __________________________________________________________________ 9 | 10 | 11 | 12 | // Initialize _________________________________________________________________ 13 | 14 | 15 | 16 | // Exports ____________________________________________________________________ 17 | 18 | export class L13DiffViewModelService extends ViewModelService { 19 | 20 | public name = 'l13-diff'; 21 | 22 | public vmc: ViewModelConstructor = L13DiffViewModel; 23 | 24 | } 25 | 26 | // Functions __________________________________________________________________ 27 | 28 | -------------------------------------------------------------------------------- /src/views/components/l13-diff/l13-diff.viewmodel.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import { ViewModel } from '../../@l13/component/view-model.abstract'; 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | export class L13DiffViewModel extends ViewModel { 16 | 17 | 18 | 19 | } 20 | 21 | // Functions __________________________________________________________________ 22 | 23 | -------------------------------------------------------------------------------- /src/views/icons/components/checked.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/copy-file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/copy-left.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/copy-right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/delete-file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/folder.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/list-error.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/list-file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/list-folder.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/list-symlink.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/list-unknown.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/open-file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/regexp.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/reveal-file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/search-conflict.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/search-other.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/select-all.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/select-deleted.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/select-modified.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/select-untracked.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/show-deleted.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/show-ignored.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/show-modified.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/show-unchanged.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/show-untracked.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/components/swap.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/panel/icon-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/icons/panel/icon-light.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/settings.ts: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | import type { DiffPanelSettings } from '../types'; 4 | 5 | import { msg } from './common'; 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | const l13Settings: DiffPanelSettings = (window).l13Settings; 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | msg.on('change:settings', (settings: DiffPanelSettings) => { 14 | 15 | if (typeof settings.enablePreview === 'boolean') enablePreview = settings.enablePreview; 16 | 17 | }); 18 | 19 | // Exports ____________________________________________________________________ 20 | 21 | export let enablePreview = l13Settings.enablePreview; 22 | 23 | // Functions __________________________________________________________________ 24 | 25 | -------------------------------------------------------------------------------- /src/views/vscode.d.ts: -------------------------------------------------------------------------------- 1 | declare function acquireVsCodeApi (): { 2 | postMessage (msg: any): any; 3 | setState (newState: any): any; 4 | getState (): any; 5 | }; -------------------------------------------------------------------------------- /tasks/icons.js: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | const fs = require('node:fs'); 4 | 5 | const glob = require('glob'); 6 | 7 | const file2json = require('../plugins/gulp-file2json'); 8 | 9 | // Variables __________________________________________________________________ 10 | 11 | const findPattern = /width="100%" height="100%" viewBox="0 0 (\d+) (\d+)"/; 12 | 13 | const iconPaths = [ 14 | 'src/**/*.svg', 15 | 'images/**/*.svg', 16 | ]; 17 | 18 | // Initialize _________________________________________________________________ 19 | 20 | 21 | 22 | // Exports ____________________________________________________________________ 23 | 24 | module.exports = [ 25 | { 26 | name: 'fix', 27 | watch: iconPaths, 28 | task: (done) => { 29 | 30 | iconPaths.forEach((globPattern) => { 31 | 32 | glob.sync(globPattern).forEach((filename) => { 33 | 34 | let content = fs.readFileSync(filename, 'utf-8'); 35 | 36 | if (findPattern.test(content)) { 37 | content = content.replace(findPattern, (match, width, height) => { 38 | 39 | return `width="${width}px" height="${height}px" viewBox="0 0 ${width} ${height}"`; 40 | 41 | }); 42 | fs.writeFileSync(filename, content, 'utf-8'); 43 | } 44 | 45 | }); 46 | 47 | }); 48 | 49 | done(); 50 | 51 | }, 52 | }, 53 | { 54 | name: 'media', 55 | src: 'src/views/icons/panel/**/*.svg', 56 | dest: 'media/icons', 57 | watch: true, 58 | }, 59 | { 60 | name: 'json', 61 | src: 'src/views/icons/components/**/*.svg', 62 | dest: 'src/views/components', 63 | watch: true, 64 | task: (stream) => { 65 | 66 | return stream 67 | .pipe(file2json({ 68 | path: 'icons.ts', 69 | indent: '\t', 70 | template: '/* eslint-disable */\nexport default __CONTENT__;', 71 | })); 72 | 73 | }, 74 | } 75 | ]; 76 | 77 | // Functions __________________________________________________________________ 78 | 79 | -------------------------------------------------------------------------------- /tasks/styles.js: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | const sass = require('gulp-sass')(require('sass')); 4 | 5 | const file2json = require('../plugins/gulp-file2json'); 6 | 7 | // Variables __________________________________________________________________ 8 | 9 | 10 | 11 | // Initialize _________________________________________________________________ 12 | 13 | 14 | 15 | // Exports ____________________________________________________________________ 16 | 17 | module.exports = [ 18 | { 19 | name: 'common', 20 | src: 'src/views/style.scss', 21 | dest: 'media', 22 | watch: true, 23 | task: (stream) => { 24 | 25 | return stream 26 | .pipe(sass.sync({ outputStyle: 'compressed' }).on('error', sass.logError)); 27 | 28 | }, 29 | }, 30 | { 31 | name: 'precompile', 32 | src: 'src/views/components/**/*.scss', 33 | dest: '.cache/src/views/components', 34 | watch: true, 35 | task: (stream) => { 36 | 37 | return stream 38 | .pipe(sass.sync({ outputStyle: 'compressed' }).on('error', sass.logError)); 39 | 40 | }, 41 | }, 42 | { 43 | name: 'json', 44 | src: '.cache/src/views/components/**/*.css', 45 | dest: 'src/views/components', 46 | watch: true, 47 | task: (stream) => { 48 | 49 | return stream 50 | .pipe(file2json({ 51 | path: 'styles.ts', 52 | indent: '\t', 53 | template: '/* eslint-disable */\nexport default __CONTENT__;', 54 | })); 55 | 56 | }, 57 | } 58 | ]; 59 | 60 | // Functions __________________________________________________________________ 61 | 62 | -------------------------------------------------------------------------------- /tasks/templates.js: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | const file2json = require('../plugins/gulp-file2json'); 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | module.exports = [ 16 | { 17 | name: 'json', 18 | src: 'src/views/components/**/*.html', 19 | dest: 'src/views/components', 20 | watch: true, 21 | task: (stream) => { 22 | 23 | return stream 24 | .pipe(file2json({ 25 | path: 'templates.ts', 26 | indent: '\t', 27 | template: '/* eslint-disable */\nexport default __CONTENT__;', 28 | })); 29 | 30 | }, 31 | }, 32 | ]; 33 | 34 | // Functions __________________________________________________________________ 35 | 36 | -------------------------------------------------------------------------------- /tasks/tests.js: -------------------------------------------------------------------------------- 1 | // Imports ____________________________________________________________________ 2 | 3 | const child_process = require('node:child_process'); 4 | 5 | // Variables __________________________________________________________________ 6 | 7 | 8 | 9 | // Initialize _________________________________________________________________ 10 | 11 | 12 | 13 | // Exports ____________________________________________________________________ 14 | 15 | module.exports = [ 16 | { 17 | name: 'run', 18 | watch: 'test/**/*.js', 19 | task: (done) => { 20 | 21 | const tests = child_process.spawn('npm', ['test']).on('close', () => done()); 22 | 23 | let logger = (buffer) => buffer.toString().split(/\n/).forEach((message) => message && console.log(message)); 24 | 25 | tests.stdout.on('data', logger); 26 | tests.stderr.on('data', logger); 27 | 28 | }, 29 | }, 30 | ]; 31 | 32 | // Functions __________________________________________________________________ 33 | 34 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "lib": [ 5 | "es6", 6 | "dom" 7 | ], 8 | "noEmitOnError": false, 9 | "removeComments": true, 10 | "emitDecoratorMetadata": true, 11 | "experimentalDecorators": true, 12 | "noImplicitAny": true, 13 | "noImplicitThis": true, 14 | "alwaysStrict": true, 15 | "strictBindCallApply": true, 16 | "strictNullChecks": false, 17 | "strictFunctionTypes": true, 18 | "strictPropertyInitialization": false, 19 | "allowSyntheticDefaultImports": true 20 | }, 21 | "exclude": [ 22 | "node_modules", 23 | ".vscode-test" 24 | ] 25 | } --------------------------------------------------------------------------------