# HG changeset patch # User Steve Losh # Date 1277818789 14400 # Node ID e42e595b17c2eb226cc61a172a5fc250489e132d # Parent 21d16bafb00b0758b5a5d28a03da94378233cb61 vim: space and conque diff -r 21d16bafb00b -r e42e595b17c2 vim/.vimrc --- a/vim/.vimrc Fri Jun 25 15:07:22 2010 -0400 +++ b/vim/.vimrc Tue Jun 29 09:39:49 2010 -0400 @@ -65,7 +65,6 @@ " Use Pathogen to load bundles call pathogen#runtime_append_all_bundles() -cab HALP call pathogen#helptags() " NERD Tree map :NERDTreeToggle @@ -136,6 +135,7 @@ " Yankring nnoremap :YRShow +nnoremap y :YRShow " Formatting, TextMate-style map q gqip @@ -153,3 +153,10 @@ " HTML tag closing imap :call InsertCloseTag()a + +" Conque +nmap sh :ConqueTermVSplit zsh +nmap SH :ConqueTermSplit zsh +nmap r :ConqueTermVSplit +nmap R :ConqueTermSplit + diff -r 21d16bafb00b -r e42e595b17c2 vim/bundle/conque/autoload/conque.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vim/bundle/conque/autoload/conque.py Tue Jun 29 09:39:49 2010 -0400 @@ -0,0 +1,910 @@ + +import vim, re, time, math + +import logging # DEBUG +LOG_FILENAME = '/home/nraffo/.vim/pylog.log' # DEBUG +#logging.basicConfig(filename=LOG_FILENAME, level=logging.DEBUG) # DEBUG + +# CONFIG CONSTANTS {{{ + +CONQUE_CTL = { + 7:'bel', # bell + 8:'bs', # backspace + 9:'tab', # tab + 10:'nl', # new line + 13:'cr' # carriage return +} +# 11 : 'vt', # vertical tab +# 12 : 'ff', # form feed +# 14 : 'so', # shift out +# 15 : 'si' # shift in + +# Escape sequences +CONQUE_ESCAPE = { + 'm':'font', + 'J':'clear_screen', + 'K':'clear_line', + '@':'add_spaces', + 'A':'cursor_up', + 'B':'cursor_down', + 'C':'cursor_right', + 'D':'cursor_left', + 'G':'cursor_to_column', + 'H':'cursor', + 'P':'delete_chars', + 'f':'cursor', + 'g':'tab_clear', + 'r':'set_coords', + 'h':'set', + 'l':'reset' +} +# 'L':'insert_lines', +# 'M':'delete_lines', +# 'd':'cusor_vpos', + +# Alternate escape sequences, no [ +CONQUE_ESCAPE_PLAIN = { + 'D':'scroll_up', + 'E':'next_line', + 'H':'set_tab', + 'M':'scroll_down' +} +# 'N':'single_shift_2', +# 'O':'single_shift_3', +# '=':'alternate_keypad', +# '>':'numeric_keypad', +# '7':'save_cursor', +# '8':'restore_cursor', + +# Uber alternate escape sequences, with # or ? +CONQUE_ESCAPE_QUESTION = { + '1h':'new_line_mode', + '3h':'132_cols', + '4h':'smooth_scrolling', + '5h':'reverse_video', + '6h':'relative_origin', + '7h':'set_auto_wrap', + '8h':'set_auto_repeat', + '9h':'set_interlacing_mode', + '1l':'set_cursor_key', + '2l':'set_vt52', + '3l':'80_cols', + '4l':'set_jump_scrolling', + '5l':'normal_video', + '6l':'absolute_origin', + '7l':'reset_auto_wrap', + '8l':'reset_auto_repeat', + '9l':'reset_interlacing_mode' +} + +CONQUE_ESCAPE_HASH = { + '8':'screen_alignment_test' +} +# '3':'double_height_top', +# '4':'double_height_bottom', +# '5':'single_height_single_width', +# '6':'single_height_double_width', + +# Font codes {{{ +CONQUE_FONT = { + 0: {'description':'Normal (default)', 'attributes': {'cterm':'NONE','ctermfg':'NONE','ctermbg':'NONE','gui':'NONE','guifg':'NONE','guibg':'NONE'}, 'normal':True}, + 1: {'description':'Bold', 'attributes': {'cterm':'BOLD','gui':'BOLD'}, 'normal':False}, + 4: {'description':'Underlined', 'attributes': {'cterm':'UNDERLINE','gui':'UNDERLINE'}, 'normal':False}, + 5: {'description':'Blink (appears as Bold)', 'attributes': {'cterm':'BOLD','gui':'BOLD'}, 'normal':False}, + 7: {'description':'Inverse', 'attributes': {'cterm':'REVERSE','gui':'REVERSE'}, 'normal':False}, + 8: {'description':'Invisible (hidden)', 'attributes': {'ctermfg':'0','ctermbg':'0','guifg':'#000000','guibg':'#000000'}, 'normal':False}, + 22: {'description':'Normal (neither bold nor faint)', 'attributes': {'cterm':'NONE','gui':'NONE'}, 'normal':True}, + 24: {'description':'Not underlined', 'attributes': {'cterm':'NONE','gui':'NONE'}, 'normal':True}, + 25: {'description':'Steady (not blinking)', 'attributes': {'cterm':'NONE','gui':'NONE'}, 'normal':True}, + 27: {'description':'Positive (not inverse)', 'attributes': {'cterm':'NONE','gui':'NONE'}, 'normal':True}, + 28: {'description':'Visible (not hidden)', 'attributes': {'ctermfg':'NONE','ctermbg':'NONE','guifg':'NONE','guibg':'NONE'}, 'normal':True}, + 30: {'description':'Set foreground color to Black', 'attributes': {'ctermfg':'16','guifg':'#000000'}, 'normal':False}, + 31: {'description':'Set foreground color to Red', 'attributes': {'ctermfg':'1','guifg':'#ff0000'}, 'normal':False}, + 32: {'description':'Set foreground color to Green', 'attributes': {'ctermfg':'2','guifg':'#00ff00'}, 'normal':False}, + 33: {'description':'Set foreground color to Yellow', 'attributes': {'ctermfg':'3','guifg':'#ffff00'}, 'normal':False}, + 34: {'description':'Set foreground color to Blue', 'attributes': {'ctermfg':'4','guifg':'#0000ff'}, 'normal':False}, + 35: {'description':'Set foreground color to Magenta', 'attributes': {'ctermfg':'5','guifg':'#990099'}, 'normal':False}, + 36: {'description':'Set foreground color to Cyan', 'attributes': {'ctermfg':'6','guifg':'#009999'}, 'normal':False}, + 37: {'description':'Set foreground color to White', 'attributes': {'ctermfg':'7','guifg':'#ffffff'}, 'normal':False}, + 39: {'description':'Set foreground color to default (original)', 'attributes': {'ctermfg':'NONE','guifg':'NONE'}, 'normal':True}, + 40: {'description':'Set background color to Black', 'attributes': {'ctermbg':'16','guibg':'#000000'}, 'normal':False}, + 41: {'description':'Set background color to Red', 'attributes': {'ctermbg':'1','guibg':'#ff0000'}, 'normal':False}, + 42: {'description':'Set background color to Green', 'attributes': {'ctermbg':'2','guibg':'#00ff00'}, 'normal':False}, + 43: {'description':'Set background color to Yellow', 'attributes': {'ctermbg':'3','guibg':'#ffff00'}, 'normal':False}, + 44: {'description':'Set background color to Blue', 'attributes': {'ctermbg':'4','guibg':'#0000ff'}, 'normal':False}, + 45: {'description':'Set background color to Magenta', 'attributes': {'ctermbg':'5','guibg':'#990099'}, 'normal':False}, + 46: {'description':'Set background color to Cyan', 'attributes': {'ctermbg':'6','guibg':'#009999'}, 'normal':False}, + 47: {'description':'Set background color to White', 'attributes': {'ctermbg':'7','guibg':'#ffffff'}, 'normal':False}, + 49: {'description':'Set background color to default (original).', 'attributes': {'ctermbg':'NONE','guibg':'NONE'}, 'normal':True}, + 90: {'description':'Set foreground color to Black', 'attributes': {'ctermfg':'8','guifg':'#000000'}, 'normal':False}, + 91: {'description':'Set foreground color to Red', 'attributes': {'ctermfg':'9','guifg':'#ff0000'}, 'normal':False}, + 92: {'description':'Set foreground color to Green', 'attributes': {'ctermfg':'10','guifg':'#00ff00'}, 'normal':False}, + 93: {'description':'Set foreground color to Yellow', 'attributes': {'ctermfg':'11','guifg':'#ffff00'}, 'normal':False}, + 94: {'description':'Set foreground color to Blue', 'attributes': {'ctermfg':'12','guifg':'#0000ff'}, 'normal':False}, + 95: {'description':'Set foreground color to Magenta', 'attributes': {'ctermfg':'13','guifg':'#990099'}, 'normal':False}, + 96: {'description':'Set foreground color to Cyan', 'attributes': {'ctermfg':'14','guifg':'#009999'}, 'normal':False}, + 97: {'description':'Set foreground color to White', 'attributes': {'ctermfg':'15','guifg':'#ffffff'}, 'normal':False}, + 100: {'description':'Set background color to Black', 'attributes': {'ctermbg':'8','guibg':'#000000'}, 'normal':False}, + 101: {'description':'Set background color to Red', 'attributes': {'ctermbg':'9','guibg':'#ff0000'}, 'normal':False}, + 102: {'description':'Set background color to Green', 'attributes': {'ctermbg':'10','guibg':'#00ff00'}, 'normal':False}, + 103: {'description':'Set background color to Yellow', 'attributes': {'ctermbg':'11','guibg':'#ffff00'}, 'normal':False}, + 104: {'description':'Set background color to Blue', 'attributes': {'ctermbg':'12','guibg':'#0000ff'}, 'normal':False}, + 105: {'description':'Set background color to Magenta', 'attributes': {'ctermbg':'13','guibg':'#990099'}, 'normal':False}, + 106: {'description':'Set background color to Cyan', 'attributes': {'ctermbg':'14','guibg':'#009999'}, 'normal':False}, + 107: {'description':'Set background color to White', 'attributes': {'ctermbg':'15','guibg':'#ffffff'}, 'normal':False} +} +# }}} + +# regular expression matching (almost) all control sequences +CONQUE_SEQ_REGEX = re.compile(ur"(\u001b\[?\??#?[0-9;]*[a-zA-Z@]|\u001b\][0-9];.*?\u0007|[\u0007-\u000f])", re.UNICODE) +CONQUE_SEQ_REGEX_CTL = re.compile(ur"^[\u0007-\u000f]$", re.UNICODE) +CONQUE_SEQ_REGEX_CSI = re.compile(ur"^\u001b\[", re.UNICODE) +CONQUE_SEQ_REGEX_TITLE = re.compile(ur"^\u001b\]", re.UNICODE) +CONQUE_SEQ_REGEX_HASH = re.compile(ur"^\u001b#", re.UNICODE) +CONQUE_SEQ_REGEX_ESC = re.compile(ur"^\u001b", re.UNICODE) + +# match table output +CONQUE_TABLE_OUTPUT = re.compile("^\s*\|\s.*\s\|\s*$|^\s*\+[=+-]+\+\s*$") + +# }}} + +################################################################################################### +class Conque: + + # CLASS PROPERTIES {{{ + + # screen object + screen = None + + # subprocess object + proc = None + + # terminal dimensions and scrolling region + columns = 80 # same as $COLUMNS + lines = 24 # same as $LINES + working_columns = 80 # can be changed by CSI ? 3 l/h + working_lines = 24 # can be changed by CSI r + + # top/bottom of the scroll region + top = 1 # relative to top of screen + bottom = 24 # relative to top of screen + + # cursor position + l = 1 # current cursor line + c = 1 # current cursor column + + # autowrap mode + autowrap = True + + # absolute coordinate mode + absolute_coords = True + + # tabstop positions + tabstops = [] + + # enable colors + enable_colors = True + + # color changes + color_changes = {} + + # color history + color_history = {} + + # don't wrap table output + unwrap_tables = True + + # wrap CUF/CUB around line breaks + wrap_cursor = False + + # }}} + + # constructor + def __init__(self): # {{{ + self.screen = ConqueScreen() + # }}} + + # start program and initialize this instance + def open(self, command, options): # {{{ + + # int vars + self.columns = vim.current.window.width + self.lines = vim.current.window.height + self.working_columns = vim.current.window.width + self.working_lines = vim.current.window.height + self.bottom = vim.current.window.height + + # init color + self.enable_colors = options['color'] + + # init tabstops + self.init_tabstops() + + # open command + self.proc = ConqueSubprocess() + self.proc.open(command, { 'TERM' : options['TERM'], 'CONQUE' : '1', 'LINES' : str(self.lines), 'COLUMNS' : str(self.columns)}) + # }}} + + # write to pty + def write(self, input): # {{{ + logging.debug('writing input ' + str(input)) + + # check if window size has changed + self.update_window_size() + + # write and read + self.proc.write(input) + self.read(1) + # }}} + + # read from pty, and update buffer + def read(self, timeout = 1): # {{{ + # read from subprocess + output = self.proc.read(timeout) + # and strip null chars + output = output.replace(chr(0), '') + + if output == '': + return + + logging.debug('read *********************************************************************') + logging.debug(str(output)) + debug_profile_start = time.time() + + chunks = CONQUE_SEQ_REGEX.split(output) + logging.debug('ouput chunking took ' + str((time.time() - debug_profile_start) * 1000) + ' ms') + logging.debug(str(chunks)) + + debug_profile_start = time.time() + + # don't go through all the csi regex if length is one (no matches) + if len(chunks) == 1: + logging.debug('short circuit') + self.plain_text(chunks[0]) + + else: + for s in chunks: + if s == '': + continue + + logging.debug(str(s) + '--------------------------------------------------------------') + logging.debug('chgs ' + str(self.color_changes)) + logging.debug('at line ' + str(self.l) + ' column ' + str(self.c)) + logging.debug('current: ' + self.screen[self.l]) + + # Check for control character match {{{ + if CONQUE_SEQ_REGEX_CTL.match(s[0]): + logging.debug('control match') + nr = ord(s[0]) + if nr in CONQUE_CTL: + getattr(self, 'ctl_' + CONQUE_CTL[nr])() + else: + logging.debug('escape not found for ' + str(s)) + pass + # }}} + + # check for escape sequence match {{{ + elif CONQUE_SEQ_REGEX_CSI.match(s): + logging.debug('csi match') + if s[-1] in CONQUE_ESCAPE: + csi = self.parse_csi(s[2:]) + logging.debug(str(csi)) + getattr(self, 'csi_' + CONQUE_ESCAPE[s[-1]])(csi) + else: + logging.debug('escape not found for ' + str(s)) + pass + # }}} + + # check for title match {{{ + elif CONQUE_SEQ_REGEX_TITLE.match(s): + logging.debug('title match') + self.change_title(s[2], s[4:-1]) + # }}} + + # check for hash match {{{ + elif CONQUE_SEQ_REGEX_HASH.match(s): + logging.debug('hash match') + if s[-1] in CONQUE_ESCAPE_HASH: + getattr(self, 'hash_' + CONQUE_ESCAPE_HASH[s[-1]])() + else: + logging.debug('escape not found for ' + str(s)) + pass + # }}} + + # check for other escape match {{{ + elif CONQUE_SEQ_REGEX_ESC.match(s): + logging.debug('escape match') + if s[-1] in CONQUE_ESCAPE_PLAIN: + getattr(self, 'esc_' + CONQUE_ESCAPE_PLAIN[s[-1]])() + else: + logging.debug('escape not found for ' + str(s)) + pass + # }}} + + # else process plain text {{{ + else: + self.plain_text(s) + # }}} + + # set cursor position + self.screen.set_cursor(self.l, self.c) + + vim.command('redraw') + + logging.info('::: read took ' + str((time.time() - debug_profile_start) * 1000) + ' ms') + # }}} + + # for polling + def auto_read(self): # {{{ + self.read(1) + if self.c == 1: + vim.command('call feedkeys("\", "t")') + else: + vim.command('call feedkeys("\", "t")') + self.screen.set_cursor(self.l, self.c) + # }}} + + ############################################################################################### + # Plain text # {{{ + + def plain_text(self, input): + logging.debug('plain -- ' + str(self.color_changes)) + current_line = self.screen[self.l] + + if len(current_line) < self.working_columns: + current_line = current_line + ' ' * (self.c - len(current_line)) + + # if line is wider than screen + if self.c + len(input) - 1 > self.working_columns: + # Table formatting hack + if self.unwrap_tables and CONQUE_TABLE_OUTPUT.match(input): + self.screen[self.l] = current_line[ : self.c - 1] + input + current_line[ self.c + len(input) - 1 : ] + self.apply_color(self.c, self.c + len(input)) + self.c += len(input) + return + logging.debug('autowrap triggered') + diff = self.c + len(input) - self.working_columns - 1 + # if autowrap is enabled + if self.autowrap: + self.screen[self.l] = current_line[ : self.c - 1] + input[ : -1 * diff ] + self.apply_color(self.c, self.working_columns) + self.ctl_nl() + self.ctl_cr() + remaining = input[ -1 * diff : ] + logging.debug('remaining text: "' + remaining + '"') + self.plain_text(remaining) + else: + self.screen[self.l] = current_line[ : self.c - 1] + input[ : -1 * diff - 1 ] + input[-1] + self.apply_color(self.c, self.working_columns) + self.c = self.working_columns + + # no autowrap + else: + self.screen[self.l] = current_line[ : self.c - 1] + input + current_line[ self.c + len(input) - 1 : ] + self.apply_color(self.c, self.c + len(input)) + self.c += len(input) + + def apply_color(self, start, end): + logging.debug('applying colors ' + str(self.color_changes)) + + # stop here if coloration is disabled + if not self.enable_colors: + return + + real_line = self.screen.get_real_line(self.l) + + # check for previous overlapping coloration + logging.debug('start ' + str(start) + ' end ' + str(end)) + to_del = [] + if self.color_history.has_key(real_line): + for i in range(len(self.color_history[real_line])): + syn = self.color_history[real_line][i] + logging.debug('checking syn ' + str(syn)) + if syn['start'] >= start and syn['start'] < end: + logging.debug('first') + vim.command('syn clear ' + syn['name']) + to_del.append(i) + # outside + if syn['end'] > end: + logging.debug('first.half') + self.exec_highlight(real_line, end, syn['end'], syn['highlight']) + elif syn['end'] > start and syn['end'] <= end: + logging.debug('second') + vim.command('syn clear ' + syn['name']) + to_del.append(i) + # outside + if syn['start'] < start: + logging.debug('second.half') + self.exec_highlight(real_line, syn['start'], start, syn['highlight']) + + if len(to_del) > 0: + to_del.reverse() + for di in to_del: + del self.color_history[real_line][di] + + # if there are no new colors + if len(self.color_changes) == 0: + return + + highlight = '' + for attr in self.color_changes.keys(): + highlight = highlight + ' ' + attr + '=' + self.color_changes[attr] + + # execute the highlight + self.exec_highlight(real_line, start, end, highlight) + + def exec_highlight(self, real_line, start, end, highlight): + unique_key = str(self.proc.pid) + + syntax_name = 'EscapeSequenceAt_' + unique_key + '_' + str(self.l) + '_' + str(start) + '_' + str(len(self.color_history) + 1) + syntax_options = ' contains=ALLBUT,ConqueString,MySQLString,MySQLKeyword oneline' + syntax_region = 'syntax match ' + syntax_name + ' /\%' + str(real_line) + 'l\%>' + str(start - 1) + 'c.*\%<' + str(end + 1) + 'c/' + syntax_options + syntax_highlight = 'highlight ' + syntax_name + highlight + + vim.command(syntax_region) + vim.command(syntax_highlight) + + # add syntax name to history + if not self.color_history.has_key(real_line): + self.color_history[real_line] = [] + + self.color_history[real_line].append({'name':syntax_name, 'start':start, 'end':end, 'highlight':highlight}) + + # }}} + + ############################################################################################### + # Control functions {{{ + + def ctl_nl(self): + # if we're in a scrolling region, scroll instead of moving cursor down + if self.lines != self.working_lines and self.l == self.bottom: + del self.screen[self.top] + self.screen.insert(self.bottom, '') + elif self.l == self.bottom: + self.screen.append('') + else: + self.l += 1 + + self.color_changes = {} + + def ctl_cr(self): + self.c = 1 + + self.color_changes = {} + + def ctl_bs(self): + if self.c > 1: + self.c += -1 + + def ctl_bel(self): + print 'BELL' + + def ctl_tab(self): + # default tabstop location + ts = self.working_columns + + # check set tabstops + for i in range(self.c, len(self.tabstops)): + if self.tabstops[i]: + ts = i + 1 + break + + logging.debug('tabbing from ' + str(self.c) + ' to ' + str(ts)) + + self.c = ts + + # }}} + + ############################################################################################### + # CSI functions {{{ + + def csi_font(self, csi): # {{{ + if not self.enable_colors: + return + + # defaults to 0 + if len(csi['vals']) == 0: + csi['vals'] = [0] + + # 256 xterm color foreground + if len(csi['vals']) == 3 and csi['vals'][0] == 38 and csi['vals'][1] == 5: + self.color_changes['ctermfg'] = str(csi['vals'][2]) + self.color_changes['guifg'] = '#' + self.xterm_to_rgb(csi['vals'][2]) + + # 256 xterm color background + elif len(csi['vals']) == 3 and csi['vals'][0] == 48 and csi['vals'][1] == 5: + self.color_changes['ctermbg'] = str(csi['vals'][2]) + self.color_changes['guibg'] = '#' + self.xterm_to_rgb(csi['vals'][2]) + + # 16 colors + else: + for val in csi['vals']: + if CONQUE_FONT.has_key(val): + logging.debug('color ' + str(CONQUE_FONT[val])) + # ignore starting normal colors + if CONQUE_FONT[val]['normal'] and len(self.color_changes) == 0: + logging.debug('a') + continue + # clear color changes + elif CONQUE_FONT[val]['normal']: + logging.debug('b') + self.color_changes = {} + # save these color attributes for next plain_text() call + else: + logging.debug('c') + for attr in CONQUE_FONT[val]['attributes'].keys(): + if self.color_changes.has_key(attr) and (attr == 'cterm' or attr == 'gui'): + self.color_changes[attr] += ',' + CONQUE_FONT[val]['attributes'][attr] + else: + self.color_changes[attr] = CONQUE_FONT[val]['attributes'][attr] + # }}} + + def csi_clear_line(self, csi): # {{{ + logging.debug(str(csi)) + + # this escape defaults to 0 + if len(csi['vals']) == 0: + csi['val'] = 0 + + logging.debug('clear line with ' + str(csi['val'])) + logging.debug('original line: ' + self.screen[self.l]) + + # 0 means cursor right + if csi['val'] == 0: + self.screen[self.l] = self.screen[self.l][0 : self.c - 1] + + # 1 means cursor left + elif csi['val'] == 1: + self.screen[self.l] = ' ' * (self.c) + self.screen[self.l][self.c : ] + + # clear entire line + elif csi['val'] == 2: + self.screen[self.l] = '' + + # clear colors + if csi['val'] == 2 or (csi['val'] == 0 and self.c == 1): + real_line = self.screen.get_real_line(self.l) + if self.color_history.has_key(real_line): + for syn in self.color_history[real_line]: + vim.command('syn clear ' + syn['name']) + + logging.debug(str(self.color_changes)) + logging.debug('new line: ' + self.screen[self.l]) + # }}} + + def csi_cursor_right(self, csi): # {{{ + # we use 1 even if escape explicitly specifies 0 + if csi['val'] == 0: + csi['val'] = 1 + + logging.debug('working columns is ' + str(self.working_columns)) + logging.debug('new col is ' + str(self.c + csi['val'])) + + if self.wrap_cursor and self.c + csi['val'] > self.working_columns: + self.l += int(math.floor( (self.c + csi['val']) / self.working_columns )) + self.c = (self.c + csi['val']) % self.working_columns + return + + self.c = self.bound(self.c + csi['val'], 1, self.working_columns) + # }}} + + def csi_cursor_left(self, csi): # {{{ + # we use 1 even if escape explicitly specifies 0 + if csi['val'] == 0: + csi['val'] = 1 + + if self.wrap_cursor and csi['val'] >= self.c: + self.l += int(math.floor( (self.c - csi['val']) / self.working_columns )) + self.c = self.working_columns - (csi['val'] - self.c) % self.working_columns + return + + self.c = self.bound(self.c - csi['val'], 1, self.working_columns) + # }}} + + def csi_cursor_to_column(self, csi): # {{{ + self.c = self.bound(csi['val'], 1, self.working_columns) + # }}} + + def csi_cursor_up(self, csi): # {{{ + self.l = self.bound(self.l - csi['val'], self.top, self.bottom) + + self.color_changes = {} + # }}} + + def csi_cursor_down(self, csi): # {{{ + self.l = self.bound(self.l + csi['val'], self.top, self.bottom) + + self.color_changes = {} + # }}} + + def csi_clear_screen(self, csi): # {{{ + # default to 0 + if len(csi['vals']) == 0: + csi['val'] = 0 + + # 2 == clear entire screen + if csi['val'] == 2: + self.l = 1 + self.c = 1 + self.screen.clear() + + # 0 == clear down + elif csi['val'] == 0: + for l in range(self.bound(self.l + 1, 1, self.lines), self.lines + 1): + self.screen[l] = '' + + # clear end of current line + self.csi_clear_line(self.parse_csi('K')) + + # 1 == clear up + elif csi['val'] == 1: + for l in range(1, self.bound(self.l, 1, self.lines + 1)): + self.screen[l] = '' + + # clear beginning of current line + self.csi_clear_line(self.parse_csi('1K')) + + # clear coloration + if csi['val'] == 2 or csi['val'] == 0: + real_line = self.screen.get_real_line(self.l) + for line in self.color_history.keys(): + if line >= real_line: + for syn in self.color_history[line]: + vim.command('syn clear ' + syn['name']) + + self.color_changes = {} + # }}} + + def csi_delete_chars(self, csi): # {{{ + self.screen[self.l] = self.screen[self.l][ : self.c ] + self.screen[self.l][ self.c + csi['val'] : ] + # }}} + + def csi_add_spaces(self, csi): # {{{ + self.screen[self.l] = self.screen[self.l][ : self.c - 1] + ' ' * csi['val'] + self.screen[self.l][self.c : ] + # }}} + + def csi_cursor(self, csi): # {{{ + if len(csi['vals']) == 2: + new_line = csi['vals'][0] + new_col = csi['vals'][1] + else: + new_line = 1 + new_col = 1 + + if self.absolute_coords: + self.l = self.bound(new_line, 1, self.lines) + else: + self.l = self.bound(self.top + new_line - 1, self.top, self.bottom) + + self.c = self.bound(new_col, 1, self.working_columns) + if self.c > len(self.screen[self.l]): + self.screen[self.l] = self.screen[self.l] + ' ' * (self.c - len(self.screen[self.l])) + + # }}} + + def csi_set_coords(self, csi): # {{{ + if len(csi['vals']) == 2: + new_start = csi['vals'][0] + new_end = csi['vals'][1] + else: + new_start = 1 + new_end = vim.current.window.height + + self.top = new_start + self.bottom = new_end + self.working_lines = new_end - new_start + 1 + + # if cursor is outside scrolling region, reset it + if self.l < self.top: + self.l = self.top + elif self.l > self.bottom: + self.l = self.bottom + + self.color_changes = {} + # }}} + + def csi_tab_clear(self, csi): # {{{ + # this escape defaults to 0 + if len(csi['vals']) == 0: + csi['val'] = 0 + + logging.debug('clearing tab with ' + str(csi['val'])) + + if csi['val'] == 0: + self.tabstops[self.c - 1] = False + elif csi['val'] == 3: + for i in range(0, self.columns + 1): + self.tabstops[i] = False + # }}} + + def csi_set(self, csi): # {{{ + # 132 cols + if csi['val'] == 3: + self.csi_clear_screen(self.parse_csi('2J')) + self.working_columns = 132 + + # relative_origin + elif csi['val'] == 6: + self.absolute_coords = False + + # set auto wrap + elif csi['val'] == 7: + self.autowrap = True + + + self.color_changes = {} + # }}} + + def csi_reset(self, csi): # {{{ + # 80 cols + if csi['val'] == 3: + self.csi_clear_screen(self.parse_csi('2J')) + self.working_columns = 80 + + # absolute origin + elif csi['val'] == 6: + self.absolute_coords = True + + # reset auto wrap + elif csi['val'] == 7: + self.autowrap = False + + + self.color_changes = {} + # }}} + + # }}} + + ############################################################################################### + # ESC functions {{{ + + def esc_scroll_up(self): # {{{ + self.ctl_nl() + + self.color_changes = {} + # }}} + + def esc_next_line(self): # {{{ + self.ctl_nl() + self.c = 1 + # }}} + + def esc_set_tab(self): # {{{ + logging.debug('set tab at ' + str(self.c)) + if self.c <= len(self.tabstops): + self.tabstops[self.c - 1] = True + # }}} + + def esc_scroll_down(self): # {{{ + if self.l == self.top: + del self.screen[self.bottom] + self.screen.insert(self.top, '') + else: + self.l += -1 + + self.color_changes = {} + # }}} + + # }}} + + ############################################################################################### + # HASH functions {{{ + + def hash_screen_alignment_test(self): # {{{ + self.csi_clear_screen(self.parse_csi('2J')) + self.working_lines = self.lines + for l in range(1, self.lines + 1): + self.screen[l] = 'E' * self.working_columns + # }}} + + # }}} + + ############################################################################################### + # Random stuff {{{ + + def change_title(self, key, val): + logging.debug(key) + logging.debug(val) + if key == '0' or key == '2': + logging.debug('setting title to ' + re.escape(val)) + vim.command('setlocal statusline=' + re.escape(val)) + + def paste(self): + self.write(vim.eval('@@')) + self.read(50) + + def paste_selection(self): + self.write(vim.eval('@@')) + + def update_window_size(self): + # resize if needed + if vim.current.window.width != self.columns or vim.current.window.height != self.lines: + + # reset all window size attributes to default + self.columns = vim.current.window.width + self.lines = vim.current.window.height + self.working_columns = vim.current.window.width + self.working_lines = vim.current.window.height + self.bottom = vim.current.window.height + + # reset screen object attributes + self.l = self.screen.reset_size(self.l) + + # reset tabstops + self.init_tabstops() + + logging.debug('signal window resize here ---') + + # signal process that screen size has changed + self.proc.window_resize(self.lines, self.columns) + + def init_tabstops(self): + for i in range(0, self.columns + 1): + if i % 8 == 0: + self.tabstops.append(True) + else: + self.tabstops.append(False) + + # }}} + + ############################################################################################### + # Utility {{{ + + def parse_csi(self, s): # {{{ + attr = { 'key' : s[-1], 'flag' : '', 'val' : 1, 'vals' : [] } + + if len(s) == 1: + return attr + + full = s[0:-1] + + if full[0] == '?': + full = full[1:] + attr['flag'] = '?' + + if full != '': + vals = full.split(';') + for val in vals: + logging.debug(val) + val = re.sub("\D", "", val) + logging.debug(val) + if val != '': + attr['vals'].append(int(val)) + + if len(attr['vals']) == 1: + attr['val'] = int(attr['vals'][0]) + + return attr + # }}} + + def bound(self, val, min, max): # {{{ + if val > max: + return max + + if val < min: + return min + + return val + # }}} + + def xterm_to_rgb(self, color_code): # {{{ + if color_code < 16: + ascii_colors = ['000000', 'CD0000', '00CD00', 'CDCD00', '0000EE', 'CD00CD', '00CDCD', 'E5E5E5', + '7F7F7F', 'FF0000', '00FF00', 'FFFF00', '5C5CFF', 'FF00FF', '00FFFF', 'FFFFFF'] + return ascii_colors[color_code] + + elif color_code < 232: + cc = int(color_code) - 16 + + p1 = "%02x" % (math.floor(cc / 36) * (255/5)) + p2 = "%02x" % (math.floor((cc % 36) / 6) * (255/5)) + p3 = "%02x" % (math.floor(cc % 6) * (255/5)) + + return p1 + p2 + p3 + else: + grey_tone = "%02x" % math.floor((255/24) * (color_code - 232)) + return grey_tone + grey_tone + grey_tone + # }}} + + # }}} + diff -r 21d16bafb00b -r e42e595b17c2 vim/bundle/conque/autoload/conque_screen.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vim/bundle/conque/autoload/conque_screen.py Tue Jun 29 09:39:49 2010 -0400 @@ -0,0 +1,169 @@ +################################################################################################### +# ConqueScreen is an extention of the vim.current.buffer object +# It restricts the working indices of the buffer object to the scroll region which pty is expecting +# It also uses 1-based indexes, to match escape sequence commands +# +# E.g.: +# s = ConqueScreen() +# ... +# s[5] = 'Set 5th line in terminal to this line' +# s.append('Add new line to terminal') +# s[5] = 'Since previous append() command scrolled the terminal down, this is a different line than first cb[5] call' +# + +import vim + +class ConqueScreen(object): + + # CLASS PROPERTIES {{{ + + # the buffer + buffer = None + + # screen and scrolling regions + screen_top = 1 + + # screen width + screen_width = 80 + screen_height = 80 + + # }}} + + def __init__(self): # {{{ + self.buffer = vim.current.buffer + + self.screen_top = 1 + self.screen_width = vim.current.window.width + self.screen_height = vim.current.window.height + # }}} + + ############################################################################################### + # List overload {{{ + def __len__(self): # {{{ + return len(self.buffer) + # }}} + + def __getitem__(self, key): # {{{ + real_line = self.get_real_idx(key) + + # if line is past buffer end, add lines to buffer + if real_line >= len(self.buffer): + for i in range(len(self.buffer), real_line + 1): + self.append(' ' * self.screen_width) + + return self.buffer[ real_line ] + # }}} + + def __setitem__(self, key, value): # {{{ + real_line = self.get_real_idx(key) + + # if line is past end of screen, append + if real_line == len(self.buffer): + self.buffer.append(value) + else: + self.buffer[ real_line ] = value + # }}} + + def __delitem__(self, key): # {{{ + del self.buffer[ self.screen_top + key - 2 ] + # }}} + + def append(self, value): # {{{ + if len(self.buffer) > self.screen_top + self.screen_height - 1: + self.buffer[len(self.buffer) - 1] = value + else: + self.buffer.append(value) + logging.debug('checking new line ' + str(len(self.buffer)) + ' against top ' + str(self.screen_top) + ' + height ' + str(self.screen_height) + ' - 1 = ' + str(self.screen_top + self.screen_height - 1)) + if len(self.buffer) > self.screen_top + self.screen_height - 1: + self.screen_top += 1 + if vim.current.buffer.number == self.buffer.number: + vim.command('normal G') + # }}} + + def insert(self, line, value): # {{{ + logging.debug('insert at line ' + str(self.screen_top + line - 2)) + l = self.screen_top + line - 2 + self.buffer[l:l] = [ value ] + + # }}} + # }}} + + ############################################################################################### + # Util {{{ + def get_top(self): # {{{ + return self.screen_top + # }}} + + def get_real_idx(self, line): # {{{ + return (self.screen_top + line - 2) + # }}} + + def get_real_line(self, line): # {{{ + return (self.screen_top + line - 1) + # }}} + + def set_screen_width(self, width): # {{{ + self.screen_width = width + # }}} + + # }}} + + ############################################################################################### + def clear(self): # {{{ + self.buffer.append(' ') + vim.command('normal Gzt') + self.screen_top = len(self.buffer) + # }}} + + def set_cursor(self, line, column): # {{{ + # figure out line + real_line = self.screen_top + line - 1 + if real_line > len(self.buffer): + for l in range(len(self.buffer) - 1, real_line): + self.buffer.append('') + + # figure out column + real_column = column + if len(self.buffer[real_line - 1]) < real_column: + self.buffer[real_line - 1] = self.buffer[real_line - 1] + ' ' * (real_column - len(self.buffer[real_line - 1])) + + # python version is occasionally grumpy + try: + vim.current.window.cursor = (real_line, real_column - 1) + except: + vim.command('call cursor(' + str(real_line) + ', ' + str(real_column) + ')') + # }}} + + def reset_size(self, line): # {{{ + logging.debug('buffer len is ' + str(len(self.buffer))) + logging.debug('buffer height ' + str(vim.current.window.height)) + logging.debug('old screen top was ' + str(self.screen_top)) + + # save cursor line number + real_line = self.screen_top + line + + # reset screen size + self.screen_width = vim.current.window.width + self.screen_height = vim.current.window.height + self.screen_top = len(self.buffer) - vim.current.window.height + 1 + if self.screen_top < 1: + self.screen_top = 1 + logging.debug('new screen top is ' + str(self.screen_top)) + + # align bottom of buffer to bottom of screen + vim.command('normal ' + str(self.screen_height) + 'kG') + + # return new relative line number + return (real_line - self.screen_top) + # }}} + + def scroll_to_bottom(self): # {{{ + vim.current.window.cursor = (len(self.buffer) - 1, 1) + # }}} + + def align(self): # {{{ + # align bottom of buffer to bottom of screen + vim.command('normal ' + str(self.screen_height) + 'kG') + # }}} + + diff -r 21d16bafb00b -r e42e595b17c2 vim/bundle/conque/autoload/conque_subprocess.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vim/bundle/conque/autoload/conque_subprocess.py Tue Jun 29 09:39:49 2010 -0400 @@ -0,0 +1,128 @@ + +import os, signal, pty, tty, select, fcntl, termios, struct + +################################################################################################### +class ConqueSubprocess: + + # process id + pid = 0 + + # stdout+stderr file descriptor + fd = None + + # constructor + def __init__(self): # {{{ + self.pid = 0 + # }}} + + # create the pty or whatever (whatever == windows) + def open(self, command, env = {}): # {{{ + command_arr = command.split() + executable = command_arr[0] + args = command_arr + + try: + self.pid, self.fd = pty.fork() + logging.debug(self.pid) + except: + pass + logging.debug("pty.fork() failed. Did you mean pty.spork() ???") + + # child proc, replace with command after altering terminal attributes + if self.pid == 0: + + # set requested environment variables + for k in env.keys(): + os.environ[k] = env[k] + + # set some attributes + try: + attrs = tty.tcgetattr(1) + attrs[0] = attrs[0] ^ tty.IGNBRK + attrs[0] = attrs[0] | tty.BRKINT | tty.IXANY | tty.IMAXBEL + attrs[2] = attrs[2] | tty.HUPCL + attrs[3] = attrs[3] | tty.ICANON | tty.ECHO | tty.ISIG | tty.ECHOKE + attrs[6][tty.VMIN] = 1 + attrs[6][tty.VTIME] = 0 + tty.tcsetattr(1, tty.TCSANOW, attrs) + except: + pass + + os.execvp(executable, args) + + # else master, do nothing + else: + pass + + # }}} + + # read from pty + # XXX - select.poll() doesn't work in OS X!!!!!!! + def read(self, timeout = 1): # {{{ + + output = '' + read_timeout = float(timeout) / 1000 + + try: + # what, no do/while? + while 1: + s_read, s_write, s_error = select.select( [ self.fd ], [], [], read_timeout) + + lines = '' + for s_fd in s_read: + try: + lines = os.read( self.fd, 32 ) + except: + pass + output = output + lines + + if lines == '': + break + except: + pass + + return output + # }}} + + # I guess this one's not bad + def write(self, input): # {{{ + try: + os.write(self.fd, input) + except: + pass + # }}} + + # signal process + def signal(self, signum): # {{{ + try: + os.kill(self.pid, signum) + except: + pass + # }}} + + # get process status + def get_status(self): #{{{ + + p_status = True + + try: + if os.waitpid( self.pid, os.WNOHANG )[0]: + p_status = False + except: + p_status = False + + return p_status + + # }}} + + # update window size in kernel, then send SIGWINCH to fg process + def window_resize(self, lines, columns): # {{{ + try: + fcntl.ioctl(self.fd, termios.TIOCSWINSZ, struct.pack("HHHH", lines, columns, 0, 0)) + os.kill(self.pid, signal.SIGWINCH) + except: + pass + + # }}} + + diff -r 21d16bafb00b -r e42e595b17c2 vim/bundle/conque/autoload/conque_term.vim --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vim/bundle/conque/autoload/conque_term.vim Tue Jun 29 09:39:49 2010 -0400 @@ -0,0 +1,385 @@ +" FILE: plugin/conque_term.vim {{{ +" +" AUTHOR: Nico Raffo +" MODIFIED: __MODIFIED__ +" VERSION: __VERSION__, for Vim 7.0 +" LICENSE: +" Conque - pty interaction in Vim +" Copyright (C) 2009-2010 Nico Raffo +" +" MIT License +" +" Permission is hereby granted, free of charge, to any person obtaining a copy +" of this software and associated documentation files (the "Software"), to deal +" in the Software without restriction, including without limitation the rights +" to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +" copies of the Software, and to permit persons to whom the Software is +" furnished to do so, subject to the following conditions: +" +" The above copyright notice and this permission notice shall be included in +" all copies or substantial portions of the Software. +" +" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +" OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +" THE SOFTWARE. +" }}} + + +" ********************************************************************************************************** +" **** VIM FUNCTIONS *************************************************************************************** +" ********************************************************************************************************** + +" launch conque +function! conque_term#open(...) "{{{ + let command = get(a:000, 0, '') + let hooks = get(a:000, 1, []) + + " bare minimum validation + if has('python') != 1 + echohl WarningMsg | echomsg "Conque requires the Python interface to be installed" | echohl None + return 0 + endif + if empty(command) + echohl WarningMsg | echomsg "No command found" | echohl None + return 0 + else + let l:cargs = split(command, '\s') + if !executable(l:cargs[0]) + echohl WarningMsg | echomsg "Not an executable: " . l:cargs[0] | echohl None + return 0 + endif + endif + + " set buffer window options + let g:ConqueTerm_BufName = substitute(command, ' ', '\\ ', 'g') . "\\ -\\ " . g:ConqueTerm_Idx + call conque_term#set_buffer_settings(command, hooks) + let b:ConqueTerm_Var = 'ConqueTerm_' . g:ConqueTerm_Idx + let g:ConqueTerm_Var = 'ConqueTerm_' . g:ConqueTerm_Idx + let g:ConqueTerm_Idx += 1 + + " open command + try + let l:config = '{"color":' . string(g:ConqueTerm_Color) . ',"TERM":"' . g:ConqueTerm_TERM . '"}' + execute 'python ' . b:ConqueTerm_Var . ' = Conque()' + execute "python " . b:ConqueTerm_Var . ".open('" . conque_term#python_escape(command) . "', " . l:config . ")" + catch + echohl WarningMsg | echomsg "Unable to open command: " . command | echohl None + return 0 + endtry + + " set buffer mappings and auto commands + call conque_term#set_mappings('start') + + startinsert! + return 1 +endfunction "}}} + +" set buffer options +function! conque_term#set_buffer_settings(command, pre_hooks) "{{{ + + " optional hooks to execute, e.g. 'split' + for h in a:pre_hooks + sil exe h + endfor + sil exe "edit " . g:ConqueTerm_BufName + + " buffer settings + setlocal nocompatible " conque won't work in compatible mode + setlocal nopaste " conque won't work in paste mode + setlocal buftype=nofile " this buffer is not a file, you can't save it + setlocal nonumber " hide line numbers + setlocal foldcolumn=0 " reasonable left margin + setlocal nowrap " default to no wrap (esp with MySQL) + setlocal noswapfile " don't bother creating a .swp file + setlocal updatetime=50 " trigger cursorhold event after 50ms / XXX - global + setlocal scrolloff=0 " don't use buffer lines. it makes the 'clear' command not work as expected + setlocal sidescrolloff=0 " don't use buffer lines. it makes the 'clear' command not work as expected + setlocal sidescroll=1 " don't use buffer lines. it makes the 'clear' command not work as expected + setlocal foldmethod=manual " don't fold on {{{}}} and stuff + setlocal bufhidden=hide " when buffer is no longer displayed, don't wipe it out + setfiletype conque_term " useful + sil exe "setlocal syntax=" . g:ConqueTerm_Syntax + +endfunction " }}} + +" set key mappings and auto commands +function! conque_term#set_mappings(action) "{{{ + + " set action + if a:action == 'toggle' + if exists('b:conque_on') && b:conque_on == 1 + let l:action = 'stop' + echohl WarningMsg | echomsg "Terminal is paused" | echohl None + else + let l:action = 'start' + echohl WarningMsg | echomsg "Terminal is resumed" | echohl None + endif + else + let l:action = a:action + endif + + " if mappings are being removed, add 'un' + let map_modifier = 'nore' + if l:action == 'stop' + let map_modifier = 'un' + endif + + " remove all auto commands + if l:action == 'stop' + execute 'autocmd! ' . b:ConqueTerm_Var + + else + execute 'augroup ' . b:ConqueTerm_Var + + " handle unexpected closing of shell, passes HUP to parent and all child processes + execute 'autocmd ' . b:ConqueTerm_Var . ' BufUnload python ' . b:ConqueTerm_Var . '.proc.signal(1)' + + " check for resized/scrolled buffer when entering buffer + execute 'autocmd ' . b:ConqueTerm_Var . ' BufEnter python ' . b:ConqueTerm_Var . '.update_window_size()' + execute 'autocmd ' . b:ConqueTerm_Var . ' VimResized python ' . b:ConqueTerm_Var . '.update_window_size()' + + " set/reset updatetime on entering/exiting buffer + autocmd BufEnter set updatetime=50 + autocmd BufLeave set updatetime=2000 + + " check for resized/scrolled buffer when entering insert mode + " XXX - messed up since we enter insert mode at each updatetime + "execute 'autocmd InsertEnter python ' . b:ConqueTerm_Var . '.screen.align()' + + " read more output when this isn't the current buffer + if g:ConqueTerm_ReadUnfocused == 1 + execute 'autocmd ' . b:ConqueTerm_Var . ' CursorHold * call conque_term#read_all()' + endif + + " poll for more output + sil execute 'autocmd ' . b:ConqueTerm_Var . ' CursorHoldI python ' . b:ConqueTerm_Var . '.auto_read()' + endif + + " use F22 key to get more input + if l:action == 'start' + sil exe 'i' . map_modifier . 'map "\\"' + sil exe 'i' . map_modifier . 'map "\\"' + else + sil exe 'i' . map_modifier . 'map ' + sil exe 'i' . map_modifier . 'map ' + endif + + " map ASCII 1-31 + for c in range(1, 31) + " + if c == 27 + continue + endif + if l:action == 'start' + sil exe 'i' . map_modifier . 'map :python ' . b:ConqueTerm_Var . '.write(chr(' . c . '))' + else + sil exe 'i' . map_modifier . 'map ' + endif + endfor + if l:action == 'start' + sil exe 'n' . map_modifier . 'map :python ' . b:ConqueTerm_Var . '.write(chr(3))' + else + sil exe 'n' . map_modifier . 'map ' + endif + + " leave insert mode + if !exists('g:ConqueTerm_EscKey') || g:ConqueTerm_EscKey == '' + " use to send to terminal + if l:action == 'start' + sil exe 'i' . map_modifier . 'map :python ' . b:ConqueTerm_Var . '.write(chr(27))' + else + sil exe 'i' . map_modifier . 'map ' + endif + else + " use to send to terminal + if l:action == 'start' + sil exe 'i' . map_modifier . 'map ' . g:ConqueTerm_EscKey . ' ' + sil exe 'i' . map_modifier . 'map :python ' . b:ConqueTerm_Var . '.write(chr(27))' + else + sil exe 'i' . map_modifier . 'map ' . g:ConqueTerm_EscKey + sil exe 'i' . map_modifier . 'map ' + endif + endif + + " Map in insert mode + if exists('g:ConqueTerm_CWInsert') && g:ConqueTerm_CWInsert == 1 + inoremap j j + inoremap k k + inoremap h h + inoremap l l + inoremap w w + endif + + " map ASCII 33-127 + for i in range(33, 127) + " + if i == 124 + if l:action == 'start' + sil exe "i" . map_modifier . "map :python " . b:ConqueTerm_Var . ".write(chr(124))" + else + sil exe "i" . map_modifier . "map " + endif + continue + endif + if l:action == 'start' + sil exe "i" . map_modifier . "map " . nr2char(i) . " :python " . b:ConqueTerm_Var . ".write(chr(" . i . "))" + else + sil exe "i" . map_modifier . "map " . nr2char(i) + endif + endfor + + " map ASCII 128-255 + for i in range(128, 255) + if l:action == 'start' + sil exe "i" . map_modifier . "map " . nr2char(i) . " :python " . b:ConqueTerm_Var . ".write('" . nr2char(i) . "')" + else + sil exe "i" . map_modifier . "map " . nr2char(i) + endif + endfor + + " Special cases + if l:action == 'start' + sil exe 'i' . map_modifier . 'map :python ' . b:ConqueTerm_Var . '.write(u"\u0008")' + sil exe 'i' . map_modifier . 'map :python ' . b:ConqueTerm_Var . '.write(" ")' + sil exe 'i' . map_modifier . 'map :python ' . b:ConqueTerm_Var . '.write(u"\u001b[A")' + sil exe 'i' . map_modifier . 'map :python ' . b:ConqueTerm_Var . '.write(u"\u001b[B")' + sil exe 'i' . map_modifier . 'map :python ' . b:ConqueTerm_Var . '.write(u"\u001b[C")' + sil exe 'i' . map_modifier . 'map :python ' . b:ConqueTerm_Var . '.write(u"\u001b[D")' + else + sil exe 'i' . map_modifier . 'map ' + sil exe 'i' . map_modifier . 'map ' + sil exe 'i' . map_modifier . 'map ' + sil exe 'i' . map_modifier . 'map ' + sil exe 'i' . map_modifier . 'map ' + sil exe 'i' . map_modifier . 'map ' + endif + + " send selected text into conque + if l:action == 'start' + sil exe 'v' . map_modifier . 'map :call conque_term#send_selected(visualmode())' + else + sil exe 'v' . map_modifier . 'map ' + endif + + " remap paste keys + if l:action == 'start' + sil exe 'n' . map_modifier . 'map p :python ' . b:ConqueTerm_Var . '.write(vim.eval("@@"))a' + sil exe 'n' . map_modifier . 'map P :python ' . b:ConqueTerm_Var . '.write(vim.eval("@@"))a' + sil exe 'n' . map_modifier . 'map ]p :python ' . b:ConqueTerm_Var . '.write(vim.eval("@@"))a' + sil exe 'n' . map_modifier . 'map [p :python ' . b:ConqueTerm_Var . '.write(vim.eval("@@"))a' + else + sil exe 'n' . map_modifier . 'map p' + sil exe 'n' . map_modifier . 'map P' + sil exe 'n' . map_modifier . 'map ]p' + sil exe 'n' . map_modifier . 'map [p' + endif + if has('gui_running') + if l:action == 'start' + sil exe 'i' . map_modifier . 'map :python ' . b:ConqueTerm_Var . ".write(vim.eval('@+'))a" + else + sil exe 'i' . map_modifier . 'map ' + endif + endif + + " disable other normal mode keys which insert text + if l:action == 'start' + sil exe 'n' . map_modifier . 'map r :echo "Replace mode disabled in shell."' + sil exe 'n' . map_modifier . 'map R :echo "Replace mode disabled in shell."' + sil exe 'n' . map_modifier . 'map c :echo "Change mode disabled in shell."' + sil exe 'n' . map_modifier . 'map C :echo "Change mode disabled in shell."' + sil exe 'n' . map_modifier . 'map s :echo "Change mode disabled in shell."' + sil exe 'n' . map_modifier . 'map S :echo "Change mode disabled in shell."' + else + sil exe 'n' . map_modifier . 'map r' + sil exe 'n' . map_modifier . 'map R' + sil exe 'n' . map_modifier . 'map c' + sil exe 'n' . map_modifier . 'map C' + sil exe 'n' . map_modifier . 'map s' + sil exe 'n' . map_modifier . 'map S' + endif + + " set conque as on or off + if l:action == 'start' + let b:conque_on = 1 + else + let b:conque_on = 0 + endif + + " map command to start stop the shell + if a:action == 'start' + nnoremap :call conque_term#set_mappings('toggle') + endif + +endfunction " }}} + + +" send selected text from another buffer +function! conque_term#send_selected(type) "{{{ + let reg_save = @@ + + " save user's sb settings + let sb_save = &switchbuf + set switchbuf=usetab + + " yank current selection + sil exe "normal! `<" . a:type . "`>y" + + " format yanked text + let @@ = substitute(@@, '^[\r\n]*', '', '') + let @@ = substitute(@@, '[\r\n]*$', '', '') + + " execute yanked text + sil exe ":sb " . g:ConqueTerm_BufName + sil exe 'python ' . g:ConqueTerm_Var . '.paste_selection()' + + " reset original values + let @@ = reg_save + sil exe 'set switchbuf=' . sb_save + + " scroll buffer left + startinsert! + normal 0zH +endfunction "}}} + +" read from all known conque buffers +function! conque_term#read_all() "{{{ + " don't run this if we're in a conque buffer + if exists('b:ConqueTerm_Var') + return + endif + + try + for i in range(1, g:ConqueTerm_Idx - 1) + execute 'python ConqueTerm_' . string(i) . '.read(1)' + endfor + catch + " probably a deleted buffer + endtry + + " restart updatetime + call feedkeys("f\e") +endfunction "}}} + +" util function to add enough \s to pass a string to python +function! conque_term#python_escape(input) "{{{ + let l:cleaned = a:input + let l:cleaned = substitute(l:cleaned, '\\', '\\\\', 'g') + let l:cleaned = substitute(l:cleaned, '\n', '\\n', 'g') + let l:cleaned = substitute(l:cleaned, '\r', '\\r', 'g') + let l:cleaned = substitute(l:cleaned, "'", "\\\\'", 'g') + return l:cleaned +endfunction "}}} + +" ********************************************************************************************************** +" **** PYTHON ********************************************************************************************** +" ********************************************************************************************************** + +let conque_py_dir = substitute(findfile('autoload/conque_term.vim', &rtp), 'conque_term.vim', '', '') +exec "pyfile " . conque_py_dir . "conque.py" +exec "pyfile " . conque_py_dir . "conque_subprocess.py" +exec "pyfile " . conque_py_dir . "conque_screen.py" + diff -r 21d16bafb00b -r e42e595b17c2 vim/bundle/conque/doc/conque_term.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vim/bundle/conque/doc/conque_term.txt Tue Jun 29 09:39:49 2010 -0400 @@ -0,0 +1,156 @@ +*ConqueTerm* Plugin to run a shell in a buffer + +The ConqueTerm plugin will convert a buffer into a terminal emulator, allowing +you to run a shell or shell application in the buffer. + + *conque_term-usage* + +Type :ConqueTerm to launch an application in the current buffer. E.g. + + :ConqueTerm bash + :ConqueTerm mysql -h localhost -u joe_lunchbox Menu + :ConqueTerm man top + +Use :ConqueTermSplit or :ConqueTermVSplit to open Conque in a new horizontal +or vertical buffer. + +Keys pressed in insert mode will be sent to the shell, along with output from +the 'p' command in normal mode. + +Press the key twice to send a single to the shell. Pressing this +key once will leave insert mode like normal. + +Press in any buffer to send a visual selection to the shell. + + + *conque_term-settings* + +Set the following in your .vimrc (default values shown) + +" Enable colors. Setting this to 0 will make your terminal faster. +let g:ConqueTerm_Color = 1 + +" Set your terminal type. I strong recommend leaving this as vt100, +" however more features may be enabled with xterm. +let g:ConqueTerm_TERM = 'vt100' + +" Set buffer syntax. Conque has highlighting for MySQL, but not much else. +let g:ConqueTerm_Syntax = 'conque' + +" Continue updating shell when it's not the current, focused buffer +let g:ConqueTerm_ReadUnfocused = 1 + + + *conque_term-requirements* + +The following minimum requirements are needed to run Conque. Conque will not +run on Windows without a Cygwin-like environment. + + - Vim 7.1 + - Python 2.3 + - Supported operating systems: *nix, Mac, or Cygwin + +Tested on: + - Vim 7.2 / Python 2.6 / Ubuntu 9.10 (Gnome & GTK) + - Vim 7.2 / Python 2.6 / FreeBSD 8.0 (GTK) + - Vim 7.1 / Python 2.6 / FreeBSD 8.0 (GTK) + x Vim 7.0 / Python 2.6 / FreeBSD 8.0 (GTK) + * feedkeys() doesn't restart updatetime + - Vim 7.2 / Python 2.4 / OpenSolaris 2009.06 (Gnome) + - Vim 7.2 / Python 2.4 / CentOS 5.3 (no GUI) + - Vim 7.1 / Python 2.3 / RHEL 4 (no GUI) + - Vim 7.2 / Python 2.5 / Cygwin (Windows Vista 64b) + - MacVim 7.2 / Python 2.3 / OS X 10.6.2 + + *conque_term-bugs* + +The following are known limitations: + + - Font/color highlighting is imperfect and slow. If you don't care about + color in your shell, set g:ConqueTerm_Color = 0 in your .vimrc + - Conque only supports the extended ASCII character set for input, not utf-8. + - VT100 escape sequence support is not complete. + - Alt/Meta key support in Vim isn't great in general, and conque is no + exception. Pressing x or instead of works in + most cases. + + *conque_term-todo* + + - Fix pasting from named registers + - Polling unfucused conque buffers (Top explodes when window resizes) + - Enable graphics character set + - Consider supporting xterm escapes + - Improve color logic + - Find a solution to UTF-8 input (See InsertCharPre in Vim todo.txt) + - Find an alternative to updatetime polling (See Vim todo.txt) + - Find a graceful solution to Meta key input + - Windows support + (See PyConsole http://www.vim.org/scripts/script.php?script_id=1974) + - Always: look for performance improvements + + + *conque_term-contribute* + +The two contributions most in need are improvements to Vim itself. I currently +use hacks to simulate a key press event and repeating CursorHold event. The +Vim todo.txt document lists proposed improvements to give users this behavior +without hacks. Having a key press event should allow Conque to work with multi- +byte input. If you are a Vim developer, please consider prioritizing these two +items: + + - todo.txt (Autocommands, line ~3137) + 8 Add an event like CursorHold that is triggered repeatedly, not just + once after typing something. + + - todo.txt (Autocommands, proposed event list, line ~3189) + InsertCharPre - user typed character Insert mode, before inserting the + char. Pattern is matched with text before the cursor. Set v:char to the + character, can be changed. (not triggered when 'paste' is set). + +Bugs, suggestions and patches are all welcome. + +For more information visit http://conque.googlecode.com + +Check out the latest from svn at http://conque.googlecode.com/svn/trunk/ + + *conque_term-changelog* + + - 1.0 / 2010-02- + * Complete python rewrite + * Add support for ncurses based applications + * Add continuous polling, instead of using + * Improve speed + * Improve syntax highlighting + + - 0.6 / 2009-12-18 + * Fix GVim errors with non-english locale + * No functional changes + + - 0.5 / 2009-12-02 + * Various performance enhancements and bugfixes. + * Rewritten escape sequence processing + + - 0.4 / 2009-10-30 + * Improved history and tab completion + * Fix escape sequence formatting and improve highlighting + * Send selected text to shell from any buffer + * Add special handling of "vi" and "man" commands + * Improve error handling + * Add key mappings for + * Various bugfixes + + - 0.3 / 2009-10-13 + * Apply escape sequence coloring to output, e.g. ls --color + * Clean up syntax files for portability + * Fix several Vim 7.1 bugs + * Bugfixes for multiple shell buffers + * Add experimental shell folding option + + - 0.2 / 2009-10-01 + * Rewritten subprocess management module in python instead of c + * Added support for OS X, partial support for Windows + * Improved tab completion + + - 0.1 / 2009-09-03 + * Initial release + diff -r 21d16bafb00b -r e42e595b17c2 vim/bundle/conque/plugin/conque_term.vim --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vim/bundle/conque/plugin/conque_term.vim Tue Jun 29 09:39:49 2010 -0400 @@ -0,0 +1,93 @@ +" FILE: plugin/conque_term.vim {{{ +" AUTHOR: Nico Raffo +" MODIFIED: __MODIFIED__ +" VERSION: __VERSION__, for Vim 7.0 +" LICENSE: +" Conque - pty interaction in Vim +" Copyright (C) 2009-2010 Nico Raffo +" +" MIT License +" +" Permission is hereby granted, free of charge, to any person obtaining a copy +" of this software and associated documentation files (the "Software"), to deal +" in the Software without restriction, including without limitation the rights +" to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +" copies of the Software, and to permit persons to whom the Software is +" furnished to do so, subject to the following conditions: +" +" The above copyright notice and this permission notice shall be included in +" all copies or substantial portions of the Software. +" +" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +" OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +" THE SOFTWARE. +" }}} + +" See docs/conque_term.txt for help or type :help conque_term + +if exists('g:ConqueTerm_Loaded') || v:version < 700 + finish +endif + +" ********************************************************************************************************** +" **** CONFIG ********************************************************************************************** +" ********************************************************************************************************** + +" Choose key mapping to leave insert mode {{{ +" If you choose something other than '', then will be sent to terminal +" Using a different key will usually fix Alt/Meta key issues +if !exists('g:ConqueTerm_EscKey') + let g:ConqueTerm_EscKey = '' +endif " }}} + +" Enable color. {{{ +" If your apps use a lot of color it will slow down the shell. +if !exists('g:ConqueTerm_Color') + let g:ConqueTerm_Color = 1 +endif " }}} + +" TERM environment setting {{{ +if !exists('g:ConqueTerm_TERM') + let g:ConqueTerm_TERM = 'vt100' +endif " }}} + +" Syntax for your buffer {{{ +if !exists('g:ConqueTerm_Syntax') + let g:ConqueTerm_Syntax = 'conque_term' +endif " }}} + +" Keep on updating the shell window after you've switched to another buffer {{{ +if !exists('g:ConqueTerm_ReadUnfocused') + let g:ConqueTerm_ReadUnfocused = 0 +endif " }}} + +" Use this regular expression to highlight prompt {{{ +if !exists('g:ConqueTerm_PromptRegex') + let g:ConqueTerm_PromptRegex = '^\w\+@[0-9A-Za-z_.-]\+:[0-9A-Za-z_./\~,:-]\+\$' +endif " }}} + +" Allow user to use keys to switch window in insert mode. {{{ +if !exists('g:ConqueTerm_CWInsert') + let g:ConqueTerm_CWInsert = 0 +endif " }}} + +" ********************************************************************************************************** +" **** Startup ********************************************************************************************* +" ********************************************************************************************************** + +" Startup {{{ + +let g:ConqueTerm_Loaded = 1 +let g:ConqueTerm_Idx = 1 + +command! -nargs=+ -complete=shellcmd ConqueTerm call conque_term#open() +command! -nargs=+ -complete=shellcmd ConqueTermSplit call conque_term#open(, ['belowright split']) +command! -nargs=+ -complete=shellcmd ConqueTermVSplit call conque_term#open(, ['belowright vsplit']) +command! -nargs=+ -complete=shellcmd ConqueTermTab call conque_term#open(, ['tabnew']) + +" }}} + diff -r 21d16bafb00b -r e42e595b17c2 vim/bundle/conque/plugin/conque_term_pylab.vim --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vim/bundle/conque/plugin/conque_term_pylab.vim Tue Jun 29 09:39:49 2010 -0400 @@ -0,0 +1,36 @@ +" FILE: plugin/conque_term_pylab.vim {{{ +" AUTHOR: Gökhan Sever +" Nico Raffo +" MODIFIED: __MODIFIED__ +" VERSION: __VERSION__, for Vim 7.0 +" LICENSE: +" }}} +" +" Summary: Ipython shortcuts contributed by Gökhan Sever +" +" Installation: place this file in your .vim/plugin/ directory. +" + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" Key mappings {{{ + +" create a new ipython buffer below +map :cd %:p:h :call conque_term#open('ipython -pylab', ['belowright split']) + +" run the current buffer in ipython +nnoremap :call conque_term_pylab#ipython_run() + +" }}} + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" Functions {{{ + +" run the current buffer in ipython +function! conque_term_pylab#ipython_run() + let cmd = "run " . expand("%:t") + silent execute 'python ' . g:ConqueTerm_Var . '.write(''' . cmd . ''' + "\n")' + startinsert! +endfunction + +" }}} + diff -r 21d16bafb00b -r e42e595b17c2 vim/bundle/conque/syntax/conque_term.vim --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vim/bundle/conque/syntax/conque_term.vim Tue Jun 29 09:39:49 2010 -0400 @@ -0,0 +1,75 @@ + +" ******************************************************************************************************************* +" MySQL ************************************************************************************************************* +" ******************************************************************************************************************* + +syn match MySQLTableHead "^ *|.*| *$" nextgroup=MySQLTableDivide contains=MySQLTableBar oneline skipwhite skipnl +syn match MySQLTableBody "^ *|.*| *$" nextgroup=MySQLTableBody,MySQLTableEnd contains=MySQLTableBar,MySQLNull,MySQLBool,MySQLNumber,MySQLStorageClass oneline skipwhite skipnl +syn match MySQLTableEnd "^ *+[+=-]\++ *$" oneline +syn match MySQLTableDivide "^ *+[+=-]\++ *$" nextgroup=MySQLTableBody oneline skipwhite skipnl +syn match MySQLTableStart "^ *+[+=-]\++ *$" nextgroup=MySQLTableHead oneline skipwhite skipnl +syn match MySQLNull " NULL " contained contains=MySQLTableBar +syn match MySQLStorageClass " PRI " contained +syn match MySQLStorageClass " MUL " contained +syn match MySQLStorageClass " UNI " contained +syn match MySQLStorageClass " CURRENT_TIMESTAMP " contained +syn match MySQLStorageClass " auto_increment " contained +syn match MySQLTableBar "|" contained +syn match MySQLNumber "|\? *\d\+ *|" contained contains=MySQLTableBar +syn match MySQLQueryStat "^\d\+ rows\? in set.*" oneline +syn match MySQLPromptLine "^.\?mysql> .*$" contains=MySQLKeyword,MySQLPrompt,MySQLString oneline +syn match MySQLPromptLine "^ -> .*$" contains=MySQLKeyword,MySQLPrompt,MySQLString oneline +syn match MySQLPrompt "^.\?mysql>" contained oneline +syn match MySQLPrompt "^ ->" contained oneline +syn case ignore +syn keyword MySQLKeyword select count max sum avg date show table tables status like as from left right outer inner join contained +syn keyword MySQLKeyword where group by having limit offset order desc asc show contained +syn case match +syn region MySQLString start=+'+ end=+'+ skip=+\\'+ contained oneline +syn region MySQLString start=+"+ end=+"+ skip=+\\"+ contained oneline +syn region MySQLString start=+`+ end=+`+ skip=+\\`+ contained oneline + +hi def link MySQLPrompt Identifier +hi def link MySQLTableHead Title +hi def link MySQLTableBody Normal +hi def link MySQLBool Boolean +hi def link MySQLStorageClass StorageClass +hi def link MySQLNumber Number +hi def link MySQLKeyword Keyword +hi def link MySQLString String + +" terms which have no reasonable default highlight group to link to +hi MySQLTableHead term=bold cterm=bold gui=bold +if &background == 'dark' + hi MySQLTableEnd term=NONE cterm=NONE gui=NONE ctermfg=238 guifg=#444444 + hi MySQLTableDivide term=NONE cterm=NONE gui=NONE ctermfg=238 guifg=#444444 + hi MySQLTableStart term=NONE cterm=NONE gui=NONE ctermfg=238 guifg=#444444 + hi MySQLTableBar term=NONE cterm=NONE gui=NONE ctermfg=238 guifg=#444444 + hi MySQLNull term=NONE cterm=NONE gui=NONE ctermfg=238 guifg=#444444 + hi MySQLQueryStat term=NONE cterm=NONE gui=NONE ctermfg=238 guifg=#444444 +elseif &background == 'light' + hi MySQLTableEnd term=NONE cterm=NONE gui=NONE ctermfg=247 guifg=#9e9e9e + hi MySQLTableDivide term=NONE cterm=NONE gui=NONE ctermfg=247 guifg=#9e9e9e + hi MySQLTableStart term=NONE cterm=NONE gui=NONE ctermfg=247 guifg=#9e9e9e + hi MySQLTableBar term=NONE cterm=NONE gui=NONE ctermfg=247 guifg=#9e9e9e + hi MySQLNull term=NONE cterm=NONE gui=NONE ctermfg=247 guifg=#9e9e9e + hi MySQLQueryStat term=NONE cterm=NONE gui=NONE ctermfg=247 guifg=#9e9e9e +endif + + +" ******************************************************************************************************************* +" Bash ************************************************************************************************************** +" ******************************************************************************************************************* + +" Typical Prompt +silent execute "syn match ConquePromptLine '" . g:ConqueTerm_PromptRegex . ".*$' contains=ConquePrompt,ConqueString oneline" +silent execute "syn match ConquePrompt '" . g:ConqueTerm_PromptRegex . "' contained oneline" +hi def link ConquePrompt Identifier + +" Strings +syn region ConqueString start=+'+ end=+'+ skip=+\\'+ contained oneline +syn region ConqueString start=+"+ end=+"+ skip=+\\"+ contained oneline +syn region ConqueString start=+`+ end=+`+ skip=+\\`+ contained oneline +hi def link ConqueString String + +" vim: foldmethod=marker diff -r 21d16bafb00b -r e42e595b17c2 vim/bundle/space/doc/space.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vim/bundle/space/doc/space.txt Tue Jun 29 09:39:49 2010 -0400 @@ -0,0 +1,215 @@ +*space.txt* Smart Space Key + + *space.vim* + + ______ ______ _____ _____ _____ + / _____\ | ___ \ / ___ \ / ___/ / ___/ + \ \____ | ___ / | \ / | | | | \__ + \___ \ | | | |X| | | |___ | /___ + /______/ \_| \_/ \_/ \____/ \____/ + + By Henrik Öhman + + + Reference Manual ~ + + + *space-toc* + +1. Intro |space-intro| +2. Usage |space-usage| +3. Hooks |space-hooks| +4. Status line integration |space-statusline| +5. Configuration |space-configuration| +6. License |space-license| + + + +============================================================================== +1. Intro *space-intro* + +space.vim is a plugin which remaps the ** key to act as a clever key +to repeat motions. To disable space.vim, set the "space_loaded" global +variable in your |vimrc| file: > + :let g:space_loaded = 1 + +space.vim hooks into several of the more complex motion commands, such as +|search-commands|, |jumpto-diffs|, |quickfix| and |location-list| and more +commands. When a command that space.vim has hooked into is issued, it remaps +the key to repeat that command, and it also remaps and + to do the reverse. + +NOTE:~Due to terminal restrictions, may not be available. For that +reason, the key is also used for reverse motions. Wherever this document +talks of , can be used in its place. + +NOTE:~space.vim has some problems with the |'foldopen'| option. Since Vim +won't open folds if a command is part of a mapping, space.vim tries to +emulate this behaviour. This works well for all Normal mode mappings and for +most Visual mode mappings. Only for searches using |/| and |?| in Visual mode +is space.vim unable to emulate |'foldopen'|. + +NOTE:~Some |filetype| plugins map the section text objects ([[, [], ][, ]]) +and the method motions ([m, [M, ]m, ]M). space.vim is unable to hook into +these mappings in a well defined way. There is definitely room for +improvement here. + +============================================================================== +2. Usage *space-usage* + +Using space.vim is intuitive. Issue a command, such as a search, and the + key to go to the next match, and to go to the previous +match. Thus, the following sequence > + /foo + n + N + +is equivalent to > + /foo + + + +This works with counts, and with Visual mode too > + /foo + V + 4 + +space.vim tries to immitate Vim in its logic when specifying the direction for +the repeated movement. For the search commands, behaves like |n|, and + behaves like |N|, which means that a following a search using +|?|, will actually find the previous match. For other commands, is +configured to use the variant of the command that has the meaning of "next". +Thus, is always mapped to |:lnext|, |[[|, |zj| etc, and never the +reverse. + +The full power of space.vim will become apparent if you use |jumpto-diffs|, +in particular on non-US keyboards, or |quickfix| and |location-list| +commands. Remember all that finger stretching and keyboard dancing to quickly +browse through a series of diffs for a fast overview of what your colleague +managed to screw up this time? No more! > + ]c Jump to the next diff + Repeat the ]c motion + ... Nothing interesting, keep pressing space + Wait, there was something! Let's go back one diff + +Or why not quickly browse through all files which contain the sentence 'over +9000' in all subdirectories? > + :lvimgrep /over 9000/ **/* Find all the matches and add them to the + location-list + is now mapped to :lnext + And is mapped to :lprevious + +Neat, huh? To get an overview of all the commands space.vim hooks into, and +enables and mappings for, read on. |space-hooks| + +============================================================================== +3. Hooks *space-hooks* + +This is a list of all the commands that space.vim hooks into and provides + and navigation for. + +Character movements: |left-right-motions| + |f||F||t||T||;||,| + +Search commands: |search-commands| + |star||gstar||#||g#||n||N| + +Diff jumps: |jumpto-diffs| + |]c||[c| + +Parenthesis and bracket jumps: |various-motions| + |])||[(||]}||[{| + +Method jumps: |various-motions| + |]m||[m||]M||[M| + +Section jumps: |object-motions| + |]]||[]||][||[[| + +Fold movements: + |zj||zk||]z||[z| + +Quickfix commands: |quickfix| + |:make| + |:vimgrep| + |:grep| + |:cc| + |:cnext| + |:cprevious| + |:cNext| + |:cfirst| + |:clast| + |:crewind| + |:cfile| + |:cnfile| + |:cpfile| + |:cNfile| + +Location list commands: |location-list| + |:lmake| + |:lvimgrep| + |:lgrep| + |:ll| + |:lcnext| + |:lcprevious| + |:lcNext| + |:lcfirst| + |:lclast| + |:lcrewind| + |:lcfile| + |:lcnfile| + |:lcpfile| + |:lcNfile| + +============================================================================== +4. Status line integration *space-statusline* + +It is possible to display the current command assigned to in the +status line using the GetSpaceMovement() function. Here's an example: > + + function! SlSpace() + if exists("*GetSpaceMovement") + return "[" . GetSpaceMovement() . "]" + else + return "" + endif + endfunc + set statusline+=%{SlSpace()} + +============================================================================== +5. Configuration *space-configuration* + +It is possible to avoid using the key for groups of navigation +commands using global variables. For instance, you may wish to use to +repeat the last command only for diff jumps and quickfix and location list +commands. Here's a list of commands that disable the use of the key + +Disable for character movements > + let g:space_no_character_movements = 1 + +Disable for search commands > + let g:space_no_search = 1 + +Disable for diff jumps > + let g:space_no_diff = 1 + +Disable for parenthesis and bracket jumps > + let g:space_no_brace = 1 + +Disable for method jumps > + let g:space_no_method = 1 + +Disable for section jumps > + let g:space_no_section = 1 + +Disable for fold movements > + let g:space_no_folds = 1 + +Disable for quickfix and location list commands > + let g:space_no_quickfix = 1 + +============================================================================== +6. License *space-license* + +space.vim is licensed under the same terms as Vim itself. +vim:tw=78:fo=tcq2:isk=!-~,^*,^\|,^\":ts=8:ft=help:norl: diff -r 21d16bafb00b -r e42e595b17c2 vim/bundle/space/plugin/space.vim --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vim/bundle/space/plugin/space.vim Tue Jun 29 09:39:49 2010 -0400 @@ -0,0 +1,396 @@ +" space.vim - Smart Space key +" Author: Henrik Öhman +" URL: http://github.com/spiiph/vim-space/tree/master +" Version: 1.7 +" LastChanged: $LastChangedDate: 2009-04-23 01:42:43 +0200 (to, 23 apr 2009) $ +" Revision: $Revision: 171 $ +" +" Licensed under the same terms as Vim itself. +" +" NOTE: Using this script has some problems with 'foldopen', since vim won't +" open folds if a command is part of a mapping. This is possible to +" emulate in Normal mode, and in most cases in Visual mode. Only for +" searches using '/' and '?' have I been unsuccessful in finding a +" solution. +" ============================================================================ + + +" Set this variable to disable space.vim +" +" let g:loaded_space = 1 + +" These variables disables the usage of for groups of different +" movement commands +" +" Disable for character movements, e.g. fFtT;, +" let g:space_no_character_movements = 1 +" +" Disable for searches, e.g. /?#*nN +" let g:space_no_search = 1 +" +" Disable for diff commands, e.g. [c and ]c +" let g:space_no_diff = 1 +" +" Disable for brace movement commands, e.g. [(, ]), [{ and ]} +" let g:space_no_brace = 1 +" +" Disable for method movement commands, e.g. [m, ]m, [M and ]M +" let g:space_no_method = 1 +" +" Disable for section movement commands, e.g. [[, ]], [] and ][ +" let g:space_no_section = 1 +" +" Disable for fold movement commands, e.g. [z, ]z, zj and zk +" let g:space_no_folds = 1 +" +" Disable for quickfix and location list commands, e.g. :cc, :ll, etc. +" let g:space_no_quickfix = 1 + +" It is possible to display the current command assigned to in the +" status line using the GetSpaceMovement() function. Here's an example: +" +" function! SlSpace() +" if exists("*GetSpaceMovement") +" return "[" . GetSpaceMovement() . "]" +" else +" return "" +" endif +" endfunc +" set statusline+=%{SlSpace()} + +" TODO: Make the mapping assignments more dynamical, and allow user defined +" commands? + +if exists("g:space_debug") + let g:space_no_character_movements = 0 + let g:space_no_search = 0 + let g:space_no_diff = 0 + let g:space_no_brace = 0 + let g:space_no_method = 0 + let g:space_no_section = 0 + let g:space_no_folds = 0 + let g:space_no_quickfix = 0 + echomsg "Running space.vim in debug mode." +elseif exists("g:space_loaded") + finish +endif +let g:space_loaded = 1 + +noremap do_space(0, "") +noremap do_space(1, "") +noremap do_space(1, "") + +" character movement commands +if !exists("g:space_no_character_movements") || !g:space_no_character_movements + noremap f setup_space("char", "f") + noremap F setup_space("char", "F") + noremap t setup_space("char", "t") + noremap T setup_space("char", "T") + noremap ; setup_space("char", ";") + noremap , setup_space("char", ",") +endif + +" search commands +if !exists("g:space_no_search") || !g:space_no_search + noremap * setup_space("search", "*") + noremap # setup_space("search", "#") + noremap g* setup_space("search", "g*") + noremap g# setup_space("search", "g#") + noremap n setup_space("search", "n") + noremap N setup_space("search", "N") + let s:search_mappings = 1 +else + let s:search_mappings = 0 +endif + +" diff next/prev +if !exists("g:space_no_diff") || !g:space_no_diff + noremap ]c setup_space("diff", "]c") + noremap [c setup_space("diff", "[c") +endif + +" previous/next unmatched ( or [ +if !exists("g:space_no_brace") || !g:space_no_brace + noremap ]) setup_space("paren", "])") + noremap [( setup_space("paren", "[(") + + noremap ]} setup_space("curly", "]}") + noremap [{ setup_space("curly", "[{") +endif + +" start/end of a method +if !exists("g:space_no_method") || !g:space_no_method + noremap ]m setup_space("method_start", "]m") + noremap [m setup_space("method_start", "[m") + + noremap ]M setup_space("method_end", "]M") + noremap [M setup_space("method_end", "[M") +endif + +" previous/next section or '}'/'{' in the first column +if !exists("g:space_no_section") || !g:space_no_section + noremap ]] setup_space("section_start", "]]") + noremap [[ setup_space("section_start", "[[") + + noremap ][ setup_space("section_end", "][") + noremap [] setup_space("section_end", "[]") +endif + +if !exists("g:space_no_folds") || !g:space_no_folds + noremap zj setup_space("fold_next", "zj") + noremap zk setup_space("fold_next", "zk") + + noremap ]z setup_space("fold_start", "]z") + noremap [z setup_space("fold_start", "[z") +endif + + +" quickfix and location list commands +if !exists("g:space_no_quickfix") || !g:space_no_quickfix + cnoremap parse_cmd_line() + let s:quickfix_mappings = 1 +else + let s:quickfix_mappings = 0 +endif + +" TODO: Have all mappings add the remapped sequence to a list, and use that +" list to remove mappings. +command! SpaceRemoveMappings call remove_space_mappings() +function! s:remove_space_mappings() + silent! unmap + silent! unmap + silent! unmap + + silent! unmap f + silent! unmap F + silent! unmap t + silent! unmap T + silent! unmap ; + silent! unmap , + + silent! unmap * + silent! unmap # + silent! unmap g* + silent! unmap g# + silent! unmap n + silent! unmap N + + silent! unmap ]c + silent! unmap [c + + silent! unmap [( + silent! unmap ]) + silent! unmap [{ + silent! unmap ]} + + silent! unmap ]] + silent! unmap [[ + silent! unmap ][ + silent! unmap [] + + silent! unmap ]m + silent! unmap [m + silent! unmap ]M + silent! unmap [M + + silent! unmap zj + silent! unmap zk + silent! unmap ]z + silent! unmap [z + + silent! cunmap + + silent! unlet g:loaded_space +endfunction + +" TODO: Check if the '\>!\=' part of the pattern fails when 'iskeyword' +" contains '!' +" NOTE: Since Vim allows commands like ":'k,'lvim /foo/ *", it's a little +" tedious to write a perfect regexp. +let s:qf_re = '\%(' . + \ 'mak\%[e]\|' . + \ 'v\%[imgrep]\|' . + \ 'gr\%[ep]\|' . + \ 'c\%(' . + \ 'c\|' . + \ 'p\%[revious]\|' . + \ '[nN]\%[ext]\|' . + \ '\(fir\|la\)\%[st]\|' . + \ 'r\%[ewind]\|' . + \ '\(f\|nf\|Nf\|pf\)\%[ile]' . + \ '\)' . + \ '\)\>!\=' + +let s:lf_re = 'l\%(' . + \ 'mak\%[e]\|' . + \ 'v\%[imgrep]\|' . + \ 'gr\%[ep]\|' . + \ 'l\|' . + \ 'p\%[revious]\|' . + \ 'ne\%[xt]\|N\%[ext]\|' . + \ '\(fir\|la\)\%[st]\|' . + \ 'r\%[ewind]\|' . + \ '\(f\|nf\|Nf\|pf\)\%[ile]' . + \ '\)\>!\=' + +function! s:parse_cmd_line() + let cmd = getcmdline() + let type = getcmdtype() + + if s:search_mappings && (type == '/' || type == '?') + return setup_space("search", cmd) + elseif s:quickfix_mappings && type == ':' + if cmd =~ s:lf_re + return setup_space("lf", cmd) + elseif cmd =~ s:qf_re + return setup_space("qf", cmd) + endif + end + return "\" +endfunc + +function! s:setup_space(type, command) + let cmd = a:command + let s:cmd_type = "undefined" + + if a:type == "char" + let s:space_move = ";" + let s:shift_space_move = "," + let s:cmd_type = "hor" + if cmd =~ "[;,]$" + let cmd = maybe_open_fold(cmd) + endif + elseif a:type == "diff" + let s:space_move = "]c" + let s:shift_space_move = "[c" + elseif a:type == "method_start" + let s:space_move = "]m" + let s:shift_space_move = "[m" + let s:cmd_type = "block" + let cmd = maybe_open_fold(cmd) + elseif a:type == "method_end" + let s:space_move = "]M" + let s:shift_space_move = "[M" + let s:cmd_type = "block" + let cmd = maybe_open_fold(cmd) + elseif a:type == "section_start" + let s:space_move = "]]" + let s:shift_space_move = "[[" + let s:cmd_type = "block" + let cmd = maybe_open_fold(cmd) + elseif a:type == "section_end" + let s:space_move = "][" + let s:shift_space_move = "[]" + let s:cmd_type = "block" + let cmd = maybe_open_fold(cmd) + elseif a:type == "paren" + let s:space_move = "])" + let s:shift_space_move = "[(" + let s:cmd_type = "block" + let cmd = maybe_open_fold(cmd) + elseif a:type == "curly" + let s:space_move = "]}" + let s:shift_space_move = "[{" + let s:cmd_type = "block" + let cmd = maybe_open_fold(cmd) + elseif a:type == "fold_next" + let s:space_move = "zj" + let s:shift_space_move = "zk" + elseif a:type == "fold_start" + let s:space_move = "]z" + let s:shift_space_move = "[z" + elseif a:type == "search" + let s:space_move = "n" + let s:shift_space_move = "N" + let s:cmd_type = "search" + let cmd = maybe_open_fold(cmd) + elseif a:type == "qf" + let s:space_move = "cn" + let s:shift_space_move = "cN" + let s:cmd_type = "quickfix" + let cmd = maybe_open_fold(cmd) + elseif a:type == "lf" + let s:space_move = "lne" + let s:shift_space_move = "lN" + let s:cmd_type = "quickfix" + let cmd = maybe_open_fold(cmd) + endif + call debug_msg("setup_space(type = " . a:type . + \ ", command = " . cmd . ")") + return cmd +endfunc + +function! s:do_space(shift, default) + " + if a:shift == 0 + if exists("s:space_move") + let cmd = maybe_open_fold(s:space_move) + call debug_msg("do_space(cmd = " . cmd . ")") + else + let cmd = a:default + endif + " and + else + if exists("s:shift_space_move") + let cmd = maybe_open_fold(s:shift_space_move) + call debug_msg("do_space(cmd = " . cmd . ")") + else + let cmd = a:default + endif + endif + return cmd +endfunc + +function! s:maybe_open_fold(cmd) + if !exists("g:space_no_foldopen") && &foldopen =~ s:cmd_type + " special treatment of :ex commands + if s:cmd_type == "quickfix" + if getcmdtype() == ':' + return "\zv" + else + return ":\" . (v:count ? v:count : "") . a:cmd . "\zv" + endif + " special treatment of /foo and ?foo commands + elseif s:cmd_type == "search" && getcmdtype() =~ "[/?]" + return "\zv" + else + if mode() =~ "[vV]" + " NOTE: That this works is probably a bug in vim. Let's hope + " it stays that way. ;) + return ":\normal! gv" . (v:count ? v:count : "") + \ . a:cmd . "zv\" + "return a:cmd . "zv" + else + return a:cmd . "zv" + endif + endif + else + if s:cmd_type == "quickfix" + if getcmdtype() == ':' + return "\" + else + return ":\" . (v:count ? v:count : "") . a:cmd . "\" + endif + elseif s:cmd_type == "search" && getcmdtype() =~ "[/?]" + return "\" + else + return a:cmd + endif + endif +endfunc + +function! s:debug_msg(string) + if exists("g:space_debug") + echomsg a:string + endif +endfunc + +function! GetSpaceMovement() + if exists("s:space_move") + return s:space_move + else + return "" + end +endfunc + +" vim: et sts=4 sw=4 diff -r 21d16bafb00b -r e42e595b17c2 vim/bundle/space/test/tests.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vim/bundle/space/test/tests.txt Tue Jun 29 09:39:49 2010 -0400 @@ -0,0 +1,181 @@ += Quick test + = normal (+folded/-folded) + + f + + /foo + + n + + ]} + + ]m + + ]] + + zj + + [z + + :cc + + :ll + = visual (-folded) + + f + + /foo + + n + + ]} + + ]m + + ]] + + zj + + [z + = visual (+folded) + / /foo + + n + + ]m + + ]] + + zj + = normal (no foldopen) + + f + + /foo + + n + + ]} + + ]m + + ]] + + zj + + [z + + :cc + + :ll + = visual (no foldopen) + + /foo + + n + + ]m + + ]] + + zj + + [z + += Test normal mode mappings + + f + + F + + t + + T + + ; + + , + + * + + g* + + # + + g# + + / + + ? + + n + + N + + ]c + + [c + + ]) + + [( + + ]} + + [{ + + ]m + + [m + + ]M + + [M + + ]] + + [[ + + ][ + + [] + += Test visual mode mappings + + f + + F + + t + + T + + ; + + , + + * + + g* + + # + + g# + + / + + ? + + n + + N + + ]c + + [c + + ]) + + [( + + ]} + + [{ + + ]m + + [m + + ]M + + [M + + ]] + + [[ + + ][ + + [] + += Test quickfix and location list commands + + :cc + + :cp + + :cN + + :cn + + :cfir + + :cla + + :cr + - :cf + + :cnf + + :cNf + + :cpf + + :ll + + :lp + + :lN + + :lne + + :lfir + + :lla + + :lr + - :lf + + :lnf + + :lNf + + :lpf + += Test folding +" set foldopen=hor,search,block,quickfix + + f hor + + F hor + + t hor + + T hor + + ; hor + + , hor + + * search + + g* search + + # search + + g# search + / / search + / ? search + + n search + + N search + + ]) block + + [( block + + ]} block + + [{ block + + ]m block + + [m block + + ]M block + + [M block + + ]] block + + [[ block + + ][ block + + [] block + + :cc qf + + :cp qf + + :cN qf + + :cn qf + + :cfir qf + + :cla qf + + :cr qf + + :ll qf + + :lp qf + + :lN qf + + :lne qf + + :lfir qf + + :lla qf + + :cr qf + += Test count + - 4fx + - 4n + - 4/foo + - :4cn + - etc + - 4 + - :4lvim //