diff --git a/.gitignore b/.gitignore index e765cea..03da90b 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,7 @@ vendor/*/* config/.history Thumbs.db *.exe +*.dll build/ Version v* +*.bak diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..758a57c --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,38 @@ +# How to contribute + +Unfortunately we all can't work on cmder every day of the year, so I have decided to write some guidelines for contributing. + +If you follow them your contribution will likely be pulled in quicker. + +## Getting Started + +* Fork the repository on GitHub (It's that easy) +* Create a feature branch based on the development branch. + +## Making Changes + +* Make changes in your seperate branch. +* Check for unnecessary whitespace with `git diff --check` before committing. +* Make sure your commit messages are easy to understand +* Squash your 'Correcting mistakes' commits if you have a lot of them. (See the 'Squashing Commits' link below) +* Make sure your changes won't affect new users or user without a customised system, try out your changes on a fresh Windows VM to see if it would affect a new user's experience. + * Sometimes a change that helps you with your cmder experience and tools doesn't always mean other people may need/want it. + +## Making Trivial Changes + +### Documentation + +* If the documentation is about a currently available feature in cmder or correcting already created documentation, you can safely make your changes on the master branch and pull request them onto master. + +## Submitting Changes + +* Push your changes to the branch in your fork of the repository. +* Submit a pull request to the develop branch of the cmder repository (unless it's a change in documentation [see above]). +* Make sure you explicitly say to not complete the pull request if you are still making changes. + + +# Additional Resources + +* [Squashing Commits](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html) +* [General GitHub documentation](http://help.github.com/) +* [GitHub pull request documentation](http://help.github.com/send-pull-requests/) diff --git a/Cmder.exe b/Cmder.exe deleted file mode 100644 index f5cab6d..0000000 Binary files a/Cmder.exe and /dev/null differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..6c3596f --- /dev/null +++ b/README.md @@ -0,0 +1,98 @@ +# Cmder + +[![Join the chat at https://gitter.im/bliker/cmder](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/cmderdev/cmder?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +![Build Status](https://ci.appveyor.com/api/projects/status/32r7s2skrgm9ubva?retina=true) + +Cmder is a **software package** created out of pure frustration over absence of usable console emulator on Windows. It is based on [ConEmu](https://conemu.github.io/) with *major* config overhaul, comes with a Monokai color scheme, amazing [clink](https://github.com/mridgers/clink) (further enhanced by [clink-completions](https://github.com/vladimir-kotikov/clink-completions)) and a custom prompt layout. + +![Cmder Screenshot](http://i.imgur.com/g1nNf0I.png) + +## Why use it + +The main advantage of Cmder is portability. It is designed to be totally self-contained with no external dependencies, that is makes it great for **USB Sticks** or **cloud storage**. So you can carry your console, aliases and binaries (like wget, curl and git) with you anywhere. + +## Installation + +1. Download the [latest release](https://github.com/cmderdev/cmder/releases/) +2. Extract +3. (optional) Place your own executable files into the `bin` folder to be injected into your PATH. +4. Run Cmder + +## Integration + +So you've experimented with Cmder a little and want to give it a shot in a more permanent home; + +### Shortcut to open Cmder in a chosen folder + +1. Open a terminal as an Administrator +2. Navigate to the directory you have placed Cmder +3. Execute `.\cmder.exe /REGISTER ALL` + _If you get a message "Access Denied" ensure you are executing the command in an **Administrator** prompt._ + +In a file explorer window right click in or on a directory to see "Cmder Here" in the context menu. + +## Keyboard shortcuts + +### Tab manipulation + +* Ctrl + T : New tab dialog (maybe you want to open cmd as admin?) +* Ctrl + W : Close tab +* Ctrl + D : Close tab (if pressed on empty command) +* Shift + Alt + #Number : Fast new tab: 1 - CMD, 2 - PowerShell +* Alt + Enter: Fullscreen + +### Shell + +* Shift + Up : Traverse up in directory structure (lovely feature!) +* End, Home, Ctrl : Traversing text with as usual on Windows +* Ctrl + R : History search +* Shift + Mouse : Select and copy text from buffer + +(Some shortcuts are not yet documented, thought they exist, please add them here) + +## Features + +### Aliases +You can define simple aliases with command `alias name=command`. + +For example there is one defined for you `alias e.=explorer .` + +All aliases will be saved in `/config/aliases` file + +### SSH Agent + +To start SSH agent simply call `start-ssh-agent`, which is in the `vendor/git-for-windows/cmd` folder. + +If you want to run SSH agent on startup, include the line `@call "%GIT_INSTALL_ROOT%/cmd/start-ssh-agent.cmd"` in `/config/user-startup.bat` (usually just uncomment it). + +## Todo + +1. Git Bash +2. Check for clink and git before injecting them (Sort of done) + +## License + +All software included is bundled with own license + +The MIT License (MIT) + +Copyright (c) 2015 Samuel Vasko + +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/Readme.md b/Readme.md deleted file mode 100644 index 8130d84..0000000 --- a/Readme.md +++ /dev/null @@ -1,102 +0,0 @@ -# Cmder - -Latest release is **[v1.1.4.1](https://github.com/bliker/cmder/releases/tag/v1.1.4.1)** - -Cmder is a **software package** created out of pure frustration over absence of usable console emulator on Windows. It is based on [ConEmu](https://code.google.com/p/conemu-maximus5/) with *major* config overhaul. Monokai color scheme, amazing [clink](https://github.com/mridgers/clink) and custom prompt layout. - -![Cmder Screenshot](http://i.imgur.com/g1nNf0I.png) - -## Why use it - -The main advantage of Cmder is portability. It is designed to be totally self-contained with no external dependencies, that is makes it great for **USB Sticks** or **Dropbox**. So you can carry your console, aliases and binaries (like wget, curl and git) with you anywhere. - -## Installation - -1. Download the latest release -1. Extract -1. (optional) Place your own executable files into the `bin` folder to be injected into your PATH. -1. Run cmder - -*(There will be a version with installer)* - -## Integration - -So you've experimented with cmder a little and want to give it a shot in a more permanent home; - -### Shortcut to open Cmder in a chosen folder - -1. Open a terminal as an Administrator -1. Navigate to the directory you have placed Cmder -1. Execute `.\cmder.exe /REGISTER ALL`* - -In a file explorer window right click in or on a directory to see "Cmder Here" in the context menu. - -*If you get a message "Access Denied" ensure you are executing the command in an Administrator prompt. - -## Keyboard shortcuts - -### Tab manipulation - -* `Ctrl + t` : new tab dialog (maybe you want to open cmd as admin?) -* `Ctrl + w` : close tab -* `Ctrl + d` : close tab (if pressed on empty command) -* `Shift + alt + number` : fast new tab: `1` - CMD, `2` - Powershell `*` - More to come -* `Alt + enter`: Fullscreen - -### Shell - -* `Shift + Up` : Traverse up in directory structure (lovely feature!) -* `End, Home, Ctrl` : Traversing text with as usual on Windows -* `Ctrl + r` : History search -* `Shift + mouse` : Select and copy text from buffer - -(Some shortcuts are not yet documented, thought they exist, please add them here) - -## Features - -### Aliases -You can define simple aliases with command `alias name=command`. - -For example there is one defined for you `alias e.=explorer .` - -All aliases will be saved in `/config/aliases` file - -### SSH Agent - -To start SSH agent simply call `agent`, which is in the `bin` folder. - -If you want to run SSH agent on startup, uncomment the line in `/vendor/init.bat`so it says `@call "%CMDER_ROOT%/bin/agent.cmd"`. - -## Todo - -1. Complete PowerShell compatibility. -2. Workaround git.exe overload after msysgit download (Granted this is an upstream issue). -3. Redo Build/Pack scripts or remove them altogether. -4. Git Bash -5. Check for clink and git before injecting them - -## License - -All software included is bundled with own license - -The MIT License (MIT) - -Copyright (c) 2015 Samuel Vasko - -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/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..6afea95 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,40 @@ +#---------------------------------# +# general configuration # +#---------------------------------# + +version: 1.0.{build}-{branch} + +# branches to build +branches: + # blacklist + except: + - gh-pages + +# Do not build on tags +skip_tags: true + +#---------------------------------# +# environment configuration # +#---------------------------------# + +# Operating system (build VM template) +os: Windows Server 2012 R2 + +#---------------------------------# +# build configuration # +#---------------------------------# + +build_script: + - ps: cd scripts; .\build.ps1 -Compile -verbose + +#---------------------------------# +# notifications # +#---------------------------------# + +notifications: + # Webhook + - provider: Webhook + url: https://webhooks.gitter.im/e/f7b9c3ae66741c2e046e + on_build_success: true + on_build_failure: true + on_build_status_changed: true diff --git a/bin/agent.cmd b/bin/agent.cmd deleted file mode 100644 index 4eaa614..0000000 --- a/bin/agent.cmd +++ /dev/null @@ -1,46 +0,0 @@ -@ECHO OFF - -REM Set default sock file -SET SSH_AUTH_SOCK=/tmp/ssh-agent.sock - -REM Check socket is available -IF NOT EXIST "%TMP%\ssh-agent.sock" GOTO:RUNAGENT - -REM Check if an ssh-agent is running -FOR /f "tokens=*" %%I IN ('ps ^| grep ssh-agent ^| sed "s/^ *\([0-9]\+\) .*/\1/"') DO SET VAR=%%I -IF "%VAR%" == "" GOTO:RUNAGENT - -REM Check if socket file is valid -ssh-add -l 1> NUL 2>&1 -IF ERRORLEVEL 1 GOTO:RUNAGENT -GOTO:ADDKEYS - -:RUNAGENT -REM Remove old socket file -rm -f /tmp/ssh-agent.sock - -REM Run ssh-agent and save (last) PID in VAR -SET VAR= -FOR /f "tokens=*" %%J IN ('ssh-agent -a /tmp/ssh-agent.sock') DO FOR /f "tokens=*" %%K IN ('echo %%J ^| grep "SSH_AGENT_PID" ^| sed "s/^SSH_AGENT_PID=\([0-9]\+\); .*/\1/"') DO SET VAR=%%K - -:ADDKEYS -SET SSH_AUTH_PID=%VAR% - -REM Check if ssh keys are known -SET KEYS= -FOR /f "tokens=*" %%I IN ('DIR /B "%HOME%\.ssh\*_rsa"') DO CALL:CHECKKEY %%I - -REM Add missing ssh keys at once -IF NOT "%KEYS%" == "" ssh-add %KEYS% -GOTO:END - -REM Functions -REM Check if ssh key has to be added -:CHECKKEY -SET VAR= -FOR /f "tokens=*" %%J IN ('ssh-add -l ^| grep "%1"') DO SET VAR=%%J -IF "%VAR%" == "" SET KEYS='%HOME%\.ssh\%1' %KEYS% -GOTO:EOF - -:END -@ECHO ON diff --git a/bin/alias.bat b/bin/alias.bat index 1dcfdc5..f71a433 100644 --- a/bin/alias.bat +++ b/bin/alias.bat @@ -1,27 +1,35 @@ @echo off set ALIASES=%CMDER_ROOT%\config\aliases +setlocal +:: handle quotes within command definition, e.g. quoted long file names +set _x="%*" +set _x=%_x:"=% -if ["%*"] == [""] echo Use /? for help & echo. & goto :p_show +:: check command usage +if ["%_x%"] == [""] echo Use /? for help & echo. & goto :p_show if ["%1"] == ["/?"] goto:p_help if ["%1"] == ["/reload"] goto:p_reload :: /d flag for delete existing alias if ["%1"] == ["/d"] goto:p_del %* -if ["%2"] == [""] echo Insufficient parameters. & goto:p_help -::validate alias -setlocal -for /f "delims== tokens=1" %%G in ("%*") do set _temp2=%%G +:: if arg is an existing alias, display it +if ["%2"] == [""] ( + doskey /macros | findstr /b %1= && goto:eof + echo Insufficient parameters. & goto:p_help +) - set _temp=%_temp2: =% +:: validate alias +for /f "delims== tokens=1" %%G in ("%_x%") do set alias=%%G +set _temp=%alias: =% -if not ["%_temp%"] == ["%_temp2%"] ( +if not ["%_temp%"] == ["%alias%"] ( echo Your alias name can not contain a space endlocal goto:eof ) :: replace already defined alias -findstr /b /v /i "%_temp%=" "%ALIASES%" >> "%ALIASES%.tmp" +findstr /b /v /i "%alias%=" "%ALIASES%" >> "%ALIASES%.tmp" echo %* >> "%ALIASES%.tmp" && type "%ALIASES%.tmp" > "%ALIASES%" & @del /f /q "%ALIASES%.tmp" doskey /macrofile="%ALIASES%" endlocal diff --git a/config/ConEmu.xml b/config/ConEmu.xml index fd30e4a..f675df0 100644 --- a/config/ConEmu.xml +++ b/config/ConEmu.xml @@ -1,7 +1,7 @@ - + @@ -77,7 +77,7 @@ - + @@ -127,8 +127,8 @@ - - + + @@ -138,7 +138,7 @@ - + @@ -483,48 +483,51 @@ - + - + + - + - + + - + - + + - - + + - + - - + + @@ -610,6 +613,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/cmder.lua b/config/cmder.lua new file mode 100644 index 0000000..b63fe95 --- /dev/null +++ b/config/cmder.lua @@ -0,0 +1,184 @@ +function lambda_prompt_filter() + clink.prompt.value = string.gsub(clink.prompt.value, "{lamb}", "λ") +end + +--- + -- Resolves closest directory location for specified directory. + -- Navigates subsequently up one level and tries to find specified directory + -- @param {string} path Path to directory will be checked. If not provided + -- current directory will be used + -- @param {string} dirname Directory name to search for + -- @return {string} Path to specified directory or nil if such dir not found +local function get_dir_contains(path, dirname) + + -- return parent path for specified entry (either file or directory) + local function pathname(path) + local prefix = "" + local i = path:find("[\\/:][^\\/:]*$") + if i then + prefix = path:sub(1, i-1) + end + return prefix + end + + -- Navigates up one level + local function up_one_level(path) + if path == nil then path = '.' end + if path == '.' then path = clink.get_cwd() end + return pathname(path) + end + + -- Checks if provided directory contains git directory + local function has_specified_dir(path, specified_dir) + if path == nil then path = '.' end + local found_dirs = clink.find_dirs(path..'/'..specified_dir) + if #found_dirs > 0 then return true end + return false + end + + -- Set default path to current directory + if path == nil then path = '.' end + + -- If we're already have .git directory here, then return current path + if has_specified_dir(path, dirname) then + return path..'/'..dirname + else + -- Otherwise go up one level and make a recursive call + local parent_path = up_one_level(path) + if parent_path == path then + return nil + else + return get_dir_contains(parent_path, dirname) + end + end +end + +local function get_hg_dir(path) + return get_dir_contains(path, '.hg') +end + +local function get_git_dir(path) + return get_dir_contains(path, '.git') +end + +--- + -- Find out current branch + -- @return {false|mercurial branch name} +--- +function get_hg_branch() + for line in io.popen("hg branch 2>nul"):lines() do + local m = line:match("(.+)$") + if m then + return m + end + end + + return false +end + +--- + -- Get the status of working dir + -- @return {bool} +--- +function get_hg_status() + for line in io.popen("hg status"):lines() do + return false + end + return true +end + +function hg_prompt_filter() + + -- Colors for mercurial status + local colors = { + clean = "\x1b[1;37;40m", + dirty = "\x1b[31;1m", + } + + if get_hg_dir() then + -- if we're inside of mercurial repo then try to detect current branch + local branch = get_hg_branch() + if branch then + -- Has branch => therefore it is a mercurial folder, now figure out status + if get_hg_status() then + color = colors.clean + else + color = colors.dirty + end + + clink.prompt.value = string.gsub(clink.prompt.value, "{hg}", color.."("..branch..")") + return false + end + end + + -- No mercurial present or not in mercurial file + clink.prompt.value = string.gsub(clink.prompt.value, "{hg}", "") + return false +end + +--- + -- Find out current branch + -- @return {false|git branch name} +--- +function get_git_branch() + for line in io.popen("git branch 2>nul"):lines() do + local m = line:match("%* (.+)$") + if m then + return m + end + end + + return false +end + +--- + -- Get the status of working dir + -- @return {bool} +--- +function get_git_status() + return os.execute("git diff --quiet --ignore-submodules HEAD 2>nul") +end + +function git_prompt_filter() + + -- Colors for git status + local colors = { + clean = "\x1b[1;37;40m", + dirty = "\x1b[31;1m", + } + + if get_git_dir() then + -- if we're inside of git repo then try to detect current branch + local branch = get_git_branch() + if branch then + -- Has branch => therefore it is a git folder, now figure out status + if get_git_status() then + color = colors.clean + else + color = colors.dirty + end + + clink.prompt.value = string.gsub(clink.prompt.value, "{git}", color.."("..branch..")") + return false + end + end + + -- No git present or not in git file + clink.prompt.value = string.gsub(clink.prompt.value, "{git}", "") + return false +end + +clink.prompt.register_filter(lambda_prompt_filter, 40) +clink.prompt.register_filter(hg_prompt_filter, 50) +clink.prompt.register_filter(git_prompt_filter, 50) + +local completions_dir = clink.get_env('CMDER_ROOT')..'/vendor/clink-completions/' +for _,lua_module in ipairs(clink.find_files(completions_dir..'*.lua')) do + -- Skip files that starts with _. This could be useful if some files should be ignored + if not string.match(lua_module, '^_.*') then + local filename = completions_dir..lua_module + -- use dofile instead of require because require caches loaded modules + -- so config reloading using Alt-Q won't reload updated modules. + dofile(filename) + end +end \ No newline at end of file diff --git a/config/git.lua b/config/git.lua deleted file mode 100644 index 7f12b0a..0000000 --- a/config/git.lua +++ /dev/null @@ -1,51 +0,0 @@ ---- - -- Find out current branch - -- @return {false|git branch name} ---- -function get_git_branch() - for line in io.popen("git branch 2>nul"):lines() do - local m = line:match("%* (.+)$") - if m then - return m - end - end - - return false -end - ---- - -- Get the status of working dir - -- @return {bool} ---- -function get_git_status() - return os.execute("git diff --quiet --ignore-submodules HEAD") -end - -function git_prompt_filter() - - -- Colors for git status - local colors = { - clean = "\x1b[1;37;40m", - dirty = "\x1b[31;1m", - } - - local branch = get_git_branch() - if branch then - -- Has branch => therefore it is a git folder, now figure out status - if get_git_status() then - color = colors.clean - else - color = colors.dirty - end - - clink.prompt.value = string.gsub(clink.prompt.value, "{git}", color.."("..branch..")") - clink.prompt.value = string.gsub(clink.prompt.value, "{hg}", "") - return true - end - - -- No git present or not in git file - clink.prompt.value = string.gsub(clink.prompt.value, "{git}", "") - return false -end - -clink.prompt.register_filter(git_prompt_filter, 50) diff --git a/config/hg.lua b/config/hg.lua deleted file mode 100644 index b630ba7..0000000 --- a/config/hg.lua +++ /dev/null @@ -1,54 +0,0 @@ ---- - -- Find out current branch - -- @return {false|mercurial branch name} ---- -function get_hg_branch() - for line in io.popen("hg branch 2>nul"):lines() do - local m = line:match("(.+)$") - if m then - return m - end - end - - return false -end - ---- - -- Get the status of working dir - -- @return {bool} ---- -function get_hg_status() - for line in io.popen("hg status"):lines() do - return false - end - return true -end - -function hg_prompt_filter() - - -- Colors for mercurial status - local colors = { - clean = "\x1b[1;37;40m", - dirty = "\x1b[31;1m", - } - - local branch = get_hg_branch() - if branch then - -- Has branch => therefore it is a mercurial folder, now figure out status - if get_hg_status() then - color = colors.clean - else - color = colors.dirty - end - - clink.prompt.value = string.gsub(clink.prompt.value, "{hg}", color.."("..branch..")") - clink.prompt.value = string.gsub(clink.prompt.value, "{git}", "") - return true - end - - -- No mercurial present or not in mercurial file - clink.prompt.value = string.gsub(clink.prompt.value, "{hg}", "") - return false -end - -clink.prompt.register_filter(hg_prompt_filter, 50) diff --git a/config/prompt.lua b/config/prompt.lua deleted file mode 100644 index 5b0c239..0000000 --- a/config/prompt.lua +++ /dev/null @@ -1,5 +0,0 @@ -function lambda_prompt_filter() - clink.prompt.value = string.gsub(clink.prompt.value, "{lamb}", "λ") -end - -clink.prompt.register_filter(lambda_prompt_filter, 40) \ No newline at end of file diff --git a/config/settings b/config/settings index 93de0be..ea1bd7e 100644 --- a/config/settings +++ b/config/settings @@ -27,7 +27,7 @@ match_colour = -1 # the line. 0 = PATH only, 1 = PATH and CWD, 2 = PATH, CWD, and directories. In # all cases both executables and directories are matched when there is a path # separator present. -exec_match_style = -1 +exec_match_style = 2 # name: Prompt colour # type: int diff --git a/launcher/CmderLauncher.sln b/launcher/CmderLauncher.sln index e130cc2..9b4bc65 100644 --- a/launcher/CmderLauncher.sln +++ b/launcher/CmderLauncher.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Express 2013 for Windows Desktop -VisualStudioVersion = 12.0.21005.1 +# Visual Studio 14 +VisualStudioVersion = 14.0.23107.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CmderLauncher", "CmderLauncher.vcxproj", "{4A8485A5-B7DD-4C44-B7F6-3E2765DD0CD3}" EndProject diff --git a/launcher/CmderLauncher.vcxproj b/launcher/CmderLauncher.vcxproj index f4ab5c3..d9012ba 100644 --- a/launcher/CmderLauncher.vcxproj +++ b/launcher/CmderLauncher.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -19,13 +19,13 @@ Application true - v120 + v140_xp Unicode Application false - v120 + v140_xp true Unicode @@ -72,6 +72,7 @@ WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) true Size + MultiThreaded Windows @@ -84,7 +85,9 @@ - + + RC + diff --git a/launcher/src/CmderLauncher.cpp b/launcher/src/CmderLauncher.cpp index 1aa720f..6df2335 100644 --- a/launcher/src/CmderLauncher.cpp +++ b/launcher/src/CmderLauncher.cpp @@ -79,6 +79,19 @@ optpair GetOption() return pair; } +bool FileExists(const wchar_t * filePath) +{ + HANDLE hFile = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + + if (hFile != INVALID_HANDLE_VALUE) + { + CloseHandle(hFile); + return true; + } + + return false; +} + void StartCmder(std::wstring path, bool is_single_mode) { #if USE_TASKBAR_API @@ -87,6 +100,7 @@ void StartCmder(std::wstring path, bool is_single_mode) wchar_t exeDir[MAX_PATH] = { 0 }; wchar_t icoPath[MAX_PATH] = { 0 }; wchar_t cfgPath[MAX_PATH] = { 0 }; + wchar_t oldCfgPath[MAX_PATH] = { 0 }; wchar_t conEmuPath[MAX_PATH] = { 0 }; wchar_t args[MAX_PATH * 2 + 256] = { 0 }; @@ -99,20 +113,42 @@ void StartCmder(std::wstring path, bool is_single_mode) PathRemoveFileSpec(exeDir); PathCombine(icoPath, exeDir, L"icons\\cmder.ico"); - PathCombine(cfgPath, exeDir, L"config\\ConEmu-%COMPUTERNAME%.xml"); + + // Check for machine-specific config file. + PathCombine(oldCfgPath, exeDir, L"config\\ConEmu-%COMPUTERNAME%.xml"); + ExpandEnvironmentStrings(oldCfgPath, oldCfgPath, sizeof(oldCfgPath) / sizeof(oldCfgPath[0])); + if (!PathFileExists(oldCfgPath)) { + PathCombine(oldCfgPath, exeDir, L"config\\ConEmu.xml"); + } + + // Check for machine-specific config file. + PathCombine(cfgPath, exeDir, L"vendor\\conemu-maximus5\\ConEmu-%COMPUTERNAME%.xml"); ExpandEnvironmentStrings(cfgPath, cfgPath, sizeof(cfgPath) / sizeof(cfgPath[0])); if (!PathFileExists(cfgPath)) { - PathCombine(cfgPath, exeDir, L"config\\ConEmu.xml"); + PathCombine(cfgPath, exeDir, L"vendor\\conemu-maximus5\\ConEmu.xml"); } + PathCombine(conEmuPath, exeDir, L"vendor\\conemu-maximus5\\ConEmu.exe"); + if (FileExists(oldCfgPath) && !FileExists(cfgPath)) + { + if (!CopyFile(oldCfgPath, cfgPath, FALSE)) + { + MessageBox(NULL, + (GetLastError() == ERROR_ACCESS_DENIED) + ? L"Failed to copy ConEmu.xml file to new location! Restart cmder as administrator." + : L"Failed to copy ConEmu.xml file to new location!", MB_TITLE, MB_ICONSTOP); + exit(1); + } + } + if (is_single_mode) { - swprintf_s(args, L"/single /Icon \"%s\" /Title Cmder /LoadCfgFile \"%s\"", icoPath, cfgPath); + swprintf_s(args, L"/single /Icon \"%s\" /Title Cmder", icoPath); } else { - swprintf_s(args, L"/Icon \"%s\" /Title Cmder /LoadCfgFile \"%s\"", icoPath, cfgPath); + swprintf_s(args, L"/Icon \"%s\" /Title Cmder", icoPath); } SetEnvironmentVariable(L"CMDER_ROOT", exeDir); diff --git a/msvcp120.dll b/msvcp120.dll deleted file mode 100644 index a237d2d..0000000 Binary files a/msvcp120.dll and /dev/null differ diff --git a/msvcr120.dll b/msvcr120.dll deleted file mode 100644 index 8c36149..0000000 Binary files a/msvcr120.dll and /dev/null differ diff --git a/packignore b/packignore index b459393..d72b3ed 100644 --- a/packignore +++ b/packignore @@ -4,6 +4,15 @@ launcher .git *.rb build +scripts config\.history packignore +icons\Thumbs.db +icons\cmder_icon.psd +icons\icon_16.png +icons\icon_32.png +icons\icon_48.png +icons\icon_256.png Cmder.bat +vendor\tmp +appveyor.yml diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 1f37096..df30fbb 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -11,11 +11,11 @@ .EXAMPLE .\build.ps1 - Executes the default build for cmder; Conemu, clink. This is equivalent to the "minimum" style package in the releases + Executes the default build for Cmder; Conemu, clink. This is equivalent to the "minimum" style package in the releases .EXAMPLE - .\build.ps1 -Full + .\build.ps1 -Compile - Executes a full build for cmder, including git. This is equivalent to the "full" style package in the releases + Recompile the launcher executable if you have the requisite build tools for C++ installed. .EXAMPLE .\build -verbose @@ -29,7 +29,7 @@ Samuel Vasko, Jack Bennett Part of the Cmder project. .LINK - https://github.com/bliker/cmder - Project Home + http://cmder.net/ - Project Home #> [CmdletBinding(SupportsShouldProcess=$true)] Param( @@ -46,8 +46,11 @@ Param( # Launcher folder location [string]$launcher = "..\launcher", - # Include git with the package build - [switch]$Full, + # Config folder location + [string]$config = "..\config", + + # New launcher if you have MSBuild tools installed + [switch]$Compile ) . "$PSScriptRoot\utils.ps1" @@ -59,31 +62,52 @@ $sources = Get-Content $sourcesPath | Out-String | Convertfrom-Json # Check for requirements Ensure-Exists $sourcesPath Ensure-Executable "7z" +New-Item -Type Directory -Path (Join-Path $saveTo "/tmp/") -ErrorAction SilentlyContinue >$null +# Preserve modified (by user) ConEmu setting file +if ($config -ne "") { + $ConEmuXml = Join-Path $saveTo "conemu-maximus5\ConEmu.xml" + if (Test-Path $ConEmuXml -pathType leaf) { + $ConEmuXmlSave = Join-Path $config "ConEmu.xml" + Write-Verbose "Backup '$ConEmuXml' to '$ConEmuXmlSave'" + Copy-Item $ConEmuXml $ConEmuXmlSave + } else { $ConEmuXml = "" } +} else { $ConEmuXml = "" } + +$vend = $pwd foreach ($s in $sources) { - if($Full -eq $false -and $s.name -eq "msysgit"){ - Continue - } - Write-Verbose "Getting $($s.name) from URL $($s.url)" # We do not care about the extensions/type of archive - $tempArchive = "$($s.name).tmp" + $tempArchive = "tmp/$($s.name).tmp" Delete-Existing $tempArchive Delete-Existing $s.name - Invoke-WebRequest -Uri $s.url -OutFile $tempArchive -ErrorAction Stop + Download-File -Url $s.url -File $vend\$tempArchive -ErrorAction Stop Extract-Archive $tempArchive $s.name if ((Get-Childitem $s.name).Count -eq 1) { Flatten-Directory($s.name) } + # Write current version to .cmderver file, for later. + "$($s.version)" | Out-File "$($s.name)/.cmderver" +} + +# Restore user configuration +if ($ConEmuXml -ne "") { + Write-Verbose "Restore '$ConEmuXmlSave' to '$ConEmuXml'" + Copy-Item $ConEmuXmlSave $ConEmuXml } Pop-Location -Push-Location -Path $launcher -msbuild CmderLauncher.vcxproj /p:configuration=Release -Pop-Location +if($Compile) { + Push-Location -Path $launcher + msbuild CmderLauncher.vcxproj /p:configuration=Release + Pop-Location +} else { + Write-Warning "You are not building a launcher, Use -Compile" + Write-Warning "This cannot be a release. Test build only!" +} Write-Verbose "All good and done!" diff --git a/scripts/pack.ps1 b/scripts/pack.ps1 index 78e8af7..a0956c5 100644 --- a/scripts/pack.ps1 +++ b/scripts/pack.ps1 @@ -16,10 +16,10 @@ Creates default archives for cmder with plenty of information .NOTES AUTHORS - Samuel Vasko, Jack Bennett + Samuel Vasko, Jack Bennett, Martin Kemp Part of the Cmder project. .LINK - https://github.com/bliker/cmder - Project Home + https://github.com/cmderdev/cmder - Project Home #> [CmdletBinding(SupportsShouldProcess=$true)] @@ -42,10 +42,11 @@ Ensure-Executable "7z" $targets = @{ "cmder.zip" = $null; "cmder.7z" = $null; - "cmder_mini.zip" = "-x!`"vendor\msysgit`""; + "cmder_mini.zip" = "-x!`"vendor\git-for-windows`""; } Delete-Existing "..\Version*" +Delete-Existing "..\build\*" $version = Invoke-Expression "git describe --abbrev=0 --tags" (New-Item -ItemType file "$cmderRoot\Version $version") | Out-Null diff --git a/scripts/utils.ps1 b/scripts/utils.ps1 index 714c983..9c5679a 100644 --- a/scripts/utils.ps1 +++ b/scripts/utils.ps1 @@ -13,7 +13,7 @@ function Ensure-Executable ($command) { set-alias -Name "7z" -Value "$env:programfiles\7-zip\7z.exe" -Scope script } ElseIf( ($command -eq "7z") -and (Test-Path "$env:programw6432\7-zip\7z.exe") ) { - set-alias -Name "7z" -Value "$env:programw6432\7-zip\7z.exe" -Scope script + set-alias -Name "7z" -Value "$env:programw6432\7-zip\7z.exe" -Scope script } Else { Write-Error "Missing $command! Ensure it is installed and on in the PATH" @@ -28,7 +28,7 @@ function Delete-Existing ($path) { } function Extract-Archive ($source, $target) { - Invoke-Expression "7z x -y -o$($target) $source > `$null" + Invoke-Expression "7z x -y -o$($target) '$source' > `$null" if ($lastexitcode -ne 0) { Write-Error "Extracting of $source failied" } @@ -54,5 +54,51 @@ function Flatten-Directory ($name) { } function Digest-MD5 ($path) { + if(Get-Command Get-FileHash -ErrorAction SilentlyContinue){ + return (Get-FileHash -Algorithm MD5 -Path $path).Hash + } + return Invoke-Expression "md5sum $path" } + +function Register-Cmder(){ + [CmdletBinding()] + Param + ( + # Text for the context menu item. + $MenuText = "Cmder Here" + + , # Defaults to the current cmder directory when run from cmder. + $PathToExe = (Join-Path $env:CMDER_ROOT "cmder.exe") + + , # Commands the context menu will execute. + $Command = "%V" + + , # Defaults to the icons folder in the cmder package. + $icon = (Split-Path $PathToExe | join-path -ChildPath 'icons/cmder.ico') + ) + Begin + { + New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT + } + Process + { + New-Item -Path "HKCR:\Directory\Shell\Cmder" -Force -Value $MenuText + New-ItemProperty -Path "HKCR:\Directory\Shell\Cmder" -Force -Name "Icon" -Value `"$icon`" + New-ItemProperty -Path "HKCR:\Directory\Shell\Cmder" -Force -Name "NoWorkingDirectory" + New-Item -Path "HKCR:\Directory\Shell\Cmder\Command" -Force -Value "`"$PathToExe`" `"$Command`" " + } +} + +function Download-File { + param ( + $Url, + $File + ) + # I think this is the problem + $File = $File -Replace "/", "\" + Write-Verbose "Downloading from $Url to $File" + $wc = new-object System.Net.WebClient + $wc.Proxy.Credentials=[System.Net.CredentialCache]::DefaultNetworkCredentials; + $wc.DownloadFile($Url, $File) +} diff --git a/vendor/init.bat b/vendor/init.bat index bf36eac..0814411 100644 --- a/vendor/init.bat +++ b/vendor/init.bat @@ -1,10 +1,12 @@ :: Init Script for cmd.exe -:: Sets some nice defaults :: Created as part of cmder project +:: !!! THIS FILE IS OVERWRITTEN WHEN CMDER IS UPDATED +:: !!! Use "%CMDER_ROOT%\config\user-startup.cmd" to add your own startup commands + :: Find root dir @if not defined CMDER_ROOT ( - for /f %%i in ("%ConEmuDir%\..\..") do @set CMDER_ROOT=%%~fi + for /f "delims=" %%i in ("%ConEmuDir%\..\..") do @set CMDER_ROOT=%%~fi ) :: Change the prompt style @@ -21,15 +23,30 @@ :: Run clink @"%CMDER_ROOT%\vendor\clink\clink_x%architecture%.exe" inject --quiet --profile "%CMDER_ROOT%\config" -:: Prepare for msysgit +:: Prepare for git-for-windows :: I do not even know, copypasted from their .bat @set PLINK_PROTOCOL=ssh @if not defined TERM set TERM=cygwin +:: Check if msysgit is installed +@if exist "%ProgramFiles%\Git" ( + set "GIT_INSTALL_ROOT=%ProgramFiles%\Git" +) else if exist "%ProgramFiles(x86)%\Git" ( + set "GIT_INSTALL_ROOT=%ProgramFiles(x86)%\Git" +) else if exist "%CMDER_ROOT%\vendor" ( + set "GIT_INSTALL_ROOT=%CMDER_ROOT%\vendor\git-for-windows" +) + +:: Add git to the path +@if defined GIT_INSTALL_ROOT ( + set "PATH=%GIT_INSTALL_ROOT%\bin;%GIT_INSTALL_ROOT%\usr\bin;%GIT_INSTALL_ROOT%\usr\share\vim\vim74;%PATH%" + :: define SVN_SSH so we can use git svn with ssh svn repositories + if not defined SVN_SSH set "SVN_SSH=%GIT_INSTALL_ROOT:\=\\%\\bin\\ssh.exe" +) + :: Enhance Path -@set git_install_root=%CMDER_ROOT%\vendor\msysgit -@set PATH=%CMDER_ROOT%\bin;%git_install_root%\bin;%git_install_root%\mingw\bin;%git_install_root%\cmd;%git_install_root%\share\vim\vim74;%CMDER_ROOT%;%PATH% +@set PATH=%CMDER_ROOT%\bin;%PATH%;%CMDER_ROOT% :: Add aliases @doskey /macrofile="%CMDER_ROOT%\config\aliases" @@ -45,4 +62,17 @@ ) ) -:: @call "%CMDER_ROOT%/bin/agent.cmd" +@if exist "%CMDER_ROOT%\config\user-startup.cmd" ( + @rem create this file and place your own command in there + call "%CMDER_ROOT%\config\user-startup.cmd" +) else ( + @echo Creating user startup file: "%CMDER_ROOT%\config\user-startup.cmd" + ( + @echo :: use this file to run your own startup commands + @echo :: use @ in front of the command to prevent printing the command + @echo. + @echo :: @call "%%GIT_INSTALL_ROOT%%/cmd/start-ssh-agent.cmd + @echo :: @set PATH=%%CMDER_ROOT%%\vendor\whatever;%%PATH%% + @echo. + ) > "%CMDER_ROOT%\config\user-startup.cmd" +) diff --git a/vendor/profile.ps1 b/vendor/profile.ps1 index 45d88c2..cc3850c 100644 --- a/vendor/profile.ps1 +++ b/vendor/profile.ps1 @@ -1,25 +1,54 @@ -# Global modules directory -$global:PsGetDestinationModulePath = $PSScriptRoot + "\..\vendor\psmodules" +# Init Script for PowerShell +# Created as part of cmder project -# Push to modules location -Push-Location -Path ($PsGetDestinationModulePath) +# !!! THIS FILE IS OVERWRITTEN WHEN CMDER IS UPDATED +# !!! Use "%CMDER_ROOT%\config\user-profile.ps1" to add your own startup commands -# Load modules from current directory -Get-ChildItem -Directory | ` -Foreach-Object{ - Import-Module .\$_\$_ +# Compatibility with PS major versions <= 2 +if(!$PSScriptRoot) { + $PSScriptRoot = Split-Path $Script:MyInvocation.MyCommand.Path } -# Come back to PWD -Pop-Location +# Add Cmder modules directory to the autoload path. +$CmderModulePath = Join-path $PSScriptRoot "psmodules/" + +if( -not $env:PSModulePath.Contains($CmderModulePath) ){ + $env:PSModulePath = $env:PSModulePath.Insert(0, "$CmderModulePath;") +} + +try { + # Check if git is on PATH, i.e. Git already installed on system + Get-command -Name "git" -ErrorAction Stop >$null +} catch { + $env:Path += ";$env:CMDER_ROOT\vendor\git-for-windows\bin" +} + +try { + Import-Module -Name "posh-git" -ErrorAction Stop >$null + $gitStatus = $true +} catch { + Write-Warning "Missing git support, install posh-git with 'Install-Module posh-git' and restart cmder." + $gitStatus = $false +} + +function checkGit($Path) { + if (Test-Path -Path (Join-Path $Path '.git/') ) { + Write-VcsStatus + return + } + $SplitPath = split-path $path + if ($SplitPath) { + checkGit($SplitPath) + } +} # Set up a Cmder prompt, adding the git prompt parts inside git repos function global:prompt { $realLASTEXITCODE = $LASTEXITCODE - $Host.UI.RawUI.ForegroundColor = "white" - Write-Host($pwd.ProviderPath) -NoNewLine -ForegroundColor "green" - if (Get-Module posh-git) { - Write-VcsStatus + $Host.UI.RawUI.ForegroundColor = "White" + Write-Host $pwd.ProviderPath -NoNewLine -ForegroundColor Green + if($gitStatus){ + checkGit($pwd.ProviderPath) } $global:LASTEXITCODE = $realLASTEXITCODE Write-Host "`nλ" -NoNewLine -ForegroundColor "DarkGray" @@ -27,8 +56,7 @@ function global:prompt { } # Load special features come from posh-git -if (Get-Module posh-git) { - Enable-GitColors +if ($gitStatus) { Start-SshAgent -Quiet } @@ -38,3 +66,16 @@ if (Test-Path Env:\CMDER_START) { } elseif ($Env:CMDER_ROOT -and $Env:CMDER_ROOT.StartsWith($pwd)) { Set-Location -Path $Env:USERPROFILE } + +# Enhance Path +$env:Path = "$Env:CMDER_ROOT\bin;$env:Path;$Env:CMDER_ROOT" + + +$CmderUserProfilePath = Join-Path $env:CMDER_ROOT "config/user-profile.ps1" +if(Test-Path $CmderUserProfilePath) { + # Create this file and place your own command in there. + . "$CmderUserProfilePath" +} else { + Write-Host "Creating user startup file: $CmderUserProfilePath" + "# Use this file to run your own startup commands" | Out-File $CmderUserProfilePath +} \ No newline at end of file diff --git a/vendor/psmodules/PsGet/PsGet.psd1 b/vendor/psmodules/PsGet/PsGet.psd1 deleted file mode 100644 index 5534b73..0000000 --- a/vendor/psmodules/PsGet/PsGet.psd1 +++ /dev/null @@ -1,88 +0,0 @@ -@{ -# These modules will be processed when the module manifest is loaded. This is only supported in PS 3.0 -#RootModule = "PsGet.psm1" - -#This is required for PS 2.0 -ModuleToProcess = "PsGet.psm1" - -# The version of this module. -ModuleVersion = '1.0' - -# This GUID is used to uniquely identify this module. -GUID = '638FF397-8108-4B94-981A-D9BDAB4774B2' - -# The author of this module. -Author = 'Mike Chaliy' - -# The company or vendor for this module. -CompanyName = '' - -# The copyright statement for this module. -Copyright = '(c) 2013' - -# Description of the functionality provided by this module -Description = 'PsGet module for installing PowerShell modules' - -# Minimum version of the Windows PowerShell engine required by this module -PowerShellVersion = '2.0' - -# Name of the Windows PowerShell host required by this module -# PowerShellHostName = '' - -# Minimum version of the Windows PowerShell host required by this module -# PowerShellHostVersion = '' - -# Minimum version of the .NET Framework required by this module -DotNetFrameworkVersion = '2.0' - -# Minimum version of the common language runtime (CLR) required by this module -CLRVersion = '2.0' - -# Processor architecture (None, X86, Amd64) required by this module -ProcessorArchitecture = 'None' - -# Modules that must be imported into the global environment prior to importing this module -# RequiredModules = @() - -# Assemblies that must be loaded prior to importing this module -# RequiredAssemblies = @() - -# Script files (.ps1) that are run in the caller's environment prior to importing this module. -# ScriptsToProcess = @() - -# Type files (.ps1xml) to be loaded when importing this module -# TypesToProcess = @() - -# Format files (.ps1xml) to be loaded when importing this module -# FormatsToProcess = @() - -# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess -NestedModules = @() - -# Functions to export from this module -FunctionsToExport = '*' - -# Cmdlets to export from this module -CmdletsToExport = '*' - -# Variables to export from this module -VariablesToExport = '*' - -# Aliases to export from this module -AliasesToExport = '*' - -# List of all modules packaged with this module. -# ModuleList = @() - -# List of all files packaged with this module -# FileList = @() - -# Private data to pass to the module specified in RootModule/ModuleToProcess -# PrivateData = '' - -# HelpInfo URI of this module -# HelpInfoURI = '' - -# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. -# DefaultCommandPrefix = '' -} \ No newline at end of file diff --git a/vendor/sources.json b/vendor/sources.json index c508f5e..69f9ab6 100644 --- a/vendor/sources.json +++ b/vendor/sources.json @@ -1,17 +1,22 @@ [ { - "name": "msysgit", - "version": "1.9.5-preview", - "url": "https://github.com/msysgit/msysgit/releases/download/Git-1.9.5-preview20141217/PortableGit-1.9.5-preview20141217.7z" + "name": "git-for-windows", + "version": "v2.6.2.windows.1", + "url": "https://github.com/git-for-windows/git/releases/download/v2.6.2.windows.1/PortableGit-2.6.2-32-bit.7z.exe" }, { "name": "clink", - "version": "0.4.4", - "url": "https://github.com/mridgers/clink/releases/download/0.4.4/clink_0.4.4.zip" + "version": "0.4.5", + "url": "https://github.com/mridgers/clink/releases/download/0.4.5/clink_0.4.5.zip" }, { "name": "conemu-maximus5", - "version": "150215", - "url": "https://conemu.codeplex.com/downloads/get/1430634" + "version": "151025", + "url": "https://github.com/Maximus5/ConEmu/releases/download/v15.10.25/ConEmuPack.151025.7z" + }, + { + "name": "clink-completions", + "version": "0.2.1", + "url": "https://github.com/vladimir-kotikov/clink-completions/archive/0.2.1.zip" } ]