├── .gitignore ├── .vimrc ├── README.md ├── autoload ├── conque_term.vim └── conque_term │ ├── conque.py │ ├── conque_globals.py │ ├── conque_screen.py │ ├── conque_sole.py │ ├── conque_sole_communicator.py │ ├── conque_sole_shared_memory.py │ ├── conque_sole_subprocess.py │ ├── conque_sole_wrapper.py │ ├── conque_subprocess.py │ └── conque_win32_util.py ├── colors └── smyck.vim ├── plugin └── conque_term.vim └── syntax ├── conque_term.vim └── php.vim /.gitignore: -------------------------------------------------------------------------------- 1 | bundle/* 2 | .VimballRecord 3 | .netrwhist 4 | yankring_history_v2.txt 5 | -------------------------------------------------------------------------------- /.vimrc: -------------------------------------------------------------------------------- 1 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 2 | " The Best vimrc Ever 3 | " Tommy MacWilliam 4 | " 5 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 6 | 7 | " long live vim 8 | set encoding=utf-8 9 | set nocompatible 10 | 11 | " vundle 12 | filetype off 13 | set rtp+=~/.vim/bundle/Vundle.vim 14 | call vundle#begin() 15 | Plugin 'gmarik/Vundle.vim' 16 | 17 | " color schemes 18 | Plugin 'hukl/Smyck-Color-Scheme' 19 | Plugin 'sainnhe/sonokai' 20 | 21 | " plugins 22 | Plugin 'scrooloose/nerdtree' 23 | Plugin 'tpope/vim-fugitive' 24 | Plugin 'jistr/vim-nerdtree-tabs' 25 | Plugin 'tpope/vim-repeat' 26 | Plugin 'tpope/vim-surround' 27 | Plugin 'tomtom/tcomment_vim' 28 | Plugin 'vim-scripts/trailing-whitespace' 29 | Plugin 'terryma/vim-multiple-cursors' 30 | Plugin 'michaeljsmith/vim-indent-object' 31 | Plugin 'gregsexton/gitv' 32 | Plugin 'bling/vim-airline' 33 | Plugin 'Chiel92/vim-autoformat' 34 | Plugin 'junegunn/fzf' 35 | Plugin 'junegunn/fzf.vim' 36 | 37 | " syntax files 38 | Plugin 'pangloss/vim-javascript' 39 | Plugin 'tpope/vim-markdown' 40 | Plugin 'voithos/vim-python-syntax' 41 | Plugin 'groenewege/vim-less' 42 | Plugin 'leafgarland/typescript-vim' 43 | Plugin 'chr4/nginx.vim' 44 | Plugin 'fatih/vim-go' 45 | Plugin 'mxw/vim-jsx' 46 | Plugin 'keith/swift.vim' 47 | Plugin 'rust-lang/rust.vim' 48 | 49 | call vundle#end() 50 | 51 | filetype plugin indent on 52 | 53 | " airline config 54 | let g:airline_powerline_fonts = 1 55 | let g:airline#extensions#tabline#enabled = 1 56 | let g:airline#extensions#tabline#fnamemod = ':t' 57 | let g:airline_theme = 'sonokai' 58 | 59 | " syntax highlighting and auto-indentation 60 | syntax on 61 | filetype indent on 62 | filetype plugin on 63 | inoremap # X# 64 | set ai 65 | set si 66 | set nu 67 | 68 | " fix some filetype detection 69 | au BufRead,BufNewFile *.g4* set filetype=antlr 70 | au BufRead,BufNewFile *.yaml* set filetype=yaml 71 | au BufRead,BufNewFile *.proto* set filetype=proto 72 | au BufRead,BufNewFile Dockerfile* set filetype=dockerfile 73 | au BufRead,BufNewFile *.tsx set filetype=typescript 74 | 75 | let g:formatdef_custom_cpp = '"clang-format -style=file"' 76 | let g:formatdef_custom_html = '"prettier --print-width=100 --parser=html"' 77 | let g:formatdef_custom_java = '"prettier --print-width=100 --parser=java"' 78 | let g:formatdef_custom_javascript = '"prettier --print-width=100 --parser=typescript"' 79 | let g:formatdef_custom_json = '"prettier --print-width=100 --parser=json"' 80 | let g:formatdef_custom_python = '"black -l 100 -q --fast -"' 81 | let g:formatdef_custom_ruby = '"prettier --print-width=100 --parser=ruby"' 82 | let g:formatdef_custom_yaml = '"prettier --print-width=100 --parser=yaml"' 83 | let g:formatters_c = ['custom_cpp'] 84 | let g:formatters_cpp = ['custom_cpp'] 85 | let g:formatters_html = ['custom_html'] 86 | let g:formatters_java = ['custom_java'] 87 | let g:formatters_javascript = ['custom_javascript'] 88 | let g:formatters_json = ['custom_json'] 89 | let g:formatters_markdown = [] 90 | let g:formatters_objcpp = ['custom_cpp'] 91 | let g:formatters_proto = [] 92 | let g:formatters_python = ['custom_python'] 93 | let g:formatters_ruby = ['custom_ruby'] 94 | let g:formatters_typescript = ['custom_javascript'] 95 | let g:formatters_yaml = ['custom_yaml'] 96 | let g:autoformat_autoindent = 0 97 | let g:autoformat_retab = 0 98 | au BufWrite * :Autoformat 99 | 100 | " expand tabs to 2 spaces 101 | set shiftwidth=2 102 | set tabstop=2 103 | set smarttab 104 | set expandtab 105 | 106 | " except 4 spaces for some formats 107 | autocmd Filetype groovy setlocal expandtab tabstop=4 shiftwidth=4 108 | autocmd Filetype markdown setlocal expandtab tabstop=4 shiftwidth=4 109 | autocmd Filetype python setlocal expandtab tabstop=4 shiftwidth=4 110 | autocmd Filetype rust setlocal expandtab tabstop=4 shiftwidth=4 111 | 112 | " omg folding is the worst 113 | set nofoldenable 114 | 115 | " omg automatic comment insertion is the worst 116 | au FileType * setlocal comments-=:// comments+=f:// 117 | 118 | " omg a limit to how many tabs can open is the worst 119 | set tabpagemax=100 120 | 121 | " omg the crazy SQL autocomplete thing is the worst 122 | let g:omni_sql_no_default_maps = 1 123 | 124 | " faster tab navigation 125 | nnoremap :tabprevious 126 | nnoremap :tabnext 127 | 128 | " always show tab line to avoid annoying resize 129 | set showtabline=2 130 | 131 | " searching options 132 | set incsearch 133 | set ignorecase 134 | set smartcase 135 | 136 | " disable backups 137 | set nobackup 138 | set nowritebackup 139 | set noswapfile 140 | 141 | " disable annoying beep on errors 142 | set noerrorbells 143 | if has('autocmd') 144 | autocmd GUIEnter * set vb t_vb= 145 | endif 146 | 147 | " font options 148 | set background=dark 149 | set termguicolors 150 | let g:sonokai_style = 'atlantis' 151 | colorscheme sonokai 152 | 153 | " keep at least 5 lines below the cursor 154 | set scrolloff=5 155 | 156 | " window options 157 | set showmode 158 | set showcmd 159 | set ruler 160 | set ttyfast 161 | set backspace=indent,eol,start 162 | set laststatus=2 163 | 164 | " cursor 165 | if exists('$TMUX') 166 | let &t_SI = "\[5 q" 167 | let &t_EI = "\[0 q" 168 | else 169 | let &t_SI = "\]50;CursorShape=1\x7" 170 | let &t_EI = "\]50;CursorShape=0\x7" 171 | endif 172 | 173 | " enable mouse support 174 | set mouse=a 175 | 176 | " word wrapping 177 | set wrap 178 | set linebreak 179 | set nolist 180 | 181 | " better tab completion on commands 182 | set wildmenu 183 | set wildmode=list:longest 184 | set wildignore+=*.pyc,__pycache__,node_modules,venv,build,*.class,bin/main,bin/test,target,dist 185 | 186 | " close buffer when tab is closed 187 | set nohidden 188 | 189 | " better moving between windows 190 | map j 191 | map k 192 | map h 193 | map l 194 | 195 | " shortcuts to common commands 196 | let mapleader = "," 197 | nnoremap a :Ack 198 | nnoremap b :TlistToggle 199 | nnoremap c :TComment 200 | nnoremap C :TCommentBlock 201 | vnoremap c :TComment 202 | vnoremap C :TCommentBlock 203 | nnoremap e (len(system('git rev-parse')) ? ':tabnew:Files' : ':tabnew:GFiles --exclude-standard --others --cached')."\" 204 | nnoremap g T 205 | nnoremap G 206 | nnoremap h :tabnew:ConqueTerm bash 207 | nnoremap l :NERDTreeTabsToggle 208 | nnoremap o (len(system('git rev-parse')) ? ':Files' : ':GFiles --exclude-standard --others --cached')."\" 209 | nnoremap p :set invpaste 210 | nnoremap t :tabnew 211 | nnoremap s :vsplit 212 | nnoremap w :tabclose 213 | 214 | " ; is better than :, and kj is better than ctrl-c 215 | nnoremap ; : 216 | inoremap kj 217 | 218 | " more logical vertical navigation 219 | nnoremap k gk 220 | nnoremap j gj 221 | 222 | " make copy/pasting nice 223 | function! ToggleMouse() 224 | if &mouse == 'a' 225 | set mouse=r 226 | set nonu 227 | else 228 | set mouse=a 229 | set nu 230 | endif 231 | endfunction 232 | nnoremap m :call ToggleMouse() 233 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Best .vimrc Ever (tm) 2 | 3 | ## Installation: 4 | 5 | mkdir ~/.vim 6 | pip3 install black 7 | sudo npm install --global prettier @prettier/plugin-ruby prettier-plugin-java 8 | git clone git://github.com/tmacwill/vimrc.git ~/.vim 9 | git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim 10 | ln -s ~/.vim/.vimrc ~/.vimrc 11 | vim +BundleInstall +qall 12 | 13 | ## Font 14 | 15 | Using one of the following fonts is recommended: https://github.com/Lokaltog/powerline-fonts. Right now, I use Inconsolata. 16 | 17 | ## Shortcuts 18 | 19 | - ; maps to : 20 | - ,a: ack from the current directory 21 | - ,c: toggle comments 22 | - ,C: toggle block comments 23 | - ,e: open file in new tab 24 | - ,l: toggle NERDTree 25 | - ,h: open a shell in a new tab 26 | - ,m: toggle mouse support 27 | - ,p: toggle paste mode 28 | - ,o: open file 29 | - ,s: split window 30 | - ,t: new tab 31 | - ,w: close tab 32 | - kj: enter normal mode and save 33 | - Ctrl+{h,j,k,l}: move among windows 34 | -------------------------------------------------------------------------------- /autoload/conque_term/conque.py: -------------------------------------------------------------------------------- 1 | # FILE: autoload/conque_term/conque.py 2 | # AUTHOR: Nico Raffo 3 | # WEBSITE: http://conque.googlecode.com 4 | # MODIFIED: 2011-09-02 5 | # VERSION: 2.3, for Vim 7.0 6 | # LICENSE: 7 | # Conque - Vim terminal/console emulator 8 | # Copyright (C) 2009-2011 Nico Raffo 9 | # 10 | # MIT License 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining a copy 13 | # of this software and associated documentation files (the "Software"), to deal 14 | # in the Software without restriction, including without limitation the rights 15 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | # copies of the Software, and to permit persons to whom the Software is 17 | # furnished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included in 20 | # all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | # THE SOFTWARE. 29 | 30 | """ 31 | Vim terminal emulator. 32 | 33 | This class is the main interface between Vim and the terminal application. It 34 | handles both updating the Vim buffer with new output and accepting new keyboard 35 | input from the Vim user. 36 | 37 | Although this class was originally designed for a Unix terminal environment, it 38 | has been extended by the ConqueSole class for Windows. 39 | 40 | Usage: 41 | term = Conque() 42 | term.open('/bin/bash', {'TERM': 'vt100'}) 43 | term.write("ls -lha\r") 44 | term.read() 45 | term.close() 46 | """ 47 | 48 | import vim 49 | import re 50 | import math 51 | 52 | 53 | class Conque: 54 | 55 | # screen object 56 | screen = None 57 | 58 | # subprocess object 59 | proc = None 60 | 61 | # terminal dimensions and scrolling region 62 | columns = 80 # same as $COLUMNS 63 | lines = 24 # same as $LINES 64 | working_columns = 80 # can be changed by CSI ? 3 l/h 65 | working_lines = 24 # can be changed by CSI r 66 | 67 | # top/bottom of the scroll region 68 | top = 1 # relative to top of screen 69 | bottom = 24 # relative to top of screen 70 | 71 | # cursor position 72 | l = 1 # current cursor line 73 | c = 1 # current cursor column 74 | 75 | # autowrap mode 76 | autowrap = True 77 | 78 | # absolute coordinate mode 79 | absolute_coords = True 80 | 81 | # tabstop positions 82 | tabstops = [] 83 | 84 | # enable colors 85 | enable_colors = True 86 | 87 | # color changes 88 | color_changes = {} 89 | 90 | # color history 91 | color_history = {} 92 | 93 | # color highlight cache 94 | highlight_groups = {} 95 | 96 | # prune terminal colors 97 | color_pruning = True 98 | 99 | # don't wrap table output 100 | unwrap_tables = True 101 | 102 | # wrap CUF/CUB around line breaks 103 | wrap_cursor = False 104 | 105 | # do we need to move the cursor? 106 | cursor_set = False 107 | 108 | # current character set, ascii or graphics 109 | character_set = 'ascii' 110 | 111 | # used for auto_read actions 112 | read_count = 0 113 | 114 | # input buffer, array of ordinals 115 | input_buffer = [] 116 | 117 | def open(self): 118 | """ Start program and initialize this instance. 119 | 120 | Arguments: 121 | command -- Command string to execute, e.g. '/bin/bash --login' 122 | options -- Dictionary of environment vars to set and other options. 123 | 124 | """ 125 | # get arguments 126 | command = vim.eval('command') 127 | options = vim.eval('options') 128 | 129 | # create terminal screen instance 130 | self.screen = ConqueScreen() 131 | 132 | # int vars 133 | self.columns = vim.current.window.width 134 | self.lines = vim.current.window.height 135 | self.working_columns = vim.current.window.width 136 | self.working_lines = vim.current.window.height 137 | self.bottom = vim.current.window.height 138 | 139 | # offset first line to make room for startup messages 140 | if int(options['offset']) > 0: 141 | self.l = int(options['offset']) 142 | 143 | # init color 144 | self.enable_colors = options['color'] and not CONQUE_FAST_MODE 145 | 146 | # init tabstops 147 | self.init_tabstops() 148 | 149 | # open command 150 | self.proc = ConqueSubprocess() 151 | self.proc.open(command, {'TERM': options['TERM'], 'CONQUE': '1', 'LINES': str(self.lines), 'COLUMNS': str(self.columns)}) 152 | 153 | # send window size signal, in case LINES/COLUMNS is ignored 154 | self.update_window_size(True) 155 | 156 | 157 | def write(self, input, set_cursor=True, read=True): 158 | """ Write a unicode string to the subprocess. 159 | 160 | set_cursor -- Position the cursor in the current buffer when finished 161 | read -- Check program for new output when finished 162 | 163 | """ 164 | # write and read 165 | self.proc.write(input) 166 | 167 | # read output immediately 168 | if read: 169 | self.read(1, set_cursor) 170 | 171 | 172 | 173 | def write_ord(self, input, set_cursor=True, read=True): 174 | """ Write a single character to the subprocess, using an unicode ordinal. """ 175 | 176 | if CONQUE_PYTHON_VERSION == 2: 177 | self.write(unichr(input), set_cursor, read) 178 | else: 179 | self.write(chr(input), set_cursor, read) 180 | 181 | 182 | 183 | def write_expr(self, expr, set_cursor=True, read=True): 184 | """ Write the value of a Vim expression to the subprocess. """ 185 | 186 | if CONQUE_PYTHON_VERSION == 2: 187 | try: 188 | val = vim.eval(expr) 189 | self.write(unicode(val, CONQUE_VIM_ENCODING, 'ignore'), set_cursor, read) 190 | except: 191 | 192 | pass 193 | else: 194 | try: 195 | # XXX - Depending on Vim to deal with encoding, sadly 196 | self.write(vim.eval(expr), set_cursor, read) 197 | except: 198 | 199 | pass 200 | 201 | 202 | def write_latin1(self, input, set_cursor=True, read=True): 203 | """ Write latin-1 string to conque. Very ugly, shood be removed. """ 204 | # XXX - this whole method is a hack, to be removed soon 205 | 206 | if CONQUE_PYTHON_VERSION == 2: 207 | try: 208 | input_unicode = input.decode('latin-1', 'ignore') 209 | self.write(input_unicode.encode('utf-8', 'ignore'), set_cursor, read) 210 | except: 211 | return 212 | else: 213 | self.write(input, set_cursor, read) 214 | 215 | 216 | def write_buffered_ord(self, chr): 217 | """ Add character ordinal to input buffer. In case we're not allowed to modify buffer a time of input. """ 218 | self.input_buffer.append(chr) 219 | 220 | 221 | def read(self, timeout=1, set_cursor=True, return_output=False, update_buffer=True): 222 | """ Read new output from the subprocess and update the Vim buffer. 223 | 224 | Arguments: 225 | timeout -- Milliseconds to wait before reading input 226 | set_cursor -- Set the cursor position in the current buffer when finished 227 | return_output -- Return new subprocess STDOUT + STDERR as a string 228 | update_buffer -- Update the current Vim buffer with the new output 229 | 230 | This method goes through the following rough steps: 231 | 1. Get new output from subprocess 232 | 2. Split output string into control codes, escape sequences, or plain text 233 | 3. Loop over and process each chunk, updating the Vim buffer as we go 234 | 235 | """ 236 | output = '' 237 | 238 | # this may not actually work 239 | try: 240 | 241 | # read from subprocess and strip null characters 242 | output = self.proc.read(timeout) 243 | 244 | if output == '': 245 | return 246 | 247 | # for bufferless terminals 248 | if not update_buffer: 249 | return output 250 | 251 | 252 | 253 | # strip null characters. I'm still not sure why they appear 254 | output = output.replace(chr(0), '') 255 | 256 | # split input into individual escape sequences, control codes, and text output 257 | chunks = CONQUE_SEQ_REGEX.split(output) 258 | 259 | 260 | 261 | # if there were no escape sequences, skip processing and treat entire string as plain text 262 | if len(chunks) == 1: 263 | self.plain_text(chunks[0]) 264 | 265 | # loop through and process escape sequences 266 | else: 267 | for s in chunks: 268 | if s == '': 269 | continue 270 | 271 | 272 | 273 | 274 | # Check for control character match 275 | if CONQUE_SEQ_REGEX_CTL.match(s[0]): 276 | 277 | nr = ord(s[0]) 278 | if nr in CONQUE_CTL: 279 | getattr(self, 'ctl_' + CONQUE_CTL[nr])() 280 | else: 281 | 282 | pass 283 | 284 | # check for escape sequence match 285 | elif CONQUE_SEQ_REGEX_CSI.match(s): 286 | 287 | if s[-1] in CONQUE_ESCAPE: 288 | csi = self.parse_csi(s[2:]) 289 | 290 | getattr(self, 'csi_' + CONQUE_ESCAPE[s[-1]])(csi) 291 | else: 292 | 293 | pass 294 | 295 | # check for title match 296 | elif CONQUE_SEQ_REGEX_TITLE.match(s): 297 | 298 | self.change_title(s[2], s[4:-1]) 299 | 300 | # check for hash match 301 | elif CONQUE_SEQ_REGEX_HASH.match(s): 302 | 303 | if s[-1] in CONQUE_ESCAPE_HASH: 304 | getattr(self, 'hash_' + CONQUE_ESCAPE_HASH[s[-1]])() 305 | else: 306 | 307 | pass 308 | 309 | # check for charset match 310 | elif CONQUE_SEQ_REGEX_CHAR.match(s): 311 | 312 | if s[-1] in CONQUE_ESCAPE_CHARSET: 313 | getattr(self, 'charset_' + CONQUE_ESCAPE_CHARSET[s[-1]])() 314 | else: 315 | 316 | pass 317 | 318 | # check for other escape match 319 | elif CONQUE_SEQ_REGEX_ESC.match(s): 320 | 321 | if s[-1] in CONQUE_ESCAPE_PLAIN: 322 | getattr(self, 'esc_' + CONQUE_ESCAPE_PLAIN[s[-1]])() 323 | else: 324 | 325 | pass 326 | 327 | # else process plain text 328 | else: 329 | self.plain_text(s) 330 | 331 | # set cusor position 332 | if set_cursor: 333 | self.screen.set_cursor(self.l, self.c) 334 | 335 | # we need to set the cursor position 336 | self.cursor_set = False 337 | 338 | except: 339 | 340 | 341 | pass 342 | 343 | if return_output: 344 | if CONQUE_PYTHON_VERSION == 3: 345 | return output 346 | else: 347 | return output.encode(CONQUE_VIM_ENCODING, 'replace') 348 | 349 | 350 | def auto_read(self): 351 | """ Poll program for more output. 352 | 353 | Since Vim doesn't have a reliable event system that can be triggered when new 354 | output is available, we have to continually poll the subprocess instead. This 355 | method is called many times a second when the terminal buffer is active, so it 356 | needs to be very fast and efficient. 357 | 358 | The feedkeys portion is required to reset Vim's timer system. The timer is used 359 | to execute this command, typically set to go off after 50 ms of inactivity. 360 | 361 | """ 362 | # process buffered input if any 363 | if len(self.input_buffer): 364 | for chr in self.input_buffer: 365 | self.write_ord(chr, set_cursor=False, read=False) 366 | self.input_buffer = [] 367 | self.read(1) 368 | 369 | # check subprocess status, but not every time since it's CPU expensive 370 | if self.read_count % 32 == 0: 371 | if not self.proc.is_alive(): 372 | vim.command('call conque_term#get_instance().close()') 373 | return 374 | 375 | if self.read_count > 512: 376 | self.read_count = 0 377 | 378 | # trim color history occasionally if desired 379 | if self.enable_colors and self.color_pruning: 380 | self.prune_colors() 381 | 382 | # ++ 383 | self.read_count += 1 384 | 385 | # read output 386 | self.read(1) 387 | 388 | # reset timer 389 | if self.c == 1: 390 | vim.command('call feedkeys("\\", "n")') 391 | else: 392 | vim.command('call feedkeys("\\", "n")') 393 | 394 | # stop here if cursor doesn't need to be moved 395 | if self.cursor_set: 396 | return 397 | 398 | # check if window size has changed 399 | if not CONQUE_FAST_MODE: 400 | self.update_window_size() 401 | 402 | 403 | # otherwise set cursor position 404 | try: 405 | self.set_cursor(self.l, self.c) 406 | except: 407 | 408 | 409 | pass 410 | 411 | self.cursor_set = True 412 | 413 | 414 | def plain_text(self, input): 415 | """ Write text output to Vim buffer. 416 | 417 | 418 | This method writes a string of characters without any control characters or escape sequences 419 | to the Vim buffer. In simple terms, it writes the input string to the buffer starting at the 420 | current cursor position, wrapping the text to a new line if needed. It also triggers the 421 | terminal coloring methods if needed. 422 | 423 | 424 | """ 425 | # translate input into graphics character set if needed 426 | if self.character_set == 'graphics': 427 | old_input = input 428 | input = u('') 429 | for i in range(0, len(old_input)): 430 | chrd = ord(old_input[i]) 431 | 432 | 433 | try: 434 | if chrd > 255: 435 | 436 | input = input + old_input[i] 437 | else: 438 | input = input + uchr(CONQUE_GRAPHICS_SET[chrd]) 439 | except: 440 | 441 | pass 442 | 443 | 444 | 445 | # get current line from Vim buffer 446 | current_line = self.screen[self.l] 447 | 448 | # pad current line with spaces, if it's shorter than cursor position 449 | if len(current_line) < self.c: 450 | current_line = current_line + ' ' * (self.c - len(current_line)) 451 | 452 | # if line is wider than screen 453 | if self.c + len(input) - 1 > self.working_columns: 454 | 455 | # Table formatting hack 456 | if self.unwrap_tables and CONQUE_TABLE_OUTPUT.match(input): 457 | self.screen[self.l] = current_line[:self.c - 1] + input + current_line[self.c + len(input) - 1:] 458 | self.apply_color(self.c, self.c + len(input)) 459 | self.c += len(input) 460 | return 461 | 462 | 463 | diff = self.c + len(input) - self.working_columns - 1 464 | 465 | # if autowrap is enabled 466 | if self.autowrap: 467 | self.screen[self.l] = current_line[:self.c - 1] + input[:-1 * diff] 468 | self.apply_color(self.c, self.working_columns) 469 | self.ctl_nl() 470 | self.ctl_cr() 471 | remaining = input[-1 * diff:] 472 | 473 | self.plain_text(remaining) 474 | else: 475 | self.screen[self.l] = current_line[:self.c - 1] + input[:-1 * diff - 1] + input[-1] 476 | self.apply_color(self.c, self.working_columns) 477 | self.c = self.working_columns 478 | 479 | # no autowrap 480 | else: 481 | self.screen[self.l] = current_line[:self.c - 1] + input + current_line[self.c + len(input) - 1:] 482 | self.apply_color(self.c, self.c + len(input)) 483 | self.c += len(input) 484 | 485 | 486 | 487 | def apply_color(self, start, end, line=0): 488 | """ Apply terminal colors to buffer for a range of characters in a single line. 489 | 490 | When a text attribute escape sequence is encountered during input processing, the 491 | attributes are recorded in the dictionary self.color_changes. After those attributes 492 | have been applied, the changes are recorded in a second dictionary self.color_history. 493 | 494 | 495 | This method inspects both dictionaries to calculate any syntax highlighting 496 | that needs to be executed to render the text attributes in the Vim buffer. 497 | 498 | 499 | """ 500 | 501 | 502 | # stop here if coloration is disabled 503 | if not self.enable_colors: 504 | return 505 | 506 | # allow custom line nr to be passed 507 | if line: 508 | buffer_line = line 509 | else: 510 | buffer_line = self.get_buffer_line(self.l) 511 | 512 | # check for previous overlapping coloration 513 | 514 | to_del = [] 515 | if buffer_line in self.color_history: 516 | for i in range(len(self.color_history[buffer_line])): 517 | syn = self.color_history[buffer_line][i] 518 | 519 | if syn['start'] >= start and syn['start'] < end: 520 | 521 | vim.command('syn clear ' + syn['name']) 522 | to_del.append(i) 523 | # outside 524 | if syn['end'] > end: 525 | 526 | self.exec_highlight(buffer_line, end, syn['end'], syn['highlight']) 527 | elif syn['end'] > start and syn['end'] <= end: 528 | 529 | vim.command('syn clear ' + syn['name']) 530 | to_del.append(i) 531 | # outside 532 | if syn['start'] < start: 533 | 534 | self.exec_highlight(buffer_line, syn['start'], start, syn['highlight']) 535 | 536 | # remove overlapped colors 537 | if len(to_del) > 0: 538 | to_del.reverse() 539 | for di in to_del: 540 | del self.color_history[buffer_line][di] 541 | 542 | # if there are no new colors 543 | if len(self.color_changes) == 0: 544 | return 545 | 546 | # build the color attribute string 547 | highlight = '' 548 | for attr in self.color_changes.keys(): 549 | highlight = highlight + ' ' + attr + '=' + self.color_changes[attr] 550 | 551 | # execute the highlight 552 | self.exec_highlight(buffer_line, start, end, highlight) 553 | 554 | 555 | def exec_highlight(self, buffer_line, start, end, highlight): 556 | """ Execute the Vim commands for a single syntax highlight """ 557 | 558 | syntax_name = 'ConqueHighLightAt_%d_%d_%d_%d' % (self.proc.pid, self.l, start, len(self.color_history) + 1) 559 | syntax_options = 'contains=ALLBUT,ConqueString,MySQLString,MySQLKeyword oneline' 560 | syntax_region = 'syntax match %s /\%%%dl\%%>%dc.\{%d}\%%<%dc/ %s' % (syntax_name, buffer_line, start - 1, end - start, end + 1, syntax_options) 561 | 562 | # check for cached highlight group 563 | hgroup = 'ConqueHL_%d' % (abs(hash(highlight))) 564 | if hgroup not in self.highlight_groups: 565 | syntax_group = 'highlight %s %s' % (hgroup, highlight) 566 | self.highlight_groups[hgroup] = hgroup 567 | vim.command(syntax_group) 568 | 569 | # link this syntax match to existing highlight group 570 | syntax_highlight = 'highlight link %s %s' % (syntax_name, self.highlight_groups[hgroup]) 571 | 572 | 573 | 574 | vim.command(syntax_region) 575 | vim.command(syntax_highlight) 576 | 577 | # add syntax name to history 578 | if not buffer_line in self.color_history: 579 | self.color_history[buffer_line] = [] 580 | 581 | self.color_history[buffer_line].append({'name': syntax_name, 'start': start, 'end': end, 'highlight': highlight}) 582 | 583 | 584 | def prune_colors(self): 585 | """ Remove old syntax highlighting from the Vim buffer 586 | 587 | The kind of syntax highlighting required for terminal colors can make 588 | Conque run slowly. The prune_colors() method will remove old highlight definitions 589 | to keep the maximum number of highlight rules within a reasonable range. 590 | 591 | """ 592 | 593 | 594 | buffer_line = self.get_buffer_line(self.l) 595 | ks = list(self.color_history.keys()) 596 | 597 | for line in ks: 598 | if line < buffer_line - CONQUE_MAX_SYNTAX_LINES: 599 | for syn in self.color_history[line]: 600 | vim.command('syn clear ' + syn['name']) 601 | del self.color_history[line] 602 | 603 | 604 | 605 | 606 | ############################################################################################### 607 | # Control functions 608 | 609 | def ctl_nl(self): 610 | """ Process the newline control character. """ 611 | # if we're in a scrolling region, scroll instead of moving cursor down 612 | if self.lines != self.working_lines and self.l == self.bottom: 613 | del self.screen[self.top] 614 | self.screen.insert(self.bottom, '') 615 | elif self.l == self.bottom: 616 | self.screen.append('') 617 | else: 618 | self.l += 1 619 | 620 | self.color_changes = {} 621 | 622 | def ctl_cr(self): 623 | """ Process the carriage return control character. """ 624 | self.c = 1 625 | 626 | self.color_changes = {} 627 | 628 | def ctl_bs(self): 629 | """ Process the backspace control character. """ 630 | if self.c > 1: 631 | self.c += -1 632 | 633 | def ctl_soh(self): 634 | """ Process the start of heading control character. """ 635 | pass 636 | 637 | def ctl_stx(self): 638 | pass 639 | 640 | def ctl_bel(self): 641 | """ Process the bell control character. """ 642 | vim.command('call conque_term#bell()') 643 | 644 | def ctl_tab(self): 645 | """ Process the tab control character. """ 646 | # default tabstop location 647 | ts = self.working_columns 648 | 649 | # check set tabstops 650 | for i in range(self.c, len(self.tabstops)): 651 | if self.tabstops[i]: 652 | ts = i + 1 653 | break 654 | 655 | 656 | 657 | self.c = ts 658 | 659 | def ctl_so(self): 660 | """ Process the shift out control character. """ 661 | self.character_set = 'graphics' 662 | 663 | def ctl_si(self): 664 | """ Process the shift in control character. """ 665 | self.character_set = 'ascii' 666 | 667 | 668 | 669 | ############################################################################################### 670 | # CSI functions 671 | 672 | def csi_font(self, csi): 673 | """ Process the text attribute escape sequence. """ 674 | if not self.enable_colors: 675 | return 676 | 677 | # defaults to 0 678 | if len(csi['vals']) == 0: 679 | csi['vals'] = [0] 680 | 681 | # 256 xterm color foreground 682 | if len(csi['vals']) == 3 and csi['vals'][0] == 38 and csi['vals'][1] == 5: 683 | self.color_changes['ctermfg'] = str(csi['vals'][2]) 684 | self.color_changes['guifg'] = '#' + self.xterm_to_rgb(csi['vals'][2]) 685 | 686 | # 256 xterm color background 687 | elif len(csi['vals']) == 3 and csi['vals'][0] == 48 and csi['vals'][1] == 5: 688 | self.color_changes['ctermbg'] = str(csi['vals'][2]) 689 | self.color_changes['guibg'] = '#' + self.xterm_to_rgb(csi['vals'][2]) 690 | 691 | # 16 colors 692 | else: 693 | for val in csi['vals']: 694 | if val in CONQUE_FONT: 695 | 696 | # ignore starting normal colors 697 | if CONQUE_FONT[val]['normal'] and len(self.color_changes) == 0: 698 | 699 | continue 700 | # clear color changes 701 | elif CONQUE_FONT[val]['normal']: 702 | 703 | self.color_changes = {} 704 | # save these color attributes for next plain_text() call 705 | else: 706 | 707 | for attr in CONQUE_FONT[val]['attributes'].keys(): 708 | if attr in self.color_changes and (attr == 'cterm' or attr == 'gui'): 709 | self.color_changes[attr] += ',' + CONQUE_FONT[val]['attributes'][attr] 710 | else: 711 | self.color_changes[attr] = CONQUE_FONT[val]['attributes'][attr] 712 | 713 | 714 | def csi_clear_line(self, csi): 715 | """ Process the line clear escape sequence. """ 716 | 717 | 718 | # this escape defaults to 0 719 | if len(csi['vals']) == 0: 720 | csi['val'] = 0 721 | 722 | 723 | 724 | 725 | # 0 means cursor right 726 | if csi['val'] == 0: 727 | self.screen[self.l] = self.screen[self.l][0:self.c - 1] 728 | 729 | # 1 means cursor left 730 | elif csi['val'] == 1: 731 | self.screen[self.l] = ' ' * (self.c) + self.screen[self.l][self.c:] 732 | 733 | # clear entire line 734 | elif csi['val'] == 2: 735 | self.screen[self.l] = '' 736 | 737 | # clear colors 738 | if csi['val'] == 2 or (csi['val'] == 0 and self.c == 1): 739 | buffer_line = self.get_buffer_line(self.l) 740 | if buffer_line in self.color_history: 741 | for syn in self.color_history[buffer_line]: 742 | vim.command('syn clear ' + syn['name']) 743 | 744 | 745 | 746 | 747 | 748 | def csi_cursor_right(self, csi): 749 | """ Process the move cursor right escape sequence. """ 750 | # we use 1 even if escape explicitly specifies 0 751 | if csi['val'] == 0: 752 | csi['val'] = 1 753 | 754 | 755 | 756 | 757 | if self.wrap_cursor and self.c + csi['val'] > self.working_columns: 758 | self.l += int(math.floor((self.c + csi['val']) / self.working_columns)) 759 | self.c = (self.c + csi['val']) % self.working_columns 760 | return 761 | 762 | self.c = self.bound(self.c + csi['val'], 1, self.working_columns) 763 | 764 | 765 | def csi_cursor_left(self, csi): 766 | """ Process the move cursor left escape sequence. """ 767 | # we use 1 even if escape explicitly specifies 0 768 | if csi['val'] == 0: 769 | csi['val'] = 1 770 | 771 | if self.wrap_cursor and csi['val'] >= self.c: 772 | self.l += int(math.floor((self.c - csi['val']) / self.working_columns)) 773 | self.c = self.working_columns - (csi['val'] - self.c) % self.working_columns 774 | return 775 | 776 | self.c = self.bound(self.c - csi['val'], 1, self.working_columns) 777 | 778 | 779 | def csi_cursor_to_column(self, csi): 780 | """ Process the move cursor to column escape sequence. """ 781 | self.c = self.bound(csi['val'], 1, self.working_columns) 782 | 783 | 784 | def csi_cursor_up(self, csi): 785 | """ Process the move cursor up escape sequence. """ 786 | self.l = self.bound(self.l - csi['val'], self.top, self.bottom) 787 | 788 | self.color_changes = {} 789 | 790 | 791 | def csi_cursor_down(self, csi): 792 | """ Process the move cursor down escape sequence. """ 793 | self.l = self.bound(self.l + csi['val'], self.top, self.bottom) 794 | 795 | self.color_changes = {} 796 | 797 | 798 | def csi_clear_screen(self, csi): 799 | """ Process the clear screen escape sequence. """ 800 | # default to 0 801 | if len(csi['vals']) == 0: 802 | csi['val'] = 0 803 | 804 | # 2 == clear entire screen 805 | if csi['val'] == 2: 806 | self.l = 1 807 | self.c = 1 808 | self.screen.clear() 809 | 810 | # 0 == clear down 811 | elif csi['val'] == 0: 812 | for l in range(self.bound(self.l + 1, 1, self.lines), self.lines + 1): 813 | self.screen[l] = '' 814 | 815 | # clear end of current line 816 | self.csi_clear_line(self.parse_csi('K')) 817 | 818 | # 1 == clear up 819 | elif csi['val'] == 1: 820 | for l in range(1, self.bound(self.l, 1, self.lines + 1)): 821 | self.screen[l] = '' 822 | 823 | # clear beginning of current line 824 | self.csi_clear_line(self.parse_csi('1K')) 825 | 826 | # clear coloration 827 | if csi['val'] == 2 or csi['val'] == 0: 828 | buffer_line = self.get_buffer_line(self.l) 829 | for line in self.color_history.keys(): 830 | if line >= buffer_line: 831 | for syn in self.color_history[line]: 832 | vim.command('syn clear ' + syn['name']) 833 | 834 | self.color_changes = {} 835 | 836 | 837 | def csi_delete_chars(self, csi): 838 | self.screen[self.l] = self.screen[self.l][:self.c] + self.screen[self.l][self.c + csi['val']:] 839 | 840 | 841 | def csi_add_spaces(self, csi): 842 | self.screen[self.l] = self.screen[self.l][: self.c - 1] + ' ' * csi['val'] + self.screen[self.l][self.c:] 843 | 844 | 845 | def csi_cursor(self, csi): 846 | if len(csi['vals']) == 2: 847 | new_line = csi['vals'][0] 848 | new_col = csi['vals'][1] 849 | else: 850 | new_line = 1 851 | new_col = 1 852 | 853 | if self.absolute_coords: 854 | self.l = self.bound(new_line, 1, self.lines) 855 | else: 856 | self.l = self.bound(self.top + new_line - 1, self.top, self.bottom) 857 | 858 | self.c = self.bound(new_col, 1, self.working_columns) 859 | if self.c > len(self.screen[self.l]): 860 | self.screen[self.l] = self.screen[self.l] + ' ' * (self.c - len(self.screen[self.l])) 861 | 862 | 863 | 864 | def csi_set_coords(self, csi): 865 | if len(csi['vals']) == 2: 866 | new_start = csi['vals'][0] 867 | new_end = csi['vals'][1] 868 | else: 869 | new_start = 1 870 | new_end = vim.current.window.height 871 | 872 | self.top = new_start 873 | self.bottom = new_end 874 | self.working_lines = new_end - new_start + 1 875 | 876 | # if cursor is outside scrolling region, reset it 877 | if self.l < self.top: 878 | self.l = self.top 879 | elif self.l > self.bottom: 880 | self.l = self.bottom 881 | 882 | self.color_changes = {} 883 | 884 | 885 | def csi_tab_clear(self, csi): 886 | # this escape defaults to 0 887 | if len(csi['vals']) == 0: 888 | csi['val'] = 0 889 | 890 | 891 | 892 | if csi['val'] == 0: 893 | self.tabstops[self.c - 1] = False 894 | elif csi['val'] == 3: 895 | for i in range(0, self.columns + 1): 896 | self.tabstops[i] = False 897 | 898 | 899 | def csi_set(self, csi): 900 | # 132 cols 901 | if csi['val'] == 3: 902 | self.csi_clear_screen(self.parse_csi('2J')) 903 | self.working_columns = 132 904 | 905 | # relative_origin 906 | elif csi['val'] == 6: 907 | self.absolute_coords = False 908 | 909 | # set auto wrap 910 | elif csi['val'] == 7: 911 | self.autowrap = True 912 | 913 | 914 | self.color_changes = {} 915 | 916 | 917 | def csi_reset(self, csi): 918 | # 80 cols 919 | if csi['val'] == 3: 920 | self.csi_clear_screen(self.parse_csi('2J')) 921 | self.working_columns = 80 922 | 923 | # absolute origin 924 | elif csi['val'] == 6: 925 | self.absolute_coords = True 926 | 927 | # reset auto wrap 928 | elif csi['val'] == 7: 929 | self.autowrap = False 930 | 931 | 932 | self.color_changes = {} 933 | 934 | 935 | 936 | 937 | ############################################################################################### 938 | # ESC functions 939 | 940 | def esc_scroll_up(self): 941 | self.ctl_nl() 942 | 943 | self.color_changes = {} 944 | 945 | 946 | def esc_next_line(self): 947 | self.ctl_nl() 948 | self.c = 1 949 | 950 | 951 | def esc_set_tab(self): 952 | 953 | if self.c <= len(self.tabstops): 954 | self.tabstops[self.c - 1] = True 955 | 956 | 957 | def esc_scroll_down(self): 958 | if self.l == self.top: 959 | del self.screen[self.bottom] 960 | self.screen.insert(self.top, '') 961 | else: 962 | self.l += -1 963 | 964 | self.color_changes = {} 965 | 966 | 967 | 968 | 969 | ############################################################################################### 970 | # HASH functions 971 | 972 | def hash_screen_alignment_test(self): 973 | self.csi_clear_screen(self.parse_csi('2J')) 974 | self.working_lines = self.lines 975 | for l in range(1, self.lines + 1): 976 | self.screen[l] = 'E' * self.working_columns 977 | 978 | 979 | 980 | ############################################################################################### 981 | # CHARSET functions 982 | 983 | def charset_us(self): 984 | self.character_set = 'ascii' 985 | 986 | def charset_uk(self): 987 | self.character_set = 'ascii' 988 | 989 | def charset_graphics(self): 990 | self.character_set = 'graphics' 991 | 992 | 993 | 994 | ############################################################################################### 995 | # Random stuff 996 | 997 | def set_cursor(self, line, col): 998 | """ Set cursor position in the Vim buffer. 999 | 1000 | Note: the line and column numbers are relative to the top left corner of the 1001 | visible screen. Not the line number in the Vim buffer. 1002 | 1003 | """ 1004 | self.screen.set_cursor(line, col) 1005 | 1006 | def change_title(self, key, val): 1007 | """ Change the Vim window title. """ 1008 | 1009 | 1010 | if key == '0' or key == '2': 1011 | 1012 | vim.command('setlocal statusline=' + re.escape(val)) 1013 | try: 1014 | vim.command('set titlestring=' + re.escape(val)) 1015 | except: 1016 | pass 1017 | 1018 | def update_window_size(self, force=False): 1019 | """ Check and save the current buffer dimensions. 1020 | 1021 | If the buffer size has changed, the update_window_size() method both updates 1022 | the Conque buffer size attributes as well as sending the new dimensions to the 1023 | subprocess pty. 1024 | 1025 | """ 1026 | # resize if needed 1027 | if force or vim.current.window.width != self.columns or vim.current.window.height != self.lines: 1028 | 1029 | # reset all window size attributes to default 1030 | self.columns = vim.current.window.width 1031 | self.lines = vim.current.window.height 1032 | self.working_columns = vim.current.window.width 1033 | self.working_lines = vim.current.window.height 1034 | self.bottom = vim.current.window.height 1035 | 1036 | # reset screen object attributes 1037 | self.l = self.screen.reset_size(self.l) 1038 | 1039 | # reset tabstops 1040 | self.init_tabstops() 1041 | 1042 | 1043 | 1044 | # signal process that screen size has changed 1045 | self.proc.window_resize(self.lines, self.columns) 1046 | 1047 | def insert_enter(self): 1048 | """ Run commands when user enters insert mode. """ 1049 | 1050 | # check window size 1051 | self.update_window_size() 1052 | 1053 | # we need to set the cursor position 1054 | self.cursor_set = False 1055 | 1056 | def init_tabstops(self): 1057 | """ Intitialize terminal tabstop positions. """ 1058 | for i in range(0, self.columns + 1): 1059 | if i % 8 == 0: 1060 | self.tabstops.append(True) 1061 | else: 1062 | self.tabstops.append(False) 1063 | 1064 | def idle(self): 1065 | """ Called when this terminal becomes idle. """ 1066 | pass 1067 | 1068 | def resume(self): 1069 | """ Called when this terminal is no longer idle. """ 1070 | pass 1071 | pass 1072 | 1073 | def close(self): 1074 | """ End the process running in the terminal. """ 1075 | self.proc.close() 1076 | 1077 | def abort(self): 1078 | """ Forcefully end the process running in the terminal. """ 1079 | self.proc.signal(1) 1080 | 1081 | 1082 | 1083 | ############################################################################################### 1084 | # Utility 1085 | 1086 | def parse_csi(self, s): 1087 | """ Parse an escape sequence into it's meaningful values. """ 1088 | 1089 | attr = {'key': s[-1], 'flag': '', 'val': 1, 'vals': []} 1090 | 1091 | if len(s) == 1: 1092 | return attr 1093 | 1094 | full = s[0:-1] 1095 | 1096 | if full[0] == '?': 1097 | full = full[1:] 1098 | attr['flag'] = '?' 1099 | 1100 | if full != '': 1101 | vals = full.split(';') 1102 | for val in vals: 1103 | 1104 | val = re.sub("\D", "", val) 1105 | 1106 | if val != '': 1107 | attr['vals'].append(int(val)) 1108 | 1109 | if len(attr['vals']) == 1: 1110 | attr['val'] = int(attr['vals'][0]) 1111 | 1112 | return attr 1113 | 1114 | 1115 | def bound(self, val, min, max): 1116 | """ TODO: This probably exists as a builtin function. """ 1117 | if val > max: 1118 | return max 1119 | 1120 | if val < min: 1121 | return min 1122 | 1123 | return val 1124 | 1125 | 1126 | def xterm_to_rgb(self, color_code): 1127 | """ Translate a terminal color number into a RGB string. """ 1128 | if color_code < 16: 1129 | ascii_colors = ['000000', 'CD0000', '00CD00', 'CDCD00', '0000EE', 'CD00CD', '00CDCD', 'E5E5E5', 1130 | '7F7F7F', 'FF0000', '00FF00', 'FFFF00', '5C5CFF', 'FF00FF', '00FFFF', 'FFFFFF'] 1131 | return ascii_colors[color_code] 1132 | 1133 | elif color_code < 232: 1134 | cc = int(color_code) - 16 1135 | 1136 | p1 = "%02x" % (math.floor(cc / 36) * (255 / 5)) 1137 | p2 = "%02x" % (math.floor((cc % 36) / 6) * (255 / 5)) 1138 | p3 = "%02x" % (math.floor(cc % 6) * (255 / 5)) 1139 | 1140 | return p1 + p2 + p3 1141 | else: 1142 | grey_tone = "%02x" % math.floor((255 / 24) * (color_code - 232)) 1143 | return grey_tone + grey_tone + grey_tone 1144 | 1145 | 1146 | 1147 | 1148 | def get_buffer_line(self, line): 1149 | """ Get the buffer line number corresponding to the supplied screen line number. """ 1150 | return self.screen.get_buffer_line(line) 1151 | 1152 | 1153 | -------------------------------------------------------------------------------- /autoload/conque_term/conque_globals.py: -------------------------------------------------------------------------------- 1 | # FILE: autoload/conque_term/conque_globals.py 2 | # AUTHOR: Nico Raffo 3 | # WEBSITE: http://conque.googlecode.com 4 | # MODIFIED: 2011-09-02 5 | # VERSION: 2.3, for Vim 7.0 6 | # LICENSE: 7 | # Conque - Vim terminal/console emulator 8 | # Copyright (C) 2009-2011 Nico Raffo 9 | # 10 | # MIT License 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining a copy 13 | # of this software and associated documentation files (the "Software"), to deal 14 | # in the Software without restriction, including without limitation the rights 15 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | # copies of the Software, and to permit persons to whom the Software is 17 | # furnished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included in 20 | # all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | # THE SOFTWARE. 29 | 30 | """Common global constants and functions for Conque.""" 31 | 32 | import sys 33 | import re 34 | 35 | 36 | 37 | 38 | # PYTHON VERSION 39 | CONQUE_PYTHON_VERSION = sys.version_info[0] 40 | 41 | # Encoding 42 | 43 | try: 44 | # Vim's character encoding 45 | import vim 46 | CONQUE_VIM_ENCODING = vim.eval('&encoding') 47 | 48 | except: 49 | CONQUE_VIM_ENCODING = 'utf-8' 50 | 51 | 52 | def u(str_val, str_encoding='utf-8', errors='strict'): 53 | """ Foolhardy attempt to make unicode string syntax compatible with both python 2 and 3. """ 54 | 55 | if not str_val: 56 | str_val = '' 57 | 58 | if CONQUE_PYTHON_VERSION == 3: 59 | return str_val 60 | 61 | else: 62 | return unicode(str_val, str_encoding, errors) 63 | 64 | def uchr(str): 65 | """ Foolhardy attempt to make unicode string syntax compatible with both python 2 and 3. """ 66 | 67 | if CONQUE_PYTHON_VERSION == 3: 68 | return chr(str) 69 | 70 | else: 71 | return unichr(str) 72 | 73 | 74 | # Logging 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | # Unix escape sequence settings 92 | 93 | CONQUE_CTL = { 94 | 1: 'soh', # start of heading 95 | 2: 'stx', # start of text 96 | 7: 'bel', # bell 97 | 8: 'bs', # backspace 98 | 9: 'tab', # tab 99 | 10: 'nl', # new line 100 | 13: 'cr', # carriage return 101 | 14: 'so', # shift out 102 | 15: 'si' # shift in 103 | } 104 | # 11 : 'vt', # vertical tab 105 | # 12 : 'ff', # form feed 106 | 107 | # Escape sequences 108 | CONQUE_ESCAPE = { 109 | 'm': 'font', 110 | 'J': 'clear_screen', 111 | 'K': 'clear_line', 112 | '@': 'add_spaces', 113 | 'A': 'cursor_up', 114 | 'B': 'cursor_down', 115 | 'C': 'cursor_right', 116 | 'D': 'cursor_left', 117 | 'G': 'cursor_to_column', 118 | 'H': 'cursor', 119 | 'P': 'delete_chars', 120 | 'f': 'cursor', 121 | 'g': 'tab_clear', 122 | 'r': 'set_coords', 123 | 'h': 'set', 124 | 'l': 'reset' 125 | } 126 | # 'L': 'insert_lines', 127 | # 'M': 'delete_lines', 128 | # 'd': 'cusor_vpos', 129 | 130 | # Alternate escape sequences, no [ 131 | CONQUE_ESCAPE_PLAIN = { 132 | 'D': 'scroll_up', 133 | 'E': 'next_line', 134 | 'H': 'set_tab', 135 | 'M': 'scroll_down' 136 | } 137 | # 'N': 'single_shift_2', 138 | # 'O': 'single_shift_3', 139 | # '=': 'alternate_keypad', 140 | # '>': 'numeric_keypad', 141 | # '7': 'save_cursor', 142 | # '8': 'restore_cursor', 143 | 144 | # Character set escape sequences, with "(" 145 | CONQUE_ESCAPE_CHARSET = { 146 | 'A': 'uk', 147 | 'B': 'us', 148 | '0': 'graphics' 149 | } 150 | 151 | # Uber alternate escape sequences, with # or ? 152 | CONQUE_ESCAPE_QUESTION = { 153 | '1h': 'new_line_mode', 154 | '3h': '132_cols', 155 | '4h': 'smooth_scrolling', 156 | '5h': 'reverse_video', 157 | '6h': 'relative_origin', 158 | '7h': 'set_auto_wrap', 159 | '8h': 'set_auto_repeat', 160 | '9h': 'set_interlacing_mode', 161 | '1l': 'set_cursor_key', 162 | '2l': 'set_vt52', 163 | '3l': '80_cols', 164 | '4l': 'set_jump_scrolling', 165 | '5l': 'normal_video', 166 | '6l': 'absolute_origin', 167 | '7l': 'reset_auto_wrap', 168 | '8l': 'reset_auto_repeat', 169 | '9l': 'reset_interlacing_mode' 170 | } 171 | 172 | CONQUE_ESCAPE_HASH = { 173 | '8': 'screen_alignment_test' 174 | } 175 | # '3': 'double_height_top', 176 | # '4': 'double_height_bottom', 177 | # '5': 'single_height_single_width', 178 | # '6': 'single_height_double_width', 179 | 180 | CONQUE_GRAPHICS_SET = [ 181 | 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 182 | 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 183 | 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 184 | 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 185 | 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 186 | 0x0028, 0x0029, 0x002A, 0x2192, 0x2190, 0x2191, 0x2193, 0x002F, 187 | 0x2588, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 188 | 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 189 | 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 190 | 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 191 | 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 192 | 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x00A0, 193 | 0x25C6, 0x2592, 0x2409, 0x240C, 0x240D, 0x240A, 0x00B0, 0x00B1, 194 | 0x2591, 0x240B, 0x2518, 0x2510, 0x250C, 0x2514, 0x253C, 0xF800, 195 | 0xF801, 0x2500, 0xF803, 0xF804, 0x251C, 0x2524, 0x2534, 0x252C, 196 | 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00B7, 0x007F, 197 | 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 198 | 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, 199 | 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 200 | 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, 201 | 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 202 | 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 203 | 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 204 | 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, 205 | 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 206 | 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, 207 | 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 208 | 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 209 | 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 210 | 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 211 | 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 212 | 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF 213 | ] 214 | 215 | # Font codes 216 | CONQUE_FONT = { 217 | 0: {'description': 'Normal (default)', 'attributes': {'cterm': 'NONE', 'ctermfg': 'NONE', 'ctermbg': 'NONE', 'gui': 'NONE', 'guifg': 'NONE', 'guibg': 'NONE'}, 'normal': True}, 218 | 1: {'description': 'Bold', 'attributes': {'cterm': 'BOLD', 'gui': 'BOLD'}, 'normal': False}, 219 | 4: {'description': 'Underlined', 'attributes': {'cterm': 'UNDERLINE', 'gui': 'UNDERLINE'}, 'normal': False}, 220 | 5: {'description': 'Blink (appears as Bold)', 'attributes': {'cterm': 'BOLD', 'gui': 'BOLD'}, 'normal': False}, 221 | 7: {'description': 'Inverse', 'attributes': {'cterm': 'REVERSE', 'gui': 'REVERSE'}, 'normal': False}, 222 | 8: {'description': 'Invisible (hidden)', 'attributes': {'ctermfg': '0', 'ctermbg': '0', 'guifg': '#000000', 'guibg': '#000000'}, 'normal': False}, 223 | 22: {'description': 'Normal (neither bold nor faint)', 'attributes': {'cterm': 'NONE', 'gui': 'NONE'}, 'normal': True}, 224 | 24: {'description': 'Not underlined', 'attributes': {'cterm': 'NONE', 'gui': 'NONE'}, 'normal': True}, 225 | 25: {'description': 'Steady (not blinking)', 'attributes': {'cterm': 'NONE', 'gui': 'NONE'}, 'normal': True}, 226 | 27: {'description': 'Positive (not inverse)', 'attributes': {'cterm': 'NONE', 'gui': 'NONE'}, 'normal': True}, 227 | 28: {'description': 'Visible (not hidden)', 'attributes': {'ctermfg': 'NONE', 'ctermbg': 'NONE', 'guifg': 'NONE', 'guibg': 'NONE'}, 'normal': True}, 228 | 30: {'description': 'Set foreground color to Black', 'attributes': {'ctermfg': '16', 'guifg': '#000000'}, 'normal': False}, 229 | 31: {'description': 'Set foreground color to Red', 'attributes': {'ctermfg': '1', 'guifg': '#ff0000'}, 'normal': False}, 230 | 32: {'description': 'Set foreground color to Green', 'attributes': {'ctermfg': '2', 'guifg': '#00ff00'}, 'normal': False}, 231 | 33: {'description': 'Set foreground color to Yellow', 'attributes': {'ctermfg': '3', 'guifg': '#ffff00'}, 'normal': False}, 232 | 34: {'description': 'Set foreground color to Blue', 'attributes': {'ctermfg': '4', 'guifg': '#0000ff'}, 'normal': False}, 233 | 35: {'description': 'Set foreground color to Magenta', 'attributes': {'ctermfg': '5', 'guifg': '#990099'}, 'normal': False}, 234 | 36: {'description': 'Set foreground color to Cyan', 'attributes': {'ctermfg': '6', 'guifg': '#009999'}, 'normal': False}, 235 | 37: {'description': 'Set foreground color to White', 'attributes': {'ctermfg': '7', 'guifg': '#ffffff'}, 'normal': False}, 236 | 39: {'description': 'Set foreground color to default (original)', 'attributes': {'ctermfg': 'NONE', 'guifg': 'NONE'}, 'normal': True}, 237 | 40: {'description': 'Set background color to Black', 'attributes': {'ctermbg': '16', 'guibg': '#000000'}, 'normal': False}, 238 | 41: {'description': 'Set background color to Red', 'attributes': {'ctermbg': '1', 'guibg': '#ff0000'}, 'normal': False}, 239 | 42: {'description': 'Set background color to Green', 'attributes': {'ctermbg': '2', 'guibg': '#00ff00'}, 'normal': False}, 240 | 43: {'description': 'Set background color to Yellow', 'attributes': {'ctermbg': '3', 'guibg': '#ffff00'}, 'normal': False}, 241 | 44: {'description': 'Set background color to Blue', 'attributes': {'ctermbg': '4', 'guibg': '#0000ff'}, 'normal': False}, 242 | 45: {'description': 'Set background color to Magenta', 'attributes': {'ctermbg': '5', 'guibg': '#990099'}, 'normal': False}, 243 | 46: {'description': 'Set background color to Cyan', 'attributes': {'ctermbg': '6', 'guibg': '#009999'}, 'normal': False}, 244 | 47: {'description': 'Set background color to White', 'attributes': {'ctermbg': '7', 'guibg': '#ffffff'}, 'normal': False}, 245 | 49: {'description': 'Set background color to default (original).', 'attributes': {'ctermbg': 'NONE', 'guibg': 'NONE'}, 'normal': True}, 246 | 90: {'description': 'Set foreground color to Black', 'attributes': {'ctermfg': '8', 'guifg': '#000000'}, 'normal': False}, 247 | 91: {'description': 'Set foreground color to Red', 'attributes': {'ctermfg': '9', 'guifg': '#ff0000'}, 'normal': False}, 248 | 92: {'description': 'Set foreground color to Green', 'attributes': {'ctermfg': '10', 'guifg': '#00ff00'}, 'normal': False}, 249 | 93: {'description': 'Set foreground color to Yellow', 'attributes': {'ctermfg': '11', 'guifg': '#ffff00'}, 'normal': False}, 250 | 94: {'description': 'Set foreground color to Blue', 'attributes': {'ctermfg': '12', 'guifg': '#0000ff'}, 'normal': False}, 251 | 95: {'description': 'Set foreground color to Magenta', 'attributes': {'ctermfg': '13', 'guifg': '#990099'}, 'normal': False}, 252 | 96: {'description': 'Set foreground color to Cyan', 'attributes': {'ctermfg': '14', 'guifg': '#009999'}, 'normal': False}, 253 | 97: {'description': 'Set foreground color to White', 'attributes': {'ctermfg': '15', 'guifg': '#ffffff'}, 'normal': False}, 254 | 100: {'description': 'Set background color to Black', 'attributes': {'ctermbg': '8', 'guibg': '#000000'}, 'normal': False}, 255 | 101: {'description': 'Set background color to Red', 'attributes': {'ctermbg': '9', 'guibg': '#ff0000'}, 'normal': False}, 256 | 102: {'description': 'Set background color to Green', 'attributes': {'ctermbg': '10', 'guibg': '#00ff00'}, 'normal': False}, 257 | 103: {'description': 'Set background color to Yellow', 'attributes': {'ctermbg': '11', 'guibg': '#ffff00'}, 'normal': False}, 258 | 104: {'description': 'Set background color to Blue', 'attributes': {'ctermbg': '12', 'guibg': '#0000ff'}, 'normal': False}, 259 | 105: {'description': 'Set background color to Magenta', 'attributes': {'ctermbg': '13', 'guibg': '#990099'}, 'normal': False}, 260 | 106: {'description': 'Set background color to Cyan', 'attributes': {'ctermbg': '14', 'guibg': '#009999'}, 'normal': False}, 261 | 107: {'description': 'Set background color to White', 'attributes': {'ctermbg': '15', 'guibg': '#ffffff'}, 'normal': False} 262 | } 263 | 264 | 265 | # regular expression matching (almost) all control sequences 266 | CONQUE_SEQ_REGEX = re.compile("(\x1b\[?\??#?[0-9;]*[a-zA-Z0-9@=>]|\x1b\][0-9];.*?\x07|[\x01-\x0f]|\x1b\([AB0])") 267 | CONQUE_SEQ_REGEX_CTL = re.compile("^[\x01-\x0f]$") 268 | CONQUE_SEQ_REGEX_CSI = re.compile("^\x1b\[") 269 | CONQUE_SEQ_REGEX_TITLE = re.compile("^\x1b\]") 270 | CONQUE_SEQ_REGEX_HASH = re.compile("^\x1b#") 271 | CONQUE_SEQ_REGEX_ESC = re.compile("^\x1b.$") 272 | CONQUE_SEQ_REGEX_CHAR = re.compile("^\x1b[()]") 273 | 274 | # match table output 275 | CONQUE_TABLE_OUTPUT = re.compile("^\s*\|\s.*\s\|\s*$|^\s*\+[=+-]+\+\s*$") 276 | 277 | # basic terminal colors 278 | CONQUE_COLOR_SEQUENCE = ( 279 | '000', '009', '090', '099', '900', '909', '990', '999', 280 | '000', '00f', '0f0', '0ff', 'f00', 'f0f', 'ff0', 'fff' 281 | ) 282 | 283 | 284 | # Windows subprocess constants 285 | 286 | # shared memory size 287 | CONQUE_SOLE_BUFFER_LENGTH = 1000 288 | CONQUE_SOLE_INPUT_SIZE = 1000 289 | CONQUE_SOLE_STATS_SIZE = 1000 290 | CONQUE_SOLE_COMMANDS_SIZE = 255 291 | CONQUE_SOLE_RESCROLL_SIZE = 255 292 | CONQUE_SOLE_RESIZE_SIZE = 255 293 | 294 | # interval of screen redraw 295 | # larger number means less frequent 296 | CONQUE_SOLE_SCREEN_REDRAW = 50 297 | 298 | # interval of full buffer redraw 299 | # larger number means less frequent 300 | CONQUE_SOLE_BUFFER_REDRAW = 500 301 | 302 | # interval of full output bucket replacement 303 | # larger number means less frequent, 1 = every time 304 | CONQUE_SOLE_MEM_REDRAW = 1000 305 | 306 | # maximum number of lines with terminal colors 307 | # ignored if g:ConqueTerm_Color = 2 308 | CONQUE_MAX_SYNTAX_LINES = 200 309 | 310 | # windows input splitting on special keys 311 | CONQUE_WIN32_REGEX_VK = re.compile("(\x1b\[[0-9;]+VK)") 312 | 313 | # windows attribute string splitting 314 | CONQUE_WIN32_REGEX_ATTR = re.compile("((.)\\2*)", re.DOTALL) 315 | 316 | # special key attributes 317 | CONQUE_VK_ATTR_CTRL_PRESSED = u('1024') 318 | 319 | 320 | -------------------------------------------------------------------------------- /autoload/conque_term/conque_screen.py: -------------------------------------------------------------------------------- 1 | # FILE: autoload/conque_term/conque_screen.py 2 | # AUTHOR: Nico Raffo 3 | # WEBSITE: http://conque.googlecode.com 4 | # MODIFIED: 2011-09-02 5 | # VERSION: 2.3, for Vim 7.0 6 | # LICENSE: 7 | # Conque - Vim terminal/console emulator 8 | # Copyright (C) 2009-2011 Nico Raffo 9 | # 10 | # MIT License 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining a copy 13 | # of this software and associated documentation files (the "Software"), to deal 14 | # in the Software without restriction, including without limitation the rights 15 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | # copies of the Software, and to permit persons to whom the Software is 17 | # furnished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included in 20 | # all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | # THE SOFTWARE. 29 | 30 | """ 31 | ConqueScreen is an extention of the vim.current.buffer object 32 | 33 | Unix terminal escape sequences usually reference line numbers relative to the 34 | top of the visible screen. However the visible portion of the Vim buffer 35 | representing the terminal probably doesn't start at the first line of the 36 | buffer. 37 | 38 | The ConqueScreen class allows access to the Vim buffer with screen-relative 39 | line numbering. And handles a few other related tasks, such as setting the 40 | correct cursor position. 41 | 42 | E.g.: 43 | s = ConqueScreen() 44 | ... 45 | s[5] = 'Set 5th line in terminal to this line' 46 | s.append('Add new line to terminal') 47 | s[5] = 'Since previous append() command scrolled the terminal down, this is a different line than first cb[5] call' 48 | 49 | """ 50 | 51 | import vim 52 | 53 | 54 | class ConqueScreen(object): 55 | 56 | # the buffer 57 | buffer = None 58 | 59 | # screen and scrolling regions 60 | screen_top = 1 61 | 62 | # screen width 63 | screen_width = 80 64 | screen_height = 80 65 | 66 | # char encoding for vim buffer 67 | screen_encoding = 'utf-8' 68 | 69 | 70 | def __init__(self): 71 | """ Initialize screen size and character encoding. """ 72 | 73 | self.buffer = vim.current.buffer 74 | 75 | # initialize screen size 76 | self.screen_top = 1 77 | self.screen_width = vim.current.window.width 78 | self.screen_height = vim.current.window.height 79 | 80 | # save screen character encoding type 81 | self.screen_encoding = vim.eval('&fileencoding') 82 | 83 | 84 | def __len__(self): 85 | """ Define the len() function for ConqueScreen objects. """ 86 | return len(self.buffer) 87 | 88 | 89 | def __getitem__(self, key): 90 | """ Define value access for ConqueScreen objects. """ 91 | buffer_line = self.get_real_idx(key) 92 | 93 | # if line is past buffer end, add lines to buffer 94 | if buffer_line >= len(self.buffer): 95 | for i in range(len(self.buffer), buffer_line + 1): 96 | self.append(' ') 97 | 98 | return u(self.buffer[buffer_line], 'utf-8') 99 | 100 | 101 | def __setitem__(self, key, value): 102 | """ Define value assignments for ConqueScreen objects. """ 103 | buffer_line = self.get_real_idx(key) 104 | 105 | if CONQUE_PYTHON_VERSION == 2: 106 | val = value.encode(self.screen_encoding) 107 | else: 108 | # XXX / Vim's python3 interface doesn't accept bytes object 109 | val = str(value) 110 | 111 | # if line is past end of screen, append 112 | if buffer_line == len(self.buffer): 113 | self.buffer.append(val) 114 | else: 115 | self.buffer[buffer_line] = val 116 | 117 | 118 | def __delitem__(self, key): 119 | """ Define value deletion for ConqueScreen objects. """ 120 | del self.buffer[self.screen_top + key - 2] 121 | 122 | 123 | def append(self, value): 124 | """ Define value appending for ConqueScreen objects. """ 125 | 126 | if len(self.buffer) > self.screen_top + self.screen_height - 1: 127 | self.buffer[len(self.buffer) - 1] = value 128 | else: 129 | self.buffer.append(value) 130 | 131 | if len(self.buffer) > self.screen_top + self.screen_height - 1: 132 | self.screen_top += 1 133 | 134 | if vim.current.buffer.number == self.buffer.number: 135 | vim.command('normal! G') 136 | 137 | 138 | def insert(self, line, value): 139 | """ Define value insertion for ConqueScreen objects. """ 140 | 141 | l = self.screen_top + line - 2 142 | try: 143 | self.buffer.append(value, l) 144 | except: 145 | self.buffer[l:l] = [value] 146 | 147 | 148 | def get_top(self): 149 | """ Get the Vim line number representing the top of the visible terminal. """ 150 | return self.screen_top 151 | 152 | 153 | def get_real_idx(self, line): 154 | """ Get the zero index Vim line number corresponding to the provided screen line. """ 155 | return (self.screen_top + line - 2) 156 | 157 | 158 | def get_buffer_line(self, line): 159 | """ Get the Vim line number corresponding to the provided screen line. """ 160 | return (self.screen_top + line - 1) 161 | 162 | 163 | def set_screen_width(self, width): 164 | """ Set the screen width. """ 165 | self.screen_width = width 166 | 167 | 168 | def clear(self): 169 | """ Clear the screen. Does not clear the buffer, just scrolls down past all text. """ 170 | 171 | self.screen_width = width 172 | self.buffer.append(' ') 173 | vim.command('normal! Gzt') 174 | self.screen_top = len(self.buffer) 175 | 176 | 177 | def set_cursor(self, line, column): 178 | """ Set cursor position. """ 179 | 180 | # figure out line 181 | buffer_line = self.screen_top + line - 1 182 | if buffer_line > len(self.buffer): 183 | for l in range(len(self.buffer) - 1, buffer_line): 184 | self.buffer.append('') 185 | 186 | # figure out column 187 | real_column = column 188 | if len(self.buffer[buffer_line - 1]) < real_column: 189 | self.buffer[buffer_line - 1] = self.buffer[buffer_line - 1] + ' ' * (real_column - len(self.buffer[buffer_line - 1])) 190 | 191 | if not CONQUE_FAST_MODE: 192 | # set cursor at byte index of real_column'th character 193 | vim.command('call cursor(' + str(buffer_line) + ', byteidx(getline(' + str(buffer_line) + '), ' + str(real_column) + '))') 194 | 195 | else: 196 | # old version 197 | # python version is occasionally grumpy 198 | try: 199 | vim.current.window.cursor = (buffer_line, real_column - 1) 200 | except: 201 | vim.command('call cursor(' + str(buffer_line) + ', ' + str(real_column) + ')') 202 | 203 | 204 | def reset_size(self, line): 205 | """ Change screen size """ 206 | 207 | 208 | 209 | 210 | 211 | # save cursor line number 212 | buffer_line = self.screen_top + line 213 | 214 | # reset screen size 215 | self.screen_width = vim.current.window.width 216 | self.screen_height = vim.current.window.height 217 | self.screen_top = len(self.buffer) - vim.current.window.height + 1 218 | if self.screen_top < 1: 219 | self.screen_top = 1 220 | 221 | 222 | # align bottom of buffer to bottom of screen 223 | vim.command('normal! ' + str(self.screen_height) + 'kG') 224 | 225 | # return new relative line number 226 | return (buffer_line - self.screen_top) 227 | 228 | 229 | def align(self): 230 | """ align bottom of buffer to bottom of screen """ 231 | vim.command('normal! ' + str(self.screen_height) + 'kG') 232 | 233 | 234 | -------------------------------------------------------------------------------- /autoload/conque_term/conque_sole.py: -------------------------------------------------------------------------------- 1 | # FILE: autoload/conque_term/conque_sole.py 2 | # AUTHOR: Nico Raffo 3 | # WEBSITE: http://conque.googlecode.com 4 | # MODIFIED: 2011-09-02 5 | # VERSION: 2.3, for Vim 7.0 6 | # LICENSE: 7 | # Conque - Vim terminal/console emulator 8 | # Copyright (C) 2009-2011 Nico Raffo 9 | # 10 | # MIT License 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining a copy 13 | # of this software and associated documentation files (the "Software"), to deal 14 | # in the Software without restriction, including without limitation the rights 15 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | # copies of the Software, and to permit persons to whom the Software is 17 | # furnished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included in 20 | # all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | # THE SOFTWARE. 29 | 30 | """ 31 | Windows Console Emulator 32 | 33 | This is the main interface to the Windows emulator. It reads new output from the background console 34 | and updates the Vim buffer. 35 | """ 36 | 37 | import vim 38 | 39 | 40 | class ConqueSole(Conque): 41 | 42 | window_top = None 43 | window_bottom = None 44 | 45 | color_cache = {} 46 | attribute_cache = {} 47 | color_mode = None 48 | color_conceals = {} 49 | 50 | buffer = None 51 | encoding = None 52 | 53 | # counters for periodic rendering 54 | buffer_redraw_ct = 1 55 | screen_redraw_ct = 1 56 | 57 | # line offset, shifts output down 58 | offset = 0 59 | 60 | 61 | def open(self): 62 | """ Start command and initialize this instance 63 | 64 | Arguments: 65 | command - Command string, e.g. "Powershell.exe" 66 | options - Dictionary of config options 67 | python_exe - Path to the python.exe executable. Usually C:\PythonXX\python.exe 68 | communicator_py - Path to subprocess controller script in user's vimfiles directory 69 | 70 | """ 71 | # get arguments 72 | command = vim.eval('command') 73 | options = vim.eval('options') 74 | python_exe = vim.eval('py_exe') 75 | communicator_py = vim.eval('py_vim') 76 | 77 | # init size 78 | self.columns = vim.current.window.width 79 | self.lines = vim.current.window.height 80 | self.window_top = 0 81 | self.window_bottom = vim.current.window.height - 1 82 | 83 | # color mode 84 | self.color_mode = vim.eval('g:ConqueTerm_ColorMode') 85 | 86 | # line offset 87 | self.offset = int(options['offset']) 88 | 89 | # init color 90 | self.enable_colors = options['color'] and not CONQUE_FAST_MODE 91 | 92 | # open command 93 | self.proc = ConqueSoleWrapper() 94 | self.proc.open(command, self.lines, self.columns, python_exe, communicator_py, options) 95 | 96 | self.buffer = vim.current.buffer 97 | self.screen_encoding = vim.eval('&fileencoding') 98 | 99 | 100 | def read(self, timeout=1, set_cursor=True, return_output=False, update_buffer=True): 101 | """ Read from console and update Vim buffer. """ 102 | 103 | try: 104 | stats = self.proc.get_stats() 105 | 106 | if not stats: 107 | return 108 | 109 | # disable screen and buffer redraws in fast mode 110 | if not CONQUE_FAST_MODE: 111 | self.buffer_redraw_ct += 1 112 | self.screen_redraw_ct += 1 113 | 114 | update_top = 0 115 | update_bottom = 0 116 | lines = [] 117 | 118 | # full buffer redraw, our favorite! 119 | #if self.buffer_redraw_ct == CONQUE_SOLE_BUFFER_REDRAW: 120 | # self.buffer_redraw_ct = 0 121 | # update_top = 0 122 | # update_bottom = stats['top_offset'] + self.lines 123 | # (lines, attributes) = self.proc.read(update_top, update_bottom) 124 | # if return_output: 125 | # output = self.get_new_output(lines, update_top, stats) 126 | # if update_buffer: 127 | # for i in range(update_top, update_bottom + 1): 128 | # if CONQUE_FAST_MODE: 129 | # self.plain_text(i, lines[i], None, stats) 130 | # else: 131 | # self.plain_text(i, lines[i], attributes[i], stats) 132 | 133 | # full screen redraw 134 | if stats['cursor_y'] + 1 != self.l or stats['top_offset'] != self.window_top or self.screen_redraw_ct >= CONQUE_SOLE_SCREEN_REDRAW: 135 | 136 | self.screen_redraw_ct = 0 137 | update_top = self.window_top 138 | update_bottom = max([stats['top_offset'] + self.lines + 1, stats['cursor_y']]) 139 | (lines, attributes) = self.proc.read(update_top, update_bottom - update_top + 1) 140 | if return_output: 141 | output = self.get_new_output(lines, update_top, stats) 142 | if update_buffer: 143 | for i in range(update_top, update_bottom + 1): 144 | if CONQUE_FAST_MODE: 145 | self.plain_text(i, lines[i - update_top], None, stats) 146 | else: 147 | self.plain_text(i, lines[i - update_top], attributes[i - update_top], stats) 148 | 149 | 150 | # single line redraw 151 | else: 152 | update_top = stats['cursor_y'] 153 | (lines, attributes) = self.proc.read(update_top, 1) 154 | if return_output: 155 | output = self.get_new_output(lines, update_top, stats) 156 | if update_buffer: 157 | if lines[0].rstrip() != u(self.buffer[update_top].rstrip()): 158 | if CONQUE_FAST_MODE: 159 | self.plain_text(update_top, lines[0], None, stats) 160 | else: 161 | self.plain_text(update_top, lines[0], attributes[0], stats) 162 | 163 | 164 | # reset current position 165 | self.window_top = stats['top_offset'] 166 | self.l = stats['cursor_y'] + 1 167 | self.c = stats['cursor_x'] + 1 168 | 169 | # reposition cursor if this seems plausible 170 | if set_cursor: 171 | self.set_cursor(self.l, self.c) 172 | 173 | if return_output: 174 | return output 175 | 176 | except: 177 | 178 | pass 179 | 180 | 181 | def get_new_output(self, lines, update_top, stats): 182 | """ Calculate the "new" output from this read. Fake but useful """ 183 | 184 | if not (stats['cursor_y'] + 1 > self.l or (stats['cursor_y'] + 1 == self.l and stats['cursor_x'] + 1 > self.c)): 185 | return "" 186 | 187 | 188 | 189 | 190 | 191 | 192 | try: 193 | num_to_return = stats['cursor_y'] - self.l + 2 194 | 195 | lines = lines[self.l - update_top - 1:] 196 | 197 | 198 | new_output = [] 199 | 200 | # first line 201 | new_output.append(lines[0][self.c - 1:].rstrip()) 202 | 203 | # the rest 204 | for i in range(1, num_to_return): 205 | new_output.append(lines[i].rstrip()) 206 | 207 | except: 208 | 209 | pass 210 | 211 | 212 | 213 | return "\n".join(new_output) 214 | 215 | 216 | def plain_text(self, line_nr, text, attributes, stats): 217 | """ Write plain text to Vim buffer. """ 218 | 219 | 220 | 221 | 222 | 223 | # handle line offset 224 | line_nr += self.offset 225 | 226 | self.l = line_nr + 1 227 | 228 | # remove trailing whitespace 229 | text = text.rstrip() 230 | 231 | # if we're using concealed text for color, then s- is weird 232 | if self.color_mode == 'conceal': 233 | 234 | text = self.add_conceal_color(text, attributes, stats, line_nr) 235 | 236 | 237 | # deal with character encoding 238 | if CONQUE_PYTHON_VERSION == 2: 239 | val = text.encode(self.screen_encoding) 240 | else: 241 | # XXX / Vim's python3 interface doesn't accept bytes object 242 | val = str(text) 243 | 244 | # update vim buffer 245 | if len(self.buffer) <= line_nr: 246 | self.buffer.append(val) 247 | else: 248 | self.buffer[line_nr] = val 249 | 250 | if self.enable_colors and not self.color_mode == 'conceal' and line_nr > self.l - CONQUE_MAX_SYNTAX_LINES: 251 | relevant = attributes[0:len(text)] 252 | if line_nr not in self.attribute_cache or self.attribute_cache[line_nr] != relevant: 253 | self.do_color(attributes=relevant, stats=stats) 254 | self.attribute_cache[line_nr] = relevant 255 | 256 | 257 | def add_conceal_color(self, text, attributes, stats, line_nr): 258 | """ Add 'conceal' color strings to output text """ 259 | 260 | # stop here if coloration is disabled 261 | if not self.enable_colors: 262 | return text 263 | 264 | # if no colors for this line, clear everything out 265 | if len(attributes) == 0 or attributes == u(chr(stats['default_attribute'])) * len(attributes): 266 | return text 267 | 268 | new_text = '' 269 | self.color_conceals[line_nr] = [] 270 | 271 | attribute_chunks = CONQUE_WIN32_REGEX_ATTR.findall(attributes) 272 | offset = 0 273 | ends = [] 274 | for attr in attribute_chunks: 275 | attr_num = ord(attr[1]) 276 | ends = [] 277 | if attr_num != stats['default_attribute']: 278 | 279 | color = self.translate_color(attr_num) 280 | 281 | new_text += chr(27) + 'sf' + color['fg_code'] + ';' 282 | ends.append(chr(27) + 'ef' + color['fg_code'] + ';') 283 | self.color_conceals[line_nr].append(offset) 284 | 285 | if attr_num > 15: 286 | new_text += chr(27) + 'sb' + color['bg_code'] + ';' 287 | ends.append(chr(27) + 'eb' + color['bg_code'] + ';') 288 | self.color_conceals[line_nr].append(offset) 289 | 290 | new_text += text[offset:offset + len(attr[0])] 291 | 292 | # close color regions 293 | ends.reverse() 294 | for i in range(0, len(ends)): 295 | self.color_conceals[line_nr].append(len(new_text)) 296 | new_text += ends[i] 297 | 298 | offset += len(attr[0]) 299 | 300 | return new_text 301 | 302 | 303 | def do_color(self, start=0, end=0, attributes='', stats=None): 304 | """ Convert Windows console attributes into Vim syntax highlighting """ 305 | 306 | # if no colors for this line, clear everything out 307 | if len(attributes) == 0 or attributes == u(chr(stats['default_attribute'])) * len(attributes): 308 | self.color_changes = {} 309 | self.apply_color(1, len(attributes), self.l) 310 | return 311 | 312 | attribute_chunks = CONQUE_WIN32_REGEX_ATTR.findall(attributes) 313 | offset = 0 314 | for attr in attribute_chunks: 315 | attr_num = ord(attr[1]) 316 | if attr_num != stats['default_attribute']: 317 | self.color_changes = self.translate_color(attr_num) 318 | self.apply_color(offset + 1, offset + len(attr[0]) + 1, self.l) 319 | offset += len(attr[0]) 320 | 321 | 322 | def translate_color(self, attr): 323 | """ Convert Windows console attributes into RGB colors """ 324 | 325 | # check for cached color 326 | if attr in self.color_cache: 327 | return self.color_cache[attr] 328 | 329 | 330 | 331 | 332 | 333 | 334 | # convert attribute integer to bit string 335 | bit_str = bin(attr) 336 | bit_str = bit_str.replace('0b', '') 337 | 338 | # slice foreground and background portions of bit string 339 | fg = bit_str[-4:].rjust(4, '0') 340 | bg = bit_str[-8:-4].rjust(4, '0') 341 | 342 | # ok, first create foreground #rbg 343 | red = int(fg[1]) * 204 + int(fg[0]) * int(fg[1]) * 51 344 | green = int(fg[2]) * 204 + int(fg[0]) * int(fg[2]) * 51 345 | blue = int(fg[3]) * 204 + int(fg[0]) * int(fg[3]) * 51 346 | fg_str = "#%02x%02x%02x" % (red, green, blue) 347 | fg_code = "%02x%02x%02x" % (red, green, blue) 348 | fg_code = fg_code[0] + fg_code[2] + fg_code[4] 349 | 350 | # ok, first create foreground #rbg 351 | red = int(bg[1]) * 204 + int(bg[0]) * int(bg[1]) * 51 352 | green = int(bg[2]) * 204 + int(bg[0]) * int(bg[2]) * 51 353 | blue = int(bg[3]) * 204 + int(bg[0]) * int(bg[3]) * 51 354 | bg_str = "#%02x%02x%02x" % (red, green, blue) 355 | bg_code = "%02x%02x%02x" % (red, green, blue) 356 | bg_code = bg_code[0] + bg_code[2] + bg_code[4] 357 | 358 | # build value for color_changes 359 | 360 | color = {'guifg': fg_str, 'guibg': bg_str} 361 | 362 | if self.color_mode == 'conceal': 363 | color['fg_code'] = fg_code 364 | color['bg_code'] = bg_code 365 | 366 | self.color_cache[attr] = color 367 | 368 | return color 369 | 370 | 371 | def write_vk(self, vk_code): 372 | """ write virtual key code to shared memory using proprietary escape seq """ 373 | 374 | self.proc.write_vk(vk_code) 375 | 376 | 377 | def update_window_size(self): 378 | """ Resize underlying console if Vim buffer size has changed """ 379 | 380 | if vim.current.window.width != self.columns or vim.current.window.height != self.lines: 381 | 382 | 383 | 384 | # reset all window size attributes to default 385 | self.columns = vim.current.window.width 386 | self.lines = vim.current.window.height 387 | self.working_columns = vim.current.window.width 388 | self.working_lines = vim.current.window.height 389 | self.bottom = vim.current.window.height 390 | 391 | self.proc.window_resize(vim.current.window.height, vim.current.window.width) 392 | 393 | 394 | def set_cursor(self, line, column): 395 | """ Update cursor position in Vim buffer """ 396 | 397 | 398 | 399 | # handle offset 400 | line += self.offset 401 | 402 | # shift cursor position to handle concealed text 403 | if self.enable_colors and self.color_mode == 'conceal': 404 | if line - 1 in self.color_conceals: 405 | for c in self.color_conceals[line - 1]: 406 | if c < column: 407 | column += 7 408 | else: 409 | break 410 | 411 | 412 | 413 | # figure out line 414 | buffer_line = line 415 | if buffer_line > len(self.buffer): 416 | for l in range(len(self.buffer) - 1, buffer_line): 417 | self.buffer.append('') 418 | 419 | # figure out column 420 | real_column = column 421 | if len(self.buffer[buffer_line - 1]) < real_column: 422 | self.buffer[buffer_line - 1] = self.buffer[buffer_line - 1] + ' ' * (real_column - len(self.buffer[buffer_line - 1])) 423 | 424 | # python version is occasionally grumpy 425 | try: 426 | vim.current.window.cursor = (buffer_line, real_column - 1) 427 | except: 428 | vim.command('call cursor(' + str(buffer_line) + ', ' + str(real_column) + ')') 429 | 430 | 431 | def idle(self): 432 | """ go into idle mode """ 433 | 434 | self.proc.idle() 435 | 436 | 437 | def resume(self): 438 | """ resume from idle mode """ 439 | 440 | self.proc.resume() 441 | 442 | 443 | def close(self): 444 | """ end console subprocess """ 445 | self.proc.close() 446 | 447 | 448 | def abort(self): 449 | """ end subprocess forcefully """ 450 | self.proc.close() 451 | 452 | 453 | def get_buffer_line(self, line): 454 | """ get buffer line """ 455 | return line 456 | 457 | 458 | # vim:foldmethod=marker 459 | -------------------------------------------------------------------------------- /autoload/conque_term/conque_sole_communicator.py: -------------------------------------------------------------------------------- 1 | # FILE: autoload/conque_term/conque_sole_communicator.py 2 | # AUTHOR: Nico Raffo 3 | # WEBSITE: http://conque.googlecode.com 4 | # MODIFIED: 2011-09-02 5 | # VERSION: 2.3, for Vim 7.0 6 | # LICENSE: 7 | # Conque - Vim terminal/console emulator 8 | # Copyright (C) 2009-2011 Nico Raffo 9 | # 10 | # MIT License 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining a copy 13 | # of this software and associated documentation files (the "Software"), to deal 14 | # in the Software without restriction, including without limitation the rights 15 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | # copies of the Software, and to permit persons to whom the Software is 17 | # furnished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included in 20 | # all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | # THE SOFTWARE. 29 | 30 | """ 31 | 32 | ConqueSoleCommunicator 33 | 34 | This script will create a new Windows console and start the requested program 35 | inside of it. This process is launched independently from the parent Vim 36 | program, so it has no access to the vim module. 37 | 38 | The main loop in this script reads data from the console and syncs it onto 39 | blocks of memory shared with the Vim process. In this way the Vim process 40 | and this script can communicate with each other. 41 | 42 | """ 43 | 44 | import time 45 | import sys 46 | 47 | from conque_globals import * 48 | from conque_win32_util import * 49 | from conque_sole_subprocess import * 50 | from conque_sole_shared_memory import * 51 | 52 | ############################################################## 53 | # only run if this file was run directly 54 | 55 | if __name__ == '__main__': 56 | 57 | # attempt to catch ALL exceptions to fend of zombies 58 | try: 59 | 60 | # simple arg validation 61 | 62 | if len(sys.argv) < 5: 63 | 64 | exit() 65 | 66 | # maximum time this thing reads. 0 means no limit. Only for testing. 67 | max_loops = 0 68 | 69 | # read interval, in seconds 70 | sleep_time = 0.01 71 | 72 | # idle read interval, in seconds 73 | idle_sleep_time = 0.10 74 | 75 | # are we idled? 76 | is_idle = False 77 | 78 | # mem key 79 | mem_key = sys.argv[1] 80 | 81 | # console width 82 | console_width = int(sys.argv[2]) 83 | 84 | # console height 85 | console_height = int(sys.argv[3]) 86 | 87 | # code page 88 | code_page = int(sys.argv[4]) 89 | 90 | # code page 91 | fast_mode = int(sys.argv[5]) 92 | 93 | # the actual subprocess to run 94 | cmd_line = " ".join(sys.argv[6:]) 95 | 96 | 97 | # width and height 98 | options = {'LINES': console_height, 'COLUMNS': console_width, 'CODE_PAGE': code_page, 'FAST_MODE': fast_mode} 99 | 100 | 101 | 102 | # set initial idle status 103 | shm_command = ConqueSoleSharedMemory(CONQUE_SOLE_COMMANDS_SIZE, 'command', mem_key, serialize=True) 104 | shm_command.create('write') 105 | 106 | cmd = shm_command.read() 107 | if cmd: 108 | 109 | if cmd['cmd'] == 'idle': 110 | is_idle = True 111 | shm_command.clear() 112 | 113 | 114 | ############################################################## 115 | # Create the subprocess 116 | 117 | proc = ConqueSoleSubprocess() 118 | res = proc.open(cmd_line, mem_key, options) 119 | 120 | if not res: 121 | 122 | exit() 123 | 124 | ############################################################## 125 | # main loop! 126 | 127 | loops = 0 128 | 129 | while True: 130 | 131 | # check for idle/resume 132 | if is_idle or loops % 25 == 0: 133 | 134 | # check process health 135 | if not proc.is_alive(): 136 | 137 | proc.close() 138 | break 139 | 140 | # check for change in buffer focus 141 | cmd = shm_command.read() 142 | if cmd: 143 | 144 | if cmd['cmd'] == 'idle': 145 | is_idle = True 146 | shm_command.clear() 147 | 148 | elif cmd['cmd'] == 'resume': 149 | is_idle = False 150 | shm_command.clear() 151 | 152 | 153 | # sleep between loops if moderation is requested 154 | if sleep_time > 0: 155 | if is_idle: 156 | time.sleep(idle_sleep_time) 157 | else: 158 | time.sleep(sleep_time) 159 | 160 | # write, read, etc 161 | proc.write() 162 | proc.read() 163 | 164 | # increment loops, and exit if max has been reached 165 | loops += 1 166 | if max_loops and loops >= max_loops: 167 | 168 | break 169 | 170 | ############################################################## 171 | # all done! 172 | 173 | 174 | 175 | proc.close() 176 | 177 | # if an exception was thrown, croak 178 | except: 179 | 180 | proc.close() 181 | 182 | 183 | # vim:foldmethod=marker 184 | -------------------------------------------------------------------------------- /autoload/conque_term/conque_sole_shared_memory.py: -------------------------------------------------------------------------------- 1 | # FILE: autoload/conque_term/conque_sole_shared_memory.py 2 | # AUTHOR: Nico Raffo 3 | # WEBSITE: http://conque.googlecode.com 4 | # MODIFIED: 2011-09-02 5 | # VERSION: 2.3, for Vim 7.0 6 | # LICENSE: 7 | # Conque - Vim terminal/console emulator 8 | # Copyright (C) 2009-2011 Nico Raffo 9 | # 10 | # MIT License 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining a copy 13 | # of this software and associated documentation files (the "Software"), to deal 14 | # in the Software without restriction, including without limitation the rights 15 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | # copies of the Software, and to permit persons to whom the Software is 17 | # furnished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included in 20 | # all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | # THE SOFTWARE. 29 | 30 | """ 31 | Wrapper class for shared memory between Windows python processes 32 | 33 | Adds a small amount of functionality to the standard mmap module. 34 | 35 | """ 36 | 37 | import mmap 38 | import sys 39 | 40 | # PYTHON VERSION 41 | CONQUE_PYTHON_VERSION = sys.version_info[0] 42 | 43 | if CONQUE_PYTHON_VERSION == 2: 44 | import cPickle as pickle 45 | else: 46 | import pickle 47 | 48 | 49 | class ConqueSoleSharedMemory(): 50 | 51 | # is the data being stored not fixed length 52 | fixed_length = False 53 | 54 | # maximum number of bytes per character, for fixed width blocks 55 | char_width = 1 56 | 57 | # fill memory with this character when clearing and fixed_length is true 58 | FILL_CHAR = None 59 | 60 | # serialize and unserialize data automatically 61 | serialize = False 62 | 63 | # size of shared memory, in bytes / chars 64 | mem_size = None 65 | 66 | # size of shared memory, in bytes / chars 67 | mem_type = None 68 | 69 | # unique key, so multiple console instances are possible 70 | mem_key = None 71 | 72 | # mmap instance 73 | shm = None 74 | 75 | # character encoding, dammit 76 | encoding = 'utf-8' 77 | 78 | # pickle terminator 79 | TERMINATOR = None 80 | 81 | 82 | def __init__(self, mem_size, mem_type, mem_key, fixed_length=False, fill_char=' ', serialize=False, encoding='utf-8'): 83 | """ Initialize new shared memory block instance 84 | 85 | Arguments: 86 | mem_size -- Memory size in characters, depends on encoding argument to calcuate byte size 87 | mem_type -- Label to identify what will be stored 88 | mem_key -- Unique, probably random key to identify this block 89 | fixed_length -- If set to true, assume the data stored will always fill the memory size 90 | fill_char -- Initialize memory block with this character, only really helpful with fixed_length blocks 91 | serialize -- Automatically serialize data passed to write. Allows storing non-byte data 92 | encoding -- Character encoding to use when storing character data 93 | 94 | """ 95 | self.mem_size = mem_size 96 | self.mem_type = mem_type 97 | self.mem_key = mem_key 98 | self.fixed_length = fixed_length 99 | self.fill_char = fill_char 100 | self.serialize = serialize 101 | self.encoding = encoding 102 | self.TERMINATOR = str(chr(0)).encode(self.encoding) 103 | 104 | if CONQUE_PYTHON_VERSION == 3: 105 | self.FILL_CHAR = fill_char 106 | else: 107 | self.FILL_CHAR = unicode(fill_char) 108 | 109 | if fixed_length and encoding == 'utf-8': 110 | self.char_width = 4 111 | 112 | 113 | def create(self, access='write'): 114 | """ Create a new block of shared memory using the mmap module. """ 115 | 116 | if access == 'write': 117 | mmap_access = mmap.ACCESS_WRITE 118 | else: 119 | mmap_access = mmap.ACCESS_READ 120 | 121 | name = "conque_%s_%s" % (self.mem_type, self.mem_key) 122 | 123 | self.shm = mmap.mmap(0, self.mem_size * self.char_width, name, mmap_access) 124 | 125 | if not self.shm: 126 | return False 127 | else: 128 | return True 129 | 130 | 131 | def read(self, chars=1, start=0): 132 | """ Read data from shared memory. 133 | 134 | If this is a fixed length block, read 'chars' characters from memory. 135 | Otherwise read up until the TERMINATOR character (null byte). 136 | If this memory is serialized, unserialize it automatically. 137 | 138 | """ 139 | # go to start position 140 | self.shm.seek(start * self.char_width) 141 | 142 | if self.fixed_length: 143 | chars = chars * self.char_width 144 | else: 145 | chars = self.shm.find(self.TERMINATOR) 146 | 147 | if chars == 0: 148 | return '' 149 | 150 | shm_str = self.shm.read(chars) 151 | 152 | # return unpickled byte object 153 | if self.serialize: 154 | return pickle.loads(shm_str) 155 | 156 | # decode byes in python 3 157 | if CONQUE_PYTHON_VERSION == 3: 158 | return str(shm_str, self.encoding) 159 | 160 | # encoding 161 | if self.encoding != 'ascii': 162 | shm_str = unicode(shm_str, self.encoding) 163 | 164 | return shm_str 165 | 166 | 167 | def write(self, text, start=0): 168 | """ Write data to memory. 169 | 170 | If memory is fixed length, simply write the 'text' characters at 'start' position. 171 | Otherwise write 'text' characters and append a null character. 172 | If memory is serializable, do so first. 173 | 174 | """ 175 | # simple scenario, let pickle create bytes 176 | if self.serialize: 177 | if CONQUE_PYTHON_VERSION == 3: 178 | tb = pickle.dumps(text, 0) 179 | else: 180 | tb = pickle.dumps(text, 0).encode(self.encoding) 181 | 182 | else: 183 | tb = text.encode(self.encoding, 'replace') 184 | 185 | # write to memory 186 | self.shm.seek(start * self.char_width) 187 | 188 | if self.fixed_length: 189 | self.shm.write(tb) 190 | else: 191 | self.shm.write(tb + self.TERMINATOR) 192 | 193 | 194 | def clear(self, start=0): 195 | """ Clear memory block using self.fill_char. """ 196 | 197 | self.shm.seek(start) 198 | 199 | if self.fixed_length: 200 | self.shm.write(str(self.fill_char * self.mem_size * self.char_width).encode(self.encoding)) 201 | else: 202 | self.shm.write(self.TERMINATOR) 203 | 204 | 205 | def close(self): 206 | """ Close/destroy memory block. """ 207 | 208 | self.shm.close() 209 | 210 | 211 | -------------------------------------------------------------------------------- /autoload/conque_term/conque_sole_subprocess.py: -------------------------------------------------------------------------------- 1 | # FILE: autoload/conque_term/conque_sole_subprocess.py 2 | # AUTHOR: Nico Raffo 3 | # WEBSITE: http://conque.googlecode.com 4 | # MODIFIED: 2011-09-02 5 | # VERSION: 2.3, for Vim 7.0 6 | # LICENSE: 7 | # Conque - Vim terminal/console emulator 8 | # Copyright (C) 2009-2011 Nico Raffo 9 | # 10 | # MIT License 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining a copy 13 | # of this software and associated documentation files (the "Software"), to deal 14 | # in the Software without restriction, including without limitation the rights 15 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | # copies of the Software, and to permit persons to whom the Software is 17 | # furnished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included in 20 | # all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | # THE SOFTWARE. 29 | 30 | """ ConqueSoleSubprocess 31 | 32 | Creates a new subprocess with it's own (hidden) console window. 33 | 34 | Mirrors console window text onto a block of shared memory (mmap), along with 35 | text attribute data. Also handles translation of text input into the format 36 | Windows console expects. 37 | 38 | Sample Usage: 39 | 40 | sh = ConqueSoleSubprocess() 41 | sh.open("cmd.exe", "unique_str") 42 | 43 | shm_in = ConqueSoleSharedMemory(mem_key = "unique_str", mem_type = "input", ...) 44 | shm_out = ConqueSoleSharedMemory(mem_key = "unique_str", mem_type = "output", ...) 45 | 46 | output = shm_out.read(...) 47 | shm_in.write("dir\r") 48 | output = shm_out.read(...) 49 | 50 | """ 51 | 52 | import time 53 | import re 54 | import os 55 | import ctypes 56 | 57 | from conque_globals import * 58 | from conque_win32_util import * 59 | from conque_sole_shared_memory import * 60 | 61 | 62 | class ConqueSoleSubprocess(): 63 | 64 | # subprocess handle and pid 65 | handle = None 66 | pid = None 67 | 68 | # input / output handles 69 | stdin = None 70 | stdout = None 71 | 72 | # size of console window 73 | window_width = 160 74 | window_height = 40 75 | 76 | # max lines for the console buffer 77 | buffer_width = 160 78 | buffer_height = 100 79 | 80 | # keep track of the buffer number at the top of the window 81 | top = 0 82 | line_offset = 0 83 | 84 | # buffer height is CONQUE_SOLE_BUFFER_LENGTH * output_blocks 85 | output_blocks = 1 86 | 87 | # cursor position 88 | cursor_line = 0 89 | cursor_col = 0 90 | 91 | # console data, array of lines 92 | data = [] 93 | 94 | # console attribute data, array of array of int 95 | attributes = [] 96 | attribute_cache = {} 97 | 98 | # default attribute 99 | default_attribute = 7 100 | 101 | # shared memory objects 102 | shm_input = None 103 | shm_output = None 104 | shm_attributes = None 105 | shm_stats = None 106 | shm_command = None 107 | shm_rescroll = None 108 | shm_resize = None 109 | 110 | # are we still a valid process? 111 | is_alive = True 112 | 113 | # running in fast mode 114 | fast_mode = 0 115 | 116 | # used for periodic execution of screen and memory redrawing 117 | screen_redraw_ct = 0 118 | mem_redraw_ct = 0 119 | 120 | 121 | def open(self, cmd, mem_key, options={}): 122 | """ Create subproccess running in hidden console window. """ 123 | 124 | 125 | 126 | self.reset = True 127 | 128 | try: 129 | # if we're already attached to a console, then unattach 130 | try: 131 | ctypes.windll.kernel32.FreeConsole() 132 | except: 133 | pass 134 | 135 | # set buffer height 136 | self.buffer_height = CONQUE_SOLE_BUFFER_LENGTH 137 | 138 | if 'LINES' in options and 'COLUMNS' in options: 139 | self.window_width = options['COLUMNS'] 140 | self.window_height = options['LINES'] 141 | self.buffer_width = options['COLUMNS'] 142 | 143 | # fast mode 144 | self.fast_mode = options['FAST_MODE'] 145 | 146 | # console window options 147 | si = STARTUPINFO() 148 | 149 | # hide window 150 | si.dwFlags |= STARTF_USESHOWWINDOW 151 | si.wShowWindow = SW_HIDE 152 | #si.wShowWindow = SW_MINIMIZE 153 | 154 | # process options 155 | flags = NORMAL_PRIORITY_CLASS | CREATE_NEW_PROCESS_GROUP | CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_CONSOLE 156 | 157 | # created process info 158 | pi = PROCESS_INFORMATION() 159 | 160 | 161 | 162 | # create the process! 163 | res = ctypes.windll.kernel32.CreateProcessW(None, u(cmd), None, None, 0, flags, None, u('.'), ctypes.byref(si), ctypes.byref(pi)) 164 | 165 | 166 | 167 | 168 | 169 | # process info 170 | self.pid = pi.dwProcessId 171 | self.handle = pi.hProcess 172 | 173 | 174 | 175 | 176 | # attach ourselves to the new console 177 | # console is not immediately available 178 | for i in range(10): 179 | time.sleep(0.25) 180 | try: 181 | 182 | res = ctypes.windll.kernel32.AttachConsole(self.pid) 183 | 184 | 185 | 186 | 187 | 188 | 189 | break 190 | except: 191 | 192 | pass 193 | 194 | # get input / output handles 195 | self.stdout = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE) 196 | self.stdin = ctypes.windll.kernel32.GetStdHandle(STD_INPUT_HANDLE) 197 | 198 | # set buffer size 199 | size = COORD(self.buffer_width, self.buffer_height) 200 | res = ctypes.windll.kernel32.SetConsoleScreenBufferSize(self.stdout, size) 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | # prev set size call needs to process 209 | time.sleep(0.2) 210 | 211 | # set window size 212 | self.set_window_size(self.window_width, self.window_height) 213 | 214 | # set utf-8 code page 215 | if 'CODE_PAGE' in options and options['CODE_PAGE'] > 0: 216 | if ctypes.windll.kernel32.IsValidCodePage(ctypes.c_uint(options['CODE_PAGE'])): 217 | 218 | ctypes.windll.kernel32.SetConsoleCP(ctypes.c_uint(options['CODE_PAGE'])) 219 | ctypes.windll.kernel32.SetConsoleOutputCP(ctypes.c_uint(options['CODE_PAGE'])) 220 | 221 | # init shared memory 222 | self.init_shared_memory(mem_key) 223 | 224 | # init read buffers 225 | self.tc = ctypes.create_unicode_buffer(self.buffer_width) 226 | self.ac = ctypes.create_unicode_buffer(self.buffer_width) 227 | 228 | return True 229 | 230 | except: 231 | 232 | return False 233 | 234 | 235 | def init_shared_memory(self, mem_key): 236 | """ Create shared memory objects. """ 237 | 238 | self.shm_input = ConqueSoleSharedMemory(CONQUE_SOLE_INPUT_SIZE, 'input', mem_key) 239 | self.shm_input.create('write') 240 | self.shm_input.clear() 241 | 242 | self.shm_output = ConqueSoleSharedMemory(self.buffer_height * self.buffer_width, 'output', mem_key, True) 243 | self.shm_output.create('write') 244 | self.shm_output.clear() 245 | 246 | if not self.fast_mode: 247 | buf_info = self.get_buffer_info() 248 | self.shm_attributes = ConqueSoleSharedMemory(self.buffer_height * self.buffer_width, 'attributes', mem_key, True, chr(buf_info.wAttributes), encoding='latin-1') 249 | self.shm_attributes.create('write') 250 | self.shm_attributes.clear() 251 | 252 | self.shm_stats = ConqueSoleSharedMemory(CONQUE_SOLE_STATS_SIZE, 'stats', mem_key, serialize=True) 253 | self.shm_stats.create('write') 254 | self.shm_stats.clear() 255 | 256 | self.shm_command = ConqueSoleSharedMemory(CONQUE_SOLE_COMMANDS_SIZE, 'command', mem_key, serialize=True) 257 | self.shm_command.create('write') 258 | self.shm_command.clear() 259 | 260 | self.shm_resize = ConqueSoleSharedMemory(CONQUE_SOLE_RESIZE_SIZE, 'resize', mem_key, serialize=True) 261 | self.shm_resize.create('write') 262 | self.shm_resize.clear() 263 | 264 | self.shm_rescroll = ConqueSoleSharedMemory(CONQUE_SOLE_RESCROLL_SIZE, 'rescroll', mem_key, serialize=True) 265 | self.shm_rescroll.create('write') 266 | self.shm_rescroll.clear() 267 | 268 | return True 269 | 270 | 271 | def check_commands(self): 272 | """ Check for and process commands from Vim. """ 273 | 274 | cmd = self.shm_command.read() 275 | 276 | if cmd: 277 | 278 | # shut it all down 279 | if cmd['cmd'] == 'close': 280 | 281 | # clear command 282 | self.shm_command.clear() 283 | 284 | self.close() 285 | return 286 | 287 | cmd = self.shm_resize.read() 288 | 289 | if cmd: 290 | 291 | # clear command 292 | self.shm_resize.clear() 293 | 294 | # resize console 295 | if cmd['cmd'] == 'resize': 296 | 297 | 298 | 299 | # only change buffer width if it's larger 300 | if cmd['data']['width'] > self.buffer_width: 301 | self.buffer_width = cmd['data']['width'] 302 | 303 | # always change console width and height 304 | self.window_width = cmd['data']['width'] 305 | self.window_height = cmd['data']['height'] 306 | 307 | # reset the console 308 | buf_info = self.get_buffer_info() 309 | self.reset_console(buf_info, add_block=False) 310 | 311 | 312 | def read(self): 313 | """ Read from windows console and update shared memory blocks. """ 314 | 315 | # no point really 316 | if self.screen_redraw_ct == 0 and not self.is_alive(): 317 | stats = {'top_offset': 0, 'default_attribute': 0, 'cursor_x': 0, 'cursor_y': self.cursor_line, 'is_alive': 0} 318 | 319 | self.shm_stats.write(stats) 320 | return 321 | 322 | # check for commands 323 | self.check_commands() 324 | 325 | # get cursor position 326 | buf_info = self.get_buffer_info() 327 | curs_line = buf_info.dwCursorPosition.Y 328 | curs_col = buf_info.dwCursorPosition.X 329 | 330 | # set update range 331 | if curs_line != self.cursor_line or self.top != buf_info.srWindow.Top or self.screen_redraw_ct == CONQUE_SOLE_SCREEN_REDRAW: 332 | self.screen_redraw_ct = 0 333 | 334 | read_start = self.top 335 | read_end = max([buf_info.srWindow.Bottom + 1, curs_line + 1]) 336 | else: 337 | 338 | read_start = curs_line 339 | read_end = curs_line + 1 340 | 341 | 342 | 343 | 344 | # vars used in for loop 345 | coord = COORD(0, 0) 346 | chars_read = ctypes.c_int(0) 347 | 348 | # read new data 349 | for i in range(read_start, read_end): 350 | 351 | coord.Y = i 352 | 353 | res = ctypes.windll.kernel32.ReadConsoleOutputCharacterW(self.stdout, ctypes.byref(self.tc), self.buffer_width, coord, ctypes.byref(chars_read)) 354 | if not self.fast_mode: 355 | ctypes.windll.kernel32.ReadConsoleOutputAttribute(self.stdout, ctypes.byref(self.ac), self.buffer_width, coord, ctypes.byref(chars_read)) 356 | 357 | t = self.tc.value 358 | if not self.fast_mode: 359 | a = self.ac.value 360 | 361 | # add data 362 | if i >= len(self.data): 363 | for j in range(len(self.data), i + 1): 364 | self.data.append('') 365 | if not self.fast_mode: 366 | self.attributes.append('') 367 | 368 | self.data[i] = t 369 | if not self.fast_mode: 370 | self.attributes[i] = a 371 | 372 | 373 | 374 | 375 | #for i in range(0, len(t)): 376 | 377 | 378 | 379 | 380 | # write new output to shared memory 381 | try: 382 | if self.mem_redraw_ct == CONQUE_SOLE_MEM_REDRAW: 383 | self.mem_redraw_ct = 0 384 | 385 | for i in range(0, len(self.data)): 386 | self.shm_output.write(text=self.data[i], start=self.buffer_width * i) 387 | if not self.fast_mode: 388 | self.shm_attributes.write(text=self.attributes[i], start=self.buffer_width * i) 389 | else: 390 | 391 | for i in range(read_start, read_end): 392 | self.shm_output.write(text=self.data[i], start=self.buffer_width * i) 393 | if not self.fast_mode: 394 | self.shm_attributes.write(text=self.attributes[i], start=self.buffer_width * i) 395 | #self.shm_output.write(text=''.join(self.data[read_start:read_end]), start=read_start * self.buffer_width) 396 | #self.shm_attributes.write(text=''.join(self.attributes[read_start:read_end]), start=read_start * self.buffer_width) 397 | 398 | # write cursor position to shared memory 399 | stats = {'top_offset': buf_info.srWindow.Top, 'default_attribute': buf_info.wAttributes, 'cursor_x': curs_col, 'cursor_y': curs_line, 'is_alive': 1} 400 | self.shm_stats.write(stats) 401 | 402 | # adjust screen position 403 | self.top = buf_info.srWindow.Top 404 | self.cursor_line = curs_line 405 | 406 | # check for reset 407 | if curs_line > buf_info.dwSize.Y - 200: 408 | self.reset_console(buf_info) 409 | 410 | except: 411 | 412 | 413 | 414 | 415 | pass 416 | 417 | # increment redraw counters 418 | self.screen_redraw_ct += 1 419 | self.mem_redraw_ct += 1 420 | 421 | return None 422 | 423 | 424 | def reset_console(self, buf_info, add_block=True): 425 | """ Extend the height of the current console if the cursor postion gets within 200 lines of the current size. """ 426 | 427 | # sometimes we just want to change the buffer width, 428 | # in which case no need to add another block 429 | if add_block: 430 | self.output_blocks += 1 431 | 432 | # close down old memory 433 | self.shm_output.close() 434 | self.shm_output = None 435 | 436 | if not self.fast_mode: 437 | self.shm_attributes.close() 438 | self.shm_attributes = None 439 | 440 | # new shared memory key 441 | mem_key = 'mk' + str(time.time()) 442 | 443 | # reallocate memory 444 | self.shm_output = ConqueSoleSharedMemory(self.buffer_height * self.buffer_width * self.output_blocks, 'output', mem_key, True) 445 | self.shm_output.create('write') 446 | self.shm_output.clear() 447 | 448 | # backfill data 449 | if len(self.data[0]) < self.buffer_width: 450 | for i in range(0, len(self.data)): 451 | self.data[i] = self.data[i] + ' ' * (self.buffer_width - len(self.data[i])) 452 | self.shm_output.write(''.join(self.data)) 453 | 454 | if not self.fast_mode: 455 | self.shm_attributes = ConqueSoleSharedMemory(self.buffer_height * self.buffer_width * self.output_blocks, 'attributes', mem_key, True, chr(buf_info.wAttributes), encoding='latin-1') 456 | self.shm_attributes.create('write') 457 | self.shm_attributes.clear() 458 | 459 | # backfill attributes 460 | if len(self.attributes[0]) < self.buffer_width: 461 | for i in range(0, len(self.attributes)): 462 | self.attributes[i] = self.attributes[i] + chr(buf_info.wAttributes) * (self.buffer_width - len(self.attributes[i])) 463 | if not self.fast_mode: 464 | self.shm_attributes.write(''.join(self.attributes)) 465 | 466 | # notify wrapper of new output block 467 | self.shm_rescroll.write({'cmd': 'new_output', 'data': {'blocks': self.output_blocks, 'mem_key': mem_key}}) 468 | 469 | # set buffer size 470 | size = COORD(X=self.buffer_width, Y=self.buffer_height * self.output_blocks) 471 | 472 | res = ctypes.windll.kernel32.SetConsoleScreenBufferSize(self.stdout, size) 473 | 474 | 475 | 476 | 477 | 478 | 479 | # prev set size call needs to process 480 | time.sleep(0.2) 481 | 482 | # set window size 483 | self.set_window_size(self.window_width, self.window_height) 484 | 485 | # init read buffers 486 | self.tc = ctypes.create_unicode_buffer(self.buffer_width) 487 | self.ac = ctypes.create_unicode_buffer(self.buffer_width) 488 | 489 | 490 | 491 | def write(self): 492 | """ Write text to console. 493 | 494 | This function just parses out special sequences for special key events 495 | and passes on the text to the plain or virtual key functions. 496 | 497 | """ 498 | # get input from shared mem 499 | text = self.shm_input.read() 500 | 501 | # nothing to do here 502 | if text == u(''): 503 | return 504 | 505 | 506 | 507 | # clear input queue 508 | self.shm_input.clear() 509 | 510 | # split on VK codes 511 | chunks = CONQUE_WIN32_REGEX_VK.split(text) 512 | 513 | # if len() is one then no vks 514 | if len(chunks) == 1: 515 | self.write_plain(text) 516 | return 517 | 518 | 519 | 520 | # loop over chunks and delegate 521 | for t in chunks: 522 | 523 | if t == '': 524 | continue 525 | 526 | if CONQUE_WIN32_REGEX_VK.match(t): 527 | 528 | self.write_vk(t[2:-2]) 529 | else: 530 | self.write_plain(t) 531 | 532 | 533 | def write_plain(self, text): 534 | """ Write simple text to subprocess. """ 535 | 536 | li = INPUT_RECORD * len(text) 537 | list_input = li() 538 | 539 | for i in range(0, len(text)): 540 | 541 | # create keyboard input 542 | ke = KEY_EVENT_RECORD() 543 | ke.bKeyDown = ctypes.c_byte(1) 544 | ke.wRepeatCount = ctypes.c_short(1) 545 | 546 | cnum = ord(text[i]) 547 | 548 | ke.wVirtualKeyCode = ctypes.windll.user32.VkKeyScanW(cnum) 549 | ke.wVirtualScanCode = ctypes.c_short(ctypes.windll.user32.MapVirtualKeyW(int(cnum), 0)) 550 | 551 | if cnum > 31: 552 | ke.uChar.UnicodeChar = uchr(cnum) 553 | elif cnum == 3: 554 | ctypes.windll.kernel32.GenerateConsoleCtrlEvent(0, self.pid) 555 | ke.uChar.UnicodeChar = uchr(cnum) 556 | ke.wVirtualKeyCode = ctypes.windll.user32.VkKeyScanW(cnum + 96) 557 | ke.dwControlKeyState |= LEFT_CTRL_PRESSED 558 | else: 559 | ke.uChar.UnicodeChar = uchr(cnum) 560 | if cnum in CONQUE_WINDOWS_VK_INV: 561 | ke.wVirtualKeyCode = cnum 562 | else: 563 | ke.wVirtualKeyCode = ctypes.windll.user32.VkKeyScanW(cnum + 96) 564 | ke.dwControlKeyState |= LEFT_CTRL_PRESSED 565 | 566 | 567 | 568 | 569 | kc = INPUT_RECORD(KEY_EVENT) 570 | kc.Event.KeyEvent = ke 571 | list_input[i] = kc 572 | 573 | 574 | 575 | # write input array 576 | events_written = ctypes.c_int() 577 | res = ctypes.windll.kernel32.WriteConsoleInputW(self.stdin, list_input, len(text), ctypes.byref(events_written)) 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | def write_vk(self, vk_code): 587 | """ Write special characters to console subprocess. """ 588 | 589 | 590 | 591 | code = None 592 | ctrl_pressed = False 593 | 594 | # this could be made more generic when more attributes 595 | # other than ctrl_pressed are available 596 | vk_attributes = vk_code.split(';') 597 | 598 | for attr in vk_attributes: 599 | if attr == CONQUE_VK_ATTR_CTRL_PRESSED: 600 | ctrl_pressed = True 601 | else: 602 | code = attr 603 | 604 | li = INPUT_RECORD * 1 605 | 606 | # create keyboard input 607 | ke = KEY_EVENT_RECORD() 608 | ke.uChar.UnicodeChar = uchr(0) 609 | ke.wVirtualKeyCode = ctypes.c_short(int(code)) 610 | ke.wVirtualScanCode = ctypes.c_short(ctypes.windll.user32.MapVirtualKeyW(int(code), 0)) 611 | ke.bKeyDown = ctypes.c_byte(1) 612 | ke.wRepeatCount = ctypes.c_short(1) 613 | 614 | # set enhanced key mode for arrow keys 615 | if code in CONQUE_WINDOWS_VK_ENHANCED: 616 | 617 | ke.dwControlKeyState |= ENHANCED_KEY 618 | 619 | if ctrl_pressed: 620 | ke.dwControlKeyState |= LEFT_CTRL_PRESSED 621 | 622 | kc = INPUT_RECORD(KEY_EVENT) 623 | kc.Event.KeyEvent = ke 624 | list_input = li(kc) 625 | 626 | # write input array 627 | events_written = ctypes.c_int() 628 | res = ctypes.windll.kernel32.WriteConsoleInputW(self.stdin, list_input, 1, ctypes.byref(events_written)) 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | def close(self): 637 | """ Close all running subproccesses """ 638 | 639 | # record status 640 | self.is_alive = False 641 | try: 642 | stats = {'top_offset': 0, 'default_attribute': 0, 'cursor_x': 0, 'cursor_y': self.cursor_line, 'is_alive': 0} 643 | self.shm_stats.write(stats) 644 | except: 645 | pass 646 | 647 | pid_list = (ctypes.c_int * 10)() 648 | num = ctypes.windll.kernel32.GetConsoleProcessList(pid_list, 10) 649 | 650 | 651 | 652 | current_pid = os.getpid() 653 | 654 | 655 | 656 | 657 | 658 | # kill subprocess pids 659 | for pid in pid_list[0:num]: 660 | if not pid: 661 | break 662 | 663 | # kill current pid last 664 | if pid == current_pid: 665 | continue 666 | try: 667 | self.close_pid(pid) 668 | except: 669 | 670 | pass 671 | 672 | # kill this process 673 | try: 674 | self.close_pid(current_pid) 675 | except: 676 | 677 | pass 678 | 679 | 680 | def close_pid(self, pid): 681 | """ Terminate a single process. """ 682 | 683 | 684 | handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, 0, pid) 685 | ctypes.windll.kernel32.TerminateProcess(handle, -1) 686 | ctypes.windll.kernel32.CloseHandle(handle) 687 | 688 | 689 | def is_alive(self): 690 | """ Check process health. """ 691 | 692 | status = ctypes.windll.kernel32.WaitForSingleObject(self.handle, 1) 693 | 694 | if status == 0: 695 | 696 | self.is_alive = False 697 | 698 | return self.is_alive 699 | 700 | 701 | def get_screen_text(self): 702 | """ Return screen data as string. """ 703 | 704 | return "\n".join(self.data) 705 | 706 | 707 | def set_window_size(self, width, height): 708 | """ Change Windows console size. """ 709 | 710 | 711 | 712 | # get current window size object 713 | window_size = SMALL_RECT(0, 0, 0, 0) 714 | 715 | # buffer info has maximum window size data 716 | buf_info = self.get_buffer_info() 717 | 718 | 719 | # set top left corner 720 | window_size.Top = 0 721 | window_size.Left = 0 722 | 723 | # set bottom right corner 724 | if buf_info.dwMaximumWindowSize.X < width: 725 | 726 | window_size.Right = buf_info.dwMaximumWindowSize.X - 1 727 | else: 728 | window_size.Right = width - 1 729 | 730 | if buf_info.dwMaximumWindowSize.Y < height: 731 | 732 | window_size.Bottom = buf_info.dwMaximumWindowSize.Y - 1 733 | else: 734 | window_size.Bottom = height - 1 735 | 736 | 737 | 738 | # set the window size! 739 | res = ctypes.windll.kernel32.SetConsoleWindowInfo(self.stdout, ctypes.c_bool(True), ctypes.byref(window_size)) 740 | 741 | 742 | 743 | 744 | 745 | 746 | # reread buffer info to get final console max lines 747 | buf_info = self.get_buffer_info() 748 | 749 | self.window_width = buf_info.srWindow.Right + 1 750 | self.window_height = buf_info.srWindow.Bottom + 1 751 | 752 | 753 | def get_buffer_info(self): 754 | """ Retrieve commonly-used buffer information. """ 755 | 756 | buf_info = CONSOLE_SCREEN_BUFFER_INFO() 757 | ctypes.windll.kernel32.GetConsoleScreenBufferInfo(self.stdout, ctypes.byref(buf_info)) 758 | 759 | return buf_info 760 | 761 | 762 | 763 | -------------------------------------------------------------------------------- /autoload/conque_term/conque_sole_wrapper.py: -------------------------------------------------------------------------------- 1 | # FILE: autoload/conque_term/conque_sole_wrapper.py 2 | # AUTHOR: Nico Raffo 3 | # WEBSITE: http://conque.googlecode.com 4 | # MODIFIED: 2011-09-02 5 | # VERSION: 2.3, for Vim 7.0 6 | # LICENSE: 7 | # Conque - Vim terminal/console emulator 8 | # Copyright (C) 2009-2011 Nico Raffo 9 | # 10 | # MIT License 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining a copy 13 | # of this software and associated documentation files (the "Software"), to deal 14 | # in the Software without restriction, including without limitation the rights 15 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | # copies of the Software, and to permit persons to whom the Software is 17 | # furnished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included in 20 | # all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | # THE SOFTWARE. 29 | 30 | """ 31 | 32 | ConqueSoleSubprocessWrapper 33 | 34 | Subprocess wrapper to deal with Windows insanity. Launches console based python, 35 | which in turn launches originally requested command. Communicates with cosole 36 | python through shared memory objects. 37 | 38 | """ 39 | 40 | import ctypes 41 | import time 42 | 43 | 44 | class ConqueSoleWrapper(): 45 | 46 | # unique key used for shared memory block names 47 | shm_key = '' 48 | 49 | # process info 50 | handle = None 51 | pid = None 52 | 53 | # queue input in this bucket 54 | bucket = None 55 | 56 | # console size 57 | lines = 24 58 | columns = 80 59 | 60 | # shared memory objects 61 | shm_input = None 62 | shm_output = None 63 | shm_attributes = None 64 | shm_stats = None 65 | shm_command = None 66 | shm_rescroll = None 67 | shm_resize = None 68 | 69 | # console python process 70 | proc = None 71 | 72 | 73 | def open(self, cmd, lines, columns, python_exe='python.exe', communicator_py='conque_sole_communicator.py', options={}): 74 | """ Launch python.exe subprocess which will in turn launch the user's program. 75 | 76 | Arguments: 77 | cmd -- The user's command to run. E.g. "Powershell.exe" or "C:\Python27\Scripts\ipython.bat" 78 | lines, columns -- The size of the console, also the size of the Vim buffer 79 | python.exe -- The path to the python executable, typically C:\PythonXX\python.exe 80 | communicator_py -- The path to the subprocess controller script in the user's vimfiles directory 81 | options -- optional configuration 82 | 83 | """ 84 | self.lines = lines 85 | self.columns = columns 86 | self.bucket = u('') 87 | 88 | # create a shm key 89 | self.shm_key = 'mk' + str(time.time()) 90 | 91 | # python command 92 | cmd_line = '%s "%s" %s %d %d %d %d %s' % (python_exe, communicator_py, self.shm_key, int(self.columns), int(self.lines), int(options['CODE_PAGE']), int(CONQUE_FAST_MODE), cmd) 93 | 94 | 95 | # console window attributes 96 | flags = NORMAL_PRIORITY_CLASS | DETACHED_PROCESS | CREATE_UNICODE_ENVIRONMENT 97 | si = STARTUPINFO() 98 | pi = PROCESS_INFORMATION() 99 | 100 | # start the stupid process already 101 | try: 102 | res = ctypes.windll.kernel32.CreateProcessW(None, u(cmd_line), None, None, 0, flags, None, u('.'), ctypes.byref(si), ctypes.byref(pi)) 103 | except: 104 | 105 | raise 106 | 107 | # handle 108 | self.pid = pi.dwProcessId 109 | 110 | 111 | 112 | # init shared memory objects 113 | self.init_shared_memory(self.shm_key) 114 | 115 | 116 | def read(self, start_line, num_lines, timeout=0): 117 | """ Read a range of console lines from shared memory. 118 | 119 | Returns a pair of lists containing the console text and console text attributes. 120 | 121 | """ 122 | # emulate timeout by sleeping timeout time 123 | if timeout > 0: 124 | read_timeout = float(timeout) / 1000 125 | 126 | time.sleep(read_timeout) 127 | 128 | output = [] 129 | attributes = [] 130 | 131 | # get output 132 | for i in range(start_line, start_line + num_lines + 1): 133 | output.append(self.shm_output.read(self.columns, i * self.columns)) 134 | if not CONQUE_FAST_MODE: 135 | attributes.append(self.shm_attributes.read(self.columns, i * self.columns)) 136 | 137 | return (output, attributes) 138 | 139 | 140 | def get_stats(self): 141 | """ Return a dictionary with current console cursor and scrolling information. """ 142 | 143 | try: 144 | rescroll = self.shm_rescroll.read() 145 | if rescroll != '' and rescroll != None: 146 | 147 | 148 | 149 | self.shm_rescroll.clear() 150 | 151 | # close down old memory 152 | self.shm_output.close() 153 | self.shm_output = None 154 | 155 | if not CONQUE_FAST_MODE: 156 | self.shm_attributes.close() 157 | self.shm_attributes = None 158 | 159 | # reallocate memory 160 | 161 | self.shm_output = ConqueSoleSharedMemory(CONQUE_SOLE_BUFFER_LENGTH * self.columns * rescroll['data']['blocks'], 'output', rescroll['data']['mem_key'], True) 162 | self.shm_output.create('read') 163 | 164 | if not CONQUE_FAST_MODE: 165 | self.shm_attributes = ConqueSoleSharedMemory(CONQUE_SOLE_BUFFER_LENGTH * self.columns * rescroll['data']['blocks'], 'attributes', rescroll['data']['mem_key'], True, encoding='latin-1') 166 | self.shm_attributes.create('read') 167 | 168 | stats_str = self.shm_stats.read() 169 | if stats_str != '': 170 | self.stats = stats_str 171 | else: 172 | return False 173 | except: 174 | 175 | return False 176 | 177 | return self.stats 178 | 179 | 180 | def is_alive(self): 181 | """ Get process status. """ 182 | 183 | if not self.shm_stats: 184 | return True 185 | 186 | stats_str = self.shm_stats.read() 187 | if stats_str: 188 | return (stats_str['is_alive']) 189 | else: 190 | return True 191 | 192 | 193 | def write(self, text): 194 | """ Write input to shared memory. """ 195 | 196 | self.bucket += text 197 | 198 | istr = self.shm_input.read() 199 | 200 | if istr == '': 201 | 202 | self.shm_input.write(self.bucket[:500]) 203 | self.bucket = self.bucket[500:] 204 | 205 | 206 | def write_vk(self, vk_code): 207 | """ Write virtual key code to shared memory using proprietary escape sequences. """ 208 | 209 | seq = u("\x1b[") + u(str(vk_code)) + u("VK") 210 | self.write(seq) 211 | 212 | 213 | def idle(self): 214 | """ Write idle command to shared memory block, so subprocess controller can hibernate. """ 215 | 216 | 217 | self.shm_command.write({'cmd': 'idle', 'data': {}}) 218 | 219 | 220 | def resume(self): 221 | """ Write resume command to shared memory block, so subprocess controller can wake up. """ 222 | 223 | self.shm_command.write({'cmd': 'resume', 'data': {}}) 224 | 225 | 226 | def close(self): 227 | """ Shut it all down. """ 228 | 229 | self.shm_command.write({'cmd': 'close', 'data': {}}) 230 | time.sleep(0.2) 231 | 232 | 233 | def window_resize(self, lines, columns): 234 | """ Resize console window. """ 235 | 236 | self.lines = lines 237 | 238 | # we don't shrink buffer width 239 | if columns > self.columns: 240 | self.columns = columns 241 | 242 | self.shm_resize.write({'cmd': 'resize', 'data': {'width': columns, 'height': lines}}) 243 | 244 | 245 | def init_shared_memory(self, mem_key): 246 | """ Create shared memory objects. """ 247 | 248 | self.shm_input = ConqueSoleSharedMemory(CONQUE_SOLE_INPUT_SIZE, 'input', mem_key) 249 | self.shm_input.create('write') 250 | self.shm_input.clear() 251 | 252 | self.shm_output = ConqueSoleSharedMemory(CONQUE_SOLE_BUFFER_LENGTH * self.columns, 'output', mem_key, True) 253 | self.shm_output.create('write') 254 | 255 | if not CONQUE_FAST_MODE: 256 | self.shm_attributes = ConqueSoleSharedMemory(CONQUE_SOLE_BUFFER_LENGTH * self.columns, 'attributes', mem_key, True, encoding='latin-1') 257 | self.shm_attributes.create('write') 258 | 259 | self.shm_stats = ConqueSoleSharedMemory(CONQUE_SOLE_STATS_SIZE, 'stats', mem_key, serialize=True) 260 | self.shm_stats.create('write') 261 | self.shm_stats.clear() 262 | 263 | self.shm_command = ConqueSoleSharedMemory(CONQUE_SOLE_COMMANDS_SIZE, 'command', mem_key, serialize=True) 264 | self.shm_command.create('write') 265 | self.shm_command.clear() 266 | 267 | self.shm_resize = ConqueSoleSharedMemory(CONQUE_SOLE_RESIZE_SIZE, 'resize', mem_key, serialize=True) 268 | self.shm_resize.create('write') 269 | self.shm_resize.clear() 270 | 271 | self.shm_rescroll = ConqueSoleSharedMemory(CONQUE_SOLE_RESCROLL_SIZE, 'rescroll', mem_key, serialize=True) 272 | self.shm_rescroll.create('write') 273 | self.shm_rescroll.clear() 274 | 275 | return True 276 | 277 | 278 | # vim:foldmethod=marker 279 | -------------------------------------------------------------------------------- /autoload/conque_term/conque_subprocess.py: -------------------------------------------------------------------------------- 1 | # FILE: autoload/conque_term/conque_subprocess.py 2 | # AUTHOR: Nico Raffo 3 | # WEBSITE: http://conque.googlecode.com 4 | # MODIFIED: 2011-09-02 5 | # VERSION: 2.3, for Vim 7.0 6 | # LICENSE: 7 | # Conque - Vim terminal/console emulator 8 | # Copyright (C) 2009-2011 Nico Raffo 9 | # 10 | # MIT License 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining a copy 13 | # of this software and associated documentation files (the "Software"), to deal 14 | # in the Software without restriction, including without limitation the rights 15 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | # copies of the Software, and to permit persons to whom the Software is 17 | # furnished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included in 20 | # all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | # THE SOFTWARE. 29 | 30 | """ 31 | ConqueSubprocess 32 | 33 | Create and interact with a subprocess through a pty. 34 | 35 | Usage: 36 | 37 | p = ConqueSubprocess() 38 | p.open('bash', {'TERM':'vt100'}) 39 | output = p.read() 40 | p.write('cd ~/vim' + "\r") 41 | p.write('ls -lha' + "\r") 42 | output += p.read(timeout = 500) 43 | p.close() 44 | """ 45 | 46 | import os 47 | import signal 48 | import pty 49 | import tty 50 | import select 51 | import fcntl 52 | import termios 53 | import struct 54 | import shlex 55 | 56 | 57 | class ConqueSubprocess: 58 | 59 | # process id 60 | pid = 0 61 | 62 | # stdout+stderr file descriptor 63 | fd = None 64 | 65 | 66 | def open(self, command, env={}): 67 | """ Create subprocess using forkpty() """ 68 | 69 | # parse command 70 | command_arr = shlex.split(command) 71 | executable = command_arr[0] 72 | args = command_arr 73 | 74 | # try to fork a new pty 75 | try: 76 | self.pid, self.fd = pty.fork() 77 | 78 | except: 79 | 80 | return False 81 | 82 | # child proc, replace with command after altering terminal attributes 83 | if self.pid == 0: 84 | 85 | # set requested environment variables 86 | for k in env.keys(): 87 | os.environ[k] = env[k] 88 | 89 | # set tty attributes 90 | try: 91 | attrs = tty.tcgetattr(1) 92 | attrs[0] = attrs[0] ^ tty.IGNBRK 93 | attrs[0] = attrs[0] | tty.BRKINT | tty.IXANY | tty.IMAXBEL 94 | attrs[2] = attrs[2] | tty.HUPCL 95 | attrs[3] = attrs[3] | tty.ICANON | tty.ECHO | tty.ISIG | tty.ECHOKE 96 | attrs[6][tty.VMIN] = 1 97 | attrs[6][tty.VTIME] = 0 98 | tty.tcsetattr(1, tty.TCSANOW, attrs) 99 | except: 100 | 101 | pass 102 | 103 | # replace this process with the subprocess 104 | os.execvp(executable, args) 105 | 106 | # else master, do nothing 107 | else: 108 | pass 109 | 110 | 111 | def read(self, timeout=1): 112 | """ Read from subprocess and return new output """ 113 | 114 | output = '' 115 | read_timeout = float(timeout) / 1000 116 | read_ct = 0 117 | 118 | try: 119 | # read from fd until no more output 120 | while 1: 121 | s_read, s_write, s_error = select.select([self.fd], [], [], read_timeout) 122 | 123 | lines = '' 124 | for s_fd in s_read: 125 | try: 126 | # increase read buffer so huge reads don't slow down 127 | if read_ct < 10: 128 | lines = os.read(self.fd, 32) 129 | elif read_ct < 50: 130 | lines = os.read(self.fd, 512) 131 | else: 132 | lines = os.read(self.fd, 2048) 133 | read_ct += 1 134 | except: 135 | pass 136 | output = output + lines.decode('utf-8') 137 | 138 | if lines == '' or read_ct > 100: 139 | break 140 | except: 141 | 142 | pass 143 | 144 | return output 145 | 146 | 147 | def write(self, input): 148 | """ Write new input to subprocess """ 149 | 150 | try: 151 | if CONQUE_PYTHON_VERSION == 2: 152 | os.write(self.fd, input.encode('utf-8', 'ignore')) 153 | else: 154 | os.write(self.fd, bytes(input, 'utf-8')) 155 | except: 156 | 157 | pass 158 | 159 | 160 | def signal(self, signum): 161 | """ signal process """ 162 | 163 | try: 164 | os.kill(self.pid, signum) 165 | except: 166 | pass 167 | 168 | 169 | def close(self): 170 | """ close process with sigterm signal """ 171 | 172 | self.signal(15) 173 | 174 | 175 | def is_alive(self): 176 | """ get process status """ 177 | 178 | p_status = True 179 | try: 180 | if os.waitpid(self.pid, os.WNOHANG)[0]: 181 | p_status = False 182 | except: 183 | p_status = False 184 | 185 | return p_status 186 | 187 | 188 | def window_resize(self, lines, columns): 189 | """ update window size in kernel, then send SIGWINCH to fg process """ 190 | 191 | try: 192 | fcntl.ioctl(self.fd, termios.TIOCSWINSZ, struct.pack("HHHH", lines, columns, 0, 0)) 193 | os.kill(self.pid, signal.SIGWINCH) 194 | except: 195 | pass 196 | 197 | 198 | # vim:foldmethod=marker 199 | -------------------------------------------------------------------------------- /autoload/conque_term/conque_win32_util.py: -------------------------------------------------------------------------------- 1 | # FILE: autoload/conque_term/conque_win32_util.py 2 | # AUTHOR: Nico Raffo 3 | # WEBSITE: http://conque.googlecode.com 4 | # MODIFIED: 2011-09-02 5 | # VERSION: 2.3, for Vim 7.0 6 | # LICENSE: 7 | # Conque - Vim terminal/console emulator 8 | # Copyright (C) 2009-2011 Nico Raffo 9 | # 10 | # MIT License 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining a copy 13 | # of this software and associated documentation files (the "Software"), to deal 14 | # in the Software without restriction, including without limitation the rights 15 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | # copies of the Software, and to permit persons to whom the Software is 17 | # furnished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included in 20 | # all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | # THE SOFTWARE. 29 | 30 | """ Python constants and structures used for ctypes interaction. """ 31 | 32 | from ctypes import * 33 | 34 | # Constants 35 | 36 | # create process flag constants 37 | 38 | CREATE_BREAKAWAY_FROM_JOB = 0x01000000 39 | CREATE_DEFAULT_ERROR_MODE = 0x04000000 40 | CREATE_NEW_CONSOLE = 0x00000010 41 | CREATE_NEW_PROCESS_GROUP = 0x00000200 42 | CREATE_NO_WINDOW = 0x08000000 43 | CREATE_PROTECTED_PROCESS = 0x00040000 44 | CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000 45 | CREATE_SEPARATE_WOW_VDM = 0x00000800 46 | CREATE_SHARED_WOW_VDM = 0x00001000 47 | CREATE_SUSPENDED = 0x00000004 48 | CREATE_UNICODE_ENVIRONMENT = 0x00000400 49 | 50 | 51 | DETACHED_PROCESS = 0x00000008 52 | EXTENDED_STARTUPINFO_PRESENT = 0x00080000 53 | INHERIT_PARENT_AFFINITY = 0x00010000 54 | 55 | 56 | # process priority constants 57 | 58 | ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000 59 | BELOW_NORMAL_PRIORITY_CLASS = 0x00004000 60 | HIGH_PRIORITY_CLASS = 0x00000080 61 | IDLE_PRIORITY_CLASS = 0x00000040 62 | NORMAL_PRIORITY_CLASS = 0x00000020 63 | REALTIME_PRIORITY_CLASS = 0x00000100 64 | 65 | 66 | # startup info constants 67 | 68 | STARTF_FORCEONFEEDBACK = 0x00000040 69 | STARTF_FORCEOFFFEEDBACK = 0x00000080 70 | STARTF_PREVENTPINNING = 0x00002000 71 | STARTF_RUNFULLSCREEN = 0x00000020 72 | STARTF_TITLEISAPPID = 0x00001000 73 | STARTF_TITLEISLINKNAME = 0x00000800 74 | STARTF_USECOUNTCHARS = 0x00000008 75 | STARTF_USEFILLATTRIBUTE = 0x00000010 76 | STARTF_USEHOTKEY = 0x00000200 77 | STARTF_USEPOSITION = 0x00000004 78 | STARTF_USESHOWWINDOW = 0x00000001 79 | STARTF_USESIZE = 0x00000002 80 | STARTF_USESTDHANDLES = 0x00000100 81 | 82 | 83 | # show window constants 84 | 85 | SW_FORCEMINIMIZE = 11 86 | SW_HIDE = 0 87 | SW_MAXIMIZE = 3 88 | SW_MINIMIZE = 6 89 | SW_RESTORE = 9 90 | SW_SHOW = 5 91 | SW_SHOWDEFAULT = 10 92 | SW_SHOWMAXIMIZED = 3 93 | SW_SHOWMINIMIZED = 2 94 | SW_SHOWMINNOACTIVE = 7 95 | SW_SHOWNA = 8 96 | SW_SHOWNOACTIVATE = 4 97 | SW_SHOWNORMAL = 1 98 | 99 | 100 | # input event types 101 | 102 | FOCUS_EVENT = 0x0010 103 | KEY_EVENT = 0x0001 104 | MENU_EVENT = 0x0008 105 | MOUSE_EVENT = 0x0002 106 | WINDOW_BUFFER_SIZE_EVENT = 0x0004 107 | 108 | 109 | # key event modifiers 110 | 111 | CAPSLOCK_ON = 0x0080 112 | ENHANCED_KEY = 0x0100 113 | LEFT_ALT_PRESSED = 0x0002 114 | LEFT_CTRL_PRESSED = 0x0008 115 | NUMLOCK_ON = 0x0020 116 | RIGHT_ALT_PRESSED = 0x0001 117 | RIGHT_CTRL_PRESSED = 0x0004 118 | SCROLLLOCK_ON = 0x0040 119 | SHIFT_PRESSED = 0x0010 120 | 121 | 122 | # process access 123 | 124 | PROCESS_CREATE_PROCESS = 0x0080 125 | PROCESS_CREATE_THREAD = 0x0002 126 | PROCESS_DUP_HANDLE = 0x0040 127 | PROCESS_QUERY_INFORMATION = 0x0400 128 | PROCESS_QUERY_LIMITED_INFORMATION = 0x1000 129 | PROCESS_SET_INFORMATION = 0x0200 130 | PROCESS_SET_QUOTA = 0x0100 131 | PROCESS_SUSPEND_RESUME = 0x0800 132 | PROCESS_TERMINATE = 0x0001 133 | PROCESS_VM_OPERATION = 0x0008 134 | PROCESS_VM_READ = 0x0010 135 | PROCESS_VM_WRITE = 0x0020 136 | 137 | 138 | # input / output handles 139 | 140 | STD_INPUT_HANDLE = c_ulong(-10) 141 | STD_OUTPUT_HANDLE = c_ulong(-11) 142 | STD_ERROR_HANDLE = c_ulong(-12) 143 | 144 | 145 | CONQUE_WINDOWS_VK = { 146 | 'VK_LBUTTON': 0x0001, 147 | 'VK_RBUTTON': 0x0002, 148 | 'VK_CANCEL': 0x0003, 149 | 'VK_BACK': 0x0008, 150 | 'VK_TAB': 0x0009, 151 | 'VK_CLEAR': 0x000C, 152 | 'VK_RETURN': 0x0D, 153 | 'VK_SHIFT': 0x10, 154 | 'VK_CONTROL': 0x11, 155 | 'VK_MENU': 0x12, 156 | 'VK_PAUSE': 0x0013, 157 | 'VK_CAPITAL': 0x0014, 158 | 'VK_ESCAPE': 0x001B, 159 | 'VK_SPACE': 0x0020, 160 | 'VK_PRIOR': 0x0021, 161 | 'VK_NEXT': 0x0022, 162 | 'VK_END': 0x0023, 163 | 'VK_HOME': 0x0024, 164 | 'VK_LEFT': 0x0025, 165 | 'VK_UP': 0x0026, 166 | 'VK_RIGHT': 0x0027, 167 | 'VK_DOWN': 0x0028, 168 | 'VK_SELECT': 0x0029, 169 | 'VK_PRINT': 0x002A, 170 | 'VK_EXECUTE': 0x002B, 171 | 'VK_SNAPSHOT': 0x002C, 172 | 'VK_INSERT': 0x002D, 173 | 'VK_DELETE': 0x002E, 174 | 'VK_HELP': 0x002F, 175 | 'VK_0': 0x0030, 176 | 'VK_1': 0x0031, 177 | 'VK_2': 0x0032, 178 | 'VK_3': 0x0033, 179 | 'VK_4': 0x0034, 180 | 'VK_5': 0x0035, 181 | 'VK_6': 0x0036, 182 | 'VK_7': 0x0037, 183 | 'VK_8': 0x0038, 184 | 'VK_9': 0x0039, 185 | 'VK_A': 0x0041, 186 | 'VK_B': 0x0042, 187 | 'VK_C': 0x0043, 188 | 'VK_D': 0x0044, 189 | 'VK_E': 0x0045, 190 | 'VK_F': 0x0046, 191 | 'VK_G': 0x0047, 192 | 'VK_H': 0x0048, 193 | 'VK_I': 0x0049, 194 | 'VK_J': 0x004A, 195 | 'VK_K': 0x004B, 196 | 'VK_L': 0x004C, 197 | 'VK_M': 0x004D, 198 | 'VK_N': 0x004E, 199 | 'VK_O': 0x004F, 200 | 'VK_P': 0x0050, 201 | 'VK_Q': 0x0051, 202 | 'VK_R': 0x0052, 203 | 'VK_S': 0x0053, 204 | 'VK_T': 0x0054, 205 | 'VK_U': 0x0055, 206 | 'VK_V': 0x0056, 207 | 'VK_W': 0x0057, 208 | 'VK_X': 0x0058, 209 | 'VK_Y': 0x0059, 210 | 'VK_Z': 0x005A, 211 | 'VK_LWIN': 0x005B, 212 | 'VK_RWIN': 0x005C, 213 | 'VK_APPS': 0x005D, 214 | 'VK_SLEEP': 0x005F, 215 | 'VK_NUMPAD0': 0x0060, 216 | 'VK_NUMPAD1': 0x0061, 217 | 'VK_NUMPAD2': 0x0062, 218 | 'VK_NUMPAD3': 0x0063, 219 | 'VK_NUMPAD4': 0x0064, 220 | 'VK_NUMPAD5': 0x0065, 221 | 'VK_NUMPAD6': 0x0066, 222 | 'VK_NUMPAD7': 0x0067, 223 | 'VK_NUMPAD8': 0x0068, 224 | 'VK_MULTIPLY': 0x006A, 225 | 'VK_ADD': 0x006B, 226 | 'VK_SEPARATOR': 0x006C, 227 | 'VK_SUBTRACT': 0x006D, 228 | 'VK_DECIMAL': 0x006E, 229 | 'VK_DIVIDE': 0x006F, 230 | 'VK_F1': 0x0070, 231 | 'VK_F2': 0x0071, 232 | 'VK_F3': 0x0072, 233 | 'VK_F4': 0x0073, 234 | 'VK_F5': 0x0074, 235 | 'VK_F6': 0x0075, 236 | 'VK_F7': 0x0076, 237 | 'VK_F8': 0x0077, 238 | 'VK_F9': 0x0078, 239 | 'VK_F10': 0x0079, 240 | 'VK_F11': 0x007A, 241 | 'VK_F12': 0x007B, 242 | 'VK_F13': 0x007C, 243 | 'VK_F14': 0x007D, 244 | 'VK_F15': 0x007E, 245 | 'VK_F16': 0x007F, 246 | 'VK_F17': 0x0080, 247 | 'VK_F18': 0x0081, 248 | 'VK_F19': 0x0082, 249 | 'VK_F20': 0x0083, 250 | 'VK_F21': 0x0084, 251 | 'VK_F22': 0x0085, 252 | 'VK_F23': 0x0086, 253 | 'VK_F24': 0x0087, 254 | 'VK_NUMLOCK': 0x0090, 255 | 'VK_SCROLL': 0x0091, 256 | 'VK_LSHIFT': 0x00A0, 257 | 'VK_RSHIFT': 0x00A1, 258 | 'VK_LCONTROL': 0x00A2, 259 | 'VK_RCONTROL': 0x00A3, 260 | 'VK_LMENU': 0x00A4, 261 | 'VK_RMENU': 0x00A5 262 | } 263 | 264 | CONQUE_WINDOWS_VK_INV = dict([v, k] for k, v in CONQUE_WINDOWS_VK.items()) 265 | 266 | CONQUE_WINDOWS_VK_ENHANCED = { 267 | str(int(CONQUE_WINDOWS_VK['VK_UP'])): 1, 268 | str(int(CONQUE_WINDOWS_VK['VK_DOWN'])): 1, 269 | str(int(CONQUE_WINDOWS_VK['VK_LEFT'])): 1, 270 | str(int(CONQUE_WINDOWS_VK['VK_RIGHT'])): 1, 271 | str(int(CONQUE_WINDOWS_VK['VK_HOME'])): 1, 272 | str(int(CONQUE_WINDOWS_VK['VK_END'])): 1 273 | } 274 | 275 | 276 | # structures used for CreateProcess 277 | 278 | # Odd types 279 | 280 | LPBYTE = POINTER(c_ubyte) 281 | LPTSTR = POINTER(c_char) 282 | 283 | 284 | class STARTUPINFO(Structure): 285 | _fields_ = [("cb", c_ulong), 286 | ("lpReserved", LPTSTR), 287 | ("lpDesktop", LPTSTR), 288 | ("lpTitle", LPTSTR), 289 | ("dwX", c_ulong), 290 | ("dwY", c_ulong), 291 | ("dwXSize", c_ulong), 292 | ("dwYSize", c_ulong), 293 | ("dwXCountChars", c_ulong), 294 | ("dwYCountChars", c_ulong), 295 | ("dwFillAttribute", c_ulong), 296 | ("dwFlags", c_ulong), 297 | ("wShowWindow", c_short), 298 | ("cbReserved2", c_short), 299 | ("lpReserved2", LPBYTE), 300 | ("hStdInput", c_void_p), 301 | ("hStdOutput", c_void_p), 302 | ("hStdError", c_void_p),] 303 | 304 | def to_str(self): 305 | return '' 306 | 307 | 308 | class PROCESS_INFORMATION(Structure): 309 | _fields_ = [("hProcess", c_void_p), 310 | ("hThread", c_void_p), 311 | ("dwProcessId", c_ulong), 312 | ("dwThreadId", c_ulong),] 313 | 314 | def to_str(self): 315 | return '' 316 | 317 | 318 | class MEMORY_BASIC_INFORMATION(Structure): 319 | _fields_ = [("BaseAddress", c_void_p), 320 | ("AllocationBase", c_void_p), 321 | ("AllocationProtect", c_ulong), 322 | ("RegionSize", c_ulong), 323 | ("State", c_ulong), 324 | ("Protect", c_ulong), 325 | ("Type", c_ulong),] 326 | 327 | def to_str(self): 328 | return '' 329 | 330 | 331 | class SECURITY_ATTRIBUTES(Structure): 332 | _fields_ = [("Length", c_ulong), 333 | ("SecDescriptor", c_void_p), 334 | ("InheritHandle", c_bool)] 335 | 336 | def to_str(self): 337 | return '' 338 | 339 | 340 | class COORD(Structure): 341 | _fields_ = [("X", c_short), 342 | ("Y", c_short)] 343 | 344 | def to_str(self): 345 | return '' 346 | 347 | 348 | class SMALL_RECT(Structure): 349 | _fields_ = [("Left", c_short), 350 | ("Top", c_short), 351 | ("Right", c_short), 352 | ("Bottom", c_short)] 353 | 354 | def to_str(self): 355 | return '' 356 | 357 | 358 | class CONSOLE_SCREEN_BUFFER_INFO(Structure): 359 | _fields_ = [("dwSize", COORD), 360 | ("dwCursorPosition", COORD), 361 | ("wAttributes", c_short), 362 | ("srWindow", SMALL_RECT), 363 | ("dwMaximumWindowSize", COORD)] 364 | 365 | def to_str(self): 366 | return '' 367 | 368 | 369 | class CHAR_UNION(Union): 370 | _fields_ = [("UnicodeChar", c_wchar), 371 | ("AsciiChar", c_char)] 372 | 373 | def to_str(self): 374 | return '' 375 | 376 | 377 | class CHAR_INFO(Structure): 378 | _fields_ = [("Char", CHAR_UNION), 379 | ("Attributes", c_short)] 380 | 381 | def to_str(self): 382 | return '' 383 | 384 | 385 | class KEY_EVENT_RECORD(Structure): 386 | _fields_ = [("bKeyDown", c_byte), 387 | ("pad2", c_byte), 388 | ('pad1', c_short), 389 | ("wRepeatCount", c_short), 390 | ("wVirtualKeyCode", c_short), 391 | ("wVirtualScanCode", c_short), 392 | ("uChar", CHAR_UNION), 393 | ("dwControlKeyState", c_int)] 394 | 395 | def to_str(self): 396 | return '' 397 | 398 | 399 | class MOUSE_EVENT_RECORD(Structure): 400 | _fields_ = [("dwMousePosition", COORD), 401 | ("dwButtonState", c_int), 402 | ("dwControlKeyState", c_int), 403 | ("dwEventFlags", c_int)] 404 | 405 | def to_str(self): 406 | return '' 407 | 408 | 409 | class WINDOW_BUFFER_SIZE_RECORD(Structure): 410 | _fields_ = [("dwSize", COORD)] 411 | 412 | def to_str(self): 413 | return '' 414 | 415 | 416 | class MENU_EVENT_RECORD(Structure): 417 | _fields_ = [("dwCommandId", c_uint)] 418 | 419 | def to_str(self): 420 | return '' 421 | 422 | 423 | class FOCUS_EVENT_RECORD(Structure): 424 | _fields_ = [("bSetFocus", c_byte)] 425 | 426 | def to_str(self): 427 | return '' 428 | 429 | 430 | class INPUT_UNION(Union): 431 | _fields_ = [("KeyEvent", KEY_EVENT_RECORD), 432 | ("MouseEvent", MOUSE_EVENT_RECORD), 433 | ("WindowBufferSizeEvent", WINDOW_BUFFER_SIZE_RECORD), 434 | ("MenuEvent", MENU_EVENT_RECORD), 435 | ("FocusEvent", FOCUS_EVENT_RECORD)] 436 | 437 | def to_str(self): 438 | return '' 439 | 440 | 441 | class INPUT_RECORD(Structure): 442 | _fields_ = [("EventType", c_short), 443 | ("Event", INPUT_UNION)] 444 | 445 | def to_str(self): 446 | return '' 447 | 448 | 449 | -------------------------------------------------------------------------------- /colors/smyck.vim: -------------------------------------------------------------------------------- 1 | " ---------------------------------------------------------------------------- 2 | " Vim color file 3 | " Maintainer: John-Paul Bader 4 | " Last Change: 2012 April 5 | " License: Beer Ware 6 | " ---------------------------------------------------------------------------- 7 | 8 | " Reset Highlighting 9 | hi clear 10 | if exists("syntax_on") 11 | syntax reset 12 | endif 13 | 14 | set background=dark 15 | set linespace=3 16 | 17 | let g:colors_name = "smyck" 18 | 19 | hi Normal cterm=none ctermbg=none ctermfg=15 gui=none guibg=#282828 guifg=#F7F7F7 20 | hi LineNr cterm=none ctermbg=none ctermfg=8 gui=none guibg=#282828 guifg=#8F8F8F 21 | hi StatusLine cterm=none ctermbg=8 ctermfg=15 gui=none guibg=#5D5D5D guifg=#FBFBFB 22 | hi StatusLineNC cterm=none ctermbg=15 ctermfg=8 gui=none guibg=#5D5D5D guifg=#FBFBFB 23 | hi Search cterm=none ctermbg=6 ctermfg=15 gui=none guibg=#2EB5C1 guifg=#F7F7F7 24 | hi IncSearch cterm=none ctermbg=3 ctermfg=8 gui=none guibg=#F6DC69 guifg=#8F8F8F 25 | hi ColumnMargin cterm=none ctermbg=0 gui=none guibg=#000000 26 | hi Error cterm=none ctermbg=1 ctermfg=15 gui=none guifg=#F7F7F7 27 | hi ErrorMsg cterm=none ctermbg=1 ctermfg=15 gui=none guifg=#F7F7F7 28 | hi Folded cterm=none ctermbg=8 ctermfg=2 gui=none guibg=#3B3B3B guifg=#90AB41 29 | hi FoldColumn cterm=none ctermbg=8 ctermfg=2 gui=none guibg=#3B3B3B guifg=#90AB41 30 | hi NonText cterm=bold ctermbg=none ctermfg=8 gui=bold guifg=#8F8F8F 31 | hi ModeMsg cterm=bold ctermbg=none ctermfg=10 gui=none 32 | hi Pmenu cterm=none ctermbg=8 ctermfg=15 gui=none guibg=#8F8F8F guifg=#F7F7F7 33 | hi PmenuSel cterm=none ctermbg=15 ctermfg=8 gui=none guibg=#F7F7F7 guifg=#8F8F8F 34 | hi PmenuSbar cterm=none ctermbg=15 ctermfg=8 gui=none guibg=#F7F7F7 guifg=#8F8F8F 35 | hi SpellBad cterm=none ctermbg=1 ctermfg=15 gui=none guifg=#F7F7F7 36 | hi SpellCap cterm=none ctermbg=4 ctermfg=15 gui=none guifg=#F7F7F7 37 | hi SpellRare cterm=none ctermbg=4 ctermfg=15 gui=none guifg=#F7F7F7 38 | hi SpellLocal cterm=none ctermbg=4 ctermfg=15 gui=none guifg=#F7F7F7 39 | hi Visual cterm=none ctermbg=15 ctermfg=8 gui=none guibg=#F7F7F7 guifg=#8F8F8F 40 | hi Directory cterm=none ctermbg=none ctermfg=4 gui=none guibg=#242424 guifg=#88CCE7 41 | hi SpecialKey cterm=none ctermbg=none ctermfg=8 gui=none guifg=#8F8F8F 42 | hi DiffAdd cterm=bold ctermbg=2 ctermfg=15 43 | hi DiffChange cterm=bold ctermbg=4 ctermfg=15 44 | hi DiffDelete cterm=bold ctermbg=1 ctermfg=15 45 | hi DiffText cterm=bold ctermbg=3 ctermfg=8 46 | hi MatchParen cterm=none ctermbg=6 ctermfg=15 gui=none guibg=#2EB5C1 guifg=#F7F7F7 47 | hi CursorLine cterm=none ctermbg=238 ctermfg=none gui=none guibg=#424242 48 | hi CursorColumn cterm=none ctermbg=238 ctermfg=none gui=none guibg=#424242 49 | hi Title cterm=none ctermbg=none ctermfg=4 gui=none guifg=#88CCE7 50 | 51 | " ---------------------------------------------------------------------------- 52 | " Syntax Highlighting 53 | " ---------------------------------------------------------------------------- 54 | hi Keyword cterm=none ctermbg=none ctermfg=10 gui=none guifg=#D1FA71 55 | hi Comment cterm=none ctermbg=none ctermfg=8 gui=none guifg=#8F8F8F 56 | hi Delimiter cterm=none ctermbg=none ctermfg=15 gui=none guifg=#F7F7F7 57 | hi Identifier cterm=none ctermbg=none ctermfg=12 gui=none guifg=#96D9F1 58 | hi Structure cterm=none ctermbg=none ctermfg=12 gui=none guifg=#9DEEF2 59 | hi Ignore cterm=none ctermbg=none ctermfg=8 gui=none guifg=bg 60 | hi Constant cterm=none ctermbg=none ctermfg=12 gui=none guifg=#96D9F1 61 | hi PreProc cterm=none ctermbg=none ctermfg=10 gui=none guifg=#D1FA71 62 | hi Type cterm=none ctermbg=none ctermfg=12 gui=none guifg=#96D9F1 63 | hi Statement cterm=none ctermbg=none ctermfg=10 gui=none guifg=#D1FA71 64 | hi Special cterm=none ctermbg=none ctermfg=6 gui=none guifg=#d7d7d7 65 | hi String cterm=none ctermbg=none ctermfg=3 gui=none guifg=#F6DC69 66 | hi Number cterm=none ctermbg=none ctermfg=3 gui=none guifg=#F6DC69 67 | hi Underlined cterm=none ctermbg=none ctermfg=magenta gui=underline guibg=#272727 68 | hi Symbol cterm=none ctermbg=none ctermfg=9 gui=none guifg=#FAB1AB 69 | hi Method cterm=none ctermbg=none ctermfg=15 gui=none guifg=#F7F7F7 70 | hi Interpolation cterm=none ctermbg=none ctermfg=6 gui=none guifg=#2EB5C1 71 | 72 | " Erlang 73 | hi link erlangAtom Keyword 74 | hi link erlangBitType Keyword 75 | 76 | hi link rubyBeginend Keyword 77 | hi link rubyClass Keyword 78 | hi link rubyModule Keyword 79 | hi link rubyKeyword Keyword 80 | hi link rubyOperator Method 81 | hi link rubyIdentifier Keyword 82 | hi link rubyClassVariable Symbol 83 | hi link rubyInstanceVariable Constant 84 | hi link rubyGlobalVariable Constant 85 | hi link rubyClassVariable Method 86 | hi link rubyConstant Constant 87 | hi link rubySymbol Symbol 88 | hi link rubyFunction Constant 89 | hi link rubyControl Keyword 90 | hi link rubyConditional Keyword 91 | hi link rubyInterpolation Interpolation 92 | hi link rubyInterpolationDelimiter Interpolation 93 | hi link rubyRailsMethod Method 94 | 95 | 96 | -------------------------------------------------------------------------------- /plugin/conque_term.vim: -------------------------------------------------------------------------------- 1 | " FILE: plugin/conque_term.vim {{{ 2 | " AUTHOR: Nico Raffo 3 | " WEBSITE: http://conque.googlecode.com 4 | " MODIFIED: 2011-09-02 5 | " VERSION: 2.3, for Vim 7.0 6 | " LICENSE: 7 | " Conque - Vim terminal/console emulator 8 | " Copyright (C) 2009-2011 Nico Raffo 9 | " 10 | " MIT License 11 | " 12 | " Permission is hereby granted, free of charge, to any person obtaining a copy 13 | " of this software and associated documentation files (the "Software"), to deal 14 | " in the Software without restriction, including without limitation the rights 15 | " to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | " copies of the Software, and to permit persons to whom the Software is 17 | " furnished to do so, subject to the following conditions: 18 | " 19 | " The above copyright notice and this permission notice shall be included in 20 | " all copies or substantial portions of the Software. 21 | " 22 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | " IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | " FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | " AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | " LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | " OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | " THE SOFTWARE. 29 | " }}} 30 | 31 | " See docs/conque_term.txt for help or type :help ConqueTerm 32 | 33 | if exists('g:ConqueTerm_Loaded') || v:version < 700 34 | finish 35 | endif 36 | 37 | " ********************************************************************************************************** 38 | " **** DEFAULT CONFIGURATION ******************************************************************************* 39 | " ********************************************************************************************************** 40 | 41 | " DO NOT EDIT CONFIGURATION SETTINGS IN THIS FILE! 42 | " Define these variables in your local .vimrc to over-ride the default values 43 | 44 | " {{{ 45 | 46 | " Fast mode {{{ 47 | " Disables all features which could cause Conque to run slowly, including: 48 | " * Disables terminal colors 49 | " * Disables some multi-byte character handling 50 | if !exists('g:ConqueTerm_FastMode') 51 | let g:ConqueTerm_FastMode = 0 52 | endif " }}} 53 | 54 | " automatically go into insert mode when entering buffer {{{ 55 | if !exists('g:ConqueTerm_InsertOnEnter') 56 | let g:ConqueTerm_InsertOnEnter = 0 57 | endif " }}} 58 | 59 | " Allow user to use keys to switch window in insert mode. {{{ 60 | if !exists('g:ConqueTerm_CWInsert') 61 | let g:ConqueTerm_CWInsert = 0 62 | endif " }}} 63 | 64 | " Choose key mapping to leave insert mode {{{ 65 | " If you choose something other than '', then will be sent to terminal 66 | " Using a different key will usually fix Alt/Meta key issues 67 | if !exists('g:ConqueTerm_EscKey') 68 | let g:ConqueTerm_EscKey = '' 69 | endif " }}} 70 | 71 | " Use this key to execute the current file in a split window. {{{ 72 | " THIS IS A GLOBAL KEY MAPPING 73 | if !exists('g:ConqueTerm_ExecFileKey') 74 | let g:ConqueTerm_ExecFileKey = '' 75 | endif " }}} 76 | 77 | " Use this key to send the current file contents to conque. {{{ 78 | " THIS IS A GLOBAL KEY MAPPING 79 | if !exists('g:ConqueTerm_SendFileKey') 80 | let g:ConqueTerm_SendFileKey = '' 81 | endif " }}} 82 | 83 | " Use this key to send selected text to conque. {{{ 84 | " THIS IS A GLOBAL KEY MAPPING 85 | if !exists('g:ConqueTerm_SendVisKey') 86 | let g:ConqueTerm_SendVisKey = '' 87 | endif " }}} 88 | 89 | " Use this key to toggle terminal key mappings. {{{ 90 | " Only mapped inside of Conque buffers. 91 | if !exists('g:ConqueTerm_ToggleKey') 92 | let g:ConqueTerm_ToggleKey = '' 93 | endif " }}} 94 | 95 | " Enable color. {{{ 96 | " If your apps use a lot of color it will slow down the shell. 97 | " 0 - no terminal colors. You still will see Vim syntax highlighting. 98 | " 1 - limited terminal colors (recommended). Past terminal color history cleared regularly. 99 | " 2 - all terminal colors. Terminal color history never cleared. 100 | if !exists('g:ConqueTerm_Color') 101 | let g:ConqueTerm_Color = 1 102 | endif " }}} 103 | 104 | " Color mode. Windows ONLY {{{ 105 | " Set this variable to 'conceal' to use Vim's conceal mode for terminal colors. 106 | " This makes colors render much faster, but has some odd baggage. 107 | if !exists('g:ConqueTerm_ColorMode') 108 | let g:ConqueTerm_ColorMode = '' 109 | endif " }}} 110 | 111 | " TERM environment setting {{{ 112 | if !exists('g:ConqueTerm_TERM') 113 | let g:ConqueTerm_TERM = 'vt100' 114 | endif " }}} 115 | 116 | " Syntax for your buffer {{{ 117 | if !exists('g:ConqueTerm_Syntax') 118 | let g:ConqueTerm_Syntax = 'conque_term' 119 | endif " }}} 120 | 121 | " Keep on updating the shell window after you've switched to another buffer {{{ 122 | if !exists('g:ConqueTerm_ReadUnfocused') 123 | let g:ConqueTerm_ReadUnfocused = 0 124 | endif " }}} 125 | 126 | " Use this regular expression to highlight prompt {{{ 127 | if !exists('g:ConqueTerm_PromptRegex') 128 | let g:ConqueTerm_PromptRegex = '^\w\+@[0-9A-Za-z_.-]\+:[0-9A-Za-z_./\~,:-]\+\$' 129 | endif " }}} 130 | 131 | " Choose which Python version to attempt to load first {{{ 132 | " Valid values are 2, 3 or 0 (no preference) 133 | if !exists('g:ConqueTerm_PyVersion') 134 | let g:ConqueTerm_PyVersion = 2 135 | endif " }}} 136 | 137 | " Path to python.exe. (Windows only) {{{ 138 | " By default, Conque will check C:\PythonNN\python.exe then will search system path 139 | " If you have installed Python in an unusual location and it's not in your path, fill in the full path below 140 | " E.g. 'C:\Program Files\Python\Python27\python.exe' 141 | if !exists('g:ConqueTerm_PyExe') 142 | let g:ConqueTerm_PyExe = '' 143 | endif " }}} 144 | 145 | " Automatically close buffer when program exits {{{ 146 | if !exists('g:ConqueTerm_CloseOnEnd') 147 | let g:ConqueTerm_CloseOnEnd = 0 148 | endif " }}} 149 | 150 | " Send function key presses to terminal {{{ 151 | if !exists('g:ConqueTerm_SendFunctionKeys') 152 | let g:ConqueTerm_SendFunctionKeys = 0 153 | endif " }}} 154 | 155 | " Session support {{{ 156 | if !exists('g:ConqueTerm_SessionSupport') 157 | let g:ConqueTerm_SessionSupport = 0 158 | endif " }}} 159 | 160 | " hide Conque startup messages {{{ 161 | " messages should only appear the first 3 times you start Vim with a new version of Conque 162 | " and include important Conque feature and option descriptions 163 | " TODO - disabled and unused for now 164 | if !exists('g:ConqueTerm_StartMessages') 165 | let g:ConqueTerm_StartMessages = 1 166 | endif " }}} 167 | 168 | " Windows character code page {{{ 169 | " Leave at 0 to use current environment code page. 170 | " Use 65001 for utf-8, although many console apps do not support it. 171 | if !exists('g:ConqueTerm_CodePage') 172 | let g:ConqueTerm_CodePage = 0 173 | endif " }}} 174 | 175 | " InsertCharPre support {{{ 176 | " Disable this feature by default, still in Beta 177 | if !exists('g:ConqueTerm_InsertCharPre') 178 | let g:ConqueTerm_InsertCharPre = 0 179 | endif " }}} 180 | 181 | " }}} 182 | 183 | " ********************************************************************************************************** 184 | " **** Startup ********************************************************************************************* 185 | " ********************************************************************************************************** 186 | 187 | " Startup {{{ 188 | 189 | let g:ConqueTerm_Loaded = 1 190 | let g:ConqueTerm_Idx = 0 191 | let g:ConqueTerm_Version = 230 192 | 193 | command! -nargs=+ -complete=shellcmd ConqueTerm call conque_term#open() 194 | command! -nargs=+ -complete=shellcmd ConqueTermSplit call conque_term#open(, ['belowright split']) 195 | command! -nargs=+ -complete=shellcmd ConqueTermVSplit call conque_term#open(, ['belowright vsplit']) 196 | command! -nargs=+ -complete=shellcmd ConqueTermTab call conque_term#open(, ['tabnew']) 197 | 198 | " }}} 199 | 200 | " ********************************************************************************************************** 201 | " **** Global Mappings & Autocommands ********************************************************************** 202 | " ********************************************************************************************************** 203 | 204 | " Startup {{{ 205 | 206 | if exists('g:ConqueTerm_SessionSupport') && g:ConqueTerm_SessionSupport == 1 207 | autocmd SessionLoadPost * call conque_term#resume_session() 208 | endif 209 | 210 | if maparg(g:ConqueTerm_ExecFileKey, 'n') == '' 211 | exe 'nnoremap ' . g:ConqueTerm_ExecFileKey . ' :call conque_term#exec_file()' 212 | endif 213 | 214 | " }}} 215 | 216 | " vim:foldmethod=marker 217 | -------------------------------------------------------------------------------- /syntax/conque_term.vim: -------------------------------------------------------------------------------- 1 | " FILE: syntax/conque_term.vim {{{ 2 | " AUTHOR: Nico Raffo 3 | " WEBSITE: http://conque.googlecode.com 4 | " MODIFIED: 2011-09-02 5 | " VERSION: 2.3, for Vim 7.0 6 | " LICENSE: 7 | " Conque - Vim terminal/console emulator 8 | " Copyright (C) 2009-2011 Nico Raffo 9 | " 10 | " MIT License 11 | " 12 | " Permission is hereby granted, free of charge, to any person obtaining a copy 13 | " of this software and associated documentation files (the "Software"), to deal 14 | " in the Software without restriction, including without limitation the rights 15 | " to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | " copies of the Software, and to permit persons to whom the Software is 17 | " furnished to do so, subject to the following conditions: 18 | " 19 | " The above copyright notice and this permission notice shall be included in 20 | " all copies or substantial portions of the Software. 21 | " 22 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | " IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | " FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | " AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | " LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | " OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | " THE SOFTWARE. 29 | " }}} 30 | 31 | 32 | " ******************************************************************************************************************* 33 | " MySQL ************************************************************************************************************* 34 | " ******************************************************************************************************************* 35 | 36 | " TODO Move these to syntax which is only executed for mysql 37 | "syn match MySQLTableBodyG "^\s*\w\+:\(.\+\)\=$" contains=MySQLTableHeadG,MySQLNullG,MySQLBool,MySQLNumberG,MySQLStorageClass oneline skipwhite skipnl 38 | "syn match MySQLTableHeadG "^\s*\w\+:" contains=MySQLTableColon skipwhite contained 39 | "syn match MySQLTableColon ":" contained 40 | 41 | syn match MySQLTableHead "^ *|.*| *$" nextgroup=MySQLTableDivide contains=MySQLTableBar oneline skipwhite skipnl 42 | syn match MySQLTableBody "^ *|.*| *$" nextgroup=MySQLTableBody,MySQLTableEnd contains=MySQLTableBar,MySQLNull,MySQLBool,MySQLNumber,MySQLStorageClass oneline skipwhite skipnl 43 | syn match MySQLTableEnd "^ *+[+=-]\++ *$" oneline 44 | syn match MySQLTableDivide "^ *+[+=-]\++ *$" nextgroup=MySQLTableBody oneline skipwhite skipnl 45 | syn match MySQLTableStart "^ *+[+=-]\++ *$" nextgroup=MySQLTableHead oneline skipwhite skipnl 46 | syn match MySQLNull " NULL " contained contains=MySQLTableBar 47 | syn match MySQLStorageClass " PRI " contained 48 | syn match MySQLStorageClass " MUL " contained 49 | syn match MySQLStorageClass " UNI " contained 50 | syn match MySQLStorageClass " CURRENT_TIMESTAMP " contained 51 | syn match MySQLStorageClass " auto_increment " contained 52 | syn match MySQLTableBar "|" contained 53 | syn match MySQLNumber "|\? *\d\+\(\.\d\+\)\? *|" contained contains=MySQLTableBar 54 | syn match MySQLQueryStat "^\d\+ rows\? in set.*" oneline 55 | syn match MySQLPromptLine "^.\?mysql> .*$" contains=MySQLKeyword,MySQLPrompt,MySQLString oneline 56 | syn match MySQLPromptLine "^ -> .*$" contains=MySQLKeyword,MySQLPrompt,MySQLString oneline 57 | syn match MySQLPrompt "^.\?mysql>" contained oneline 58 | syn match MySQLPrompt "^ ->" contained oneline 59 | syn case ignore 60 | syn keyword MySQLKeyword select count max sum avg date show table tables status like as from left right outer inner join contained 61 | syn keyword MySQLKeyword where group by having limit offset order desc asc show contained and interval is null on 62 | syn case match 63 | syn region MySQLString start=+'+ end=+'+ skip=+\\'+ contained oneline 64 | syn region MySQLString start=+"+ end=+"+ skip=+\\"+ contained oneline 65 | syn region MySQLString start=+`+ end=+`+ skip=+\\`+ contained oneline 66 | 67 | 68 | hi def link MySQLPrompt Identifier 69 | hi def link MySQLTableHead Title 70 | hi def link MySQLTableBody Normal 71 | hi def link MySQLBool Boolean 72 | hi def link MySQLStorageClass StorageClass 73 | hi def link MySQLNumber Number 74 | hi def link MySQLKeyword Keyword 75 | hi def link MySQLString String 76 | 77 | " terms which have no reasonable default highlight group to link to 78 | hi MySQLTableHead term=bold cterm=bold gui=bold 79 | if &background == 'dark' 80 | hi MySQLTableEnd term=NONE cterm=NONE gui=NONE ctermfg=238 guifg=#444444 81 | hi MySQLTableDivide term=NONE cterm=NONE gui=NONE ctermfg=238 guifg=#444444 82 | hi MySQLTableStart term=NONE cterm=NONE gui=NONE ctermfg=238 guifg=#444444 83 | hi MySQLTableBar term=NONE cterm=NONE gui=NONE ctermfg=238 guifg=#444444 84 | hi MySQLNull term=NONE cterm=NONE gui=NONE ctermfg=238 guifg=#444444 85 | hi MySQLQueryStat term=NONE cterm=NONE gui=NONE ctermfg=238 guifg=#444444 86 | elseif &background == 'light' 87 | hi MySQLTableEnd term=NONE cterm=NONE gui=NONE ctermfg=247 guifg=#9e9e9e 88 | hi MySQLTableDivide term=NONE cterm=NONE gui=NONE ctermfg=247 guifg=#9e9e9e 89 | hi MySQLTableStart term=NONE cterm=NONE gui=NONE ctermfg=247 guifg=#9e9e9e 90 | hi MySQLTableBar term=NONE cterm=NONE gui=NONE ctermfg=247 guifg=#9e9e9e 91 | hi MySQLNull term=NONE cterm=NONE gui=NONE ctermfg=247 guifg=#9e9e9e 92 | hi MySQLQueryStat term=NONE cterm=NONE gui=NONE ctermfg=247 guifg=#9e9e9e 93 | endif 94 | 95 | 96 | " ******************************************************************************************************************* 97 | " Bash ************************************************************************************************************** 98 | " ******************************************************************************************************************* 99 | 100 | " Typical Prompt 101 | if g:ConqueTerm_PromptRegex != '' 102 | silent execute "syn match ConquePromptLine '" . g:ConqueTerm_PromptRegex . ".*$' contains=ConquePrompt,ConqueString oneline" 103 | silent execute "syn match ConquePrompt '" . g:ConqueTerm_PromptRegex . "' contained oneline" 104 | hi def link ConquePrompt Identifier 105 | endif 106 | 107 | " Strings 108 | syn region ConqueString start=+'+ end=+'+ skip=+\\'+ contained oneline 109 | syn region ConqueString start=+"+ end=+"+ skip=+\\"+ contained oneline 110 | syn region ConqueString start=+`+ end=+`+ skip=+\\`+ contained oneline 111 | hi def link ConqueString String 112 | 113 | " vim: foldmethod=marker 114 | --------------------------------------------------------------------------------