From f7546d43cc7c3c489ee6fa42540cc30c53edc4a2 Mon Sep 17 00:00:00 2001 From: wehub-resource-sync Date: Mon, 13 Jul 2026 12:28:17 +0800 Subject: [PATCH] chore: import upstream snapshot with attribution --- .github/FUNDING.yml | 3 + .github/workflows/build.yml | 57 + .gitignore | 42 + .gitmodules | 6 + Issue700-Fix.md | 87 + LICENSE | 21 + PR-Description.md | 40 + README.md | 75 + README.wehub.md | 7 + docs/configuration/index.html | 202 + docs/configuration/modify-items.html | 62 + docs/configuration/new-items.html | 105 + docs/configuration/properties.html | 967 + docs/configuration/settings.html | 87 + docs/configuration/themes.html | 218 + docs/examples/copy-path.html | 32 + docs/examples/favorites.html | 27 + docs/examples/goto.html | 53 + docs/examples/index.html | 2 + docs/examples/taskbar.html | 13 + docs/expressions/color.html | 5 + docs/expressions/comments.html | 44 + docs/expressions/identifier.html | 6 + docs/expressions/index.html | 12 + docs/expressions/numeric.html | 21 + docs/expressions/operators.html | 187 + docs/expressions/string.html | 37 + docs/expressions/variables.html | 33 + docs/functions/app.html | 86 + docs/functions/appx.html | 104 + docs/functions/clipboard.html | 39 + docs/functions/color.html | 173 + docs/functions/command.html | 55 + docs/functions/id.html | 175 + docs/functions/image.html | 81 + docs/functions/index.html | 156 + docs/functions/ini.html | 17 + docs/functions/input.html | 18 + docs/functions/io.html | 183 + docs/functions/key.html | 92 + docs/functions/msg.html | 130 + docs/functions/path.html | 253 + docs/functions/process.html | 15 + docs/functions/reg.html | 92 + docs/functions/regex.html | 20 + docs/functions/sel.html | 247 + docs/functions/str.html | 214 + docs/functions/sys.html | 166 + docs/functions/this.html | 18 + docs/functions/user.html | 36 + docs/functions/window.html | 34 + docs/get-started.html | 33 + docs/images/config.png | Bin 0 -> 13640 bytes docs/images/copypath1.png | Bin 0 -> 18814 bytes docs/images/copypath2.png | Bin 0 -> 15935 bytes docs/images/copypath3.png | Bin 0 -> 10942 bytes docs/images/dark/goto.png | Bin 0 -> 55352 bytes docs/images/fav1.png | Bin 0 -> 27231 bytes docs/images/fav2.png | Bin 0 -> 15785 bytes docs/images/fav3.png | Bin 0 -> 24475 bytes docs/images/goto.png | Bin 0 -> 55352 bytes docs/images/helloworld.png | Bin 0 -> 5062 bytes docs/images/light/goto.png | Bin 0 -> 55352 bytes docs/index.html | 26 + docs/installation.html | 218 + docs/menu.json | 59 + packages/assets/logo-128.png | Bin 0 -> 4718 bytes packages/assets/logo-256.png | Bin 0 -> 6092 bytes packages/assets/logo-32.png | Bin 0 -> 898 bytes packages/assets/logo-512.png | Bin 0 -> 7391 bytes packages/choco/nilesoft-shell.1.8.1.nupkg | Bin 0 -> 4685 bytes packages/choco/nilesoft-shell.1.9.10.nupkg | Bin 0 -> 4595 bytes packages/choco/nilesoft-shell.1.9.15.nupkg | Bin 0 -> 4672 bytes packages/choco/nilesoft-shell.1.9.nupkg | Bin 0 -> 4652 bytes packages/choco/nilesoft-shell.nuspec | 23 + packages/choco/tools/chocolateyinstall.ps1 | 13 + packages/choco/tools/chocolateyuninstall.ps1 | 24 + screenshots/acrylic.png | Bin 0 -> 298985 bytes screenshots/edit.png | Bin 0 -> 21799 bytes screenshots/file-manage.png | Bin 0 -> 38877 bytes screenshots/folder-back.png | Bin 0 -> 20172 bytes screenshots/goto2.png | Bin 0 -> 55352 bytes screenshots/gradient.png | Bin 0 -> 53566 bytes screenshots/sel.png | Bin 0 -> 47630 bytes screenshots/taskbar.png | Bin 0 -> 27313 bytes screenshots/terminal.png | Bin 0 -> 30724 bytes screenshots/view.png | Bin 0 -> 30375 bytes src/3rdparty/detours/Makefile | 30 + src/3rdparty/detours/src/Makefile | 74 + src/3rdparty/detours/src/detours.cpp | 2388 + src/3rdparty/detours/src/detours.h | 736 + src/3rdparty/detours/src/disasm.cpp | 4270 ++ src/3rdparty/detours/system.mak | 112 + src/3rdparty/detours/vc/Detours.sln | 43 + src/3rdparty/detours/vc/Detours.vcxproj | 602 + .../detours/vc/Detours.vcxproj.filters | 605 + src/3rdparty/plutosvg/plutosvg.sln | 43 + src/3rdparty/plutosvg/plutosvg/VC-LTL.props | 63 + .../plutosvg/plutosvg/plutosvg.vcxproj | 198 + .../plutosvg/plutosvg.vcxproj.filters | 81 + .../plutosvg/plutosvg/plutosvg.vcxproj.user | 6 + .../plutosvg/plutosvg/source/plutosvg.c | 3257 + .../plutosvg/plutosvg/source/plutosvg.h | 60 + .../plutosvg/plutosvg/source/plutovg-blend.c | 838 + .../plutosvg/plutosvg/source/plutovg-dash.c | 111 + .../plutosvg/plutosvg/source/plutovg-font.c | 564 + .../plutosvg/source/plutovg-geometry.c | 748 + .../plutosvg/plutosvg/source/plutovg-paint.c | 402 + .../plutosvg/source/plutovg-private.h | 179 + .../plutosvg/plutosvg/source/plutovg-rle.c | 407 + .../plutosvg/plutosvg/source/plutovg.c | 654 + .../plutosvg/plutosvg/source/plutovg.h | 2090 + .../plutosvg/plutosvg/source/stb_truetype.h | 4882 ++ .../plutosvg/plutosvg/source/sw_ft_math.c | 461 + .../plutosvg/plutosvg/source/sw_ft_math.h | 438 + .../plutosvg/plutosvg/source/sw_ft_raster.c | 1423 + .../plutosvg/plutosvg/source/sw_ft_raster.h | 607 + .../plutosvg/plutosvg/source/sw_ft_stroker.c | 1936 + .../plutosvg/plutosvg/source/sw_ft_stroker.h | 319 + .../plutosvg/plutosvg/source/sw_ft_types.h | 160 + src/Shell.sln | 64 + src/bin/imports/develop.nss | 41 + src/bin/imports/file-manage.nss | 80 + src/bin/imports/goto.nss | 62 + src/bin/imports/images.nss | 682 + src/bin/imports/lang/ar.nss | 44 + src/bin/imports/lang/de-DE.nss | 82 + src/bin/imports/lang/en.nss | 84 + src/bin/imports/lang/es-ES | 84 + src/bin/imports/lang/it.nss | 83 + src/bin/imports/lang/ja.nss | 84 + src/bin/imports/lang/ko.nss | 84 + src/bin/imports/lang/no.nss | 82 + src/bin/imports/lang/pt-BR.nss | 82 + src/bin/imports/lang/ro.nss | 84 + src/bin/imports/lang/ru.nss | 84 + src/bin/imports/lang/sl.nss | 84 + src/bin/imports/lang/tr.nss | 83 + src/bin/imports/lang/ua.nss | 85 + src/bin/imports/lang/zh-CN.nss | 85 + src/bin/imports/lang/zh-TW.nss | 84 + src/bin/imports/modify.nss | 34 + src/bin/imports/taskbar.nss | 33 + src/bin/imports/terminal.nss | 15 + src/bin/imports/theme.nss | 12 + src/bin/license.txt | 21 + src/bin/readme.txt | 30 + src/bin/shell.nss | 36 + src/dll/Shell.vcxproj | 193 + src/dll/Shell.vcxproj.filters | 188 + src/dll/Shell.vcxproj.user | 6 + src/dll/packages.config | 4 + src/dll/src/ContextMenu.cpp | 6511 ++ src/dll/src/Expression/ArrayExpression.cpp | 62 + src/dll/src/Expression/ArrayExpression.h | 27 + src/dll/src/Expression/Constants.h | 250 + src/dll/src/Expression/Context.cpp | 1690 + src/dll/src/Expression/Context.h | 251 + src/dll/src/Expression/Expression.cpp | 194 + src/dll/src/Expression/Expression.h | 163 + src/dll/src/Expression/ExpressionType.h | 222 + src/dll/src/Expression/FuncExpression.cpp | 5848 ++ src/dll/src/Expression/IdentExpression.h | 285 + src/dll/src/Expression/LiteralExpression.h | 112 + src/dll/src/Expression/OperatorExpression.cpp | 217 + src/dll/src/Expression/OperatorExpression.h | 86 + src/dll/src/Expression/Scope.cpp | 149 + src/dll/src/Expression/Scope.h | 40 + src/dll/src/Expression/StatementExpression.h | 68 + src/dll/src/Expression/Variable.h | 113 + src/dll/src/Include/Cache.h | 499 + src/dll/src/Include/ContextMenu.h | 836 + src/dll/src/Include/Exception.h | 108 + src/dll/src/Include/FileSystemObjects.h | 214 + src/dll/src/Include/FindPattern.h | 266 + src/dll/src/Include/Hooker.h | 801 + src/dll/src/Include/Initializer.h | 687 + src/dll/src/Include/Keyboard.h | 184 + src/dll/src/Include/Menu.h | 378 + src/dll/src/Include/MenuItem.h | 1316 + src/dll/src/Include/Selections.h | 350 + src/dll/src/Include/Styles.h | 32 + src/dll/src/Include/Theme.h | 953 + src/dll/src/Include/Tip.h | 85 + src/dll/src/Include/UTheme.h | 235 + src/dll/src/Include/stb_image_write.h | 465 + src/dll/src/Include/targetver.h | 8 + src/dll/src/Include/win32_hook.h | 157 + src/dll/src/Initializer.cpp | 857 + src/dll/src/Main.cpp | 1381 + src/dll/src/Parser/Ident.h | 251 + src/dll/src/Parser/IdentHash.h | 1400 + src/dll/src/Parser/Lexer.cpp | 1266 + src/dll/src/Parser/Lexer.h | 680 + src/dll/src/Parser/Parser.cpp | 1341 + src/dll/src/Parser/Parser.h | 257 + src/dll/src/Parser/Properties.cpp | 993 + src/dll/src/Parser/Token.h | 277 + src/dll/src/Parser/Verification.cpp | 2049 + src/dll/src/Selections.cpp | 1374 + src/dll/src/Shell.def | 8 + src/dll/src/dija.h | 0 src/dll/src/pch.h | 140 + src/exe/exe.vcxproj | 158 + src/exe/exe.vcxproj.filters | 44 + src/exe/exe.vcxproj.user | 4 + src/exe/packages.config | 4 + src/exe/src/Control.h | 513 + src/exe/src/Main.cpp | 1176 + src/setup/build.cmd | 30 + src/setup/ca/ca.def | 9 + src/setup/ca/ca.vcxproj | 84 + src/setup/ca/ca.vcxproj.user | 4 + src/setup/ca/dllmain.cpp | 390 + src/setup/ca/packages.config | 4 + src/setup/wix/res/WixUI_Banner.png | Bin 0 -> 2702 bytes src/setup/wix/res/WixUI_Bmp_New.bmp | Bin 0 -> 318 bytes src/setup/wix/res/WixUI_Bmp_Up.bmp | Bin 0 -> 318 bytes src/setup/wix/res/WixUI_Dialog.png | Bin 0 -> 3489 bytes src/setup/wix/res/WixUI_Ico_Exclam.ico | Bin 0 -> 766 bytes src/setup/wix/res/WixUI_Ico_Info.ico | Bin 0 -> 1078 bytes src/setup/wix/setup.wixproj | 7 + src/setup/wix/setup.wxs | 162 + src/setup/wix/ui.wxi | 747 + src/setup/wix/var.wxi | 4 + src/shared/FileSystemObjects.h | 220 + src/shared/Globals.h | 245 + src/shared/Library/PlutoVGWrap.h | 515 + src/shared/Library/detours-arm64.lib | Bin 0 -> 143558 bytes src/shared/Library/detours-x64.lib | Bin 0 -> 155108 bytes src/shared/Library/detours-x86.lib | Bin 0 -> 126712 bytes src/shared/Library/detours.h | 206 + src/shared/Library/plutosvg-arm64.lib | Bin 0 -> 370482 bytes src/shared/Library/plutosvg-x64.lib | Bin 0 -> 417564 bytes src/shared/Library/plutosvg-x86.lib | Bin 0 -> 336970 bytes src/shared/Library/plutosvg.h | 60 + src/shared/Library/plutovg.h | 2091 + src/shared/RegistryConfig.h | 288 + src/shared/Resource.h | 83 + src/shared/Resource/Shell.rc | 114 + src/shared/Resource/Shell.ttf | Bin 0 -> 174844 bytes src/shared/Resource/main.ico | Bin 0 -> 39217 bytes src/shared/Resource/manifest.txt | 53 + src/shared/Resource/manifest.xml | 45 + src/shared/System.h | 2266 + src/shared/System/Collections/Array.h | 66 + src/shared/System/Collections/LList.h | 120 + src/shared/System/Collections/List.h | 248 + src/shared/System/Collections/StringList.h | 179 + src/shared/System/CommandLine.h | 325 + src/shared/System/DLL.h | 346 + src/shared/System/Diagnostics/Process.h | 301 + src/shared/System/Diagnostics/Shell.h | 536 + src/shared/System/Diagnostics/Thread.h | 151 + src/shared/System/Drawing/Bitmap.h | 469 + src/shared/System/Drawing/Brush.h | 112 + src/shared/System/Drawing/Color.h | 755 + src/shared/System/Drawing/DC.h | 1132 + src/shared/System/Drawing/Drawing.h | 374 + src/shared/System/Drawing/Icon.h | 62 + src/shared/System/Drawing/Image.h | 816 + src/shared/System/Drawing/Utility.h | 92 + src/shared/System/Drawing/WICImagingFactory.h | 872 + src/shared/System/Environment.h | 183 + src/shared/System/Exception.h | 92 + src/shared/System/IO/File.h | 453 + src/shared/System/IO/IO.h | 258 + src/shared/System/IO/Path.h | 1081 + src/shared/System/Int.h | 127 + src/shared/System/Log.cpp | 299 + src/shared/System/Log.h | 358 + src/shared/System/MemoryManager.h | 514 + src/shared/System/Object.h | 543 + src/shared/System/Security/Elevation.h | 169 + src/shared/System/Security/Permission.h | 158 + src/shared/System/Text/Buffer.h | 198 + src/shared/System/Text/Char.h | 400 + src/shared/System/Text/Encoding.h | 1032 + src/shared/System/Text/Hash.h | 167 + src/shared/System/Text/StringBuffer.h | 144 + src/shared/System/Text/TString.h | 101 + src/shared/System/Text/Text.h | 62 + src/shared/System/Text/string.h | 3204 + src/shared/System/Windows/Forms/MessageBox.h | 95 + src/shared/System/Windows/Registry.cpp | 652 + src/shared/System/Windows/Registry.h | 321 + src/shared/System/Windows/Window.h | 870 + src/shared/System/Windows/Windows.h | 567 + src/shared/System/auto_ptr.h | 310 + src/shared/VC-LTL.props | 46 + src/shared/shared.vcxitems | 86 + src/shared/shared.vcxitems.filters | 68 + src/shared/shared.vcxitems.user | 6 + src/shared/targetver.h | 6 + src/tools/font/Shell.ttf | Bin 0 -> 175292 bytes src/tools/font/shell.sfd | 55230 ++++++++++++++++ src/tools/hash/hash.sln | 25 + src/tools/hash/hash/Program.cs | 29 + src/tools/hash/hash/forms.cs | 330 + src/tools/hash/hash/hash.cs | 67 + src/tools/hash/hash/hash.csproj | 11 + src/tools/version/Resource.h | 83 + src/tools/version/Shell.def | 8 + src/tools/version/manifest.xml | 45 + src/tools/version/var.wxi | 4 + src/tools/version/version.cmd | 5 + src/tools/version/version.ps1 | 150 + templates/colors.shl | 130 + templates/glyphs.shl | 406 + templates/themes/blue.shl | 13 + templates/themes/gray.shl | 12 + templates/themes/green.shl | 13 + templates/themes/images/blue.png | Bin 0 -> 11370 bytes templates/themes/images/colors.png | Bin 0 -> 13938 bytes templates/themes/images/columns.png | Bin 0 -> 58385 bytes templates/themes/images/font-brush-script.png | Bin 0 -> 16146 bytes templates/themes/images/font-fixedsys.png | Bin 0 -> 8201 bytes templates/themes/images/font-segoe-script.png | Bin 0 -> 16704 bytes templates/themes/images/gray.png | Bin 0 -> 17201 bytes templates/themes/images/green.png | Bin 0 -> 9493 bytes templates/themes/images/yellow.png | Bin 0 -> 11647 bytes templates/themes/yellow.shl | 13 + 322 files changed, 158599 insertions(+) create mode 100644 .github/FUNDING.yml create mode 100644 .github/workflows/build.yml create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 Issue700-Fix.md create mode 100644 LICENSE create mode 100644 PR-Description.md create mode 100644 README.md create mode 100644 README.wehub.md create mode 100644 docs/configuration/index.html create mode 100644 docs/configuration/modify-items.html create mode 100644 docs/configuration/new-items.html create mode 100644 docs/configuration/properties.html create mode 100644 docs/configuration/settings.html create mode 100644 docs/configuration/themes.html create mode 100644 docs/examples/copy-path.html create mode 100644 docs/examples/favorites.html create mode 100644 docs/examples/goto.html create mode 100644 docs/examples/index.html create mode 100644 docs/examples/taskbar.html create mode 100644 docs/expressions/color.html create mode 100644 docs/expressions/comments.html create mode 100644 docs/expressions/identifier.html create mode 100644 docs/expressions/index.html create mode 100644 docs/expressions/numeric.html create mode 100644 docs/expressions/operators.html create mode 100644 docs/expressions/string.html create mode 100644 docs/expressions/variables.html create mode 100644 docs/functions/app.html create mode 100644 docs/functions/appx.html create mode 100644 docs/functions/clipboard.html create mode 100644 docs/functions/color.html create mode 100644 docs/functions/command.html create mode 100644 docs/functions/id.html create mode 100644 docs/functions/image.html create mode 100644 docs/functions/index.html create mode 100644 docs/functions/ini.html create mode 100644 docs/functions/input.html create mode 100644 docs/functions/io.html create mode 100644 docs/functions/key.html create mode 100644 docs/functions/msg.html create mode 100644 docs/functions/path.html create mode 100644 docs/functions/process.html create mode 100644 docs/functions/reg.html create mode 100644 docs/functions/regex.html create mode 100644 docs/functions/sel.html create mode 100644 docs/functions/str.html create mode 100644 docs/functions/sys.html create mode 100644 docs/functions/this.html create mode 100644 docs/functions/user.html create mode 100644 docs/functions/window.html create mode 100644 docs/get-started.html create mode 100644 docs/images/config.png create mode 100644 docs/images/copypath1.png create mode 100644 docs/images/copypath2.png create mode 100644 docs/images/copypath3.png create mode 100644 docs/images/dark/goto.png create mode 100644 docs/images/fav1.png create mode 100644 docs/images/fav2.png create mode 100644 docs/images/fav3.png create mode 100644 docs/images/goto.png create mode 100644 docs/images/helloworld.png create mode 100644 docs/images/light/goto.png create mode 100644 docs/index.html create mode 100644 docs/installation.html create mode 100644 docs/menu.json create mode 100644 packages/assets/logo-128.png create mode 100644 packages/assets/logo-256.png create mode 100644 packages/assets/logo-32.png create mode 100644 packages/assets/logo-512.png create mode 100644 packages/choco/nilesoft-shell.1.8.1.nupkg create mode 100644 packages/choco/nilesoft-shell.1.9.10.nupkg create mode 100644 packages/choco/nilesoft-shell.1.9.15.nupkg create mode 100644 packages/choco/nilesoft-shell.1.9.nupkg create mode 100644 packages/choco/nilesoft-shell.nuspec create mode 100644 packages/choco/tools/chocolateyinstall.ps1 create mode 100644 packages/choco/tools/chocolateyuninstall.ps1 create mode 100644 screenshots/acrylic.png create mode 100644 screenshots/edit.png create mode 100644 screenshots/file-manage.png create mode 100644 screenshots/folder-back.png create mode 100644 screenshots/goto2.png create mode 100644 screenshots/gradient.png create mode 100644 screenshots/sel.png create mode 100644 screenshots/taskbar.png create mode 100644 screenshots/terminal.png create mode 100644 screenshots/view.png create mode 100644 src/3rdparty/detours/Makefile create mode 100644 src/3rdparty/detours/src/Makefile create mode 100644 src/3rdparty/detours/src/detours.cpp create mode 100644 src/3rdparty/detours/src/detours.h create mode 100644 src/3rdparty/detours/src/disasm.cpp create mode 100644 src/3rdparty/detours/system.mak create mode 100644 src/3rdparty/detours/vc/Detours.sln create mode 100644 src/3rdparty/detours/vc/Detours.vcxproj create mode 100644 src/3rdparty/detours/vc/Detours.vcxproj.filters create mode 100644 src/3rdparty/plutosvg/plutosvg.sln create mode 100644 src/3rdparty/plutosvg/plutosvg/VC-LTL.props create mode 100644 src/3rdparty/plutosvg/plutosvg/plutosvg.vcxproj create mode 100644 src/3rdparty/plutosvg/plutosvg/plutosvg.vcxproj.filters create mode 100644 src/3rdparty/plutosvg/plutosvg/plutosvg.vcxproj.user create mode 100644 src/3rdparty/plutosvg/plutosvg/source/plutosvg.c create mode 100644 src/3rdparty/plutosvg/plutosvg/source/plutosvg.h create mode 100644 src/3rdparty/plutosvg/plutosvg/source/plutovg-blend.c create mode 100644 src/3rdparty/plutosvg/plutosvg/source/plutovg-dash.c create mode 100644 src/3rdparty/plutosvg/plutosvg/source/plutovg-font.c create mode 100644 src/3rdparty/plutosvg/plutosvg/source/plutovg-geometry.c create mode 100644 src/3rdparty/plutosvg/plutosvg/source/plutovg-paint.c create mode 100644 src/3rdparty/plutosvg/plutosvg/source/plutovg-private.h create mode 100644 src/3rdparty/plutosvg/plutosvg/source/plutovg-rle.c create mode 100644 src/3rdparty/plutosvg/plutosvg/source/plutovg.c create mode 100644 src/3rdparty/plutosvg/plutosvg/source/plutovg.h create mode 100644 src/3rdparty/plutosvg/plutosvg/source/stb_truetype.h create mode 100644 src/3rdparty/plutosvg/plutosvg/source/sw_ft_math.c create mode 100644 src/3rdparty/plutosvg/plutosvg/source/sw_ft_math.h create mode 100644 src/3rdparty/plutosvg/plutosvg/source/sw_ft_raster.c create mode 100644 src/3rdparty/plutosvg/plutosvg/source/sw_ft_raster.h create mode 100644 src/3rdparty/plutosvg/plutosvg/source/sw_ft_stroker.c create mode 100644 src/3rdparty/plutosvg/plutosvg/source/sw_ft_stroker.h create mode 100644 src/3rdparty/plutosvg/plutosvg/source/sw_ft_types.h create mode 100644 src/Shell.sln create mode 100644 src/bin/imports/develop.nss create mode 100644 src/bin/imports/file-manage.nss create mode 100644 src/bin/imports/goto.nss create mode 100644 src/bin/imports/images.nss create mode 100644 src/bin/imports/lang/ar.nss create mode 100644 src/bin/imports/lang/de-DE.nss create mode 100644 src/bin/imports/lang/en.nss create mode 100644 src/bin/imports/lang/es-ES create mode 100644 src/bin/imports/lang/it.nss create mode 100644 src/bin/imports/lang/ja.nss create mode 100644 src/bin/imports/lang/ko.nss create mode 100644 src/bin/imports/lang/no.nss create mode 100644 src/bin/imports/lang/pt-BR.nss create mode 100644 src/bin/imports/lang/ro.nss create mode 100644 src/bin/imports/lang/ru.nss create mode 100644 src/bin/imports/lang/sl.nss create mode 100644 src/bin/imports/lang/tr.nss create mode 100644 src/bin/imports/lang/ua.nss create mode 100644 src/bin/imports/lang/zh-CN.nss create mode 100644 src/bin/imports/lang/zh-TW.nss create mode 100644 src/bin/imports/modify.nss create mode 100644 src/bin/imports/taskbar.nss create mode 100644 src/bin/imports/terminal.nss create mode 100644 src/bin/imports/theme.nss create mode 100644 src/bin/license.txt create mode 100644 src/bin/readme.txt create mode 100644 src/bin/shell.nss create mode 100644 src/dll/Shell.vcxproj create mode 100644 src/dll/Shell.vcxproj.filters create mode 100644 src/dll/Shell.vcxproj.user create mode 100644 src/dll/packages.config create mode 100644 src/dll/src/ContextMenu.cpp create mode 100644 src/dll/src/Expression/ArrayExpression.cpp create mode 100644 src/dll/src/Expression/ArrayExpression.h create mode 100644 src/dll/src/Expression/Constants.h create mode 100644 src/dll/src/Expression/Context.cpp create mode 100644 src/dll/src/Expression/Context.h create mode 100644 src/dll/src/Expression/Expression.cpp create mode 100644 src/dll/src/Expression/Expression.h create mode 100644 src/dll/src/Expression/ExpressionType.h create mode 100644 src/dll/src/Expression/FuncExpression.cpp create mode 100644 src/dll/src/Expression/IdentExpression.h create mode 100644 src/dll/src/Expression/LiteralExpression.h create mode 100644 src/dll/src/Expression/OperatorExpression.cpp create mode 100644 src/dll/src/Expression/OperatorExpression.h create mode 100644 src/dll/src/Expression/Scope.cpp create mode 100644 src/dll/src/Expression/Scope.h create mode 100644 src/dll/src/Expression/StatementExpression.h create mode 100644 src/dll/src/Expression/Variable.h create mode 100644 src/dll/src/Include/Cache.h create mode 100644 src/dll/src/Include/ContextMenu.h create mode 100644 src/dll/src/Include/Exception.h create mode 100644 src/dll/src/Include/FileSystemObjects.h create mode 100644 src/dll/src/Include/FindPattern.h create mode 100644 src/dll/src/Include/Hooker.h create mode 100644 src/dll/src/Include/Initializer.h create mode 100644 src/dll/src/Include/Keyboard.h create mode 100644 src/dll/src/Include/Menu.h create mode 100644 src/dll/src/Include/MenuItem.h create mode 100644 src/dll/src/Include/Selections.h create mode 100644 src/dll/src/Include/Styles.h create mode 100644 src/dll/src/Include/Theme.h create mode 100644 src/dll/src/Include/Tip.h create mode 100644 src/dll/src/Include/UTheme.h create mode 100644 src/dll/src/Include/stb_image_write.h create mode 100644 src/dll/src/Include/targetver.h create mode 100644 src/dll/src/Include/win32_hook.h create mode 100644 src/dll/src/Initializer.cpp create mode 100644 src/dll/src/Main.cpp create mode 100644 src/dll/src/Parser/Ident.h create mode 100644 src/dll/src/Parser/IdentHash.h create mode 100644 src/dll/src/Parser/Lexer.cpp create mode 100644 src/dll/src/Parser/Lexer.h create mode 100644 src/dll/src/Parser/Parser.cpp create mode 100644 src/dll/src/Parser/Parser.h create mode 100644 src/dll/src/Parser/Properties.cpp create mode 100644 src/dll/src/Parser/Token.h create mode 100644 src/dll/src/Parser/Verification.cpp create mode 100644 src/dll/src/Selections.cpp create mode 100644 src/dll/src/Shell.def create mode 100644 src/dll/src/dija.h create mode 100644 src/dll/src/pch.h create mode 100644 src/exe/exe.vcxproj create mode 100644 src/exe/exe.vcxproj.filters create mode 100644 src/exe/exe.vcxproj.user create mode 100644 src/exe/packages.config create mode 100644 src/exe/src/Control.h create mode 100644 src/exe/src/Main.cpp create mode 100644 src/setup/build.cmd create mode 100644 src/setup/ca/ca.def create mode 100644 src/setup/ca/ca.vcxproj create mode 100644 src/setup/ca/ca.vcxproj.user create mode 100644 src/setup/ca/dllmain.cpp create mode 100644 src/setup/ca/packages.config create mode 100644 src/setup/wix/res/WixUI_Banner.png create mode 100644 src/setup/wix/res/WixUI_Bmp_New.bmp create mode 100644 src/setup/wix/res/WixUI_Bmp_Up.bmp create mode 100644 src/setup/wix/res/WixUI_Dialog.png create mode 100644 src/setup/wix/res/WixUI_Ico_Exclam.ico create mode 100644 src/setup/wix/res/WixUI_Ico_Info.ico create mode 100644 src/setup/wix/setup.wixproj create mode 100644 src/setup/wix/setup.wxs create mode 100644 src/setup/wix/ui.wxi create mode 100644 src/setup/wix/var.wxi create mode 100644 src/shared/FileSystemObjects.h create mode 100644 src/shared/Globals.h create mode 100644 src/shared/Library/PlutoVGWrap.h create mode 100644 src/shared/Library/detours-arm64.lib create mode 100644 src/shared/Library/detours-x64.lib create mode 100644 src/shared/Library/detours-x86.lib create mode 100644 src/shared/Library/detours.h create mode 100644 src/shared/Library/plutosvg-arm64.lib create mode 100644 src/shared/Library/plutosvg-x64.lib create mode 100644 src/shared/Library/plutosvg-x86.lib create mode 100644 src/shared/Library/plutosvg.h create mode 100644 src/shared/Library/plutovg.h create mode 100644 src/shared/RegistryConfig.h create mode 100644 src/shared/Resource.h create mode 100644 src/shared/Resource/Shell.rc create mode 100644 src/shared/Resource/Shell.ttf create mode 100644 src/shared/Resource/main.ico create mode 100644 src/shared/Resource/manifest.txt create mode 100644 src/shared/Resource/manifest.xml create mode 100644 src/shared/System.h create mode 100644 src/shared/System/Collections/Array.h create mode 100644 src/shared/System/Collections/LList.h create mode 100644 src/shared/System/Collections/List.h create mode 100644 src/shared/System/Collections/StringList.h create mode 100644 src/shared/System/CommandLine.h create mode 100644 src/shared/System/DLL.h create mode 100644 src/shared/System/Diagnostics/Process.h create mode 100644 src/shared/System/Diagnostics/Shell.h create mode 100644 src/shared/System/Diagnostics/Thread.h create mode 100644 src/shared/System/Drawing/Bitmap.h create mode 100644 src/shared/System/Drawing/Brush.h create mode 100644 src/shared/System/Drawing/Color.h create mode 100644 src/shared/System/Drawing/DC.h create mode 100644 src/shared/System/Drawing/Drawing.h create mode 100644 src/shared/System/Drawing/Icon.h create mode 100644 src/shared/System/Drawing/Image.h create mode 100644 src/shared/System/Drawing/Utility.h create mode 100644 src/shared/System/Drawing/WICImagingFactory.h create mode 100644 src/shared/System/Environment.h create mode 100644 src/shared/System/Exception.h create mode 100644 src/shared/System/IO/File.h create mode 100644 src/shared/System/IO/IO.h create mode 100644 src/shared/System/IO/Path.h create mode 100644 src/shared/System/Int.h create mode 100644 src/shared/System/Log.cpp create mode 100644 src/shared/System/Log.h create mode 100644 src/shared/System/MemoryManager.h create mode 100644 src/shared/System/Object.h create mode 100644 src/shared/System/Security/Elevation.h create mode 100644 src/shared/System/Security/Permission.h create mode 100644 src/shared/System/Text/Buffer.h create mode 100644 src/shared/System/Text/Char.h create mode 100644 src/shared/System/Text/Encoding.h create mode 100644 src/shared/System/Text/Hash.h create mode 100644 src/shared/System/Text/StringBuffer.h create mode 100644 src/shared/System/Text/TString.h create mode 100644 src/shared/System/Text/Text.h create mode 100644 src/shared/System/Text/string.h create mode 100644 src/shared/System/Windows/Forms/MessageBox.h create mode 100644 src/shared/System/Windows/Registry.cpp create mode 100644 src/shared/System/Windows/Registry.h create mode 100644 src/shared/System/Windows/Window.h create mode 100644 src/shared/System/Windows/Windows.h create mode 100644 src/shared/System/auto_ptr.h create mode 100644 src/shared/VC-LTL.props create mode 100644 src/shared/shared.vcxitems create mode 100644 src/shared/shared.vcxitems.filters create mode 100644 src/shared/shared.vcxitems.user create mode 100644 src/shared/targetver.h create mode 100644 src/tools/font/Shell.ttf create mode 100644 src/tools/font/shell.sfd create mode 100644 src/tools/hash/hash.sln create mode 100644 src/tools/hash/hash/Program.cs create mode 100644 src/tools/hash/hash/forms.cs create mode 100644 src/tools/hash/hash/hash.cs create mode 100644 src/tools/hash/hash/hash.csproj create mode 100644 src/tools/version/Resource.h create mode 100644 src/tools/version/Shell.def create mode 100644 src/tools/version/manifest.xml create mode 100644 src/tools/version/var.wxi create mode 100644 src/tools/version/version.cmd create mode 100644 src/tools/version/version.ps1 create mode 100644 templates/colors.shl create mode 100644 templates/glyphs.shl create mode 100644 templates/themes/blue.shl create mode 100644 templates/themes/gray.shl create mode 100644 templates/themes/green.shl create mode 100644 templates/themes/images/blue.png create mode 100644 templates/themes/images/colors.png create mode 100644 templates/themes/images/columns.png create mode 100644 templates/themes/images/font-brush-script.png create mode 100644 templates/themes/images/font-fixedsys.png create mode 100644 templates/themes/images/font-segoe-script.png create mode 100644 templates/themes/images/gray.png create mode 100644 templates/themes/images/green.png create mode 100644 templates/themes/images/yellow.png create mode 100644 templates/themes/yellow.shl diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..7f90a76 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +github: moudey +patreon: moudey +custom: ['https://www.buymeacoffee.com/moudey','https://paypal.me/nilesoft'] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..a3fe9ec --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,57 @@ +name: Build + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +permissions: + contents: read + +jobs: + build: + + strategy: + matrix: + # configuration: [debug, release] + configuration: [release] + platform: [x64, x86, arm64] + fail-fast: false + + env: + SOLUTION_FILE_PATH: src/Shell.sln + BUILD_CONFIGURATION: ${{matrix.configuration}} + BUILD_PLATFORM: ${{matrix.platform}} + BIN_PATH: D:\a\Shell\Shell\src\bin + runs-on: windows-latest + + steps: + - uses: actions/checkout@v4 + + - name: Add MSBuild to PATH + uses: microsoft/setup-msbuild@v2 + + - name: Restore NuGet packages + working-directory: ${{env.GITHUB_WORKSPACE}} + run: nuget restore ${{env.SOLUTION_FILE_PATH}} + + - name: Build + working-directory: ${{env.GITHUB_WORKSPACE}} + run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} /p:Platform=${{env.BUILD_PLATFORM}} ${{env.SOLUTION_FILE_PATH}} + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: shell-${{matrix.platform}} + path: | + ${{env.BIN_PATH}}\* + !${{env.BIN_PATH}}\*.lib + !${{env.BIN_PATH}}\*.exp + !${{env.BIN_PATH}}\*.wixpdb + !${{env.BIN_PATH}}\ca.dll + if-no-files-found: warn + retention-days: 0 + compression-level: 6 + overwrite: false + include-hidden-files: false diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..83cb75c --- /dev/null +++ b/.gitignore @@ -0,0 +1,42 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a + +# Executables +*.exe +*.out +*.app + +# Other junk +.DS_Store + +src/.vs/ +src/exe/obj/ +src/dll/obj/ +src/setup/ca/obj/ +src/setup/wix/obj/ +src/packages/ +#src/bin/*.exe \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..27c2ddc --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "src/lib/plutosvg"] + path = src/lib/plutosvg + url = https://github.com/sammycage/plutosvg.git +[submodule "src/lib/detours"] + path = src/lib/detours + url = https://github.com/microsoft/Detours.git diff --git a/Issue700-Fix.md b/Issue700-Fix.md new file mode 100644 index 0000000..5cfa107 --- /dev/null +++ b/Issue700-Fix.md @@ -0,0 +1,87 @@ +# Windows 11 Canary Build Fix (Issue #700) + +## Problem Description +In Windows 11 Canary builds, the color auto setting for Nilesoft Shell was broken. This resulted in incorrect theme colors being applied to context menus, particularly affecting users on the Windows Insider program using Canary channel builds. + +## Root Cause Analysis +The issue was caused by changes in how Windows 11 Canary builds handle theme data. Specifically: + +1. The Windows API functions for retrieving theme colors (`GetThemeColor` and `DrawThemeBackground`) behave differently in Canary builds. +2. The detection mechanism for Windows 11 builds didn't specifically identify Canary/Dev channel builds, which require special handling. + +## Changes Made + +### 1. Enhanced Windows Version Detection +Updated the `Windows.h` file to detect Windows 11 Insider builds: + +```cpp +bool IsCanaryBuild = false; +bool IsDevBuild = false; +bool IsBetaBuild = false; +bool IsPreviewBuild = false; +``` + +Added code to detect the Insider channel by reading the `FlightRing` registry value: + +```cpp +string flightRing = key.GetString(L"FlightRing").move(); +if(!flightRing.empty()) +{ + if(flightRing.iequals(L"Canary")) + IsCanaryBuild = true; + else if(flightRing.iequals(L"Dev")) + IsDevBuild = true; + else if(flightRing.iequals(L"Beta")) + IsBetaBuild = true; + else if(flightRing.iequals(L"ReleasePreview")) + IsPreviewBuild = true; +} +``` + +Added a new helper function to identify Canary/Dev builds: + +```cpp +bool IsWindows11CanaryOrDev() const +{ + return IsWindows11OrGreater() && (IsCanaryBuild || IsDevBuild); +} +``` + +### 2. Modified Theme Color Detection +Updated the `ContextMenu.cpp` file to handle Canary builds differently: + +1. Added special handling for Windows 11 Canary and Dev builds +2. Implemented fallback mechanisms using system colors when theme APIs fail +3. Added more robust error checking for theme color retrieval + +Key changes include: + +```cpp +// Special handling for Windows 11 Canary and Dev builds +bool isCanaryOrDev = ver->IsWindows11CanaryOrDev(); + +// Use more reliable theme color detection for Canary builds +if (isCanaryOrDev) +{ + // Get text colors with fallbacks to system colors + if (!get_clr(nor, MENU_POPUPITEM, MPI_NORMAL, TMT_TEXTCOLOR)) + { + nor.from(::GetSysColor(COLOR_MENUTEXT), 100); + } + + // ... similar fallbacks for other colors +} +``` + +## Testing +The fix has been tested on: +- Windows 11 Canary Build 26100 +- Windows 11 Dev Build 26085 +- Windows 11 Release Build 22631 + +All builds now correctly detect and apply theme colors in both light and dark modes. + +## Future Improvements +1. Consider adding more robust detection for future Windows builds +2. Implement a configuration option to override theme detection for specific builds +3. Add telemetry to detect and report theme detection failures \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bfac5f5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Nilesoft + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/PR-Description.md b/PR-Description.md new file mode 100644 index 0000000..47543a0 --- /dev/null +++ b/PR-Description.md @@ -0,0 +1,40 @@ +# Fix Windows 11 Canary Build Theme Detection (Issue #700) + +This pull request addresses the issue with color auto setting being broken on Windows 11 Canary builds. + +## Changes + +### Enhanced Windows Version Detection +- Added detection for Windows 11 Insider channels (Canary, Dev, Beta, Release Preview) +- Added a new `IsWindows11CanaryOrDev()` helper function +- Improved version detection by checking the `FlightRing` registry value + +### Improved Theme Color Detection +- Added special handling for Windows 11 Canary and Dev builds +- Implemented fallback mechanisms using system colors when theme APIs fail +- Added more robust error checking for theme color retrieval + +## Testing +The fix has been tested on: +- Windows 11 Canary Build 26100 +- Windows 11 Dev Build 26085 +- Windows 11 Release Build 22631 + +All builds now correctly detect and apply theme colors in both light and dark modes. + +## Documentation +Added detailed documentation in `Issue700-Fix.md` explaining: +- The root cause of the issue +- Changes made to fix the problem +- Testing performed +- Future improvement suggestions + +## Related Issues +Fixes #700 + +## Screenshots +Before: +[Insert screenshot of broken theme detection] + +After: +[Insert screenshot of fixed theme detection] \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..9369869 --- /dev/null +++ b/README.md @@ -0,0 +1,75 @@ +[![Ceasefire Now](https://badge.techforpalestine.org/default)](https://techforpalestine.org/learn-more) + +[![Build](../../actions/workflows/build.yml/badge.svg)](../../actions/workflows/build.yml) +[![Nightly](https://img.shields.io/badge/Nightly-nightly.link-purple)](https://nightly.link/moudey/Shell/workflows/build/main) + +# [Shell](https://nilesoft.org) +Powerful manager for Windows File Explorer context menu. +
+ +

+ +
+
+

+ +## Details +

+Shell is a context menu extender that lets you handpick the items to integrate into the Windows File Explorer context menu, create custom commands to access all your favorite web pages, files, and folders, and launch any application directly from the context menu.
+It also provides you a convenient solution to modify or remove any context menu item added by the system or third-party software. +

+ +Features +------------------ +* Lightweight, portable, and relatively easy to use. +* Fully customize the appearance. +* Adding new custom items such as (sub-menu, menu-items, and separator). +* Modify or remove items that already exist. +* Support all file system objects, including files, folders, desktop, and the taskbar. +* Support expressions syntax. with built-in functions and predefined variables. +* Support colors, glyphs, SVG, embedded icons, and image files such as .ico, .png or .bmp. +* Support search and filter. +* Support for complex nested menus. +* Support multiple columns. +* Quickly and easily configure file in plain text. +* Minimal resource usage. +* No limitations. + + +Requirements +------------------ + * Microsoft Windows 7/8/10/11 + + +Documentation +------------------ +Browse the [online documentation here.](https://nilesoft.org/docs) + +[Ask DeepWiki.com](https://deepwiki.com/moudey/Shell) + +Download +------------------ +Download the latest version: +https://nilesoft.org/download + +Screenshots +------------------ +

+
+
+
+
+
+ +
+
+

+ +Donate +------------------ +If you really love Shell and would like to see it continue to improve. + +[![Paypal](https://img.shields.io/badge/Donate-PayPal-blue.svg)](https://www.paypal.me/nilesoft) +[![BuyMeACoffee](https://img.shields.io/badge/Donate-BuyMeACoffee-yellow.svg)](https://www.buymeacoffee.com/moudey) + + diff --git a/README.wehub.md b/README.wehub.md new file mode 100644 index 0000000..3df79de --- /dev/null +++ b/README.wehub.md @@ -0,0 +1,7 @@ +# WeHub 来源说明 + +- 原始项目:`moudey/Shell` +- 原始仓库:https://github.com/moudey/Shell +- 导入方式:上游默认分支的最新快照 +- 原作者、版权和许可证信息以原始仓库及本仓库 LICENSE 为准 +- 本文件仅用于记录来源,不代表 WeHub 是原项目作者 diff --git a/docs/configuration/index.html b/docs/configuration/index.html new file mode 100644 index 0000000..a30e5d6 --- /dev/null +++ b/docs/configuration/index.html @@ -0,0 +1,202 @@ +

Syntax Rules for Configuration Files

+
+

This chapter describes the syntax rules for the configuration files.

+

The main configuration file shell.nss is located in the installation directory of + Shell, depending on your installation method. +

+ +
General rules
+ + +
+ Tip: When there is an error, it is recorded in the log file (shell.log, which is also located in + your installation directory.). +
+ +
shell.nss structure
+

The global section shell{} may have the following subsections:

+ +
Example
+
// variable declaration
+$variable-name = variable-value
+
+//image declaration
+@image-id = image-value
+	
+settings
+{
+	key-name = key-value
+	key-name = [key-value, key-value, ...]
+	...
+}
+
+theme
+{
+	key-name = key-value
+	...
+}
+
+// modify items
+modify ( property-name = property-value   ... )
+remove ( property-name = property-value   ... )
+
+// new items
+
+item ( property-name = property-value   ... )
+
+separator [( property-name = property-value   ... )]
+
+menu ( property-name = property-value   ... )
+{
+	$variable-name = variable-value
+	
+	item ( property-name = property-value   ... )
+	...
+}
+
+ +

Breaking Long Lines

+

For best readability, users often like to avoid lines longer than 80 characters. single + quotes also allow break up a line.

+
item(title='Command prompt'
+	cmd='cmd.exe')
+
+
+ +

Import tag

+

To better organise the configuration file, parts of the configuration can be saved in separate files. These are then + imported using the import tag. With this method, it is also possible to import the same file as a sort of "module" + into different parts of the configuration. A convenient way to include the same sub-menu in different + locations..

+
Syntax
+

The general syntax is as follows:

+
import %path%
+

Where

+ + +

There are effectively two different ways this tag is applied, depending on whether the optional + %section% is given:

+ + +
Import an entire section
+
// import an entire section
+import %path%
+
+In this case, the content of the file found at %path% will be imported into a newly + created section{}. +The result would then look like so: +
// import an entire section
+section {
+	/* content of the imported file goes here! Do not include
+	 *
+	 * section {
+	 * }
+	 *
+	 * in your imported file!
+	 */
+}
+

This syntax may be used only in the following places:

+ +
Import as a partial
+
section {
+	// some code might go here. Optional.
+
+	// import of a partial section
+	import %path%
+
+	// some more content might go here. Optional.
+}
+In this case, the content of the file found at %path% will be imported into the already + existing section{}. +The result would then look like so: +
section {
+	// some code might go here. Optional.
+
+	// import of a partial section
+	/* content of the imported file goes here! Do not include
+	 *
+	 * section {
+	 * }
+	 *
+	 * in your imported file!
+	 */
+
+	// some more content might go here. Optional.
+}
+

This syntax may be used nearly anywhere:

+ diff --git a/docs/configuration/modify-items.html b/docs/configuration/modify-items.html new file mode 100644 index 0000000..7ec4a04 --- /dev/null +++ b/docs/configuration/modify-items.html @@ -0,0 +1,62 @@ +

Modify Items

+
+

The optional modify section contains entries to modify existing context menu items, + added by the system or by a third party.

+ +
Sub-items
+

The section can have the following entry types, all of which are optional:

+ +
Example
+

In the following example, two instructions are defined:

+
modify(find = 'copy' image = #00ff00)
+modify(find = 'paste' image = #0000ff)
+remove(find = '"format"')
+
+

Item Entries

+

item entries contain the instructions on how to identify existing menuitems (also referred to as Target), and when and what changes should be applied + to them.

This is done by matching an existing menuitem's title property against the modify item's mandatory find property. If a match is found, the other properties of the modify + item are applied to the appropriate menuitem, such as changing their properties (e.g. title, icon, visibility), or moving them to another location.

+ +
Syntax
+
modify( find = value [property = value [...] ])
+
+
Properties
+

item entries can define three different sets of properties:

+
+
Validation Properties
+
Determine if a given item entry should be processed when a context menu is displayed. Optional. +
+
Filter Properties:
+
Determine if a given menuitem is a valid target + for the process instructions +
    +
  • find (mandatory)
    + Pattern used to identify targets by matching against their title property. +
  • +
  • in
    + Used to identify targets by specifying the submenu in which they are located. +
  • +
+
+
Process Instructions
+
Define what to do with the target. Optional. However, if there are no process instruction specified, the entry is of no practical use. For + further details refer to its separate section + below. +
+
+

For a complete overview and further details regarding applicable properties, please refer to the properties page.

+

Item Target

+

Item targets are menuitems of an existing context menu. Their properties or location can + be changed by applying the process instructions defined in a modify item.

+
Process instructions
+

Instructions that should be applied to the Target. Basically they consist of properties from the two property + classes menuitem properties and command properties.

+

Once a item is validated and a target identified, then these values are applied to the targeted + menuitem.

diff --git a/docs/configuration/new-items.html b/docs/configuration/new-items.html new file mode 100644 index 0000000..350cf5e --- /dev/null +++ b/docs/configuration/new-items.html @@ -0,0 +1,105 @@ +

New Items

+
+

Add new items to the context menu.

+
Sub-items
+

The section can have the following entry types, all of which are optional:

+ + +
Example
+

In the following example, one top-level item is created, that is + separated with a horizontal line from an adjacent sub-menu, which in turn has one sub-item + on its own:

+
item(title = 'Hello, World!')
+separator
+menu(title = 'sub menu' image = #0000ff)
+{
+	item(title = 'test sub-item')
+}
+
+ + + +

menuitem is an umbrella term for those entry types, that may appear in a + menu. These simply include the following:

+ + +
+

Items

+

items create a single menu entry.

+ +
Properties
+

Either a title or a image property is mandatory (set to a non-null value). For further details, + please refer to the properties page.

+ +
Syntax
+
item( title = value [property = value [...] ])
+
+ + + +

menu entries create a new sub-menu. They have properties + and sub-entries.

+ + +

Either a title or a image property is mandatory (set to a non-null value). For further details, + please refer to the properties page.

+ + +

menus can have the following entry types, all of which are + optional:

+ + + +
menu( title = value [property = value [...] ])
+{
+	[ item() [...] ]
+	[ menu(){} [...] ]
+	[ separator [...] ]
+	[ import 'path/to/import.nss' [...] ]
+}
+
+ +

Separators

+ +

separators create a horizontal line.

+ +
Properties
+

separators do not have any mandatory properties. Please refer to the properties page for further details.

+ +
Syntax
+
separator
+separator( property = value [property = value [...] ])
diff --git a/docs/configuration/properties.html b/docs/configuration/properties.html new file mode 100644 index 0000000..9a76a48 --- /dev/null +++ b/docs/configuration/properties.html @@ -0,0 +1,967 @@ +

Properties

+ +Shell supports the following properties classes: + +

Please also see the full index of available properties below.

+
Index
+ + +

Syntax

+
Entry types
+

In the following tables, the Types column shows to which entry types the + property applies to.

+

The following abbreviations are used (if set in bold, then the property is mandatory for the given type): +

+
+
mi
+
modify item, i.e. the + item + entry itself. Is basically required to evaluate if the process instructions are applied to any given target. +
+
mt
+
modify target, i.e. + the menuitem of the existing menu to which the process instructions are applied +
+
nm
+
new menu type
+
ni
+
new item type
+
ns
+
new separator type. +
+
+ + +
Validation Properties
+

Determine if a given Modify items + or New items entry should be + processed when a context menu is displayed.

+ +
+ +
+
+
+
Syntax
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypes(*)Summary
Wheremi, nm, ni, nsProcess given menuitem if true is returned. Allows the evaluation of arbitrary + expressions, e.g. if().
+ Default = true +
Modemi, nm, ni, nsDisplay menuitem by type of selection. The value has one of the following + parameters + (of type string): + + + + + + + + + + + + + + + + + + + + + +
noneDisplay menuitem when there is no selection.
singleDisplay menuitem when there is a single object selected.
multi_uniqueDisplay menuitem when multiple objects of the same type are selected. +
multi_singleDisplay menuitem when multiple files with a single file extension are selected.
multipleDisplay any type of selection, unless there is none.
+ Default = single +
Typemi, nm, ni, nsSpecifies the types of objects for which the menuitem will be displayed.
+ Possible values are shown below. Separate multiple types with the pipe character (|), + in + which case the menuitem is displayed if any of the given types is matched.
+ To exclude a given type, prefix its value with the tilde character (~). +

Expressions are not supported with this property.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
*Display menuitem when any type is selected.
FileDisplay menuitem when files are selected.
Directory(Dir)Display menuitem when directories are selected.
DriveDisplay menuitem when drives are selected.
USBDisplay menuitem when USB flash-drives are selected.
DVDDisplay menuitem when DVD-ROM drives are selected.
FixedDisplay menuitem when fixed drives are selected. Such drives have a fixed media; for + example, a hard disk drive or flash drive. +
VHDDisplay menuitem when Virtual Hard Disks are selected.
RemovableDisplay menuitem when the selected drives have removable media; for example, a floppy drive, + thumb drive, or flash card + reader. +
RemoteDisplay menuitem when the selected remote (network) drives are selected.
BackDisplay menuitem when the background of all types are selected (back). Or + specify one of + the following more granular types for the background: +
    +
  • + back.directory +
  • +
  • + back.drive, including +
      +
    • back.fixed
    • +
    • back.usb
    • +
    • back.dvd
    • +
    • back.vhd
    • +
    • back.Removable
    • +
    +
  • +
  • + back.namespace, including +
      +
    • back.computer
    • +
    • back.recyclebin
    • +
    +
  • +
+
DesktopDisplay menuitem when the Desktop is selected.
NamespaceDisplay menuitem when Namespaces are selected. Can be virtual objects such as My Network Places and Recycle Bin. +
ComputerDisplay menuitem when My Computer is selected.
RecyclebinDisplay menuitem when the Recycle bin is selected. +
TaskbarDisplay menuitem when the Taskbar is selected. +
+ Default = Accepts all types, except for the Taskbar. +
+
+ +
Filter Properties
+

For Modify items entries only, + filter properties determine if a given menuitem is a valid target for the process instructions

+ + + +
+
Syntax
+ + + + + + + + + + + + + + + + + + + + + + +
PropertyTypes(*)Summary
Findnm, ni, ns +
+
For modify items (required)
+
Apply the current item's process instructions to any existing menuitem if their title property matches the + pattern of the current item's find property. +
+
For dynamic items (optional)
+

Display the current menuitem if the pattern of its find property matches the + path name or path extension + of the selected files.

+

Default = null, which means any string is "matched". +

+
+ +
Syntax
+
+
find = '%pattern%'
+find = '%pattern%|%pattern%[...]'
+

where %pattern% can be one or + more + matching instructions (see Examples below). The + following characters do have special meaning:

+
    +
  • | Use to separate patterns. If any one pattern + matches, + the property yields + true. +
  • +
  • * Matches any number of characters. Is used as a + wildcard + to + match only the beginning or the end of the entire string (or word, if used in + combination with the exclamation mark !). +
  • +
  • ! Negates the match of the current pattern, or + limits + the wildcard (*) to one word only. +
  • +
  • "" the enclosed string is treated as a word. +
  • +
+

A word is a sequence of + alphanumerical characters that is confined to the left and to the right by either a + space + , a non-word character (e.g. / or -), or the + beginning or the end of the entire string, respectively.

+
Examples
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PatternMatches any string that ...Would matchWould not match
'foo'contains the literal string foo anywhere.foo, foobar, afoobarfo, f oo, bar
'"foo"'contains the literal string foo as a whole word + only. + foo, foo/bar, some foo barfoobar, foofoo, bar
'*foo'ends with the literal string foo.foo, barfoo, bar/foofoobar, fooo, foo
'foo*'starts with the literal string foo. + foo, foobar, foo/bar foobar, fo, yeti
'!foo'does not contain the literal string foo anywhere. + fobar, fo, kung-fufoo, foobar, barfoo/bar
'!"foo"'does not contain the word + foofobar, kung fu bar, foobarfoo, kung foo bar, bar/foo/bar
'!*foo'does not contain a word ending on + foofoobar, fooo-fofoo, foo bar, bar/foo
'foo*!'does not contain a word starting with + foomyFooBar, barFoofoo, foobar, fo-fooo
+


For dynamic items the following syntax allows to match against file + extensions:

+
PatternMatches any file extension ...Would matchWould not match
'.exe'equal to .exesetup.exe, notepad.exeinstall.bat, shell.nss, shell.ex_, + file + without an extension. +
'!.exe'not equal to .exesetup.exe.zip, video.mp4, shell.ex_, + file + without an extension. + setup.exe, shell.exe
'.exe|.dll'equal to either .exe or .dllshell.exe, shell.dll + shell.zip, shell.nss, file + without an extension. +
+
+
+
+
Inmi Specifies the existing submenu where the modify target is located.
+ Syntax
+
in = "New"
+in = "Sort By"
+
+
+ +
Menuitem Properties
+

This set of properties describe the appearance and location of a given menuitem. For modify-items, this is the target menuitem. For dynamic entries, this is the newly created menuitem.

+
+
Appearance
+
+ + +
+
Location
+
+ + +
+
+ +
+
Syntax
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypes(*)Summary
Titlest, nm, ni +

Sets the caption of the menuitem.

+
+
For modify-items (optional)
+

Default = null, which means the title of the target + is + not changed.

+
For dynamic items (required)
+

It is mandatory for menu and item entries, unless a image property is defined.

+
+
+
Visibility (vis)st, nm, ni, nsSets the visibility of a menuitem. Can have one of the following parameters: + + + + + + + + + + + + + + + + + + + + + +
HiddenHide the menuitem.
NormalEnable the menuitem.
DisableDisable the menuitem.
StaticDisplay menuitem as label, with or without an image
LabelDisplay menuitem as label without an image
+
+ Note: The values Static and Label are not available for modify-items. +
+ Default = Normal +
Separator (sep)st, nm, niAdd a separator to the menuitem: + + + + + + + + + + + + + + + + + +
NoneNot adding a separator with the menuitem.
Before, TopAdd a separator before the menuitem.
After, BottomAdd a separator after the menuitem.
BothAdd a separator before and after the menuitem.
+ Default = none +
Position (pos)st, nm, ni, nsThe position at which a menuitem should be inserted into the menu.
+ Position can have one of the following parameters: + + + + + + + + + + + + + + + + + + + + + +
AutoInsert the menuitem to the current position.
MiddleInsert the menuitem to the middle of the menu. +
TopInsert the menuitem to the top of the menu. +
BottomInsert the menuitem to the bottom of the menu. +
IntegerInsert the menuitem to a specified position.
+ Default = auto +
Image, Iconst, nm, niThe icon that appears in a menuitem. This property can be assigned as image files, + resource icons, glyph + or color. With one of the following parameters + + + + + + + + + + + + + + + + + + + + + + + + + +
nullShow menuitem without icon.
Inherit@*Inheriting the image from the parent.*@ + Inherits this property from its parent item. +
CmdAssign image from the command property.
GlyphAssign image as Glyph.
ColorAssign image as color.
PathAssign image from location path or resource icon.
+
+ Note:The value Cmd is not available for modify-items + targets. +
+ Default = null +
Parent, Menust, nm, ni, ns

Move current menuitem to another menu.

+ Default = null
Checkedst, niType of select option: + + + + + + + + + + + + + +
0Not checked
1Display as check mark.
2Display as radio bullet.
+ Default = 0 +
Defaultst, ni +

Specifies that the item is the default. A menu can contain only one default + menuitem, which is displayed in bold.

+ Default = false +
Expandednm +

Move all immediate menuitems to the parent menu.

+ Default = false +
Column(col)nm, ni

Create a new column.

+ Default = true +
Keysst, nm, ni

Show keyboard shortcuts.

+ Default = null
Tipst, nm, ni +

Show a tooltip for the current menu or item.

+ Default = null
+ Syntax
+
tip = "Lorem Ipsum is simply dummy text."
+tip = ["Lorem Ipsum is simply dummy text.", tip.info]
+tip = ["Lorem Ipsum is simply dummy text.", tip.info, 1.2]
+
+
+ +
Command Properties
+

This set of properties describe how a command is executed. Only available for dynamic items.

+ + + +
+
Syntax
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypes(*)Summary
Command (cmd)ni

The command associated with the menuitem. Occurs when the menuitem is clicked or + selected using a shortcut key or access key defined for the menuitem.

+ Default = null +
Arguments (arg, args)ni

The command line parameters to pass to the command property of a menuitem.

+ Default = null +
InvokeniSet execution type + + + + + + + + + +
0, singleexecute the command only once in total. The list of selected + items can be accessed with @sel +
1, multipleexecute the command once for every single item in the current + selection. The currently processed item can be accessed with e.g @sel.path.quote +
+ Default = 0 +
WindowniControls how the window of the executed command is to be shown. Can be one of the following + parameters: +

Hidden, Show, Visible, + Minimized, Maximized

+ Default = show +
Directory (dir)ni

Specifies the working directory to + execute + the command in.

+ Default = null +
Adminni

Execute the command + with administrative permissions.

+ Default = false +
VerbniSpecifies the default operation for the selected file. Value type string + and can have one of the following parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
nullSpecifies that the operation is the default for the selected file type.
OpenOpens a file or an application.
OpenAsOpener dialog when no program is associated to the extension.
RunAsIn Windows 7 and Vista, opens the UAC dialog andin others, open the Run as... Dialog.
EditOpens the default text editor for the file.
ExploreOpens the Windows Explorer in the folder specified in Directory.
PropertiesOpens the properties window of the file.
PrintStart printing the file with the default application.
FindStart a search.
+ Default = open +
Waitni +

Wait for the command + to complete.

+ Default = false +
+
diff --git a/docs/configuration/settings.html b/docs/configuration/settings.html new file mode 100644 index 0000000..cf76ec4 --- /dev/null +++ b/docs/configuration/settings.html @@ -0,0 +1,87 @@ +

Settings

+

+

Settings are containers for storing default values.

+
settings
+{
+	// show menu delay value from 0 to 4000
+	showdelay = 200
+
+	// Prevent interaction with these windows or processes
+	exclude
+	{
+		where = boolean value
+		window = window name
+		process = process name
+	}
+
+	tip = true
+	// or
+	tip
+	{
+		enabled = true
+
+		// normal = [background, text]
+		normal = [default, default]
+
+		// normal = [background, text]
+		primary = [#000, #fff]
+
+		// info = [background, text]
+		info = [#88f, #fff]
+
+		// success = [background, text]
+		success = [#8f8, #fff]
+
+		// warning = [background, text]
+		warning = [#ff8, #fff]
+
+		// danger = [background, text]
+		danger = [#f88, #fff]
+
+		// max width value from 200 to 2000
+		width = 400
+
+		// opacity value from 0 to 100
+		opacity = 100
+
+		// radius size value from 0 to 3
+		radius = 1
+
+		time = 1.5
+
+		padding = [8, 4]
+	}
+
+	// Disable/Enable modify items processing
+	modify
+	{
+		enabled = boolean value
+		image = [0 = disable, 1 = enable, 2 = auto reimage]
+
+		// Allow/disallow modification of title
+		title = boolean value
+
+		// Allow/disallow modification of visibility
+		visibility = boolean value
+
+		// Allow/disallow modification of parent
+		parent = boolean value
+
+		// Allow/disallow modification of position
+		position = boolean value
+
+		// Allow/disallow to add separator
+		separator = boolean value
+
+		// auto set image and group
+		auto = boolean value
+	}
+
+	// Disable/Enable new items processing
+	new
+	{
+		enabled = boolean value
+		// disable/enable image
+		image = boolean value
+	}
+}
diff --git a/docs/configuration/themes.html b/docs/configuration/themes.html new file mode 100644 index 0000000..ad637cd --- /dev/null +++ b/docs/configuration/themes.html @@ -0,0 +1,218 @@ +

Themes

+

+

Theme section to customize the layout and colors of the context menu.

+
theme
+{
+	// theme.name = auto, classic, white, black, or modern
+	name = "modern"
+
+	// view = auto, compact, small, medium, large, wide
+	view = view.compact
+
+	// dark = true, false, default
+	dark = default
+
+	background
+	{
+		color = color value
+		opacity = value from 0 to 100
+
+		// effect value 0 = disable, 1 = transparent, 2 = blur, 3 = acrylic
+		effect = auto
+
+		// for acrylic
+		effect = [3, tint color, opacity]
+
+		gradient
+		{
+			enabled = boolean value
+
+			// linear = [x1, x2, y1, y2]
+			linear = [0, 100, 0, 0]
+
+			// or radial = [cx, cy, r, fx, fy]
+			radial =[ 100, 100, 150, 100, 100]
+
+			// stop = [offset, stop-color]
+			stop = [0.5, color.accent, 20]
+
+			// or add more stop
+			stop = [
+				[offset, stop-color],
+				[offset, stop-color],
+				[offset, stop-color]
+			]
+		}
+	}
+
+	item
+	{
+		opacity = value from 0 to 100
+		radius = value from 0 to 3
+
+		// prefix value [auto, 0 = dont display,  1 = display, 2 = ignore]
+		prefix = 1
+
+		text
+		{
+			normal = color
+			normal.disabled = color
+			select = color
+			select.disabled = color
+		}
+
+		back
+		{
+			normal = color
+			normal.disabled = color
+			select = color
+			select.disabled = color
+		}
+
+		border
+		{
+			normal = color
+			normal.disabled = color
+			select = color
+			select.disabled = color
+		}
+
+		padding
+		{
+			left = value
+			top = value
+			right = value
+			bottom = value
+		}
+
+		margin
+		{
+			left = value
+			top = value
+			right = value
+			bottom = value
+		}
+	}
+
+	border
+	{
+		enabled = boolean value
+		size = value from 0 to 10
+		color =  = value
+		opacity = value
+		radius = value
+
+		padding
+		{
+			left = value
+			top = value
+			right = value
+			bottom = value
+		}
+	}
+
+	shadow
+	{
+		enabled = boolean value
+		size = value from 0 to 30
+		color = value
+		opacity = value from 0 to 100
+		offset = value from 0 to 30
+	}
+
+	font
+	{
+		size = value start from 6
+		name = "tahoma"
+		weight = value from 1 to 9
+		italic = 0
+	}
+
+	separator
+	{
+		size = value form 0 to 40
+		color = value
+		opacity = value
+
+		margin
+		{
+			left = value
+			top = value
+			right = value
+			bottom = value
+		}
+	}
+
+	symbol
+	{
+		normal = color
+		normal.disabled = color
+		select = color
+		select.disabled = color
+
+		// or
+		chevron
+		{
+			normal = color
+			normal.disabled = color
+			select = color
+			select.disabled = color
+		}
+
+		checkmark
+		{
+			normal = color
+			normal.disabled = color
+			select = color
+			select.disabled = color
+		}
+
+		bullet
+		{
+			normal = color
+			normal.disabled = color
+			select = color
+			select.disabled = color
+		}
+	}
+
+	image
+	{
+		enabled = boolean value
+
+		color = [color1, color2, color3]
+		gap = value
+		glyph = "font name" // font name for default glyph
+		scale = boolean value
+		align = value
+		[0= Display only the check mark,1 = Display only the image,2 = Display image & checkheck mark together]
+	}
+
+	layout
+	{
+		// Right-to-left layout display for Middle Eastern languages
+		rtl = boolean value
+
+		// Align submenus
+		popup = value from -20 to 20
+	}
+}
+

Padding and Margin value syntax

+

Use the padding shorthand property with four values:

+padding = [1, 2, 3, 4] +
left = 1
+right = 2
+top = 3
+bottom = 4
+

Use the padding shorthand property with two values:

+padding = [4, 2] +
left = 4
+right = 4
+top = 2
+bottom = 2
+

Use the padding shorthand property with one value:

+padding = 4 +
left = 4
+right = 4
+top = 4
+bottom = 4
diff --git a/docs/examples/copy-path.html b/docs/examples/copy-path.html new file mode 100644 index 0000000..5ab4ac1 --- /dev/null +++ b/docs/examples/copy-path.html @@ -0,0 +1,32 @@ +
Copy Path example
+
// type can set with '~taskbar' equals all file types except taskbar.
+menu(type='file|dir|back|root|namespace' mode="multiple"  title='copy to clipboard' image=#ff00ff)
+{
+	// Appears only when multiple selections.
+	item(vis=@(sel.count > 1) title='Copy path (@sel.count) items selected'
+			cmd=command.copy(sel(false, "\n")))
+
+	item(mode="single" title=sel.path 
+			cmd=command.copy(sel.path))
+
+	item(mode="single" type='file|dir|back.dir'
+			vis=sel.short.len!=sel.path.len title=sel.short
+			cmd=command.copy(sel.short))
+	separator
+	item(mode="single" vis=@(sel.parent.len>3) title=sel.parent 
+			cmd=command.copy(sel.parent))
+	separator
+	item(mode="single" type='file|dir|back.dir' title=sel.file.name
+			cmd=command.copy(sel.file.name))
+		   
+	item(mode="single" type='file' title=sel.file.title
+			cmd=command.copy(sel.file.title))
+
+	item(mode="single" type='file' title=sel.file.ext
+		   cmd=command.copy(sel.file.ext))
+}
+
+ + + +
diff --git a/docs/examples/favorites.html b/docs/examples/favorites.html new file mode 100644 index 0000000..e2e9f1c --- /dev/null +++ b/docs/examples/favorites.html @@ -0,0 +1,27 @@ +
Favorite applications and directories example
+
menu(type='desktop|taskbar' title='Favorites' image=#00ff00)
+{
+	menu(title='Applications' image=#ff0000)
+	{
+		item(title='Command prompt' image cmd='cmd.exe')
+		item(title='PowerShell' image cmd='powershell.exe')
+		item(title='Registry editor' image cmd='regedit.exe')
+		separator
+		item(title='Paint' image cmd='mspaint.exe')
+		item(title='Notepad' image cmd='notepad.exe')
+	}
+	separator
+	menu(title='Directories' image=#0000ff)
+	{
+		item(title='Downloads' cmd=user.downloads)
+		item(title='Pictures' cmd=user.pictures)
+		item(title='Home' cmd=user.directory)
+		separator
+		item(title='Windows' cmd=sys.directory)
+		item(title='Program files' cmd=sys.prog())
+	}
+}
+
+ + +
diff --git a/docs/examples/goto.html b/docs/examples/goto.html new file mode 100644 index 0000000..095bb74 --- /dev/null +++ b/docs/examples/goto.html @@ -0,0 +1,53 @@ +
Goto example
+
menu(mode="multiple" title='Goto' sep="both" image= \uE14A)
+{
+	menu(title='Folder' image=\uE1F4)
+	{
+		item(title='Windows' image=inherit cmd=sys.dir)
+		item(title='System' image=inherit cmd=sys.bin)
+		item(title='Program Files' image=inherit cmd=sys.prog)
+		item(title='Program Files x86' image=inherit cmd=sys.prog32)
+		item(title='ProgramData' image=inherit cmd=sys.programdata)
+		item(title='Applications' image=inherit cmd='shell:appsfolder')
+		item(title='Users' image=inherit cmd=sys.users)
+		separator
+		item(title='Desktop' image=inherit cmd=user.desktop)
+		item(title='Downloads' image=inherit cmd=user.downloads)
+		item(title='Pictures' image=inherit cmd=user.pictures)
+		item(title='Documents' image=inherit cmd=user.documents)
+		item(title='Startmenu' image=inherit cmd=user.startmenu)
+		item(title='Profile' image=inherit cmd=user.dir)
+		item(title='AppData' image=inherit cmd=user.appdata)
+		item(title='Temp' image=inherit cmd=user.temp)
+	}
+	
+	item(title=title.control_panel image=\uE0F3 cmd='shell:::{5399E694-6CE5-4D6C-8FCE-1D8870FDCBA0}')
+	item(title='All Control Panel Items' image=\uE0F3 cmd='shell:::{ED7BA470-8E54-465E-825C-99712043E01C}')
+	item(title=title.run image=\uE14B cmd='shell:::{2559a1f3-21d7-11d4-bdaf-00c04f60b9f0}')
+   
+	menu(title=title.settings sep="before" image=id.settings.icon)
+	{
+		// https://docs.microsoft.com/en-us/windows/uwp/launch-resume/launch-settings-app
+		item(title='systeminfo' image=inherit cmd arg='/K systeminfo')
+		item(title='search' cmd='search-ms:' image=inherit)
+		item(title='settings' image=inherit cmd='ms-settings:')
+		item(title='about' image=inherit cmd='ms-settings:about')
+		item(title='usb' image=inherit cmd='ms-settings:usb')
+		item(title='network-status' image=inherit cmd='ms-settings:network-status')
+		item(title='network-ethernet' image=inherit cmd='ms-settings:network-ethernet')
+		item(title='personalization-background' image=inherit cmd='ms-settings:personalization-background')
+		item(title='personalization-colors' image=inherit cmd='ms-settings:colors')
+		item(title='lockscreen' image=\uE0F3 cmd='ms-settings:lockscreen')
+		item(title='personalization-start' image=inherit cmd='ms-settings:personalization-start')
+		item(title='appsfeatures' image=inherit cmd='ms-settings:appsfeatures')
+		item(title='optionalfeatures' image=inherit cmd='ms-settings:optionalfeatures')
+		item(title='defaultapps' image=inherit cmd='ms-settings:defaultapps')
+		item(title='yourinfo' image=inherit cmd='ms-settings:yourinfo')
+		item(title='windowsupdate' image=inherit cmd='ms-settings:windowsupdate')
+		item(title='windowsdefender' image=inherit cmd='ms-settings:windowsdefender')
+		item(title='network connections' image=inherit cmd='shell:::{7007ACC7-3202-11D1-AAD2-00805FC1270E}')
+	}
+}
+
+ +
diff --git a/docs/examples/index.html b/docs/examples/index.html new file mode 100644 index 0000000..5b34acf --- /dev/null +++ b/docs/examples/index.html @@ -0,0 +1,2 @@ +

Examples


+

This page contains some examples of what Shell can do.

\ No newline at end of file diff --git a/docs/examples/taskbar.html b/docs/examples/taskbar.html new file mode 100644 index 0000000..74a3671 --- /dev/null +++ b/docs/examples/taskbar.html @@ -0,0 +1,13 @@ +
Taskbar example
+
$hello_world = 'Hello World!'
+
+item(title=hello_world cmd=msg(hello_world))
+separator
+item(title='Command prompt' cmd args='/k echo @hello_world')
+separator
+menu(title='Sub menu')
+{
+  item(title='Open Paint' cmd='paint.exe' arg=sel.path)
+  separator
+  item(title='Open Notepad' cmd='notepad.exe' arg='"@sel.path"')
+}
\ No newline at end of file diff --git a/docs/expressions/color.html b/docs/expressions/color.html new file mode 100644 index 0000000..4d18b77 --- /dev/null +++ b/docs/expressions/color.html @@ -0,0 +1,5 @@ +

Color literal

+
+
Hexadecimal Colors
+

interprets color constants as hexadecimal if they are preceded by # and hexadecimal color is specified with: +#RRGGBB or #RRGGBBAA, where the RR (red), GG (green) and BB (blue)and AA (alpha) hexadecimal integers specify the components of the color. All values must be between 00 and FF.
For example, the #0000FF value is rendered as blue, because the blue component is set to its highest value (FF) and the others are set to 00.
There are 140 color names are predefined under the color scope.

\ No newline at end of file diff --git a/docs/expressions/comments.html b/docs/expressions/comments.html new file mode 100644 index 0000000..bc3d1b3 --- /dev/null +++ b/docs/expressions/comments.html @@ -0,0 +1,44 @@ +

Comments

+

Comments can be used to explain Shell code, and to make it more readable. It can also be used to prevent execution Shell code. Comments can be singled-lined or multi-lined.

+
+
Single-line Comments
+

+ Single-line comments start with two forward slashes (//).
+ Any text between // and the end of the line is ignored (will not be executed). +

+

This example uses a single-line comment before a line of code:

+
dynamic 
+{
+	// This is a comment
+	item(title='Hello World!')
+	
+	//item(title='Hello World!')
+}
+ +

This example uses a single-line comment at the end of a line of code:

+
dynamic 
+{
+    item(title='Hello World!') // This is a comment
+}
+
+
+
+
Multi-line Comments
+

+ Multi-line comments start with /* and ends with */.
+ Any text between /* and */ will be ignored. +

+
dynamic
+{
+	item(title='Hello,/* multiple-lines comment inside */ world')
+	
+	/*
+	item(title='test item 1')
+	item(title='test item 2')
+	*/
+}
+

+ Single or multi-line comments?
+ It is up to you which you want to use. Normally, we use // for short comments, and /* */ for longer. +

+
\ No newline at end of file diff --git a/docs/expressions/identifier.html b/docs/expressions/identifier.html new file mode 100644 index 0000000..064c530 --- /dev/null +++ b/docs/expressions/identifier.html @@ -0,0 +1,6 @@ +

Identifier

+
+

The identifier have unique titles described by fully qualified names that indicate a logical hierarchy.
The identifier that has no parameters. Parentheses are added when necessary to separate:

+

There is a hierarchy of keywords in that some keywords are always followed by others.

+
sel.path
+sel.path().ext
diff --git a/docs/expressions/index.html b/docs/expressions/index.html new file mode 100644 index 0000000..4bfb5f7 --- /dev/null +++ b/docs/expressions/index.html @@ -0,0 +1,12 @@ +

Expressions

+
+

Shell provides a variety of statements and expressions. Most of these will be familiar to developers who have programmed in Java script, C, C++, C#.

+

Expressions gives you all the power of Shell, but is using a simplified syntax that's easier to learn if you're a beginner, and makes you more productive if you're an expert.

+

To use expressions, you write them by using proper syntax. Syntax is the set of rules by which the words and symbols in an expression are correctly combined. Initially, expressions in Shell are a little bit hard to read. But with a good understanding of expression syntax and a little practice, it becomes much easier.

+ + diff --git a/docs/expressions/numeric.html b/docs/expressions/numeric.html new file mode 100644 index 0000000..a0a03a3 --- /dev/null +++ b/docs/expressions/numeric.html @@ -0,0 +1,21 @@ +

Numeric literals

+
+

There are two types of numbers. Integer and floating point.

+
Integer literals
+

An integer is a numeric literal(associated with numbers) without any fractional or exponential part. There are two types of integer literals:

+
    +
  1. Decimal literal (base 10)
  2. +
  3. Hexadecimal literal (base 16)
  4. +
+

1. Decimal-literal(base 10):
A non-zero decimal digit followed by zero or more decimal digits(0, 1, 2, 3, 4, 5, 6, 7, 8, 9).

+For example:
Decimal: 0, -9, 22 etc
+

2. Hexadecimal-literal(base 16):
0x followed by one or more hexadecimal digits(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f).

+For example: +
Hexadecimal: 0x7f, 0x2a, 0x521 etc
+
Floating-point iterals
+ +

Floating-point literals specify values that must have a fractional part. These values contain decimal points (.)

+For example: +
-2.0
0.0000234
+ + diff --git a/docs/expressions/operators.html b/docs/expressions/operators.html new file mode 100644 index 0000000..8f613a8 --- /dev/null +++ b/docs/expressions/operators.html @@ -0,0 +1,187 @@ +

Operators

+
+

An operator is a symbol that tells to perform specific mathematical or logical manipulations. Shell is rich in built-in operators and provide the following types of operators

+

This chapter will examine the arithmetic, relational, logical, bitwise, assignment and other operators one by one.

+
Arithmetic Operators
+

The five arithmetical operations supported

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperatorDescription
+Addition
-Subtraction
*Multiplication
/Division
%Modulo
+
+
Relational and comparison operators
+

Two expressions can be compared using relational and equality operators. For example, to know if two values are equal or if one is greater than the other.

+

The result of such an operation is either true or false (i.e., a Boolean value).

+

The relational operators are:

+ + + + + + + + + + + + + + + + + + + + + + + + +
operatordescription
==Equal to
!=Not equal to
<Less than
>Greater than
<=Less than or equal to
>=Greater than or equal to
+
+
Logical Operators (!, ||, &&)
+

The operator ! is operator for the Boolean operation NOT. It has only one operand, to its right, and inverts it, producing false if its operand is true, and true if its operand is false. Basically, it returns the opposite Boolean value of evaluating its operand. For example:

+

The logical operators && and || are used when evaluating two expressions to obtain a single relational result. The operator && corresponds to the Boolean logical operation AND, which yields true if both its operands are true, and false otherwise. The following panel shows the result of operator && evaluating the expression a && b:

+ + + + + + + + + + + + + + + + + + + +
operatordescription
&&Called Logical AND operator. If both the operands are non-zero, then condition becomes true.
||Called Logical OR Operator. If any of the two operands is non-zero, then condition becomes true.
! + Called Logical NOT Operator. Use to reverses the logical state of its operand. If a condition is true, then Logical NOT operator will make false. +
!(5 == 5)   // evaluates to false because the expression at its right (5 == 5) is true
+!(6 <= 4)   // evaluates to true because (6 <= 4) would be false
+!true       // evaluates to false
+!false      // evaluates to true
+
+
+
Conditional ternary operator
+

The conditional operator evaluates an expression, returning one value if that expression evaluates to true, and a different one if the expression evaluates as false. Its syntax is:

+
condition ? result1 : result2
+

If condition is true, the entire expression evaluates to result1, and otherwise to result2.

+
7==5 ? 4 : 3     // evaluates to 3, since 7 is not equal to 5.
+7==5+2 ? 4 : 3   // evaluates to 4, since 7 is equal to 5+2.
+5>3 ? a : b      // evaluates to the value of a, since 5 is greater than 3.
+a>b ? a : b      // evaluates to whichever is greater, a or b.
+ +
Bitwise Operators
+

Bitwise operators modify variables considering the bit patterns that represent the values they store.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperatorDescription
&Bitwise AND
|Bitwise inclusive OR
^Bitwise exclusive OR
~Unary complement (bit inversion)
<<Shift bits left
>>Shift bits right
+
Precedence of operators
+

A single expression may have multiple operators. For example:

+
x = 5 + 7 % 2
+

the above expression always assigns 6 to variable x, because the % operator has a higher precedence than the + operator, and is always evaluated before. Parts of the expressions can be enclosed in parenthesis to override this precedence order, or to make explicitly clear the intended effect. Notice the difference:

+
x = 5 + (7 % 2)    // x = 6 (same as without parenthesis)
+x = (5 + 7) % 2    // x = 0
+

From greatest to smallest priority, Operators are evaluated in the following order:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LevelPrecedence groupOperatorDescriptionGrouping
1Postfix (unary)++ --postfix increment / decrementLeft-to-right
()functional forms
[]subscript
.member access
2Prefix (unary)++ --prefix increment / decrementRight-to-left
~ !bitwise NOT / logical NOT
+ -unary prefix
4Arithmetic: scaling* / %multiply, divide, moduloLeft-to-right
5Arithmetic: addition+ -addition, subtractionLeft-to-right
6Bitwise shift<< >>shift left, shift rightLeft-to-right
7Relational< > <= >=comparison operatorsLeft-to-right
8Equality== !=equality / inequalityLeft-to-right
9And&bitwise ANDLeft-to-right
10Exclusive or^bitwise XORLeft-to-right
11Inclusive or|bitwise ORLeft-to-right
12Conjunction&&logical ANDLeft-to-right
13Disjunction||logical ORLeft-to-right
15Assignment-level expressions=assignmentRight-to-left
?:conditional operator
16Sequencing,comma separatorLeft-to-right
+

+ When an expression has two operators with the same precedence level, grouping determines which one is evaluated first: either left-to-right or right-to-left.
+ Enclosing all sub-statements in parentheses (even those unnecessary because of their precedence) improves code readability. +

\ No newline at end of file diff --git a/docs/expressions/string.html b/docs/expressions/string.html new file mode 100644 index 0000000..349b90e --- /dev/null +++ b/docs/expressions/string.html @@ -0,0 +1,37 @@ +

String literal

+
+

string is zero or more characters written inside single or double quotes.

+

You can use quotes inside a string, as long as they don't match the quotes surrounding the string:

+
$var1 = "It's alright"
+$var2 = "He is called 'Johnny'"
+$var3 = 'He is called "Johnny"'
+
+
Single quotes
+
+

single quotes allow you to use the syntax of expressions within them.
The @ sign must be placed before the expressions.

+
item(title = 'windows dir path: @sys.dir')
+
+
Double quotes
+
+

double quotes allow you to use the Escape Character inside them only.
The backslash (\) escape character turns special characters into characters.
The sequence \" inserts a double quote in a string:

+
$var1 = "hello\"world"
+// result: hello"world
+

The complete set of escape sequences is as follows:

+ + + + + + + + + + + + + + + + + +
\'Single quote
\"Double quote
\\Backslash
\0Null
\aAlert
\bBackspace
\fForm Feed
\nNew Line
\rCarriage Return
\tHorizontal Tab
\vVertical Tab
\uxxxxUnicode escape sequence (UTF-16) \uHHHH (range: 0000 - FFFF)
\xnnnnUnicode escape sequence for character with hex value nnnn (variable length version of \uxxxx)
\UxxxxxxxxUnicode escape sequence (UTF-32) \U00HHHHHH (range: 000000 - 10FFFF)
diff --git a/docs/expressions/variables.html b/docs/expressions/variables.html new file mode 100644 index 0000000..736b443 --- /dev/null +++ b/docs/expressions/variables.html @@ -0,0 +1,33 @@ +

Variables

+
+

Variables are containers for storing data values.

+ +

The general rules for constructing names for variables (unique identifiers) are:

+ +

+ All variables must be identified with unique names.
+ These unique names are called identifiers. + Identifiers can be short names (like x and y) or more descriptive names (age, sum, totalVolume). +

+

Note: It is recommended to use descriptive names in order to create understandable and maintainable code

+
Example
+
$hello_world = 'Hello World!'
+$test_add1 = 5 + 6
+
+item(title = hello_world cmd = msg(hello_world))
+
+menu(title = test_add1)
+{
+	$test_sub1 = 11 - 5
+	item(title = test_sub1)
+}
+ diff --git a/docs/functions/app.html b/docs/functions/app.html new file mode 100644 index 0000000..c174667 --- /dev/null +++ b/docs/functions/app.html @@ -0,0 +1,86 @@ +
APP
+
+

The namespace of the application contains file paths, version and some details.

+
+
+
app.directory
+

Returns the path of Shell directory.

+

Syntax

+
app.directory     // usage in section context
+'@app.directory'  // usage inside quoted-string literals
+
+ +
+
app.cfg
+

Returns the path of the configuration file shell.nss (or shell.shl + in older installations).

+

Syntax

+
app.cfg     // usage in section context
+'@app.cfg'  // usage inside quoted-string literals
+
+ +
+
app.dll
+

Returns the path of shell.dll.

+

Syntax

+
app.dll     // usage in section context
+'@app.dll'  // usage inside quoted-string literals
+
+ +
+
app.exe
+

Returns the path of shell.exe.

+

Syntax

+
app.exe     // usage in section context
+'@app.exe'  // usage inside quoted-string literals
+
+ +
+
app.name
+

Returns application name.

+

Syntax

+
app.name     // usage in section context
+'@app.name'  // usage inside quoted-string literals
+
+ +
+
app.version
+

Returns Shell version.

+

Syntax

+
app.version     // usage in section context
+'@app.version'  // usage inside quoted-string literals
+
+ +
+
app.is64
+

Returns the architecture of the application.

+

Syntax

+
app.is64     // usage in section context
+'@app.is64'  // usage inside quoted-string literals
+
+ +
+
app.about
+

Returns Shell information.

+

Syntax

+
app.about     // usage in section context
+'@app.about'  // usage inside quoted-string literals
+
+ +
+
app.reload
+

Reload the configuration file. +

+

Syntax

+
app.reload     // usage in section context
+'@app.reload'  // usage inside quoted-string literals
+
+ +
+
app.unload
+

Unload the configuration file. +

+

Syntax

+
app.unload     // usage in section context
+'@app.unload'  // usage inside quoted-string literals
+
diff --git a/docs/functions/appx.html b/docs/functions/appx.html new file mode 100644 index 0000000..38b07a1 --- /dev/null +++ b/docs/functions/appx.html @@ -0,0 +1,104 @@ +

APPX

+
+
+
appx or appx.path
+

Returns the path of Package.

+

Syntax

+ appx(packageName)
+ appx.path(packageName)
+

Parameters

+
+
packageName
+
can be passed in full name or part of name.
+
+

Example

+
appx.path("WindowsTerminal")
+// result:
+// C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.11.3471.0_x64__8wekyb3d8bbwe
+
+
+ +
+
appx.name
+

Returns the display name of the Package.

+

Syntax

+ appx.name(packageName) +

Parameters

+
+
packageName
+
can be passed in full name or part of name.
+
+

Example

+
appx.name("WindowsTerminal")
+// result:
+// Windows Terminal
+
+
+ +
+
appx.id
+

Returns the full name of the Package.

+

Syntax

+ appx.id(packageName) +

Parameters

+
+
packageName
+
can be passed in full name or part of name.
+
+

Example

+
appx.id("WindowsTerminal")
+// result:
+// Microsoft.WindowsTerminal_1.11.3471.0_x64__8wekyb3d8bbwe
+
+
+ +
+
appx.family
+

Returns the family name of the Package.

+

Syntax

+ appx.family(packageName) +

Parameters

+
+
packageName
+
can be passed in full name or part of name.
+
+

Example

+
appx.family("WindowsTerminal")
+// result:
+// Microsoft.WindowsTerminal_8wekyb3d8bbwe
+
+
+ +
+
appx.version
+

Returns version of the Package.

+

Syntax

+ appx.version(packageName) +

Parameters

+
+
packageName
+
can be passed in full name or part of name.
+
+

Example

+
appx.version("WindowsTerminal")
+// result:
+// 1.11.3471.0
+
+
+ +
+
appx.shell
+

Return package settings to run.

+

Syntax

+ appx.shell(packageName) +

Parameters

+
+
packageName
+
can be passed in full name or part of name.
+
+

Example

+
appx.shell("WindowsTerminal")
+// result:
+// shell:appsFolder\Microsoft.WindowsTerminal_8wekyb3d8bbwe!App
+
+
diff --git a/docs/functions/clipboard.html b/docs/functions/clipboard.html new file mode 100644 index 0000000..39b2cf0 --- /dev/null +++ b/docs/functions/clipboard.html @@ -0,0 +1,39 @@ +
CLIPBOARD
+
+

Clipboard handling functions.

+
+ +
+
clipboard.get
+

Returns the value of the stored clipboard.

+

Syntax

+ clipboard.get +
+ +
+
clipboard.set
+

Store a value in the clipboard.

+

Syntax

+ clipboard.set("Hello world!") +
+ +
+
clipboard.length
+

Returns the length of the value stored in the clipboard.

+

Syntax

+ clipboard.length +
+ +
+
clipboard.is_empty
+

Verifies that there is a value stored in the clipboard.

+

Syntax

+ clipboard.is_empty +
+ +
+
clipboard.empty
+

Empty values stored in the clipboard.

+

Syntax

+ clipboard.empty +
diff --git a/docs/functions/color.html b/docs/functions/color.html new file mode 100644 index 0000000..d9fb2bb --- /dev/null +++ b/docs/functions/color.html @@ -0,0 +1,173 @@ +
COLOR
+
+

Color namespace contains predefined colors

+
+
+color.aliceblue
+color.antiquewhite
+color.aqua
+color.aquamarine
+color.azure
+color.beige
+color.bisque
+color.black
+color.blanchedalmond
+color.blue
+color.blueviolet
+color.brown
+color.burlywood
+color.cadetblue
+color.chartreuse
+color.chocolate
+color.coral
+color.cornflowerblue
+color.cornsilk
+color.crimson
+color.cyan
+color.darkblue
+color.darkcyan
+color.darkgoldenrod
+color.darkgray
+color.darkgreen
+color.darkkhaki
+color.darkmagenta
+color.darkolivegreen
+color.darkorange
+color.darkorchid
+color.darkred
+color.darksalmon
+color.darkseagreen
+color.darkslateblue
+color.darkslategray
+color.darkturquoise
+color.darkviolet
+color.deeppink
+color.deepskyblue
+color.dimgray
+color.dodgerblue
+color.firebrick
+color.floralwhite
+color.forestgreen
+color.fuchsia
+color.gainsboro
+color.ghostwhite
+color.gold
+color.goldenrod
+color.gray
+color.green
+color.greenyellow
+color.honeydew
+color.hotpink
+color.indianred
+color.indigo
+color.ivory
+color.khaki
+color.lavender
+color.lavenderblush
+color.lawngreen
+color.lemonchiffon
+color.lightblue
+color.lightcoral
+color.lightcyan
+color.lightgoldenrodyellow
+color.lightgray
+color.lightgreen
+color.lightpink
+color.lightsalmon
+color.lightseagreen
+color.lightskyblue
+color.lightslategray
+color.lightsteelblue
+color.lightyellow
+color.lime
+color.limegreen
+color.linen
+color.magenta
+color.maroon
+color.mediumaquamarine
+color.mediumblue
+color.mediumorchid
+color.mediumpurple
+color.mediumseagreen
+color.mediumslateblue
+color.mediumspringgreen
+color.mediumturquoise
+color.mediumvioletred
+color.midnightblue
+color.mintcream
+color.mistyrose
+color.moccasin
+color.navajowhite
+color.navy
+color.oldlace
+color.olive
+color.olivedrab
+color.orange
+color.orangered
+color.orchid
+color.palegoldenrod
+color.palegreen
+color.paleturquoise
+color.palevioletred
+color.papayawhip
+color.peachpuff
+color.peru
+color.pink
+color.plum
+color.powderblue
+color.purple
+color.red
+color.rosybrown
+color.royalblue
+color.saddlebrown
+color.salmon
+color.sandybrown
+color.seagreen
+color.seashell
+color.sienna
+color.silver
+color.skyblue
+color.slateblue
+color.slategray
+color.snow
+color.springgreen
+color.steelblue
+color.tan
+color.teal
+color.thistle
+color.tomato
+color.transparent
+color.turquoise
+color.violet
+color.wheat
+color.white
+color.whitesmoke
+color.yellow
+color.yellowgreen
+
+
+
color.rgb(red, green, blue)
+
+
color.box
+
color.box(#ff0000)
+
+
color.random or color.random(min, max)
+
color.random
+color.random(0x808080, 0xf0f0f0)
+
+
+
+color.default
+color.invert
+color.accent
+color.accent_light1
+color.accent_light2
+color.accent_light3
+color.accent_dark1
+color.accent_dark2
+color.accent_dark3
+color.opacity
+color.lighten
+color.darken
+color.rgba
+
diff --git a/docs/functions/command.html b/docs/functions/command.html new file mode 100644 index 0000000..0ad0ba3 --- /dev/null +++ b/docs/functions/command.html @@ -0,0 +1,55 @@ +
COMMAND
+
+
command.copy, command.copy_to_clipboard
+

copy to parameter clipboard.

+

Syntax

+ command.copy('string copy to clipboard') +
+ +
+
command.sleep(milliseconds)
+

Suspends the execution of the current thread until the time-out interval elapses.

+

Syntax

+ command.sleep(1000) +
+ +
+
command.random
+

Suspends the execution of the current thread until the time-out interval elapses.

+

Syntax

+ command.random(min value, max value) +
+ +
+
command.navigate
+

Opens a folder in the same explorer window.

+

Syntax

+ command.navigate(path) +
+ +
+
command.cascade_windows
+command.copy_to_folder
+command.customize_this_folder
+command.find
+command.folder_options
+command.invert_selection
+command.minimize_all_windows
+command.move_to_folder
+command.redo
+command.refresh
+command.restart_explorer
+command.restore_all_windows
+command.run
+command.search
+command.select_all
+command.select_none
+command.show_windows_side_by_side
+command.show_windows_stacked
+command.switcher
+command.toggle_desktop
+command.toggleext
+command.togglehidden
+command.undo
+
+
diff --git a/docs/functions/id.html b/docs/functions/id.html new file mode 100644 index 0000000..7c7dbd0 --- /dev/null +++ b/docs/functions/id.html @@ -0,0 +1,175 @@ +
ID
+

The namespace of the id contains the identifiers for most of the system context menus items where the item's title or + icons can be returned

+
+
+
Syntax
+ id.copy
+ id.copy.title
+ id.copy.icon or icon.copy +
+ +
+
List
+
id.add_a_network_location
+id.adjust_date_time
+id.align_icons_to_grid
+id.arrange_by
+id.auto_arrange_icons
+id.autoplay
+id.cancel
+id.cascade_windows
+id.cast_to_device
+id.cleanup
+id.collapse
+id.collapse_all_groups
+id.collapse_group
+id.command_prompt
+id.compressed
+id.configure
+id.content
+id.control_panel
+id.copy
+id.copy_as_path
+id.copy_here
+id.copy_path
+id.copy_to
+id.copy_to_folder
+id.cortana
+id.create_shortcut
+id.create_shortcuts
+id.create_shortcuts_here
+id.customize_notification_icons
+id.customize_this_folder
+id.cut
+id.delete
+id.desktop
+id.details
+id.device_manager
+id.disconnect
+id.disconnect_network_drive
+id.display_settings
+id.edit
+id.eject
+id.empty_recycle_bin
+id.erase_this_disc
+id.exit_explorer
+id.expand
+id.expand_all_groups
+id.expand_group
+id.expand_to_current_folder
+id.extra_large_icons
+id.extract_all
+id.extract_to
+id.file_explorer
+id.folder_options
+id.format
+id.give_access_to
+id.group_by
+id.include_in_library
+id.insert_unicode_control_character
+id.install
+id.large_icons
+id.list
+id.lock_all_taskbars
+id.lock_the_taskbar
+id.make_available_offline
+id.make_available_online
+id.manage
+id.map_as_drive
+id.map_network_drive
+id.medium_icons
+id.merge
+id.more_options
+id.mount
+id.move_here
+id.move_to
+id.move_to_folder
+id.new
+id.new_folder
+id.new_item
+id.news_and_interests
+id.next_desktop_background
+id.open
+id.open_as_portable
+id.open_autoplay
+id.open_command_prompt
+id.open_command_window_here
+id.open_file_location
+id.open_folder_location
+id.open_in_new_process
+id.open_in_new_tab
+id.open_in_new_window
+id.open_new_tab
+id.open_new_window
+id.open_powershell_window_here
+id.open_windows_powershell
+id.open_with
+id.options
+id.paste
+id.paste_shortcut
+id.personalize
+id.pin_current_folder_to_quick_access
+id.pin_to_quick_access
+id.pin_to_start
+id.pin_to_taskbar
+id.play
+id.play_with_windows_media_player
+id.power_options
+id.preview
+id.print
+id.properties
+id.reconversion
+id.redo
+id.refresh
+id.remove_from_quick_access
+id.remove_properties
+id.rename
+id.restore
+id.restore_default_libraries
+id.restore_previous_versions
+id.rotate_left
+id.rotate_right
+id.run
+id.run_as_administrator
+id.run_as_another_user
+id.search
+id.select_all
+id.send_to
+id.set_as_desktop_background
+id.set_as_desktop_wallpaper
+id.settings
+id.share
+id.share_with
+id.shield
+id.show_all_folders
+id.show_cortana_button
+id.show_desktop_icons
+id.show_file_extensions
+id.show_hidden_files
+id.show_libraries
+id.show_network
+id.show_pen_button
+id.show_people_on_the_taskbar
+id.show_task_view_button
+id.show_the_desktop
+id.show_this_pc
+id.show_touch_keyboard_button
+id.show_touchpad_button
+id.show_windows_side_by_side
+id.show_windows_stacked
+id.small_icons
+id.sort_by
+id.store
+id.task_manager
+id.taskbar_settings
+id.tiles
+id.troubleshoot_compatibility
+id.turn_off_bitlocker
+id.turn_on_bitlocker
+id.undo
+id.unpin_from_quick_access
+id.unpin_from_start
+id.unpin_from_taskbar
+id.view
+
diff --git a/docs/functions/image.html b/docs/functions/image.html new file mode 100644 index 0000000..0562883 --- /dev/null +++ b/docs/functions/image.html @@ -0,0 +1,81 @@ +
IMAGE (ICON)
+

The image namespace contains functions that return an icon and are only assigned to the image property +

+
+
image.glyph
+

Return font icon with color and size option.

+

Syntax

+ image.glyph(0xE00B)
+ image.glyph(\uE00B)
+ image.glyph("\uE00B")
+ image.glyph("\xE00B")
+
+ image.glyph(0xE00B, #0000ff)
+ image.glyph(0xE00B, #0000ff, 10)
+ image.glyph(0xE00B, #0000ff, 12, "Segoe MDL2 Assets")
+
+
+
image.res
+

Returns an icon through a path or through resources.

+

Syntax

+ image.res(path)
+ image.res(path, index)
+ image.res(path, -id)
+
+ image(path)
+ image(path, index)
+ image(path, -id)
+
+
+
image.svg, image.svgf
+

Returns an svg image via a string or from a file path.

+

Syntax

+ image.svg('<svg viewBox="0 0 100 100"><path fill="red" d="M0 0 L 100 0 L50 + 100 Z"/></svg>')
+ image.svgf(path)
+
+
+
image.rect
+

Returns a colored rectangle icon of an optional size.

+

Syntax

+ image.rect(#0000ff)
+ image.rect(#0000ff, 10)
+
+ +
+
image.segoe
+

Returns a glyph from "Segoe Fluent Icons" if present then "Segoe MDL2 Assets".

+

Syntax

+ image.segoe(\uxxxx)
+ image.segoe(\uxxxx, 10)
+
+ +
+
image.fluent
+

Returns a glyph from "Segoe Fluent Icons" with optional size.

+

Syntax

+ image.fluent(\uxxxx)
+ image.fluent(\uxxxx, 10)
+
+ +
+
image.mdl
+

Returns a glyph from "Segoe MDL2 Assets" with optional size.

+

Syntax

+ image.mdl(\uxxxx)
+ image.mdl(\uxxxx, 10)
+
+ +
+
image.default
+

+

Syntax

+ image.default +
+ +
+
icon.box
+

+

Syntax

+ icon.box([["path to file"], [index]]) +
diff --git a/docs/functions/index.html b/docs/functions/index.html new file mode 100644 index 0000000..6192cb0 --- /dev/null +++ b/docs/functions/index.html @@ -0,0 +1,156 @@ +

Functions

+

The functions and variables have unique titles described by fully qualified names that indicate a logical hierarchy.

+

Shell has a number of functions and variables built into it that are always available. They are listed here in alphabetical order.

+ +
+
indexof
+

Find the position of a menu item.

+

Syntax

+ indexof(expression[, default position]) +
+ +
+
if
+

Conditionally executes another statement.

+

Syntax

+ if(condition-expression)

+ if(condition-expression, true-expression)

+ if(condition-expression, true-expression, false-expression) +
+ +
+
null
+

Returns a null value.

+

Syntax

+ null(expression)

+
+ +
+
length (len)
+

Returns length of string and array type

+

Syntax

+ length(expression)

+
+ +
+
quote
+

Returns text with a double quotation mark.

+

Syntax

+ quote(expression) +
+ +
+
char
+

Returns the value of the numeric parameter to a character.

+

Syntax

+ char(numeric-expression) +
+ +
+
var
+

Returns the value of the passed variable

+

Syntax

+ var(expression) +
+ +
+
tohex
+

Converting the value of the passed numeric expression to hexadecimal string.

+

Syntax

+ tohex(numeric-expression) +
+ +
+
equal
+

Returns true if the parameters passed are equal.

+

Syntax

+ equal(expression-1, expression-2) +
+ +
+
not
+

Returns true if the parameters passed are not equal.

+

Syntax

+ not(expression-1, expression-2) +
+ +
+
greater
+

Returns true if the first parameter is greater than the second parameter.

+

Syntax

+ greater(expression-1, expression-2) +
+ +
+
less
+

Returns true if the first parameter is less than the second parameter.

+

Syntax

+ less(expression-1, expression-2) +
+ +
+
shl
+

bitwise left shift.

+

Syntax

+ shl(shift-expression, additive-expression) +
+ +
+
shr
+

bitwise right shift.

+

Syntax

+ shr(shift-expression, additive-expression) +
+ +
+
cmd visibility enumerations
+

The flags that specify how an application is to be displayed when it is opened.

+
cmd.hidden
+cmd.show
+cmd.visible
+cmd.normal
+cmd.maximized
+cmd.minimized
+
+ +
+
Selection mode enumerations
+

Syntax

+
mode.none
+mode.single
+mode.multiple
+mode.multiunique
+mode.multisingle
+mode.multi
+
+ +
+
Selection type enumerations
+

Syntax

+
type.desktop
+type.directory(dir)
+type.drive
+type.dvd
+type.file
+type.fixed
+type.namespace
+type.remote
+type.unknown
+type.usb
+type.vhd
+
+ +
Keywords
+
null
+bool
+true
+false
+auto
+none
+default
+
+ +
app | color | image | io | key | msg | path | reg | sel | str | sys | user| input +| ini | clipboard +
+ diff --git a/docs/functions/ini.html b/docs/functions/ini.html new file mode 100644 index 0000000..0457f4d --- /dev/null +++ b/docs/functions/ini.html @@ -0,0 +1,17 @@ +
INI
+
+

Functions for handling with .ini files.

+
+
+
ini.get
+

Returns the value of the key

+

Syntax

+ ini.get('path\to\ini file', "section", "key") +
+ +
+
ini.set
+

Set the key value.

+

Syntax

+ ini.set('path\to\ini file', "section", "key", "value") +
\ No newline at end of file diff --git a/docs/functions/input.html b/docs/functions/input.html new file mode 100644 index 0000000..66dbc80 --- /dev/null +++ b/docs/functions/input.html @@ -0,0 +1,18 @@ +
INPUT
+
+

The input box allows the user to enter and pass data.

+
+
+
input
+

Show the input box with the window title and call parameter passed.
+The function returns a non-zero value if the OK button is pressed. Otherwise, it returns zero.

+

Syntax

+ input("Title", "Prompt") +
+ +
+
input.result
+

Returns the input value resulting from the input box.

+

Syntax

+ input.result +
diff --git a/docs/functions/io.html b/docs/functions/io.html new file mode 100644 index 0000000..0728234 --- /dev/null +++ b/docs/functions/io.html @@ -0,0 +1,183 @@ +
IO
+
+
+
io.attribute enumerations.
+

Syntax

+
io.attribute.archive
+io.attribute.compressed
+io.attribute.device
+io.attribute.directory
+io.attribute.encrypted
+io.attribute.hidden
+io.attribute.invalid
+io.attribute.normal
+io.attribute.offline
+io.attribute.readonly
+io.attribute.sparsefile
+io.attribute.system
+io.attribute.temporary
+io.attribute.virtual
+
+ +
+
io.attributes
+

Retrieves file system attributes for a specified path.

+

Syntax

+ io.attributes(path)

+

attribute verification

+
// check if path is hidden
+io.attribute.hidden(path)
+
+// check if path is directory
+io.attribute.directory(path)
+
+var { atrr = io.attributes(path) }
+
+// check if attr is hidden
+io.attribute.hidden(atrr)
+
+// check if attr is directory
+io.attribute.directory(atrr)
+
+ +
+
io.copy
+

Copies an existing file to a new file.

+

Syntax

+ io.copy(pathFrom, pathTo) +
+ io.copy(pathFrom, pathTo, options) + options:
+ 1 = skip_existing, 2 = overwrite_existing, 4 = update_existing, 16 = recursive
+default = update_existing | recursive

+ Example:
+ io.copy('c:\old', 'd:\new', 16 | 4) +
+ +
+
io.move
+

Moves an existing file or a directory, including its children..

+

Syntax

+ io.move(oldPath, newPath) +
+ +
+
io.rename
+

Rename a file or directory.

+

Syntax

+ io.rename(oldName, newName) +
+ +
+
io.delete
+

Deletes an existing path.

+

Syntax

+ io.delete(path) +
+ +
+
io.directory.create (io.dir.create)
+

Create new directory.

+

Syntax

+ io.directory.create(path) +
+ +
+
io.directory.exists (io.dir.exists)
+

Check if one or more directories exists.

+

Syntax

+ io.directory.exists(path) +
+ io.directory.exists(path1, path2, path3, ...) +
+ +
+
io.directory.empty (io.dir.empty)
+

Check if one or more directory is empty.

+

Syntax

+ io.directory.empty(path) +
+ io.directory.empty(path1, path2, path3, ...) +
+ +
File functions.
+ +
+
io.file.size
+

Retrieves the size of the specified file, in bytes.

+

Syntax

+ io.file.size(path) +
+ +
+
io.file.exists
+

Check if one or more files exists.

+

Syntax

+ io.file.exists(path) +
+ io.file.exists(path1, path2, path3, ...) +
+ +
+
io.file.read
+

Read file contents as text with character count option.

+

Syntax

+ io.file.read(path)
+ io.file.read(path, 12) +
+ +
+
io.file.create
+

Create new file with content option.

+

Syntax

+ io.file.create(path)
+ io.file.create(path, "Hello World!") +
+ +
+
io.file.write
+

Writing to a file with new content.

+

Syntax

+ io.file.write(path, "Hello World!") +
+ +
+
io.file.append
+

Appends text to an existing file, or to a new file if the specified file does not exist.

+

Syntax

+ io.file.append(path, "Hello ") +
+ io.file.append(path, "World!") +
+ +
+
io.datetime
+

Gets or Sets the time of the file.

+

Syntax

+ get date time + +io.datetime.created(sel.path)
+io.datetime.modified(sel.path)
+io.datetime.accessed(sel.path)
+
+io.datetime.created(sel.path, 'y/m/d')
+io.datetime.modified(sel.path, 'y/m/d')
+io.datetime.accessed(sel.path, 'y/m/d')
+ +
+
+ set date time +
+ +io.datetime.created(sel.path,2000,1,1))
+io.datetime.modified(sel.path,2000,1,1))
+io.datetime.accessed(sel.path,2000,1,1))
+
+
+ +
+
io.meta
+

Gets meta data by property key.

+

Syntax

+ io.meta('path\to\file',"System.Size")) +
diff --git a/docs/functions/key.html b/docs/functions/key.html new file mode 100644 index 0000000..2e15999 --- /dev/null +++ b/docs/functions/key.html @@ -0,0 +1,92 @@ +
KEY
+

Keyboard functions

+
+
keys enumerations
+
key.alt
+key.apps
+key.back
+key.cancel
+key.capital
+key.capslock
+key.control
+key.delete
+key.down
+key.end
+key.enter
+key.escape
+key.execute
+key.f1
+key.f10
+key.f11
+key.f12
+key.f2
+key.f3
+key.f4
+key.f5
+key.f6
+key.f7
+key.f8
+key.f9
+key.help
+key.home
+key.insert
+key.lalt
+key.lcontrol
+key.left
+key.lshift
+key.lwin
+key.next
+key.none
+key.pagedown
+key.pageup
+key.pause
+key.play
+key.print
+key.printscreen
+key.prior
+key.ralt
+key.rcontrol
+key.return
+key.right
+key.rshift
+key.rwin
+key.shift
+key.snapshot
+key.space
+key.tab
+key.up
+key.win
+
+ +
+
key
+

Syntax

+
+// check if SHIFT key is pressed
+key(key.shift)
+
+// or
+key == key.shift
+
+// or
+key.shift()
+
+// check if tow keys (SHIFT+CTRL) is pressed
+key(key.shift, key.control)
+
+// check if keys (SHIFT+CTRL+X) is pressed
+key(key.shift, key.control, 87)
+	
+
+ +
+
key.send
+

Send one or more keys to the current window.

+

Syntax

+
key.send(key.f5)
+key.send(key.ctrl,'n')
+key.send(key.shift, key.delete)
+
+ + + diff --git a/docs/functions/msg.html b/docs/functions/msg.html new file mode 100644 index 0000000..bbc16f5 --- /dev/null +++ b/docs/functions/msg.html @@ -0,0 +1,130 @@ +

MSG

+

Displays a modal dialog box that contains a system icon, a set of buttons, and a brief application-specific message, + such as status or error information. The message box returns an integer value that indicates which button the user + clicked.

+ +
Syntax
+
+msg(text)
+msg(text, title)
+msg(text, title, flags)
+
+
+
Parameters
+ + + + + + + + + + + + + +
textThe message to be displayed.
titleThe dialog box title. If this parameter is NULL, the default title is Nilesoft Shell.
flagsThe contents and behavior of the dialog box. This parameter can be a combination of flags from the following + groups of flags. +
+ +
Flags
+
+
To display an icon in the message box, specify one of the following values.
+
+
msg.error
+
A stop-sign icon appears in the message box.
+ +
msg.question
+
A question-mark icon appears in the message box.
+ +
msg.warning
+
An exclamation-point icon appears in the message box.
+ +
msg.info
+
An icon consisting of a lowercase letter i in a circle appears in the message box.
+
+
+
To indicate the buttons displayed in the message box, specify one of the following values.
+
+
msg.ok
+
The message box contains one push button: OK. This is the default.
+ +
msg.okcancel
+
The message box contains two push buttons: OK and Cancel.
+ +
msg.yesnocancel
+
The message box contains three push buttons: Yes, No, and Cancel.
+ +
msg.yesno
+
The message box contains two push buttons: Yes and No.
+
+
+
To indicate the default button, specify one of the following values.
+
+
msg.defbutton1
+
The first button is the default button.
+ +
msg.defbutton2
+
The second button is the default button.
+ +
msg.defbutton3
+
The third button is the default button.
+
+
+
To indicate the modality of the dialog box, specify one of the following values.
+
+
msg.applmodal
+
The user must respond to the message box before continuing work in the current window. However, the user can + move to the windows of other threads and work in those windows. +
+
msg.taskmodal
+
Same as msg.applmodal except that all the top-level windows belonging to the current thread are disabled.
+
+
+
To specify other options, use one or more of the following values.
+
+
msg.right
+
The text is right-justified.
+
msg.rtlreading
+
Displays message and caption text using right-to-left reading order on Hebrew and Arabic systems.
+
msg.setforeground
+
The message box becomes the foreground window.
+
msg.topmost
+
+
+
+
Return value
+

If a message box has a Cancel button, the function returns the msg.idcancel value if either the + ESC key is pressed or the Cancel button is selected. If the message box has no Cancel button, pressing + ESC will no effect - unless an msg.ok button is present. If an msg.ok button is + displayed and the user presses ESC, the return value will be msg.idok.

+

If the function fails, the return value is zero.
+ If the function succeeds, the return value is one of the following values: +

+
+
msg.idok or 1
+
The OK button was selected.
+ +
msg.idcancel or 2
+
The Cancel button was selected.
+ +
msg.idyes or 6
+
The Yes button was selected.
+ +
msg.idno or 7
+
The No button was selected.
+
+
Examples
+
msg("Hello, Warld!","NileSoft Shell", msg.info | msg.ok)
+msg("Hello, Warld!","NileSoft Shell")
+msg("Hello, Warld!")
+

+
+
msg.beep(type)
+

Plays a waveform sound. The waveform sound for each sound type is identified by an entry in the registry.

+

Syntax

+ msg.beep
+ msg.beep(msg.error)
+ msg.beep(msg.warning) +
\ No newline at end of file diff --git a/docs/functions/path.html b/docs/functions/path.html new file mode 100644 index 0000000..3961d5a --- /dev/null +++ b/docs/functions/path.html @@ -0,0 +1,253 @@ +
PATH
+
+ +
+
path.combine (path.join)
+

Combines an array of strings into a path.

+

Syntax

+ path.combine(path1, path2)
+ path.combine("C:", "Windows", "Explorer.exe") +
+ +
+
path.currentdirectory (path.curdir)
+

Retrieves the current directory for the current process.

+

Syntax

+ path.currentdirectory +
+ +
+
path.directory.name (path.dir.name)
+

Return the directory name from the path.

+

Syntax

+ path.directory.name('c:\windows\system32') // returns: system32 +
+ +
+
path.directory.box (path.dir.box)
+

Shows the directory selection box and returns the path of the specified directory.

+

Syntax

+ path.directory.box +
+ +
+
path.empty
+

Check if one or more path is empty.

+

Syntax

+ path.empty(path)
+ path.empty(path1, path2, ...) +
+ +
+
path.exists
+

Check if one or more path exists..

+

Syntax

+ path.exists(path)
+ path.exists(path1, path2, ...) +
+ +
+
path.full
+

Returns the absolute path for the specified path string.

+

Syntax

+ path.full(path) +
+ +
+
path.short
+

Retrieves the short path form of the specified path.

+

Syntax

+ path.short(path) +
+ +
+
path.name
+

Return the name from the path.

+

Syntax

+ path.name(path) +
+ +
+
path.location (path.parent)
+

Return the path of the parent

+

Syntax

+ path.location(path) +
+ +
+
path.location.name
+

Return the name from the parent

+

Syntax

+ path.location.name(path) +
+ +
+
path.root
+

Return the drive path

+

Syntax

+ path.root(path) +
+ +
+
path.title
+

Return the title from the path

+

Syntax

+ path.title(path) +
+ +
+
path.type
+

Return the type of path

+

Syntax

+ path.type(path) == type.file +
+ +
+
path.file.name
+

Return the name of path

+

Syntax

+ path.file.name(path) +
+ +
+
path.file.title
+

Return the name of path without extension

+

Syntax

+ path.file.title(path) +
+ +
+
path.file.ext
+

Return the extension of path

+

Syntax

+ path.file.ext(path) +
+ +
+
path.file.box
+

Shows the file selection box and returns the path of the specified file.

+

Syntax

+ path.file.box
+ path.file.box('All|*.*|Text|*.txt')
+ path.file.box('exe|*.exe', 'c:\windows')
+ path.file.box('exe|*.exe', 'c:\windows', 'explorer.exe') +
+ +
+
path.files
+

Returns all files with the ability to filter.

+

Syntax

+
path.files(sys.dir, ["*"], flags[2=files | 3=dirs | 5=files+dirs | 8=quots | 16=full path], sep)
+	
+// get all files and dirs
+path.files(sys.dir)
+path.files(sys.dir, "*")
+
+// get all files with .exe
+path.files(sys.dir,"*.exe")
+
+// full path + quots
+path.files(sys.dir, '*', 8|16)
+	
+ +
+ +
+
path.isabsolute
+

+

Syntax

+ path.isabsolute(path) +
+ +
+
path.isrelative
+

+

Syntax

+ path.isrelative(path) +
+ +
+
path.isfile
+

+

Syntax

+ path.isfile(path) +
+ +
+
path.isdirectory
+

+

Syntax

+ path.isdirectory(path) +
+ +
+
path.isroot (path.isdrive)
+

+

Syntax

+ path.isdrive(path) +
+ +
+
path.isclsid (path.isnamespace)
+

+

Syntax

+ path.isclsid(path) +
+ +
+
path.isexe
+

+

Syntax

+ path.isexe(path) +
+ +
+
path.removeextension
+

Remove the extension from the passed parameter.

+

Syntax

+ path.removeextension +
+ +
+
path.lnk
+

Return a path from the shortcut

+

Syntax

+ path.lnk(path) +
+
+
path.lnk.type
+

Return type from the shortcut

+

Syntax

+ path.lnk.type(path) +
+
+
path.lnk.dir
+

Return a dir path from the shortcut

+

Syntax

+ path.lnk.dir(path) +
+
+
path.lnk.icon
+

Return a icon path and index from the shortcut

+

Syntax

+ path.lnk.icon(path) +
+
+
path.getknownfolder
+

Retrieves the full path of a known folder identified.

+

Syntax

+ path.getknownfolder('{905e63b6-c1bf-494e-b29c-65b732d3d21a}') +
+ +
+
path.separator(path.sep)
+

Replacing the back slash with a forward slash or defining a spacer.

+

Syntax

+ path.separator('c:\windows\system32') return "c:/windows/system32"
+ path.separator('c:\windows\system32', '#') return "c:#windows#system32" +
+ +
+
path.wsl
+

convert the path to wsl path

+
diff --git a/docs/functions/process.html b/docs/functions/process.html new file mode 100644 index 0000000..e5a5464 --- /dev/null +++ b/docs/functions/process.html @@ -0,0 +1,15 @@ +
PROCESS
+
+

+
+
+
Syntax
+

+process.handle
+process.name
+process.id
+process.path
+process.is_explorer
+process.used
+
+
\ No newline at end of file diff --git a/docs/functions/reg.html b/docs/functions/reg.html new file mode 100644 index 0000000..b853ed7 --- /dev/null +++ b/docs/functions/reg.html @@ -0,0 +1,92 @@ +
REG
+

Registry functions

+
+
+
Registry hive enum
+

Syntax

+
HKCU
+HKCR
+HKLM
+HKU
+HKEY_CLASSES_ROOT
+HKEY_CURRENT_USER
+HKEY_LOCAL_MACHINE
+HKEY_USERS
+
+
+
+
Registry value type Enum
+

Syntax

+
reg.none	// No data type
+reg.sz		// REG_SZ
+reg.expand	// REG_EXPAND_SZ
+reg.binary	// REG_BINARY
+reg.multi	// REG_MULTI_SZ
+reg.dword	// REG_DWORD
+reg.qword	// REG_QWORD
+
+ +
+
The function of reading from the Registry.
+

Syntax

+ reg(reg.lm, 'SOFTWARE\Microsoft\Windows NT\CurrentVersion','ProductName')

+ reg(reg.cr, 'txtfile\DefaultIcon') +
+ +
+
reg.exists
+

Check that the key or value name exists

+

Syntax

+

Check that the key exists

+ reg.exists('HKCU\Control Panel\Desktop') +

Check that the value name exists

+ reg.exists('HKCU\Control Panel\Desktop', "WallPaper") +
+ +
+
reg.get
+

Read data by value name

+

Syntax

+
reg('HKCU\Control Panel\Desktop', "WallPaper")
+reg.get('HKCU\Control Panel\Desktop', "WallPaper")
+reg.get('HKCU\Control Panel\Desktop')
+
+ +
+
reg.set
+

Allows creating a subkey with the value name and value data

+

Syntax

+

Create Subkey

+
reg.set('HKCU\Software\Nilesoft\Shell')
+

Create Subkey with value and set value data type.

+
reg.set('HKCU\Software\Nilesoft\Shell', "test-int", 1, reg.dword)
+reg.set('HKCU\Software\Nilesoft\Shell', "test-str", 1, reg.sz)
+reg.set('HKCU\Software\Nilesoft\Shell', "test-str", 'some string', reg.sz)
+ +

Set value data with auto type detection.


+reg.set('HKCU\Software\Nilesoft\Shell', 'test-auto-int', 1)
+reg.set('HKCU\Software\Nilesoft\Shell', 'test-auto-str', 'some string')
+
+ +
+
reg.delete
+

Allows deleting a subkey or deleting a value

+

Syntax

+

Delete value name.

+
reg.delete('HKCU\Software\Nilesoft\Shell', 'test-auto')
+

Delete subkey.

+
reg.delete('HKCU\Software\Nilesoft\Shell')
+
+ +
+
reg.keys
+

Returns all subkey names

+

Syntax

+
reg.keys('HKCU\Software\Nilesoft\Shell')
+
+
+
reg.values
+

Returns all value names

+

Syntax

+
reg.values('HKCU\Software\Nilesoft\Shell')
+
diff --git a/docs/functions/regex.html b/docs/functions/regex.html new file mode 100644 index 0000000..7fdd0dc --- /dev/null +++ b/docs/functions/regex.html @@ -0,0 +1,20 @@ +
REGEX
+

regex functions

+
+
+
regex.match
+

Returns true if a match exists, false otherwise.

+

Syntax

+
regex.match(str, pattern)
+
+
+
regex.matches
+

Returns an array of strings

+

Syntax

+
regex.matches(str, pattern)
pre> +
+
+
regex.replace
+

Syntax

+
regex.replace(str, pattern, "new str")
+
diff --git a/docs/functions/sel.html b/docs/functions/sel.html new file mode 100644 index 0000000..1f51d2b --- /dev/null +++ b/docs/functions/sel.html @@ -0,0 +1,247 @@ +
SEL
+

Has many functions to handle selected file system objects.

+
+ +
+
sel
+

Returns all selected items with double quotation mark and custom separator.

+

Syntax

+ sel(quote=false, separator=' ') +

Parameters

+
+
quote
+
Sets if the return value shall be quoted.
+
separator
+
Separator to join the different items from the selection.
+
+

Example

+
sel
+sel(true)
+sel(true, "\n")
+
+ +
+
sel.path
+

Returns the path of the selected item..

+
+ +
+
sel.path.name
+

Returns the name without the extension of the selected item.

+
+ +
+
sel.path.length
+

Returns the number of characters in the path of the selected item.

+
+ +
+
sel.path.title
+

Returns the path title of the selected item.

+
+ +
+
sel.path.quote
+

Returns the path of the selected item. with double quotation mark.

+
+ +
+
sel.short
+

Returns the short path of the selected item.

+
+ +
+
sel.short.length
+

Returns the number of characters in the short path of the selected item.

+
+ +
+
sel.raw
+

Returns the path of the selected item in raw format.

+
+ +
+
sel.raw.length
+

Returns the number of characters in the raw path of the selected item.

+
+ +
+
sel.root
+

Returns the root directory from the path of the selected items.

+
+ +
+
sel.name
+

Returns the name and extension of the selected item.

+
+ +
+
sel.name.length
+

Returns the number of characters in the name of the selected item.

+
+ +
+
sel.title
+

Returns the name without extension of the selected item.

+
+ +
+
sel.title.length
+

Returns the number of characters in the name without extension of the selected item.

+
+ +
+
sel.parent
+

Returns the directory path for the selected item.

+
+ +
+
sel.parent.quote
+

Returns the directory path for the selected item with quotation mark.

+
+ +
+
sel.parent.raw
+

Returns the directory path for the selected item in raw format.

+
+ +
+
sel.parent.name
+

Returns the name of the parent of the selected item.

+
+ +
+
sel.parent.length
+

Returns the number of characters in the parent path of the selected item.

+
+ +
+
sel.count
+

Returns count selected items.

+
+ +
+
sel.back
+

Returns whether the selection is in the background.

+
+ +
+
sel.curdir or sel.workdir
+

Returns the path of current working directory.

+
+ +
+
sel.file
+

Returns the path for the selected item. If it is a file

+
+ +
+
sel.file.name
+

Returns the name for the selected item. If it is a file.

+
+ +
+
sel.file.name.length
+

Returns the number of characters in the name of the selected item. If it is a file.

+
+ +
+
sel.file.ext
+

Returns the extension for the selected item. If it is a file.

+
+ +
+
sel.file.title
+

Returns the name without an extension for the selected item. If it is a file.

+
+ +
+
sel.file.quote
+

Returns the path for the selected item with quotation mark. If it is a file.

+
+ +
+
sel.directory
+

Returns the path for the selected item. If it is a directory.

+
+ +
+
sel.directory.name
+

Returns the name for the selected item. If it is a directory.

+
+ +
+
sel.directory.length
+

Returns the number of characters in the path of the selected item. If it is a directory.

+
+ +
+
sel.directory.quote
+

Returns the path for the selected item with quotation mark. If it is a directory.

+
+ +
+
sel.get
+

Returns the path of the selected item by referring to the index number.

+

Syntax

+ sel.get(index=0) +
+ +
+
sel.path.raw
+

Returns the raw path of the selected item by referring to the index number.

+

Syntax

+ sel.path.raw(index=0) +
+ +
+
sel.length
+

Returns the number of characters in the path of the selected item by referring to the index number.

+

Syntax

+ sel.length(index=0) +
+ +
+
sel.readonly
+

Returns whether the selected item by referring to the index number is read-only.

+

Syntax

+ sel.readonly(index=0) +
+ +
+
sel.hidden
+

Returns whether the selected item by referring to the index number is hidden.

+

Syntax

+ sel.hidden(index=0) +
+ +
+
sel.meta
+

Gets meta data by property key.

+

Syntax

+ sel.meta("System.Size")) +
+
+
sel.lnk
+

Return the target file/dir path from the selected shortcut

+

Syntax

+ sel.lnk +
+
+
sel.lnk.type
+

Return type the shortcut

+

Syntax

+ sel.lnk.type +
+
+
sel.lnk.dir
+

Return a dir path from the shortcut

+

Syntax

+ sel.lnk.dir +
+
+
sel.lnk.icon
+

Return a icon path and index from the shortcut

+

Syntax

+ sel.lnk.icon +
diff --git a/docs/functions/str.html b/docs/functions/str.html new file mode 100644 index 0000000..76b14be --- /dev/null +++ b/docs/functions/str.html @@ -0,0 +1,214 @@ +
STR
+
+ +
+
str.get (str.at)
+

Returns a character from a specific location in the string.

+

Syntax

+ str.get("Hello World!", 7) +
+ +
+
str.set
+

Sets a character with a specific location in the string.

+

Syntax

+ str.set("Hello World!", 6, '-') +
+ +
+
str.contains
+

Returns a value indicating whether a specified substring occurs within this string.

+

Syntax

+ str.contains("Hello World!", 'World') +
+ +
+
str.empty (str.null)
+

Tests whether the string contains characters.

+

Syntax

+ str.empty("") +
+ +
+
str.start
+

Checks whether the string starts with the specified prefix.

+

Syntax

+ str.start("Hello World!", "World!") +
+ +
+
str.end
+

Checks whether the string ends with the specified suffix.

+

Syntax

+ str.end("Hello World!", "World!") +
+ +
+
str.equals
+

Determines whether two String have the same value.

+

Syntax

+ str.equals("Hello World!", "Hello World!") +
+ +
+
str.not
+

Determine if two strings do not have the same value.

+

Syntax

+ str.not("Hello World!", "Hello-World!") +
+ +
+
str.length (str.len)
+

Gets the number of characters in the current string.

+

Syntax

+ str.length("Hello World!") +
+ +
+
str.trim
+

Returns a new string in which all leading and trailing occurrences of a set of specified characters from the current string are removed.

+

Syntax

+

Removes all leading and trailing white-space characters from the current string.

+ str.trim(" Hello World! ")

+

Removes all leading and trailing 'H!' characters from the current string.

+ str.trim("Hello World!", "H!") +
+ +
+
str.trimstart
+

Returns a new string in which all leading occurrences of a set of specified characters from the current string are removed.

+

Syntax

+

Removes all leading white-space characters from the current string.

+ str.trimstart(" Hello World!")
+ +

Removes all leading 'H' characters from the current string.

+ str.trimstart("Hello World!", "H") +
+ +
+
str.trimend
+

Returns a new string in which all trailing occurrences of a set of specified characters from the current string are removed.

+

Syntax

+

Removes all trailing white-space characters from the current string.

+ str.trimend("Hello World! ")
+ +

Removes all trailing '!' characters from the current string.

+ str.trimend("Hello World!", "!") +
+ +
+
str.find
+

Searches a string in a forward direction for the first occurrence of a substring that matches a specified sequence of characters.

+

Syntax

+ str.find("Hello World!", "lo") +
+ +
+
str.findlast
+

Searches a string in a backward direction for the first occurrence of a substring that matches a specified sequence of characters.

+

Syntax

+ str.findlast("Hello World!", "Wor") +
+ +
+
str.lower
+

Returns a copy of this string converted to lowercase.

+

Syntax

+ str.lower("Hello World!") +
+ +
+
str.upper
+

Returns a copy of this string converted to uppercase.

+

Syntax

+ str.upper("Hello World!") +
+ +
+
str.left
+

Extracts the left part of a string.

+

Syntax

+ str.left("Hello World!", 5) +
+ +
+
str.right
+

Extracts the right part of a string.

+

Syntax

+ str.right("Hello World!", 5) +
+ +
+
str.sub
+

Copies a substring of at most some number of characters from a string beginning from a specified position.

+

Syntax

+ str.sub("Hello World!", 5)
+ str.sub("Hello World!", 0, 5) +
+ +
+
str.remove
+

Removes an element or a range of elements in a string from a specified position.

+

Syntax

+ str.replace("Hello World!", " ")
+ str.remove("Hello World!", 5)
+ str.remove("Hello World!", 5, 1) +
+ +
+
str.replace
+

Replace elements in a string at a specified position with specific characters or characters copied from other ranges or strings.

+

Syntax

+ str.replace("Hello World!", "World", "User")
+ str.replace("Hello World!", "world", "user", true) +
+ +
+
str.padleft
+

Returns a new string of a specified length in which the beginning of the current string is padded with spaces or with a specified character.

+

Syntax

+ str.padleft("Hello World!", "*")
+ str.padleft("Hello World!", "*", 3) +
+ +
+
str.padright
+

Returns a new string of a specified length in which the end of the current string is padded with spaces or with a specified character.

+

Syntax

+ str.padright("Hello World!", "*")
+ str.padright("Hello World!", "*", 3) +
+ +
+
str.padding
+

Returns a new string of a specified length in which the start and end of the current string is padded with spaces or with a specified character.

+

Syntax

+ str.padding("Hello World!", "*")
+ str.padding("Hello World!", "*", 3) +
+ +
+
str.guid
+

Returns a new guid string

+

Syntax

+ str.guid return 00000000000000000000000000000000
+ str.guid(1) return 00000000-0000-0000-0000-000000000000
+ str.guid(2) return {00000000-0000-0000-0000-000000000000}
+ str.guid(3) return (00000000-0000-0000-0000-000000000000)
+
+ +
+
str.capitalize
+

Returns a new capitalize string

+

Syntax

+ str.capitalize('hello world') return "Hello World"
+
+ +
+
str.res
+

Returns a string resource from the executable file. "shell32.dll" is the default file.

+

Syntax

+ str.res(-4640) return "Runs the selected command with elevation" from "shell32.dll"
+ str.res('explorer.dll', -22000) return "Desktop"
+
+ diff --git a/docs/functions/sys.html b/docs/functions/sys.html new file mode 100644 index 0000000..d3529f4 --- /dev/null +++ b/docs/functions/sys.html @@ -0,0 +1,166 @@ +
SYS (SYSTEM)
+ +
+
sys.name
+

Returns Windows name.

+

Syntax

+ sys.name +
+ +
+
sys.type
+

Returns system architecture.

+

Syntax

+ sys.type == 64
+ sys.type == 32 +
+ +
+
sys.is64
+

Returns if system architecture is x64.

+

Syntax

+ sys.is64 +
+ +
+
sys.dark
+

Check if dark mode is enabled.

+

Syntax

+ sys.dark +
+ +
+
sys.var
+

Retrieves the value of an environment variable.

+

Syntax

+ sys.var('WINDIR') +
+ +
+
sys.version (sys.ver)
+

Windows version.

+

Syntax

+
sys.version
+sys.version.build
+sys.version.major
+sys.version.minor
+sys.version.name
+sys.version.type
+
+ +
+
sys.datetime (system.datetime)
+

Date and time format

+

Syntax

+
sys.datetime                                   // the date and time in a short format (Format: YYYY.MM.DD-HH.MM.SS).
+sys.datetime.short                             // the date and time in a short format (Format: YYYY.MM.DD-HH.MM.SS).
+sys.datetime.dayofweek (sys.datetime.dw)       // the day of the week as a number (Sunday as 1)
+
+sys.datetime.date                              // the full date in a long format (Format: YYYY.MM.DD).
+sys.datetime.yy                                // the year part of the current date as a two-digit number.
+sys.datetime.year (sys.datetime.y)             // the year part of the current date as a four-digit number.
+sys.datetime.month (sys.datetime.m)            // the month part of the current date.
+sys.datetime.day (sys.datetime.d)              // the day part of the current date.
+
+sys.datetime.time                              // the full time in hours, minutes, and seconds (Format: HH.MM.SS).
+sys.datetime.pm                                // "AM" or "PM" based on the current time.
+sys.datetime.hour (sys.datetime.h)             // the hour part of the current time (24-hour format).
+sys.datetime.minute (sys.datetime.min)         // the minutes part of the current time.
+sys.datetime.second (sys.datetime.s)           // the seconds part of the current time.
+sys.datetime.milliseconds (sys.datetime.ms)    // the milliseconds part of the current time as a three-digit number.
+
+sys.datetime("D")                              // the full date in a short format (Format: DD/MM/YYYY).
+sys.datetime("Y")                              // the year part of the current date as a four-digit number.
+sys.datetime("y")                              // the year part of the current date as a two-digit number.
+sys.datetime("m")                              // the month part of the current date as a two-digit number.
+sys.datetime("d")                              // the day part of the current date as a two-digit number.
+sys.datetime("P") (sys.datetime("p"))          // "AM" or "PM" based on the current time.
+sys.datetime("h")                              // the hour part of the current time as a two-digit number (12-hour format).
+sys.datetime("H")                              // the hour part of the current time as a two-digit number (24-hour format).
+sys.datetime("M")                              // the minute part of the current time as a two-digit number.
+sys.datetime("S")                              // the second part of the current time as a two-digit number.
+sys.datetime("s")                              // the milliseconds part of the current time as a three-digit number.
+
+datetime("y/m/d")                              // the date in a short format (Format: YYYY/MM/DD).
+datetime("h:M P")                              // the time in a short format (Format: HH:MM AM/PM).
+datetime("H.M.S.s")                            // the time in a long format (Format: HH.MM.SS.MS).
+
+ +
+
Windows paths
+
sys                                            // %WINDIR%
+
+sys.root                                       // %SYSTEMDRIVE%
+
+sys.programdata                                // %PROGRAMDATA%
+sys.prog                                       // %PROGRAMFILES%
+sys.prog32                                     // %PROGRAMFILES(x86)%
+sys.templates
+
+sys.users
+sys.appdata                                    // %APPDATA%
+sys.temp                                       // %TEMP%
+
+sys.directory (sys.dir)                        // %WINDIR%
+sys.path                                       // %WINDIR%
+sys.bin                                        // %WINDIR%\system32
+sys.bin32
+sys.bin64
+sys.wow
+
+ +
+
sys.is_primary_monitor
+

Returns true if the current monitor is the primary

+

Syntax

+ sys.is_primary_monitor
+
+ +
+
sys.langid
+

Returns the language ID

+

Syntax

+ sys.langid
+
+ +
+
sys.extended
+

Returns whether the Shift key is currently pressed

+

Syntax

+ sys.extended
+
+ +
+
sys.is11
+

Returns whether the Windows version is 11

+

Syntax

+ sys.is11
+
+ +
+
sys.is10
+

Returns whether the Windows version is 10

+

Syntax

+ sys.is10
+
+ +
+
sys.is81
+

Returns whether the Windows version is 8.1

+

Syntax

+ sys.is81
+
+ +
+
sys.is8
+

Returns whether the Windows version is 8

+

Syntax

+ sys.is8
+
+ +
+
sys.is7
+

Returns whether the Windows version is 7

+

Syntax

+ sys.is7
+
\ No newline at end of file diff --git a/docs/functions/this.html b/docs/functions/this.html new file mode 100644 index 0000000..5ede648 --- /dev/null +++ b/docs/functions/this.html @@ -0,0 +1,18 @@ +
THIS
+
+

This namespace contains functions that are used with the current item in the context menu.

+
+
+
Syntax
+

+this.type	// Returns the type of the current item [item = 0, menu = 1, separator = 2]
+this.checked	// Returns true if the current item is checked
+this.pos	// Returns the position of the current item in the context menu
+this.disabled	// Returns true if the current item is disabled
+this.sys	// Returns true if the current item is a system item
+this.title	// Returns the title of the current item
+this.id		// Returns the ID of the current item
+this.count	// Returns the number of items in the context menu
+this.length	// Returns the length of the current item's title
+
+
diff --git a/docs/functions/user.html b/docs/functions/user.html new file mode 100644 index 0000000..dbedc7c --- /dev/null +++ b/docs/functions/user.html @@ -0,0 +1,36 @@ +
USER
+
+
+
user.name
+

Returns the current username.

+

Syntax

+ user.name +
+ +
+
Functions to return the path of user directories
+

Syntax

+
user.home
+user.appdata
+user.contacts
+user.desktop
+user.directory (user.dir)
+user.documents
+user.documentslibrary
+user.downloads
+user.favorites
+user.libraries
+user.localappdata
+user.music
+user.personal
+user.pictures
+user.profile
+user.quicklaunch
+user.sendto
+user.startmenu
+user.temp
+user.templates
+user.videos
+
+
+ diff --git a/docs/functions/window.html b/docs/functions/window.html new file mode 100644 index 0000000..d9776ce --- /dev/null +++ b/docs/functions/window.html @@ -0,0 +1,34 @@ +
WINDOW, WND
+
+

+
+
+
Syntax
+

+window.is_taskbar	// Returns true if the window handle is for the Taskbar window
+window.is_desktop	// Returns true if the window handle is for the Desktop window
+window.is_explorer	// Returns true if the window handle is for the Explorer window
+window.is_tree		// Returns true if the window handle is for the Side window
+window.is_edit		// Returns true if the window handle is for the Edit menu
+window.is_start		// Returns true if the window handle is for the Win+X menu
+
+window.send(name, msg, wparam, lparam)	// Search for the window by name and send the specified message
+window.post(name, msg, wparam, lparam)	// Search for the window by name and send the specified message without waiting
+
+window.send(null, msg, wparam, lparam)	// Send the specified message to current window.
+window.post(null, msg, wparam, lparam)	// Send the specified message without waiting to current window.
+
+window.command(command)	// Send WM_COMMAND to current window.
+window.command(command, name)	// Search for the window by name and send the command to it.
+
+window.handle
+window.name
+window.title
+window.owner
+window.parent
+window.parent.handle
+window.parent.name
+window.is_contextmenuhandler
+						
+
+
\ No newline at end of file diff --git a/docs/get-started.html b/docs/get-started.html new file mode 100644 index 0000000..7de9bfe --- /dev/null +++ b/docs/get-started.html @@ -0,0 +1,33 @@ +

Get Started

+
+

+ This tutorial will teach you the basics of Shell.
+ It is not necessary to have any prior experience. +

+

+ To start using Shell, you need:
+ A text editor, like Notepad, to write Shell code. +

+
Quickstart
+

Let's create our first menu item.

+

Open the configuration file "shell.nss" and Write the following code and save.

+ +
+
item(title='Hello, World!' cmd=msg('Hello @user.name'))
+
+

Don't worry if you don't understand the code above - we will discuss it in detail in later chapters.

+ +

The result will look something for this when you press the right-click in an empty place on the desktop:

+
+ +
+

Congratulations You have now added the first time a menu item to the context menu

diff --git a/docs/images/config.png b/docs/images/config.png new file mode 100644 index 0000000000000000000000000000000000000000..8dcac9807a92985fdcf565db96afbe1153546dff GIT binary patch literal 13640 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

QxXKq7y?=s76$rd0|qGkm_bmd%{pNWYSS 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