├── demo.gif ├── Default (Linux).sublime-keymap ├── Default (OSX).sublime-keymap ├── Default (Windows).sublime-keymap ├── Default.sublime-commands ├── .gitignore ├── LICENSE ├── ShellExec.sublime-settings ├── README.md └── ShellExec.py /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbaptista/sublime-3-shell-exec/HEAD/demo.gif -------------------------------------------------------------------------------- /Default (Linux).sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | { "keys": ["ctrl+shift+c"], "command": "shell_exec_open" } 3 | ] 4 | -------------------------------------------------------------------------------- /Default (OSX).sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | { "keys": ["shift+super+c"], "command": "shell_exec_open" } 3 | ] 4 | -------------------------------------------------------------------------------- /Default (Windows).sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | { "keys": ["shift+ctrl+c"], "command": "shell_exec_open" } 3 | ] 4 | -------------------------------------------------------------------------------- /Default.sublime-commands: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "caption": "Shell Exec: Open", 4 | "command": "shell_exec_open" 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | 26 | # PyInstaller 27 | # Usually these files are written by a python script from a template 28 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 29 | *.manifest 30 | *.spec 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | 36 | # Unit test / coverage reports 37 | htmlcov/ 38 | .tox/ 39 | .coverage 40 | .coverage.* 41 | .cache 42 | nosetests.xml 43 | coverage.xml 44 | *,cover 45 | 46 | # Translations 47 | *.mo 48 | *.pot 49 | 50 | # Django stuff: 51 | *.log 52 | 53 | # Sphinx documentation 54 | docs/_build/ 55 | 56 | # PyBuilder 57 | target/ 58 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Guilherme Baptista 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /ShellExec.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | // You can use this file to load RVM, ~/.bashrc, custom shell functions... 3 | // "shell_exec_load_sh_file": "your-sh-file-to-load-before-commands.sh", 4 | 5 | // Shell executable: "/bin/bash", "/bin/sh", "/usr/bin/zsh"... 6 | "shell_exec_executable": "/bin/bash", 7 | 8 | // Shell executable option: --login # Run as login load your ~/.bashrc or other user settings. 9 | "shell_exec_executable_option": "--login", // ["-l"] ["--login"] 10 | 11 | // The output of the command can be shown on the Panel or in a New File: "panel", "file" or "none". 12 | "shell_exec_output": "file", 13 | 14 | // Set the Output File Syntax. Default is Ruby, because Ruby looks nice. =) 15 | "shell_exec_output_syntax": "Ruby", 16 | 17 | // Enable or Disable the word wrap at the Output File. 18 | "shell_exec_output_word_wrap": true, 19 | 20 | // Enable or Disable the Debug infos (for plugin developers). 21 | "shell_exec_debug": false, 22 | 23 | // Name of the Shell Exec command box. 24 | "shell_exec_title": "Shell Exec", 25 | 26 | // Defines where the command should be executed: false, "project_folder" or "file_folder". 27 | // If "project_folder" is set, will execute: cd project_folder && your_commnad. 28 | "shell_exec_context": "project_folder" 29 | } 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Shell Exec 2 | 3 | Run shell commands like git, rvm, rspec, ls, etc. with Bash, Zsh and others inside your Sublime Text 3. 4 | 5 | ![Demo: RSpec inside Sublime](https://raw.githubusercontent.com/gbaptista/sublime-3-shell-exec/master/demo.gif) 6 | 7 | * [Command Palette](#command-palette) 8 | * [Default Shortcuts](#default-shortcuts) 9 | * [Settings](#settings) 10 | * [Custom Shortcuts](#custom-shortcuts) 11 | - [Command Format Syntax](#command-format-syntax) 12 | * [Common Problems](#common-problems) 13 | - [RVM Command, ~/.bashrc, ~/.bash_profile, ~/.zshrc...](#rvm-command-bashrc-bash_profile-zshrc) 14 | - [Debugging](#debugging) 15 | * [Some Cool Demos](#some-cool-demos) 16 | - [Git](#git) 17 | - [RSpec](#rspec) 18 | - [Unix](#unix) 19 | 20 | ### Command Palette 21 | 22 | Shell Exec: Open `shell_exec_open` 23 | 24 | ### Default Shortcuts 25 | * Linux: _ctrl + shift + c_ 26 | * Mac: _shift + super + c_ 27 | * Windows: _ctrl + shift + c_ 28 | 29 | ### Settings 30 | 31 | `User/Preferences.sublime-settings`: 32 | ```javascript 33 | // You can use this file to load RVM, ~/.bashrc, custom shell functions... 34 | // "shell_exec_load_sh_file": "your-sh-file-to-load-before-commands.sh", 35 | 36 | // Shell executable: "/bin/bash", "/bin/sh", "/usr/bin/zsh"... 37 | "shell_exec_executable": "/bin/bash", 38 | 39 | // Shell executable option: --login # Run as login load your ~/.bashrc or other user settings. 40 | "shell_exec_executable_option": "--login", // ["-l"] ["--login"] 41 | 42 | // The output of the command can be shown on the Panel or in a New File: "panel", "file" or "none". 43 | "shell_exec_output": "file", 44 | 45 | // Set the Output File Syntax. Default is Ruby, because Ruby looks nice. =) 46 | "shell_exec_output_syntax": "Ruby", 47 | 48 | // Enable or Disable the word wrap at the Output File. 49 | "shell_exec_output_word_wrap": true, 50 | 51 | // Enable or Disable the Debug infos (for plugin developers). 52 | "shell_exec_debug": false, 53 | 54 | // Name of the Shell Exec command box. 55 | "shell_exec_title": "Shell Exec", 56 | 57 | // Defines where the command should be executed: false, "project_folder" or "file_folder". 58 | // If "project_folder" is set, will execute: cd project_folder && your_commnad. 59 | "shell_exec_context": "project_folder", 60 | ``` 61 | 62 | ### Custom Shortcuts 63 | `shell_exec_open`: Open Shell Exec box to input some command. 64 | 65 | `shell_exec_run`: Runs a predefined command. 66 | 67 | `User/Default (Linux).sublime-keymap`: 68 | ```javascript 69 | { 70 | // (ctrl+shift+c+o) key binding 71 | "keys": ["ctrl+shift+c", "ctrl+shift+o"], 72 | 73 | // "shell_exec_open": Open Shell Exec box to input some command. 74 | // "shell_exec_run": Runs a predefined command. 75 | "command": "shell_exec_open", 76 | 77 | "args": { 78 | // Title of the Shell Exec box. 79 | "title": "Shell Exec", 80 | 81 | // Predefined command. 82 | "command": "git status", 83 | 84 | // Format the command with variables. 85 | "format": "git ${input}", 86 | 87 | // You can use this file to load RVM, ~/.bashrc, custom shell functions... 88 | // "load_sh_file": "your-sh-file-to-load-before-commands.sh", 89 | 90 | // Shell executable: "/bin/bash", "/bin/sh", "/usr/bin/zsh"... 91 | "executable": "/bin/bash", 92 | 93 | // Shell executable option: --login # Run as login load your ~/.bashrc or other user settings. 94 | "executable_option": "--login", // ["-l"] ["--login"] 95 | 96 | // The output of the command can be shown on the Panel or in a New File: "panel", "file". 97 | "output": "file", 98 | 99 | // Set the Output File Syntax. Default is Ruby, because Ruby looks nice. =) 100 | "output_syntax": "Ruby", 101 | 102 | // Enable or Disable the word wrap at the Output File. 103 | "output_word_wrap": true, 104 | 105 | // Enable or Disable the Debug infos (for plugin developers). 106 | "debug": false, 107 | 108 | // Name of the Shell Exec command box. 109 | "title": "Shell Exec", 110 | 111 | // Defines where the command should be executed: false, "project_folder" or "file_folder". 112 | // If "project_folder" is set, will execute: cd project_folder && your_commnad. 113 | "context": "project_folder", 114 | } 115 | } 116 | ``` 117 | 118 | #### Command Format Syntax 119 | ```javascript 120 | // (ctrl+shift+c+f) key binding 121 | "keys": ["ctrl+shift+c", "ctrl+shift+f"], 122 | 123 | // "shell_exec_open": Open Shell Exec box to input some command. 124 | // "shell_exec_run": Runs a predefined command. 125 | "command": "shell_exec_exec", 126 | 127 | "args": { 128 | // Format the command with variables. 129 | "format": "rspec '${file}:${row}'" 130 | } 131 | ``` 132 | Available variables: 133 | * `${input}`: _Input from Shell Exec box._ 134 | * `${region}`: _Selected text._ 135 | * `${row}`: _Selected row number or the cursor position at file._ 136 | * `${file_name}`: _ShellExec.py_ 137 | * `${file}`: _/home/user/.config/sublime-text-3/Packages/shell-exec/ShellExec.py_ 138 | * `${packages}`: _/home/user/.config/sublime-text-3/Packages_ 139 | * `${file_base_name}`: _ShellExec_ 140 | * `${platform}`: _Linux_ 141 | * `${file_extension}`: _py_ 142 | * `${file_path}`: _/home/user/.config/sublime-text-3/Packages/shell-exec_ 143 | * `${folder}`: _/home/user/.config/sublime-text-3/Packages/shell-exec_ 144 | 145 | ### Common Problems 146 | 147 | #### RVM Command, ~/.bashrc, ~/.bash_profile, ~/.zshrc... 148 | 149 | You can load RVM and profile files with login mode: 150 | ```javascript 151 | // Shell executable: "/bin/bash", "/bin/sh", "/usr/bin/zsh"... 152 | "shell_exec_executable": "/bin/bash", 153 | 154 | // Shell executable option: --login # Run as login load your ~/.bashrc or other user settings. 155 | "shell_exec_executable_option": "--login", // ["-l"] ["--login"] 156 | ``` 157 | 158 | Or... You can load a custom sh file: 159 | ```javascript 160 | "shell_exec_load_sh_file": "my-config-loader-file.sh" 161 | ``` 162 | 163 | `my-config-loader-file.sh`: Loading ~/.bashrc simulating interactive shell: 164 | ```shell 165 | PS1=true # Simulate Interactive Shell 166 | source ~/.bashrc 167 | ``` 168 | 169 | `my-config-loader-file.sh`: Loading RVM command: 170 | ```shell 171 | export PATH="$PATH:$HOME/.rvm/bin" # Add RVM to PATH for scripting 172 | [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" 173 | ``` 174 | 175 | #### Debugging 176 | Just enable the debug to see panel outputs: 177 | `User/Preferences.sublime-settings`: 178 | ```javascript 179 | // Enable or Disable the Debug infos (for plugin developers). 180 | "shell_exec_debug": true, 181 | ``` 182 | 183 | ### Some Cool Demos 184 | #### Git 185 | ```javascript 186 | { 187 | "keys": ["ctrl+shift+g", "ctrl+shift+g"], 188 | "command": "shell_exec_open", 189 | "args": { "title": "Git Command:", "format": "git ${input}" } 190 | }, 191 | { 192 | "keys": ["ctrl+shift+g", "ctrl+shift+c"], 193 | "command": "shell_exec_open", 194 | "args": { 195 | "title": "Git Checkout:", 196 | "format": "git checkout ${input}", 197 | "command": "'${file}'" 198 | } 199 | }, 200 | { 201 | "keys": ["ctrl+shift+g", "ctrl+shift+s"], 202 | "command": "shell_exec_run", 203 | "args": { "command": "git status" } 204 | }, 205 | { 206 | "keys": ["ctrl+shift+g", "ctrl+shift+d", "ctrl+shift+a"], 207 | "command": "shell_exec_run", 208 | "args": { "command": "git diff", "output_syntax": "Diff" } 209 | }, 210 | { 211 | "keys": ["ctrl+shift+g", "ctrl+shift+d", "ctrl+shift+f"], 212 | "command": "shell_exec_run", 213 | "args": { "command": "git diff '${file}'", "output_syntax": "Diff" } 214 | }, 215 | { 216 | "keys": ["ctrl+shift+g", "ctrl+shift+b"], 217 | "command": "shell_exec_run", 218 | "args": { "command": "git blame '${file}'", "output_syntax": "Git Blame" } 219 | } 220 | ``` 221 | 222 | #### RSpec 223 | ```javascript 224 | { 225 | "keys": ["ctrl+shift+r", "ctrl+shift+r"], 226 | "command": "shell_exec_open", 227 | "args": { 228 | "title": "RSpec Command:", "format": "rspec ${input} --require spec_helper" 229 | } 230 | }, 231 | { 232 | "keys": ["ctrl+shift+r", "ctrl+shift+o"], 233 | "command": "shell_exec_open", 234 | "args": { 235 | "title": "RSpec Command:", 236 | "command": "'${file}:${row}'", 237 | "format": "rspec ${input} --require spec_helper" 238 | } 239 | }, 240 | { 241 | "keys": ["ctrl+shift+r", "ctrl+shift+a"], 242 | "command": "shell_exec_run", 243 | "args": { "command": "rspec spec --require spec_helper" } 244 | }, 245 | { 246 | "keys": ["ctrl+shift+r", "ctrl+shift+f"], 247 | "command": "shell_exec_run", 248 | "args": { "command": "rspec '${file}' --require spec_helper" } 249 | }, 250 | { 251 | "keys": ["ctrl+shift+r", "ctrl+shift+l"], 252 | "command": "shell_exec_run", 253 | "args": { "command": "rspec '${file}:${row}' --require spec_helper" } 254 | }, 255 | { 256 | "keys": ["ctrl+shift+r", "ctrl+shift+s"], 257 | "command": "shell_exec_run", 258 | "args": { "command": "rspec '${region}' --require spec_helper" } 259 | } 260 | ``` 261 | 262 | #### Unix 263 | ```javascript 264 | { 265 | "keys": ["ctrl+shift+u", "ctrl+shift+p"], 266 | "command": "shell_exec_open", 267 | "args": { 268 | "title": "Find Process", 269 | "format": "ps aux | grep ${input}" 270 | } 271 | } 272 | ``` 273 | -------------------------------------------------------------------------------- /ShellExec.py: -------------------------------------------------------------------------------- 1 | import sys, time, sublime, sublime_plugin, re 2 | from subprocess import Popen, PIPE, STDOUT 3 | from threading import Thread 4 | 5 | class ShellExecRun(sublime_plugin.TextCommand): 6 | def run(self, edit, **args): 7 | self.args = args 8 | 9 | if ShellExec.get_setting('debug', self.args): 10 | print("\n\n>>>>>>>>>>>>>>>>>> Start Shell Exec Debug:") 11 | 12 | if not args.get("command"): 13 | args["command"] = "" 14 | 15 | ShellExec.run_shell_command(self.args, self.view, args.get("command")) 16 | 17 | class ShellExecOpen(sublime_plugin.TextCommand): 18 | def run(self, edit, **args): 19 | self.args = args 20 | 21 | if ShellExec.get_setting('debug', self.args): 22 | print("\n\n>>>>>>>>>>>>>>>>>> Start Shell Exec Debug:") 23 | 24 | command = "" 25 | 26 | if args.get("command"): 27 | command = ShellExec.command_variables(args, self.view, args["command"], False) 28 | 29 | def runShellExec(user_command): 30 | ShellExec.run_shell_command(self.args, self.view, user_command) 31 | 32 | sublime.active_window().show_input_panel(ShellExec.get_setting('title', self.args), command, runShellExec, None, None) 33 | 34 | class ShellExecViewInsertCommand(sublime_plugin.TextCommand): 35 | def run(self, edit, pos, text): 36 | self.view.insert(edit, pos, text) 37 | 38 | class ShellExec: 39 | def __init__(self): 40 | self.output_file = None 41 | self.panel_output = None 42 | 43 | def command_variables(args, view, command, format=True): 44 | if format and args.get("format"): 45 | command = args["format"].replace('${input}', command) 46 | 47 | for region in view.sel(): 48 | (row,col) = view.rowcol(view.sel()[0].begin()) 49 | 50 | command = command.replace('${row}', str(row+1)) 51 | command = command.replace('${region}', view.substr(region)) 52 | break 53 | 54 | # packages, platform, file, file_path, file_name, file_base_name, 55 | # file_extension, folder, project, project_path, project_name, 56 | # project_base_name, project_extension. 57 | command = sublime.expand_variables(command, sublime.active_window().extract_variables()) 58 | 59 | return command 60 | 61 | def load_sh_file(source, path, args): 62 | if(path): 63 | try: 64 | with open(path, encoding='utf-8') as f: 65 | new_source = f.read() 66 | source += "\n" + new_source + "\n" 67 | if ShellExec.get_setting('debug', args): 68 | print(path + ' loaded:') 69 | print('------------------------------------') 70 | print(new_source) 71 | print('------------------------------------') 72 | except: 73 | if ShellExec.get_setting('debug', args): 74 | print(path + ' error: ' + str(sys.exc_info()[0])) 75 | 76 | return source 77 | 78 | def run_shell_command(args, view, command): 79 | command = ShellExec.command_variables(args, view, command) 80 | if 'folder' in sublime.active_window().extract_variables(): 81 | if sublime.platform() == 'windows': 82 | pure_command = command.replace(sublime.active_window().extract_variables()['folder'] + '\\', '') 83 | else: 84 | pure_command = command.replace(sublime.active_window().extract_variables()['folder'] + '/', '') 85 | else: 86 | pure_command = command 87 | 88 | if ShellExec.get_setting('context', args) == 'project_folder': 89 | if 'folder' in sublime.active_window().extract_variables(): 90 | command = "cd '" + sublime.active_window().extract_variables()['folder'] + "' && " + command 91 | if ShellExec.get_setting('context', args) == 'file_folder': 92 | if 'file_path' in sublime.active_window().extract_variables(): 93 | command = "cd '" + sublime.active_window().extract_variables()['file_path'] + "' && " + command 94 | 95 | sublime_shell_source = '' 96 | 97 | sh_file_settings = ShellExec.get_setting('load_sh_file', args, True) 98 | sh_file_shortcut = ShellExec.get_setting('load_sh_file', args, False) 99 | 100 | sublime_shell_source = ShellExec.load_sh_file(sublime_shell_source, sh_file_settings, args) 101 | 102 | if sh_file_settings != sh_file_shortcut: 103 | sublime_shell_source = ShellExec.load_sh_file(sublime_shell_source, sh_file_shortcut, args) 104 | 105 | if ShellExec.get_setting('debug', args): 106 | print('new Thread') 107 | 108 | t = Thread(target=ShellExec.execute_shell_command, args=(sublime_shell_source, command, pure_command, args)) 109 | t.start() 110 | 111 | def new_output_file(args, pure_command): 112 | if ShellExec.get_setting('debug', args): 113 | print('open new empty file: ' + pure_command) 114 | output_file = sublime.active_window().new_file() 115 | output_file.set_name(pure_command[0:60]) 116 | output_file.set_scratch(True) 117 | 118 | if ShellExec.get_setting('output_syntax', args): 119 | if ShellExec.get_setting('debug', args): 120 | print('set output syntax: ' + ShellExec.get_setting('output_syntax', args)) 121 | 122 | if sublime.find_resources(ShellExec.get_setting('output_syntax', args) + '.tmLanguage'): 123 | output_file.set_syntax_file(sublime.find_resources(ShellExec.get_setting('output_syntax', args) + '.tmLanguage')[0]) 124 | 125 | if ShellExec.get_setting('output_word_wrap', args): 126 | output_file.settings().set('word_wrap', True) 127 | else: 128 | output_file.settings().set('word_wrap', False) 129 | 130 | return output_file 131 | 132 | def increment_output(self, value, args, pure_command): 133 | if ShellExec.get_setting('output', args) == "file": 134 | if not self.output_file: 135 | self.output_file = ShellExec.new_output_file(args, pure_command) 136 | 137 | self.output_file.run_command('shell_exec_view_insert', {'pos': self.output_file.size(), 'text': value}) 138 | elif ShellExec.get_setting('output', args) == "none": 139 | self.panel_output = False 140 | else: 141 | if not self.panel_output: 142 | self.panel_output = True 143 | sublime.active_window().run_command('show_panel', {"panel": "console", "toggle": False}) 144 | sys.stdout.write(value) 145 | 146 | def execute_shell_command(sublime_shell_source, command, pure_command, args, return_error=True): 147 | code = sublime_shell_source + "\n" + command 148 | 149 | shell_command_do_gui_instance = ShellExec() 150 | 151 | if ShellExec.get_setting('debug', args): 152 | sublime.active_window().run_command('show_panel', {"panel": "console", "toggle": False}) 153 | print("run command: " + command) 154 | 155 | ShellExec.increment_output(shell_command_do_gui_instance, "> " + pure_command + "\n\n", args, pure_command) 156 | 157 | if return_error: 158 | stderr = STDOUT 159 | else: 160 | stderr = None 161 | 162 | if ShellExec.get_setting('executable_option', args): 163 | if ShellExec.get_setting('debug', args): 164 | print('create Popen: executable=' + ShellExec.get_setting('executable', args) + ' ' + ShellExec.get_setting('executable_option', args)) 165 | console_command = Popen([ShellExec.get_setting('executable', args), ShellExec.get_setting('executable_option', args), '-c', code], shell=False, stderr=stderr, stdout=PIPE) 166 | else: 167 | if ShellExec.get_setting('debug', args): 168 | print('create Popen: executable=' + ShellExec.get_setting('executable', args)) 169 | console_command = Popen(code, executable=ShellExec.get_setting('executable', args), shell=True, stderr=stderr, stdout=PIPE) 170 | 171 | if ShellExec.get_setting('debug', args): 172 | print('waiting for stdout...') 173 | 174 | # TODO: This code is shameful, needs to be improved... 175 | initial_time = time.time() 176 | while True: 177 | diff_time = float(re.sub(r"e-*", '', str(time.time()-initial_time))) 178 | if diff_time > 0.01: 179 | char = str(console_command.stdout.read(1)) # last was slow 180 | initial_time = time.time() 181 | else: 182 | char = str(console_command.stdout.read(10)) # last was fast 183 | initial_time = time.time() 184 | 185 | if not char == "b''": 186 | if re.search(r"^b('|\")", char): 187 | char = re.sub(r"^b('|\")|('|\")$", '', char) 188 | 189 | char = bytes(char, "utf-8").decode("unicode_escape") 190 | ShellExec.increment_output(shell_command_do_gui_instance, char, args, pure_command) 191 | 192 | if console_command.poll() != None: 193 | if ShellExec.get_setting('debug', args): 194 | print('stdout complete!') 195 | 196 | output = str(console_command.stdout.read()) 197 | output = re.sub(r"^b('|\")|('|\")$", '', output) 198 | output = bytes(output, "utf-8").decode("unicode_escape") 199 | output = re.sub(r"\n$", '', output) 200 | 201 | if ShellExec.get_setting('debug', args): 202 | print('send result to output file.') 203 | ShellExec.increment_output(shell_command_do_gui_instance, str(output) + "\n", args, pure_command) 204 | break 205 | 206 | if ShellExec.get_setting('debug', args): 207 | print(">>>>>>>>>>>>>>>>>> Shell Exec Debug Finished!") 208 | 209 | sublime.status_message('Shell Exec | Done! > ' + pure_command[0:60]) 210 | 211 | def get_setting(config, args, force_default=False): 212 | if (not force_default) and args.get(config): 213 | return args[config] 214 | 215 | settings = sublime.load_settings('Preferences.sublime-settings') 216 | if settings.get('shell_exec_' + config): 217 | return settings.get('shell_exec_' + config) 218 | else: 219 | settings = sublime.load_settings('ShellExec.sublime-settings') 220 | return settings.get('shell_exec_' + config) 221 | --------------------------------------------------------------------------------