moved plugins to Vundle

This commit is contained in:
Andrea Mistrali 2015-08-17 14:26:39 +02:00
parent d1e2801be5
commit 35911ffb93
31 changed files with 5 additions and 12909 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,319 +0,0 @@
# FILE: autoload/conque_term/conque_globals.py
# AUTHOR: Nico Raffo <nicoraffo@gmail.com>
# WEBSITE: http://conque.googlecode.com
# MODIFIED: 2011-08-12
# VERSION: 2.2, for Vim 7.0
# LICENSE:
# Conque - Vim terminal/console emulator
# Copyright (C) 2009-__YEAR__ 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.
"""Common global constants and functions for Conque."""
import sys
import re
import os # DEBUG
import traceback # DEBUG
# PYTHON VERSION
CONQUE_PYTHON_VERSION = sys.version_info[0]
# Encoding
try:
# Vim's character encoding
import vim
CONQUE_VIM_ENCODING = vim.eval('&encoding')
except:
CONQUE_VIM_ENCODING = 'utf-8'
def u(str_val, str_encoding='utf-8', errors='strict'):
""" Foolhardy attempt to make unicode string syntax compatible with both python 2 and 3. """
if not str_val:
str_val = ''
if CONQUE_PYTHON_VERSION == 3:
return str_val
else:
return unicode(str_val, str_encoding, errors)
def uchr(str):
""" Foolhardy attempt to make unicode string syntax compatible with both python 2 and 3. """
if CONQUE_PYTHON_VERSION == 3:
return chr(str)
else:
return unichr(str)
# Unix escape sequence settings
CONQUE_CTL = {
1: 'soh', # start of heading
2: 'stx', # start of text
7: 'bel', # bell
8: 'bs', # backspace
9: 'tab', # tab
10: 'nl', # new line
13: 'cr', # carriage return
14: 'so', # shift out
15: 'si' # shift in
}
# 11 : 'vt', # vertical tab
# 12 : 'ff', # form feed
# 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',
# Character set escape sequences, with "("
CONQUE_ESCAPE_CHARSET = {
'A': 'uk',
'B': 'us',
'0': 'graphics'
}
# 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',
CONQUE_GRAPHICS_SET = [
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002A, 0x2192, 0x2190, 0x2191, 0x2193, 0x002F,
0x2588, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x00A0,
0x25C6, 0x2592, 0x2409, 0x240C, 0x240D, 0x240A, 0x00B0, 0x00B1,
0x2591, 0x240B, 0x2518, 0x2510, 0x250C, 0x2514, 0x253C, 0xF800,
0xF801, 0x2500, 0xF803, 0xF804, 0x251C, 0x2524, 0x2534, 0x252C,
0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00B7, 0x007F,
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
]
# 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("(\x1b\[?\??#?[0-9;]*[a-zA-Z0-9@=>]|\x1b\][0-9];.*?\x07|[\x01-\x0f]|\x1b\([AB0])")
CONQUE_SEQ_REGEX_CTL = re.compile("^[\x01-\x0f]$")
CONQUE_SEQ_REGEX_CSI = re.compile("^\x1b\[")
CONQUE_SEQ_REGEX_TITLE = re.compile("^\x1b\]")
CONQUE_SEQ_REGEX_HASH = re.compile("^\x1b#")
CONQUE_SEQ_REGEX_ESC = re.compile("^\x1b.$")
CONQUE_SEQ_REGEX_CHAR = re.compile("^\x1b[()]")
# match table output
CONQUE_TABLE_OUTPUT = re.compile("^\s*\|\s.*\s\|\s*$|^\s*\+[=+-]+\+\s*$")
# basic terminal colors
CONQUE_COLOR_SEQUENCE = (
'000', '009', '090', '099', '900', '909', '990', '999',
'000', '00f', '0f0', '0ff', 'f00', 'f0f', 'ff0', 'fff'
)
# Windows subprocess constants
# shared memory size
CONQUE_SOLE_BUFFER_LENGTH = 1000
CONQUE_SOLE_INPUT_SIZE = 1000
CONQUE_SOLE_STATS_SIZE = 1000
CONQUE_SOLE_COMMANDS_SIZE = 255
CONQUE_SOLE_RESCROLL_SIZE = 255
CONQUE_SOLE_RESIZE_SIZE = 255
# interval of screen redraw
# larger number means less frequent
CONQUE_SOLE_SCREEN_REDRAW = 50
# interval of full buffer redraw
# larger number means less frequent
CONQUE_SOLE_BUFFER_REDRAW = 500
# interval of full output bucket replacement
# larger number means less frequent, 1 = every time
CONQUE_SOLE_MEM_REDRAW = 1000
# maximum number of lines with terminal colors
# ignored if g:ConqueTerm_Color = 2
CONQUE_MAX_SYNTAX_LINES = 200
# windows input splitting on special keys
CONQUE_WIN32_REGEX_VK = re.compile("(\x1b\[[0-9;]+VK)")
# windows attribute string splitting
CONQUE_WIN32_REGEX_ATTR = re.compile("((.)\\2*)", re.DOTALL)
# special key attributes
CONQUE_VK_ATTR_CTRL_PRESSED = u('1024')

View File

@ -1,230 +0,0 @@
# FILE: autoload/conque_term/conque_screen.py
# AUTHOR: Nico Raffo <nicoraffo@gmail.com>
# WEBSITE: http://conque.googlecode.com
# MODIFIED: 2011-08-12
# VERSION: 2.2, for Vim 7.0
# LICENSE:
# Conque - Vim terminal/console emulator
# Copyright (C) 2009-__YEAR__ 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.
"""
ConqueScreen is an extention of the vim.current.buffer object
Unix terminal escape sequences usually reference line numbers relative to the
top of the visible screen. However the visible portion of the Vim buffer
representing the terminal probably doesn't start at the first line of the
buffer.
The ConqueScreen class allows access to the Vim buffer with screen-relative
line numbering. And handles a few other related tasks, such as setting the
correct cursor position.
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):
# the buffer
buffer = None
# screen and scrolling regions
screen_top = 1
# screen width
screen_width = 80
screen_height = 80
# char encoding for vim buffer
screen_encoding = 'utf-8'
def __init__(self):
""" Initialize screen size and character encoding. """
self.buffer = vim.current.buffer
# initialize screen size
self.screen_top = 1
self.screen_width = vim.current.window.width
self.screen_height = vim.current.window.height
# save screen character encoding type
self.screen_encoding = vim.eval('&fileencoding')
def __len__(self):
""" Define the len() function for ConqueScreen objects. """
return len(self.buffer)
def __getitem__(self, key):
""" Define value access for ConqueScreen objects. """
buffer_line = self.get_real_idx(key)
# if line is past buffer end, add lines to buffer
if buffer_line >= len(self.buffer):
for i in range(len(self.buffer), buffer_line + 1):
self.append(' ')
return u(self.buffer[buffer_line], 'utf-8')
def __setitem__(self, key, value):
""" Define value assignments for ConqueScreen objects. """
buffer_line = self.get_real_idx(key)
if CONQUE_PYTHON_VERSION == 2:
val = value.encode(self.screen_encoding)
else:
# XXX / Vim's python3 interface doesn't accept bytes object
val = str(value)
# if line is past end of screen, append
if buffer_line == len(self.buffer):
self.buffer.append(val)
else:
self.buffer[buffer_line] = val
def __delitem__(self, key):
""" Define value deletion for ConqueScreen objects. """
del self.buffer[self.screen_top + key - 2]
def append(self, value):
""" Define value appending for ConqueScreen objects. """
if len(self.buffer) > self.screen_top + self.screen_height - 1:
self.buffer[len(self.buffer) - 1] = value
else:
self.buffer.append(value)
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):
""" Define value insertion for ConqueScreen objects. """
l = self.screen_top + line - 2
self.buffer.append(value, l)
def get_top(self):
""" Get the Vim line number representing the top of the visible terminal. """
return self.screen_top
def get_real_idx(self, line):
""" Get the zero index Vim line number corresponding to the provided screen line. """
return (self.screen_top + line - 2)
def get_buffer_line(self, line):
""" Get the Vim line number corresponding to the provided screen line. """
return (self.screen_top + line - 1)
def set_screen_width(self, width):
""" Set the screen width. """
self.screen_width = width
def clear(self):
""" Clear the screen. Does not clear the buffer, just scrolls down past all text. """
self.screen_width = width
self.buffer.append(' ')
vim.command('normal! Gzt')
self.screen_top = len(self.buffer)
def set_cursor(self, line, column):
""" Set cursor position. """
# figure out line
buffer_line = self.screen_top + line - 1
if buffer_line > len(self.buffer):
for l in range(len(self.buffer) - 1, buffer_line):
self.buffer.append('')
# figure out column
real_column = column
if len(self.buffer[buffer_line - 1]) < real_column:
self.buffer[buffer_line - 1] = self.buffer[buffer_line - 1] + ' ' * (real_column - len(self.buffer[buffer_line - 1]))
if not CONQUE_FAST_MODE:
# set cursor at byte index of real_column'th character
vim.command('call cursor(' + str(buffer_line) + ', byteidx(getline(' + str(buffer_line) + '), ' + str(real_column) + '))')
else:
# old version
# python version is occasionally grumpy
try:
vim.current.window.cursor = (buffer_line, real_column - 1)
except:
vim.command('call cursor(' + str(buffer_line) + ', ' + str(real_column) + ')')
def reset_size(self, line):
""" Change screen size """
# save cursor line number
buffer_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
# align bottom of buffer to bottom of screen
vim.command('normal! ' + str(self.screen_height) + 'kG')
# return new relative line number
return (buffer_line - self.screen_top)
def align(self):
""" align bottom of buffer to bottom of screen """
vim.command('normal! ' + str(self.screen_height) + 'kG')

View File

@ -1,458 +0,0 @@
# FILE: autoload/conque_term/conque_sole.py
# AUTHOR: Nico Raffo <nicoraffo@gmail.com>
# WEBSITE: http://conque.googlecode.com
# MODIFIED: 2011-08-12
# VERSION: 2.2, for Vim 7.0
# LICENSE:
# Conque - Vim terminal/console emulator
# Copyright (C) 2009-__YEAR__ 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.
"""
Windows Console Emulator
This is the main interface to the Windows emulator. It reads new output from the background console
and updates the Vim buffer.
"""
import vim
class ConqueSole(Conque):
window_top = None
window_bottom = None
color_cache = {}
attribute_cache = {}
color_mode = None
color_conceals = {}
buffer = None
encoding = None
# counters for periodic rendering
buffer_redraw_ct = 1
screen_redraw_ct = 1
# line offset, shifts output down
offset = 0
def open(self):
""" Start command and initialize this instance
Arguments:
command - Command string, e.g. "Powershell.exe"
options - Dictionary of config options
python_exe - Path to the python.exe executable. Usually C:\PythonXX\python.exe
communicator_py - Path to subprocess controller script in user's vimfiles directory
"""
# get arguments
command = vim.eval('command')
options = vim.eval('options')
python_exe = vim.eval('py_exe')
communicator_py = vim.eval('py_vim')
# init size
self.columns = vim.current.window.width
self.lines = vim.current.window.height
self.window_top = 0
self.window_bottom = vim.current.window.height - 1
# color mode
self.color_mode = vim.eval('g:ConqueTerm_ColorMode')
# line offset
self.offset = int(options['offset'])
# init color
self.enable_colors = options['color'] and not CONQUE_FAST_MODE
# open command
self.proc = ConqueSoleWrapper()
self.proc.open(command, self.lines, self.columns, python_exe, communicator_py, options)
self.buffer = vim.current.buffer
self.screen_encoding = vim.eval('&fileencoding')
def read(self, timeout=1, set_cursor=True, return_output=False, update_buffer=True):
""" Read from console and update Vim buffer. """
try:
stats = self.proc.get_stats()
if not stats:
return
# disable screen and buffer redraws in fast mode
if not CONQUE_FAST_MODE:
self.buffer_redraw_ct += 1
self.screen_redraw_ct += 1
update_top = 0
update_bottom = 0
lines = []
# full buffer redraw, our favorite!
#if self.buffer_redraw_ct == CONQUE_SOLE_BUFFER_REDRAW:
# self.buffer_redraw_ct = 0
# update_top = 0
# update_bottom = stats['top_offset'] + self.lines
# (lines, attributes) = self.proc.read(update_top, update_bottom)
# if return_output:
# output = self.get_new_output(lines, update_top, stats)
# if update_buffer:
# for i in range(update_top, update_bottom + 1):
# if CONQUE_FAST_MODE:
# self.plain_text(i, lines[i], None, stats)
# else:
# self.plain_text(i, lines[i], attributes[i], stats)
# full screen redraw
if stats['cursor_y'] + 1 != self.l or stats['top_offset'] != self.window_top or self.screen_redraw_ct >= CONQUE_SOLE_SCREEN_REDRAW:
self.screen_redraw_ct = 0
update_top = self.window_top
update_bottom = max([stats['top_offset'] + self.lines + 1, stats['cursor_y']])
(lines, attributes) = self.proc.read(update_top, update_bottom - update_top + 1)
if return_output:
output = self.get_new_output(lines, update_top, stats)
if update_buffer:
for i in range(update_top, update_bottom + 1):
if CONQUE_FAST_MODE:
self.plain_text(i, lines[i - update_top], None, stats)
else:
self.plain_text(i, lines[i - update_top], attributes[i - update_top], stats)
# single line redraw
else:
update_top = stats['cursor_y']
(lines, attributes) = self.proc.read(update_top, 1)
if return_output:
output = self.get_new_output(lines, update_top, stats)
if update_buffer:
if lines[0].rstrip() != u(self.buffer[update_top].rstrip()):
if CONQUE_FAST_MODE:
self.plain_text(update_top, lines[0], None, stats)
else:
self.plain_text(update_top, lines[0], attributes[0], stats)
# reset current position
self.window_top = stats['top_offset']
self.l = stats['cursor_y'] + 1
self.c = stats['cursor_x'] + 1
# reposition cursor if this seems plausible
if set_cursor:
self.set_cursor(self.l, self.c)
if return_output:
return output
except:
pass
def get_new_output(self, lines, update_top, stats):
""" Calculate the "new" output from this read. Fake but useful """
if not (stats['cursor_y'] + 1 > self.l or (stats['cursor_y'] + 1 == self.l and stats['cursor_x'] + 1 > self.c)):
return ""
try:
num_to_return = stats['cursor_y'] - self.l + 2
lines = lines[self.l - update_top - 1:]
new_output = []
# first line
new_output.append(lines[0][self.c - 1:].rstrip())
# the rest
for i in range(1, num_to_return):
new_output.append(lines[i].rstrip())
except:
pass
return "\n".join(new_output)
def plain_text(self, line_nr, text, attributes, stats):
""" Write plain text to Vim buffer. """
# handle line offset
line_nr += self.offset
self.l = line_nr + 1
# remove trailing whitespace
text = text.rstrip()
# if we're using concealed text for color, then s- is weird
if self.color_mode == 'conceal':
text = self.add_conceal_color(text, attributes, stats, line_nr)
# deal with character encoding
if CONQUE_PYTHON_VERSION == 2:
val = text.encode(self.screen_encoding)
else:
# XXX / Vim's python3 interface doesn't accept bytes object
val = str(text)
# update vim buffer
if len(self.buffer) <= line_nr:
self.buffer.append(val)
else:
self.buffer[line_nr] = val
if self.enable_colors and not self.color_mode == 'conceal' and line_nr > self.l - CONQUE_MAX_SYNTAX_LINES:
relevant = attributes[0:len(text)]
if line_nr not in self.attribute_cache or self.attribute_cache[line_nr] != relevant:
self.do_color(attributes=relevant, stats=stats)
self.attribute_cache[line_nr] = relevant
def add_conceal_color(self, text, attributes, stats, line_nr):
""" Add 'conceal' color strings to output text """
# stop here if coloration is disabled
if not self.enable_colors:
return text
# if no colors for this line, clear everything out
if len(attributes) == 0 or attributes == u(chr(stats['default_attribute'])) * len(attributes):
return text
new_text = ''
self.color_conceals[line_nr] = []
attribute_chunks = CONQUE_WIN32_REGEX_ATTR.findall(attributes)
offset = 0
ends = []
for attr in attribute_chunks:
attr_num = ord(attr[1])
ends = []
if attr_num != stats['default_attribute']:
color = self.translate_color(attr_num)
new_text += chr(27) + 'sf' + color['fg_code'] + ';'
ends.append(chr(27) + 'ef' + color['fg_code'] + ';')
self.color_conceals[line_nr].append(offset)
if attr_num > 15:
new_text += chr(27) + 'sb' + color['bg_code'] + ';'
ends.append(chr(27) + 'eb' + color['bg_code'] + ';')
self.color_conceals[line_nr].append(offset)
new_text += text[offset:offset + len(attr[0])]
# close color regions
ends.reverse()
for i in range(0, len(ends)):
self.color_conceals[line_nr].append(len(new_text))
new_text += ends[i]
offset += len(attr[0])
return new_text
def do_color(self, start=0, end=0, attributes='', stats=None):
""" Convert Windows console attributes into Vim syntax highlighting """
# if no colors for this line, clear everything out
if len(attributes) == 0 or attributes == u(chr(stats['default_attribute'])) * len(attributes):
self.color_changes = {}
self.apply_color(1, len(attributes), self.l)
return
attribute_chunks = CONQUE_WIN32_REGEX_ATTR.findall(attributes)
offset = 0
for attr in attribute_chunks:
attr_num = ord(attr[1])
if attr_num != stats['default_attribute']:
self.color_changes = self.translate_color(attr_num)
self.apply_color(offset + 1, offset + len(attr[0]) + 1, self.l)
offset += len(attr[0])
def translate_color(self, attr):
""" Convert Windows console attributes into RGB colors """
# check for cached color
if attr in self.color_cache:
return self.color_cache[attr]
# convert attribute integer to bit string
bit_str = bin(attr)
bit_str = bit_str.replace('0b', '')
# slice foreground and background portions of bit string
fg = bit_str[-4:].rjust(4, '0')
bg = bit_str[-8:-4].rjust(4, '0')
# ok, first create foreground #rbg
red = int(fg[1]) * 204 + int(fg[0]) * int(fg[1]) * 51
green = int(fg[2]) * 204 + int(fg[0]) * int(fg[2]) * 51
blue = int(fg[3]) * 204 + int(fg[0]) * int(fg[3]) * 51
fg_str = "#%02x%02x%02x" % (red, green, blue)
fg_code = "%02x%02x%02x" % (red, green, blue)
fg_code = fg_code[0] + fg_code[2] + fg_code[4]
# ok, first create foreground #rbg
red = int(bg[1]) * 204 + int(bg[0]) * int(bg[1]) * 51
green = int(bg[2]) * 204 + int(bg[0]) * int(bg[2]) * 51
blue = int(bg[3]) * 204 + int(bg[0]) * int(bg[3]) * 51
bg_str = "#%02x%02x%02x" % (red, green, blue)
bg_code = "%02x%02x%02x" % (red, green, blue)
bg_code = bg_code[0] + bg_code[2] + bg_code[4]
# build value for color_changes
color = {'guifg': fg_str, 'guibg': bg_str}
if self.color_mode == 'conceal':
color['fg_code'] = fg_code
color['bg_code'] = bg_code
self.color_cache[attr] = color
return color
def write_vk(self, vk_code):
""" write virtual key code to shared memory using proprietary escape seq """
self.proc.write_vk(vk_code)
def update_window_size(self):
""" Resize underlying console if Vim buffer size has changed """
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
self.proc.window_resize(vim.current.window.height, vim.current.window.width)
def set_cursor(self, line, column):
""" Update cursor position in Vim buffer """
# handle offset
line += self.offset
# shift cursor position to handle concealed text
if self.enable_colors and self.color_mode == 'conceal':
if line - 1 in self.color_conceals:
for c in self.color_conceals[line - 1]:
if c < column:
column += 7
else:
break
# figure out line
buffer_line = line
if buffer_line > len(self.buffer):
for l in range(len(self.buffer) - 1, buffer_line):
self.buffer.append('')
# figure out column
real_column = column
if len(self.buffer[buffer_line - 1]) < real_column:
self.buffer[buffer_line - 1] = self.buffer[buffer_line - 1] + ' ' * (real_column - len(self.buffer[buffer_line - 1]))
# python version is occasionally grumpy
try:
vim.current.window.cursor = (buffer_line, real_column - 1)
except:
vim.command('call cursor(' + str(buffer_line) + ', ' + str(real_column) + ')')
def idle(self):
""" go into idle mode """
self.proc.idle()
def resume(self):
""" resume from idle mode """
self.proc.resume()
def close(self):
""" end console subprocess """
self.proc.close()
def abort(self):
""" end subprocess forcefully """
self.proc.close()
def get_buffer_line(self, line):
""" get buffer line """
return line
# vim:foldmethod=marker

View File

@ -1,183 +0,0 @@
# FILE: autoload/conque_term/conque_sole_communicator.py
# AUTHOR: Nico Raffo <nicoraffo@gmail.com>
# WEBSITE: http://conque.googlecode.com
# MODIFIED: 2011-08-12
# VERSION: 2.2, for Vim 7.0
# LICENSE:
# Conque - Vim terminal/console emulator
# Copyright (C) 2009-__YEAR__ 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.
"""
ConqueSoleCommunicator
This script will create a new Windows console and start the requested program
inside of it. This process is launched independently from the parent Vim
program, so it has no access to the vim module.
The main loop in this script reads data from the console and syncs it onto
blocks of memory shared with the Vim process. In this way the Vim process
and this script can communicate with each other.
"""
import time
import sys
from conque_globals import *
from conque_win32_util import *
from conque_sole_subprocess import *
from conque_sole_shared_memory import *
##############################################################
# only run if this file was run directly
if __name__ == '__main__':
# attempt to catch ALL exceptions to fend of zombies
try:
# simple arg validation
if len(sys.argv) < 5:
exit()
# maximum time this thing reads. 0 means no limit. Only for testing.
max_loops = 0
# read interval, in seconds
sleep_time = 0.01
# idle read interval, in seconds
idle_sleep_time = 0.10
# are we idled?
is_idle = False
# mem key
mem_key = sys.argv[1]
# console width
console_width = int(sys.argv[2])
# console height
console_height = int(sys.argv[3])
# code page
code_page = int(sys.argv[4])
# code page
fast_mode = int(sys.argv[5])
# the actual subprocess to run
cmd_line = " ".join(sys.argv[6:])
# width and height
options = {'LINES': console_height, 'COLUMNS': console_width, 'CODE_PAGE': code_page, 'FAST_MODE': fast_mode}
# set initial idle status
shm_command = ConqueSoleSharedMemory(CONQUE_SOLE_COMMANDS_SIZE, 'command', mem_key, serialize=True)
shm_command.create('write')
cmd = shm_command.read()
if cmd:
if cmd['cmd'] == 'idle':
is_idle = True
shm_command.clear()
##############################################################
# Create the subprocess
proc = ConqueSoleSubprocess()
res = proc.open(cmd_line, mem_key, options)
if not res:
exit()
##############################################################
# main loop!
loops = 0
while True:
# check for idle/resume
if is_idle or loops % 25 == 0:
# check process health
if not proc.is_alive():
proc.close()
break
# check for change in buffer focus
cmd = shm_command.read()
if cmd:
if cmd['cmd'] == 'idle':
is_idle = True
shm_command.clear()
elif cmd['cmd'] == 'resume':
is_idle = False
shm_command.clear()
# sleep between loops if moderation is requested
if sleep_time > 0:
if is_idle:
time.sleep(idle_sleep_time)
else:
time.sleep(sleep_time)
# write, read, etc
proc.write()
proc.read()
# increment loops, and exit if max has been reached
loops += 1
if max_loops and loops >= max_loops:
break
##############################################################
# all done!
proc.close()
# if an exception was thrown, croak
except:
proc.close()
# vim:foldmethod=marker

View File

@ -1,210 +0,0 @@
# FILE: autoload/conque_term/conque_sole_shared_memory.py
# AUTHOR: Nico Raffo <nicoraffo@gmail.com>
# WEBSITE: http://conque.googlecode.com
# MODIFIED: 2011-08-12
# VERSION: 2.2, for Vim 7.0
# LICENSE:
# Conque - Vim terminal/console emulator
# Copyright (C) 2009-__YEAR__ 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.
"""
Wrapper class for shared memory between Windows python processes
Adds a small amount of functionality to the standard mmap module.
"""
import mmap
import sys
# PYTHON VERSION
CONQUE_PYTHON_VERSION = sys.version_info[0]
if CONQUE_PYTHON_VERSION == 2:
import cPickle as pickle
else:
import pickle
class ConqueSoleSharedMemory():
# is the data being stored not fixed length
fixed_length = False
# maximum number of bytes per character, for fixed width blocks
char_width = 1
# fill memory with this character when clearing and fixed_length is true
FILL_CHAR = None
# serialize and unserialize data automatically
serialize = False
# size of shared memory, in bytes / chars
mem_size = None
# size of shared memory, in bytes / chars
mem_type = None
# unique key, so multiple console instances are possible
mem_key = None
# mmap instance
shm = None
# character encoding, dammit
encoding = 'utf-8'
# pickle terminator
TERMINATOR = None
def __init__(self, mem_size, mem_type, mem_key, fixed_length=False, fill_char=' ', serialize=False, encoding='utf-8'):
""" Initialize new shared memory block instance
Arguments:
mem_size -- Memory size in characters, depends on encoding argument to calcuate byte size
mem_type -- Label to identify what will be stored
mem_key -- Unique, probably random key to identify this block
fixed_length -- If set to true, assume the data stored will always fill the memory size
fill_char -- Initialize memory block with this character, only really helpful with fixed_length blocks
serialize -- Automatically serialize data passed to write. Allows storing non-byte data
encoding -- Character encoding to use when storing character data
"""
self.mem_size = mem_size
self.mem_type = mem_type
self.mem_key = mem_key
self.fixed_length = fixed_length
self.fill_char = fill_char
self.serialize = serialize
self.encoding = encoding
self.TERMINATOR = str(chr(0)).encode(self.encoding)
if CONQUE_PYTHON_VERSION == 3:
self.FILL_CHAR = fill_char
else:
self.FILL_CHAR = unicode(fill_char)
if fixed_length and encoding == 'utf-8':
self.char_width = 4
def create(self, access='write'):
""" Create a new block of shared memory using the mmap module. """
if access == 'write':
mmap_access = mmap.ACCESS_WRITE
else:
mmap_access = mmap.ACCESS_READ
name = "conque_%s_%s" % (self.mem_type, self.mem_key)
self.shm = mmap.mmap(0, self.mem_size * self.char_width, name, mmap_access)
if not self.shm:
return False
else:
return True
def read(self, chars=1, start=0):
""" Read data from shared memory.
If this is a fixed length block, read 'chars' characters from memory.
Otherwise read up until the TERMINATOR character (null byte).
If this memory is serialized, unserialize it automatically.
"""
# go to start position
self.shm.seek(start * self.char_width)
if self.fixed_length:
chars = chars * self.char_width
else:
chars = self.shm.find(self.TERMINATOR)
if chars == 0:
return ''
shm_str = self.shm.read(chars)
# return unpickled byte object
if self.serialize:
return pickle.loads(shm_str)
# decode byes in python 3
if CONQUE_PYTHON_VERSION == 3:
return str(shm_str, self.encoding)
# encoding
if self.encoding != 'ascii':
shm_str = unicode(shm_str, self.encoding)
return shm_str
def write(self, text, start=0):
""" Write data to memory.
If memory is fixed length, simply write the 'text' characters at 'start' position.
Otherwise write 'text' characters and append a null character.
If memory is serializable, do so first.
"""
# simple scenario, let pickle create bytes
if self.serialize:
if CONQUE_PYTHON_VERSION == 3:
tb = pickle.dumps(text, 0)
else:
tb = pickle.dumps(text, 0).encode(self.encoding)
else:
tb = text.encode(self.encoding, 'replace')
# write to memory
self.shm.seek(start * self.char_width)
if self.fixed_length:
self.shm.write(tb)
else:
self.shm.write(tb + self.TERMINATOR)
def clear(self, start=0):
""" Clear memory block using self.fill_char. """
self.shm.seek(start)
if self.fixed_length:
self.shm.write(str(self.fill_char * self.mem_size * self.char_width).encode(self.encoding))
else:
self.shm.write(self.TERMINATOR)
def close(self):
""" Close/destroy memory block. """
self.shm.close()

View File

@ -1,762 +0,0 @@
# FILE: autoload/conque_term/conque_sole_subprocess.py
# AUTHOR: Nico Raffo <nicoraffo@gmail.com>
# WEBSITE: http://conque.googlecode.com
# MODIFIED: 2011-08-12
# VERSION: 2.2, for Vim 7.0
# LICENSE:
# Conque - Vim terminal/console emulator
# Copyright (C) 2009-__YEAR__ 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.
""" ConqueSoleSubprocess
Creates a new subprocess with it's own (hidden) console window.
Mirrors console window text onto a block of shared memory (mmap), along with
text attribute data. Also handles translation of text input into the format
Windows console expects.
Sample Usage:
sh = ConqueSoleSubprocess()
sh.open("cmd.exe", "unique_str")
shm_in = ConqueSoleSharedMemory(mem_key = "unique_str", mem_type = "input", ...)
shm_out = ConqueSoleSharedMemory(mem_key = "unique_str", mem_type = "output", ...)
output = shm_out.read(...)
shm_in.write("dir\r")
output = shm_out.read(...)
"""
import time
import re
import os
import ctypes
from conque_globals import *
from conque_win32_util import *
from conque_sole_shared_memory import *
class ConqueSoleSubprocess():
# subprocess handle and pid
handle = None
pid = None
# input / output handles
stdin = None
stdout = None
# size of console window
window_width = 160
window_height = 40
# max lines for the console buffer
buffer_width = 160
buffer_height = 100
# keep track of the buffer number at the top of the window
top = 0
line_offset = 0
# buffer height is CONQUE_SOLE_BUFFER_LENGTH * output_blocks
output_blocks = 1
# cursor position
cursor_line = 0
cursor_col = 0
# console data, array of lines
data = []
# console attribute data, array of array of int
attributes = []
attribute_cache = {}
# default attribute
default_attribute = 7
# shared memory objects
shm_input = None
shm_output = None
shm_attributes = None
shm_stats = None
shm_command = None
shm_rescroll = None
shm_resize = None
# are we still a valid process?
is_alive = True
# running in fast mode
fast_mode = 0
# used for periodic execution of screen and memory redrawing
screen_redraw_ct = 0
mem_redraw_ct = 0
def open(self, cmd, mem_key, options={}):
""" Create subproccess running in hidden console window. """
self.reset = True
try:
# if we're already attached to a console, then unattach
try:
ctypes.windll.kernel32.FreeConsole()
except:
pass
# set buffer height
self.buffer_height = CONQUE_SOLE_BUFFER_LENGTH
if 'LINES' in options and 'COLUMNS' in options:
self.window_width = options['COLUMNS']
self.window_height = options['LINES']
self.buffer_width = options['COLUMNS']
# fast mode
self.fast_mode = options['FAST_MODE']
# console window options
si = STARTUPINFO()
# hide window
si.dwFlags |= STARTF_USESHOWWINDOW
si.wShowWindow = SW_HIDE
#si.wShowWindow = SW_MINIMIZE
# process options
flags = NORMAL_PRIORITY_CLASS | CREATE_NEW_PROCESS_GROUP | CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_CONSOLE
# created process info
pi = PROCESS_INFORMATION()
# create the process!
res = ctypes.windll.kernel32.CreateProcessW(None, u(cmd), None, None, 0, flags, None, u('.'), ctypes.byref(si), ctypes.byref(pi))
# process info
self.pid = pi.dwProcessId
self.handle = pi.hProcess
# attach ourselves to the new console
# console is not immediately available
for i in range(10):
time.sleep(0.25)
try:
res = ctypes.windll.kernel32.AttachConsole(self.pid)
break
except:
pass
# get input / output handles
self.stdout = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
self.stdin = ctypes.windll.kernel32.GetStdHandle(STD_INPUT_HANDLE)
# set buffer size
size = COORD(self.buffer_width, self.buffer_height)
res = ctypes.windll.kernel32.SetConsoleScreenBufferSize(self.stdout, size)
# prev set size call needs to process
time.sleep(0.2)
# set window size
self.set_window_size(self.window_width, self.window_height)
# set utf-8 code page
if 'CODE_PAGE' in options and options['CODE_PAGE'] > 0:
if ctypes.windll.kernel32.IsValidCodePage(ctypes.c_uint(options['CODE_PAGE'])):
ctypes.windll.kernel32.SetConsoleCP(ctypes.c_uint(options['CODE_PAGE']))
ctypes.windll.kernel32.SetConsoleOutputCP(ctypes.c_uint(options['CODE_PAGE']))
# init shared memory
self.init_shared_memory(mem_key)
# init read buffers
self.tc = ctypes.create_unicode_buffer(self.buffer_width)
self.ac = ctypes.create_unicode_buffer(self.buffer_width)
return True
except:
return False
def init_shared_memory(self, mem_key):
""" Create shared memory objects. """
self.shm_input = ConqueSoleSharedMemory(CONQUE_SOLE_INPUT_SIZE, 'input', mem_key)
self.shm_input.create('write')
self.shm_input.clear()
self.shm_output = ConqueSoleSharedMemory(self.buffer_height * self.buffer_width, 'output', mem_key, True)
self.shm_output.create('write')
self.shm_output.clear()
if not self.fast_mode:
buf_info = self.get_buffer_info()
self.shm_attributes = ConqueSoleSharedMemory(self.buffer_height * self.buffer_width, 'attributes', mem_key, True, chr(buf_info.wAttributes), encoding='latin-1')
self.shm_attributes.create('write')
self.shm_attributes.clear()
self.shm_stats = ConqueSoleSharedMemory(CONQUE_SOLE_STATS_SIZE, 'stats', mem_key, serialize=True)
self.shm_stats.create('write')
self.shm_stats.clear()
self.shm_command = ConqueSoleSharedMemory(CONQUE_SOLE_COMMANDS_SIZE, 'command', mem_key, serialize=True)
self.shm_command.create('write')
self.shm_command.clear()
self.shm_resize = ConqueSoleSharedMemory(CONQUE_SOLE_RESIZE_SIZE, 'resize', mem_key, serialize=True)
self.shm_resize.create('write')
self.shm_resize.clear()
self.shm_rescroll = ConqueSoleSharedMemory(CONQUE_SOLE_RESCROLL_SIZE, 'rescroll', mem_key, serialize=True)
self.shm_rescroll.create('write')
self.shm_rescroll.clear()
return True
def check_commands(self):
""" Check for and process commands from Vim. """
cmd = self.shm_command.read()
if cmd:
# shut it all down
if cmd['cmd'] == 'close':
# clear command
self.shm_command.clear()
self.close()
return
cmd = self.shm_resize.read()
if cmd:
# clear command
self.shm_resize.clear()
# resize console
if cmd['cmd'] == 'resize':
# only change buffer width if it's larger
if cmd['data']['width'] > self.buffer_width:
self.buffer_width = cmd['data']['width']
# always change console width and height
self.window_width = cmd['data']['width']
self.window_height = cmd['data']['height']
# reset the console
buf_info = self.get_buffer_info()
self.reset_console(buf_info, add_block=False)
def read(self):
""" Read from windows console and update shared memory blocks. """
# no point really
if self.screen_redraw_ct == 0 and not self.is_alive():
stats = {'top_offset': 0, 'default_attribute': 0, 'cursor_x': 0, 'cursor_y': self.cursor_line, 'is_alive': 0}
self.shm_stats.write(stats)
return
# check for commands
self.check_commands()
# get cursor position
buf_info = self.get_buffer_info()
curs_line = buf_info.dwCursorPosition.Y
curs_col = buf_info.dwCursorPosition.X
# set update range
if curs_line != self.cursor_line or self.top != buf_info.srWindow.Top or self.screen_redraw_ct == CONQUE_SOLE_SCREEN_REDRAW:
self.screen_redraw_ct = 0
read_start = self.top
read_end = max([buf_info.srWindow.Bottom + 1, curs_line + 1])
else:
read_start = curs_line
read_end = curs_line + 1
# vars used in for loop
coord = COORD(0, 0)
chars_read = ctypes.c_int(0)
# read new data
for i in range(read_start, read_end):
coord.Y = i
res = ctypes.windll.kernel32.ReadConsoleOutputCharacterW(self.stdout, ctypes.byref(self.tc), self.buffer_width, coord, ctypes.byref(chars_read))
if not self.fast_mode:
ctypes.windll.kernel32.ReadConsoleOutputAttribute(self.stdout, ctypes.byref(self.ac), self.buffer_width, coord, ctypes.byref(chars_read))
t = self.tc.value
if not self.fast_mode:
a = self.ac.value
# add data
if i >= len(self.data):
for j in range(len(self.data), i + 1):
self.data.append('')
if not self.fast_mode:
self.attributes.append('')
self.data[i] = t
if not self.fast_mode:
self.attributes[i] = a
#for i in range(0, len(t)):
# write new output to shared memory
try:
if self.mem_redraw_ct == CONQUE_SOLE_MEM_REDRAW:
self.mem_redraw_ct = 0
for i in range(0, len(self.data)):
self.shm_output.write(text=self.data[i], start=self.buffer_width * i)
if not self.fast_mode:
self.shm_attributes.write(text=self.attributes[i], start=self.buffer_width * i)
else:
for i in range(read_start, read_end):
self.shm_output.write(text=self.data[i], start=self.buffer_width * i)
if not self.fast_mode:
self.shm_attributes.write(text=self.attributes[i], start=self.buffer_width * i)
#self.shm_output.write(text=''.join(self.data[read_start:read_end]), start=read_start * self.buffer_width)
#self.shm_attributes.write(text=''.join(self.attributes[read_start:read_end]), start=read_start * self.buffer_width)
# write cursor position to shared memory
stats = {'top_offset': buf_info.srWindow.Top, 'default_attribute': buf_info.wAttributes, 'cursor_x': curs_col, 'cursor_y': curs_line, 'is_alive': 1}
self.shm_stats.write(stats)
# adjust screen position
self.top = buf_info.srWindow.Top
self.cursor_line = curs_line
# check for reset
if curs_line > buf_info.dwSize.Y - 200:
self.reset_console(buf_info)
except:
pass
# increment redraw counters
self.screen_redraw_ct += 1
self.mem_redraw_ct += 1
return None
def reset_console(self, buf_info, add_block=True):
""" Extend the height of the current console if the cursor postion gets within 200 lines of the current size. """
# sometimes we just want to change the buffer width,
# in which case no need to add another block
if add_block:
self.output_blocks += 1
# close down old memory
self.shm_output.close()
self.shm_output = None
if not self.fast_mode:
self.shm_attributes.close()
self.shm_attributes = None
# new shared memory key
mem_key = 'mk' + str(time.time())
# reallocate memory
self.shm_output = ConqueSoleSharedMemory(self.buffer_height * self.buffer_width * self.output_blocks, 'output', mem_key, True)
self.shm_output.create('write')
self.shm_output.clear()
# backfill data
if len(self.data[0]) < self.buffer_width:
for i in range(0, len(self.data)):
self.data[i] = self.data[i] + ' ' * (self.buffer_width - len(self.data[i]))
self.shm_output.write(''.join(self.data))
if not self.fast_mode:
self.shm_attributes = ConqueSoleSharedMemory(self.buffer_height * self.buffer_width * self.output_blocks, 'attributes', mem_key, True, chr(buf_info.wAttributes), encoding='latin-1')
self.shm_attributes.create('write')
self.shm_attributes.clear()
# backfill attributes
if len(self.attributes[0]) < self.buffer_width:
for i in range(0, len(self.attributes)):
self.attributes[i] = self.attributes[i] + chr(buf_info.wAttributes) * (self.buffer_width - len(self.attributes[i]))
if not self.fast_mode:
self.shm_attributes.write(''.join(self.attributes))
# notify wrapper of new output block
self.shm_rescroll.write({'cmd': 'new_output', 'data': {'blocks': self.output_blocks, 'mem_key': mem_key}})
# set buffer size
size = COORD(X=self.buffer_width, Y=self.buffer_height * self.output_blocks)
res = ctypes.windll.kernel32.SetConsoleScreenBufferSize(self.stdout, size)
# prev set size call needs to process
time.sleep(0.2)
# set window size
self.set_window_size(self.window_width, self.window_height)
# init read buffers
self.tc = ctypes.create_unicode_buffer(self.buffer_width)
self.ac = ctypes.create_unicode_buffer(self.buffer_width)
def write(self):
""" Write text to console.
This function just parses out special sequences for special key events
and passes on the text to the plain or virtual key functions.
"""
# get input from shared mem
text = self.shm_input.read()
# nothing to do here
if text == u(''):
return
# clear input queue
self.shm_input.clear()
# split on VK codes
chunks = CONQUE_WIN32_REGEX_VK.split(text)
# if len() is one then no vks
if len(chunks) == 1:
self.write_plain(text)
return
# loop over chunks and delegate
for t in chunks:
if t == '':
continue
if CONQUE_WIN32_REGEX_VK.match(t):
self.write_vk(t[2:-2])
else:
self.write_plain(t)
def write_plain(self, text):
""" Write simple text to subprocess. """
li = INPUT_RECORD * len(text)
list_input = li()
for i in range(0, len(text)):
# create keyboard input
ke = KEY_EVENT_RECORD()
ke.bKeyDown = ctypes.c_byte(1)
ke.wRepeatCount = ctypes.c_short(1)
cnum = ord(text[i])
ke.wVirtualKeyCode = ctypes.windll.user32.VkKeyScanW(cnum)
ke.wVirtualScanCode = ctypes.c_short(ctypes.windll.user32.MapVirtualKeyW(int(cnum), 0))
if cnum > 31:
ke.uChar.UnicodeChar = uchr(cnum)
elif cnum == 3:
ctypes.windll.kernel32.GenerateConsoleCtrlEvent(0, self.pid)
ke.uChar.UnicodeChar = uchr(cnum)
ke.wVirtualKeyCode = ctypes.windll.user32.VkKeyScanW(cnum + 96)
ke.dwControlKeyState |= LEFT_CTRL_PRESSED
else:
ke.uChar.UnicodeChar = uchr(cnum)
if cnum in CONQUE_WINDOWS_VK_INV:
ke.wVirtualKeyCode = cnum
else:
ke.wVirtualKeyCode = ctypes.windll.user32.VkKeyScanW(cnum + 96)
ke.dwControlKeyState |= LEFT_CTRL_PRESSED
kc = INPUT_RECORD(KEY_EVENT)
kc.Event.KeyEvent = ke
list_input[i] = kc
# write input array
events_written = ctypes.c_int()
res = ctypes.windll.kernel32.WriteConsoleInputW(self.stdin, list_input, len(text), ctypes.byref(events_written))
def write_vk(self, vk_code):
""" Write special characters to console subprocess. """
code = None
ctrl_pressed = False
# this could be made more generic when more attributes
# other than ctrl_pressed are available
vk_attributes = vk_code.split(';')
for attr in vk_attributes:
if attr == CONQUE_VK_ATTR_CTRL_PRESSED:
ctrl_pressed = True
else:
code = attr
li = INPUT_RECORD * 1
# create keyboard input
ke = KEY_EVENT_RECORD()
ke.uChar.UnicodeChar = uchr(0)
ke.wVirtualKeyCode = ctypes.c_short(int(code))
ke.wVirtualScanCode = ctypes.c_short(ctypes.windll.user32.MapVirtualKeyW(int(code), 0))
ke.bKeyDown = ctypes.c_byte(1)
ke.wRepeatCount = ctypes.c_short(1)
# set enhanced key mode for arrow keys
if code in CONQUE_WINDOWS_VK_ENHANCED:
ke.dwControlKeyState |= ENHANCED_KEY
if ctrl_pressed:
ke.dwControlKeyState |= LEFT_CTRL_PRESSED
kc = INPUT_RECORD(KEY_EVENT)
kc.Event.KeyEvent = ke
list_input = li(kc)
# write input array
events_written = ctypes.c_int()
res = ctypes.windll.kernel32.WriteConsoleInputW(self.stdin, list_input, 1, ctypes.byref(events_written))
def close(self):
""" Close all running subproccesses """
# record status
self.is_alive = False
try:
stats = {'top_offset': 0, 'default_attribute': 0, 'cursor_x': 0, 'cursor_y': self.cursor_line, 'is_alive': 0}
self.shm_stats.write(stats)
except:
pass
pid_list = (ctypes.c_int * 10)()
num = ctypes.windll.kernel32.GetConsoleProcessList(pid_list, 10)
current_pid = os.getpid()
# kill subprocess pids
for pid in pid_list[0:num]:
if not pid:
break
# kill current pid last
if pid == current_pid:
continue
try:
self.close_pid(pid)
except:
pass
# kill this process
try:
self.close_pid(current_pid)
except:
pass
def close_pid(self, pid):
""" Terminate a single process. """
handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, 0, pid)
ctypes.windll.kernel32.TerminateProcess(handle, -1)
ctypes.windll.kernel32.CloseHandle(handle)
def is_alive(self):
""" Check process health. """
status = ctypes.windll.kernel32.WaitForSingleObject(self.handle, 1)
if status == 0:
self.is_alive = False
return self.is_alive
def get_screen_text(self):
""" Return screen data as string. """
return "\n".join(self.data)
def set_window_size(self, width, height):
""" Change Windows console size. """
# get current window size object
window_size = SMALL_RECT(0, 0, 0, 0)
# buffer info has maximum window size data
buf_info = self.get_buffer_info()
# set top left corner
window_size.Top = 0
window_size.Left = 0
# set bottom right corner
if buf_info.dwMaximumWindowSize.X < width:
window_size.Right = buf_info.dwMaximumWindowSize.X - 1
else:
window_size.Right = width - 1
if buf_info.dwMaximumWindowSize.Y < height:
window_size.Bottom = buf_info.dwMaximumWindowSize.Y - 1
else:
window_size.Bottom = height - 1
# set the window size!
res = ctypes.windll.kernel32.SetConsoleWindowInfo(self.stdout, ctypes.c_bool(True), ctypes.byref(window_size))
# reread buffer info to get final console max lines
buf_info = self.get_buffer_info()
self.window_width = buf_info.srWindow.Right + 1
self.window_height = buf_info.srWindow.Bottom + 1
def get_buffer_info(self):
""" Retrieve commonly-used buffer information. """
buf_info = CONSOLE_SCREEN_BUFFER_INFO()
ctypes.windll.kernel32.GetConsoleScreenBufferInfo(self.stdout, ctypes.byref(buf_info))
return buf_info

View File

@ -1,278 +0,0 @@
# FILE: autoload/conque_term/conque_sole_wrapper.py
# AUTHOR: Nico Raffo <nicoraffo@gmail.com>
# WEBSITE: http://conque.googlecode.com
# MODIFIED: 2011-08-12
# VERSION: 2.2, for Vim 7.0
# LICENSE:
# Conque - Vim terminal/console emulator
# Copyright (C) 2009-__YEAR__ 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.
"""
ConqueSoleSubprocessWrapper
Subprocess wrapper to deal with Windows insanity. Launches console based python,
which in turn launches originally requested command. Communicates with cosole
python through shared memory objects.
"""
import ctypes
import time
class ConqueSoleWrapper():
# unique key used for shared memory block names
shm_key = ''
# process info
handle = None
pid = None
# queue input in this bucket
bucket = None
# console size
lines = 24
columns = 80
# shared memory objects
shm_input = None
shm_output = None
shm_attributes = None
shm_stats = None
shm_command = None
shm_rescroll = None
shm_resize = None
# console python process
proc = None
def open(self, cmd, lines, columns, python_exe='python.exe', communicator_py='conque_sole_communicator.py', options={}):
""" Launch python.exe subprocess which will in turn launch the user's program.
Arguments:
cmd -- The user's command to run. E.g. "Powershell.exe" or "C:\Python27\Scripts\ipython.bat"
lines, columns -- The size of the console, also the size of the Vim buffer
python.exe -- The path to the python executable, typically C:\PythonXX\python.exe
communicator_py -- The path to the subprocess controller script in the user's vimfiles directory
options -- optional configuration
"""
self.lines = lines
self.columns = columns
self.bucket = u('')
# create a shm key
self.shm_key = 'mk' + str(time.time())
# python command
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)
# console window attributes
flags = NORMAL_PRIORITY_CLASS | DETACHED_PROCESS | CREATE_UNICODE_ENVIRONMENT
si = STARTUPINFO()
pi = PROCESS_INFORMATION()
# start the stupid process already
try:
res = ctypes.windll.kernel32.CreateProcessW(None, u(cmd_line), None, None, 0, flags, None, u('.'), ctypes.byref(si), ctypes.byref(pi))
except:
raise
# handle
self.pid = pi.dwProcessId
# init shared memory objects
self.init_shared_memory(self.shm_key)
def read(self, start_line, num_lines, timeout=0):
""" Read a range of console lines from shared memory.
Returns a pair of lists containing the console text and console text attributes.
"""
# emulate timeout by sleeping timeout time
if timeout > 0:
read_timeout = float(timeout) / 1000
time.sleep(read_timeout)
output = []
attributes = []
# get output
for i in range(start_line, start_line + num_lines + 1):
output.append(self.shm_output.read(self.columns, i * self.columns))
if not CONQUE_FAST_MODE:
attributes.append(self.shm_attributes.read(self.columns, i * self.columns))
return (output, attributes)
def get_stats(self):
""" Return a dictionary with current console cursor and scrolling information. """
try:
rescroll = self.shm_rescroll.read()
if rescroll != '' and rescroll != None:
self.shm_rescroll.clear()
# close down old memory
self.shm_output.close()
self.shm_output = None
if not CONQUE_FAST_MODE:
self.shm_attributes.close()
self.shm_attributes = None
# reallocate memory
self.shm_output = ConqueSoleSharedMemory(CONQUE_SOLE_BUFFER_LENGTH * self.columns * rescroll['data']['blocks'], 'output', rescroll['data']['mem_key'], True)
self.shm_output.create('read')
if not CONQUE_FAST_MODE:
self.shm_attributes = ConqueSoleSharedMemory(CONQUE_SOLE_BUFFER_LENGTH * self.columns * rescroll['data']['blocks'], 'attributes', rescroll['data']['mem_key'], True, encoding='latin-1')
self.shm_attributes.create('read')
stats_str = self.shm_stats.read()
if stats_str != '':
self.stats = stats_str
else:
return False
except:
return False
return self.stats
def is_alive(self):
""" Get process status. """
if not self.shm_stats:
return True
stats_str = self.shm_stats.read()
if stats_str:
return (stats_str['is_alive'])
else:
return True
def write(self, text):
""" Write input to shared memory. """
self.bucket += text
istr = self.shm_input.read()
if istr == '':
self.shm_input.write(self.bucket[:500])
self.bucket = self.bucket[500:]
def write_vk(self, vk_code):
""" Write virtual key code to shared memory using proprietary escape sequences. """
seq = u("\x1b[") + u(str(vk_code)) + u("VK")
self.write(seq)
def idle(self):
""" Write idle command to shared memory block, so subprocess controller can hibernate. """
self.shm_command.write({'cmd': 'idle', 'data': {}})
def resume(self):
""" Write resume command to shared memory block, so subprocess controller can wake up. """
self.shm_command.write({'cmd': 'resume', 'data': {}})
def close(self):
""" Shut it all down. """
self.shm_command.write({'cmd': 'close', 'data': {}})
time.sleep(0.2)
def window_resize(self, lines, columns):
""" Resize console window. """
self.lines = lines
# we don't shrink buffer width
if columns > self.columns:
self.columns = columns
self.shm_resize.write({'cmd': 'resize', 'data': {'width': columns, 'height': lines}})
def init_shared_memory(self, mem_key):
""" Create shared memory objects. """
self.shm_input = ConqueSoleSharedMemory(CONQUE_SOLE_INPUT_SIZE, 'input', mem_key)
self.shm_input.create('write')
self.shm_input.clear()
self.shm_output = ConqueSoleSharedMemory(CONQUE_SOLE_BUFFER_LENGTH * self.columns, 'output', mem_key, True)
self.shm_output.create('write')
if not CONQUE_FAST_MODE:
self.shm_attributes = ConqueSoleSharedMemory(CONQUE_SOLE_BUFFER_LENGTH * self.columns, 'attributes', mem_key, True, encoding='latin-1')
self.shm_attributes.create('write')
self.shm_stats = ConqueSoleSharedMemory(CONQUE_SOLE_STATS_SIZE, 'stats', mem_key, serialize=True)
self.shm_stats.create('write')
self.shm_stats.clear()
self.shm_command = ConqueSoleSharedMemory(CONQUE_SOLE_COMMANDS_SIZE, 'command', mem_key, serialize=True)
self.shm_command.create('write')
self.shm_command.clear()
self.shm_resize = ConqueSoleSharedMemory(CONQUE_SOLE_RESIZE_SIZE, 'resize', mem_key, serialize=True)
self.shm_resize.create('write')
self.shm_resize.clear()
self.shm_rescroll = ConqueSoleSharedMemory(CONQUE_SOLE_RESCROLL_SIZE, 'rescroll', mem_key, serialize=True)
self.shm_rescroll.create('write')
self.shm_rescroll.clear()
return True
# vim:foldmethod=marker

View File

@ -1,198 +0,0 @@
# FILE: autoload/conque_term/conque_subprocess.py
# AUTHOR: Nico Raffo <nicoraffo@gmail.com>
# WEBSITE: http://conque.googlecode.com
# MODIFIED: 2011-08-12
# VERSION: 2.2, for Vim 7.0
# LICENSE:
# Conque - Vim terminal/console emulator
# Copyright (C) 2009-__YEAR__ 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.
"""
ConqueSubprocess
Create and interact with a subprocess through a pty.
Usage:
p = ConqueSubprocess()
p.open('bash', {'TERM':'vt100'})
output = p.read()
p.write('cd ~/vim' + "\r")
p.write('ls -lha' + "\r")
output += p.read(timeout = 500)
p.close()
"""
import os
import signal
import pty
import tty
import select
import fcntl
import termios
import struct
import shlex
class ConqueSubprocess:
# process id
pid = 0
# stdout+stderr file descriptor
fd = None
def open(self, command, env={}):
""" Create subprocess using forkpty() """
# parse command
command_arr = shlex.split(command)
executable = command_arr[0]
args = command_arr
# try to fork a new pty
try:
self.pid, self.fd = pty.fork()
except:
return False
# 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 tty 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
# replace this process with the subprocess
os.execvp(executable, args)
# else master, do nothing
else:
pass
def read(self, timeout=1):
""" Read from subprocess and return new output """
output = ''
read_timeout = float(timeout) / 1000
read_ct = 0
try:
# read from fd until no more output
while 1:
s_read, s_write, s_error = select.select([self.fd], [], [], read_timeout)
lines = ''
for s_fd in s_read:
try:
# increase read buffer so huge reads don't slow down
if read_ct < 10:
lines = os.read(self.fd, 32)
elif read_ct < 50:
lines = os.read(self.fd, 512)
else:
lines = os.read(self.fd, 2048)
read_ct += 1
except:
pass
output = output + lines.decode('utf-8')
if lines == '' or read_ct > 100:
break
except:
pass
return output
def write(self, input):
""" Write new input to subprocess """
try:
if CONQUE_PYTHON_VERSION == 2:
os.write(self.fd, input.encode('utf-8', 'ignore'))
else:
os.write(self.fd, bytes(input, 'utf-8'))
except:
pass
def signal(self, signum):
""" signal process """
try:
os.kill(self.pid, signum)
except:
pass
def close(self):
""" close process with sigterm signal """
self.signal(15)
def is_alive(self):
""" get process status """
p_status = True
try:
if os.waitpid(self.pid, os.WNOHANG)[0]:
p_status = False
except:
p_status = False
return p_status
def window_resize(self, lines, columns):
""" update window size in kernel, then send SIGWINCH to fg process """
try:
fcntl.ioctl(self.fd, termios.TIOCSWINSZ, struct.pack("HHHH", lines, columns, 0, 0))
os.kill(self.pid, signal.SIGWINCH)
except:
pass
# vim:foldmethod=marker

View File

@ -1,448 +0,0 @@
# FILE: autoload/conque_term/conque_win32_util.py
# AUTHOR: Nico Raffo <nicoraffo@gmail.com>
# WEBSITE: http://conque.googlecode.com
# MODIFIED: 2011-08-12
# VERSION: 2.2, for Vim 7.0
# LICENSE:
# Conque - Vim terminal/console emulator
# Copyright (C) 2009-__YEAR__ 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.
""" Python constants and structures used for ctypes interaction. """
from ctypes import *
# Constants
# create process flag constants
CREATE_BREAKAWAY_FROM_JOB = 0x01000000
CREATE_DEFAULT_ERROR_MODE = 0x04000000
CREATE_NEW_CONSOLE = 0x00000010
CREATE_NEW_PROCESS_GROUP = 0x00000200
CREATE_NO_WINDOW = 0x08000000
CREATE_PROTECTED_PROCESS = 0x00040000
CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000
CREATE_SEPARATE_WOW_VDM = 0x00000800
CREATE_SHARED_WOW_VDM = 0x00001000
CREATE_SUSPENDED = 0x00000004
CREATE_UNICODE_ENVIRONMENT = 0x00000400
DEBUG_ONLY_THIS_PROCESS = 0x00000002
DEBUG_PROCESS = 0x00000001
DETACHED_PROCESS = 0x00000008
EXTENDED_STARTUPINFO_PRESENT = 0x00080000
INHERIT_PARENT_AFFINITY = 0x00010000
# process priority constants
ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000
BELOW_NORMAL_PRIORITY_CLASS = 0x00004000
HIGH_PRIORITY_CLASS = 0x00000080
IDLE_PRIORITY_CLASS = 0x00000040
NORMAL_PRIORITY_CLASS = 0x00000020
REALTIME_PRIORITY_CLASS = 0x00000100
# startup info constants
STARTF_FORCEONFEEDBACK = 0x00000040
STARTF_FORCEOFFFEEDBACK = 0x00000080
STARTF_PREVENTPINNING = 0x00002000
STARTF_RUNFULLSCREEN = 0x00000020
STARTF_TITLEISAPPID = 0x00001000
STARTF_TITLEISLINKNAME = 0x00000800
STARTF_USECOUNTCHARS = 0x00000008
STARTF_USEFILLATTRIBUTE = 0x00000010
STARTF_USEHOTKEY = 0x00000200
STARTF_USEPOSITION = 0x00000004
STARTF_USESHOWWINDOW = 0x00000001
STARTF_USESIZE = 0x00000002
STARTF_USESTDHANDLES = 0x00000100
# show window constants
SW_FORCEMINIMIZE = 11
SW_HIDE = 0
SW_MAXIMIZE = 3
SW_MINIMIZE = 6
SW_RESTORE = 9
SW_SHOW = 5
SW_SHOWDEFAULT = 10
SW_SHOWMAXIMIZED = 3
SW_SHOWMINIMIZED = 2
SW_SHOWMINNOACTIVE = 7
SW_SHOWNA = 8
SW_SHOWNOACTIVATE = 4
SW_SHOWNORMAL = 1
# input event types
FOCUS_EVENT = 0x0010
KEY_EVENT = 0x0001
MENU_EVENT = 0x0008
MOUSE_EVENT = 0x0002
WINDOW_BUFFER_SIZE_EVENT = 0x0004
# key event modifiers
CAPSLOCK_ON = 0x0080
ENHANCED_KEY = 0x0100
LEFT_ALT_PRESSED = 0x0002
LEFT_CTRL_PRESSED = 0x0008
NUMLOCK_ON = 0x0020
RIGHT_ALT_PRESSED = 0x0001
RIGHT_CTRL_PRESSED = 0x0004
SCROLLLOCK_ON = 0x0040
SHIFT_PRESSED = 0x0010
# process access
PROCESS_CREATE_PROCESS = 0x0080
PROCESS_CREATE_THREAD = 0x0002
PROCESS_DUP_HANDLE = 0x0040
PROCESS_QUERY_INFORMATION = 0x0400
PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
PROCESS_SET_INFORMATION = 0x0200
PROCESS_SET_QUOTA = 0x0100
PROCESS_SUSPEND_RESUME = 0x0800
PROCESS_TERMINATE = 0x0001
PROCESS_VM_OPERATION = 0x0008
PROCESS_VM_READ = 0x0010
PROCESS_VM_WRITE = 0x0020
# input / output handles
STD_INPUT_HANDLE = c_ulong(-10)
STD_OUTPUT_HANDLE = c_ulong(-11)
STD_ERROR_HANDLE = c_ulong(-12)
CONQUE_WINDOWS_VK = {
'VK_LBUTTON': 0x0001,
'VK_RBUTTON': 0x0002,
'VK_CANCEL': 0x0003,
'VK_BACK': 0x0008,
'VK_TAB': 0x0009,
'VK_CLEAR': 0x000C,
'VK_RETURN': 0x0D,
'VK_SHIFT': 0x10,
'VK_CONTROL': 0x11,
'VK_MENU': 0x12,
'VK_PAUSE': 0x0013,
'VK_CAPITAL': 0x0014,
'VK_ESCAPE': 0x001B,
'VK_SPACE': 0x0020,
'VK_PRIOR': 0x0021,
'VK_NEXT': 0x0022,
'VK_END': 0x0023,
'VK_HOME': 0x0024,
'VK_LEFT': 0x0025,
'VK_UP': 0x0026,
'VK_RIGHT': 0x0027,
'VK_DOWN': 0x0028,
'VK_SELECT': 0x0029,
'VK_PRINT': 0x002A,
'VK_EXECUTE': 0x002B,
'VK_SNAPSHOT': 0x002C,
'VK_INSERT': 0x002D,
'VK_DELETE': 0x002E,
'VK_HELP': 0x002F,
'VK_0': 0x0030,
'VK_1': 0x0031,
'VK_2': 0x0032,
'VK_3': 0x0033,
'VK_4': 0x0034,
'VK_5': 0x0035,
'VK_6': 0x0036,
'VK_7': 0x0037,
'VK_8': 0x0038,
'VK_9': 0x0039,
'VK_A': 0x0041,
'VK_B': 0x0042,
'VK_C': 0x0043,
'VK_D': 0x0044,
'VK_E': 0x0045,
'VK_F': 0x0046,
'VK_G': 0x0047,
'VK_H': 0x0048,
'VK_I': 0x0049,
'VK_J': 0x004A,
'VK_K': 0x004B,
'VK_L': 0x004C,
'VK_M': 0x004D,
'VK_N': 0x004E,
'VK_O': 0x004F,
'VK_P': 0x0050,
'VK_Q': 0x0051,
'VK_R': 0x0052,
'VK_S': 0x0053,
'VK_T': 0x0054,
'VK_U': 0x0055,
'VK_V': 0x0056,
'VK_W': 0x0057,
'VK_X': 0x0058,
'VK_Y': 0x0059,
'VK_Z': 0x005A,
'VK_LWIN': 0x005B,
'VK_RWIN': 0x005C,
'VK_APPS': 0x005D,
'VK_SLEEP': 0x005F,
'VK_NUMPAD0': 0x0060,
'VK_NUMPAD1': 0x0061,
'VK_NUMPAD2': 0x0062,
'VK_NUMPAD3': 0x0063,
'VK_NUMPAD4': 0x0064,
'VK_NUMPAD5': 0x0065,
'VK_NUMPAD6': 0x0066,
'VK_NUMPAD7': 0x0067,
'VK_NUMPAD8': 0x0068,
'VK_MULTIPLY': 0x006A,
'VK_ADD': 0x006B,
'VK_SEPARATOR': 0x006C,
'VK_SUBTRACT': 0x006D,
'VK_DECIMAL': 0x006E,
'VK_DIVIDE': 0x006F,
'VK_F1': 0x0070,
'VK_F2': 0x0071,
'VK_F3': 0x0072,
'VK_F4': 0x0073,
'VK_F5': 0x0074,
'VK_F6': 0x0075,
'VK_F7': 0x0076,
'VK_F8': 0x0077,
'VK_F9': 0x0078,
'VK_F10': 0x0079,
'VK_F11': 0x007A,
'VK_F12': 0x007B,
'VK_F13': 0x007C,
'VK_F14': 0x007D,
'VK_F15': 0x007E,
'VK_F16': 0x007F,
'VK_F17': 0x0080,
'VK_F18': 0x0081,
'VK_F19': 0x0082,
'VK_F20': 0x0083,
'VK_F21': 0x0084,
'VK_F22': 0x0085,
'VK_F23': 0x0086,
'VK_F24': 0x0087,
'VK_NUMLOCK': 0x0090,
'VK_SCROLL': 0x0091,
'VK_LSHIFT': 0x00A0,
'VK_RSHIFT': 0x00A1,
'VK_LCONTROL': 0x00A2,
'VK_RCONTROL': 0x00A3,
'VK_LMENU': 0x00A4,
'VK_RMENU': 0x00A5
}
CONQUE_WINDOWS_VK_INV = dict([v, k] for k, v in CONQUE_WINDOWS_VK.items())
CONQUE_WINDOWS_VK_ENHANCED = {
str(int(CONQUE_WINDOWS_VK['VK_UP'])): 1,
str(int(CONQUE_WINDOWS_VK['VK_DOWN'])): 1,
str(int(CONQUE_WINDOWS_VK['VK_LEFT'])): 1,
str(int(CONQUE_WINDOWS_VK['VK_RIGHT'])): 1,
str(int(CONQUE_WINDOWS_VK['VK_HOME'])): 1,
str(int(CONQUE_WINDOWS_VK['VK_END'])): 1
}
# structures used for CreateProcess
# Odd types
LPBYTE = POINTER(c_ubyte)
LPTSTR = POINTER(c_char)
class STARTUPINFO(Structure):
_fields_ = [("cb", c_ulong),
("lpReserved", LPTSTR),
("lpDesktop", LPTSTR),
("lpTitle", LPTSTR),
("dwX", c_ulong),
("dwY", c_ulong),
("dwXSize", c_ulong),
("dwYSize", c_ulong),
("dwXCountChars", c_ulong),
("dwYCountChars", c_ulong),
("dwFillAttribute", c_ulong),
("dwFlags", c_ulong),
("wShowWindow", c_short),
("cbReserved2", c_short),
("lpReserved2", LPBYTE),
("hStdInput", c_void_p),
("hStdOutput", c_void_p),
("hStdError", c_void_p),]
def to_str(self):
return ''
class PROCESS_INFORMATION(Structure):
_fields_ = [("hProcess", c_void_p),
("hThread", c_void_p),
("dwProcessId", c_ulong),
("dwThreadId", c_ulong),]
def to_str(self):
return ''
class MEMORY_BASIC_INFORMATION(Structure):
_fields_ = [("BaseAddress", c_void_p),
("AllocationBase", c_void_p),
("AllocationProtect", c_ulong),
("RegionSize", c_ulong),
("State", c_ulong),
("Protect", c_ulong),
("Type", c_ulong),]
def to_str(self):
return ''
class SECURITY_ATTRIBUTES(Structure):
_fields_ = [("Length", c_ulong),
("SecDescriptor", c_void_p),
("InheritHandle", c_bool)]
def to_str(self):
return ''
class COORD(Structure):
_fields_ = [("X", c_short),
("Y", c_short)]
def to_str(self):
return ''
class SMALL_RECT(Structure):
_fields_ = [("Left", c_short),
("Top", c_short),
("Right", c_short),
("Bottom", c_short)]
def to_str(self):
return ''
class CONSOLE_SCREEN_BUFFER_INFO(Structure):
_fields_ = [("dwSize", COORD),
("dwCursorPosition", COORD),
("wAttributes", c_short),
("srWindow", SMALL_RECT),
("dwMaximumWindowSize", COORD)]
def to_str(self):
return ''
class CHAR_UNION(Union):
_fields_ = [("UnicodeChar", c_wchar),
("AsciiChar", c_char)]
def to_str(self):
return ''
class CHAR_INFO(Structure):
_fields_ = [("Char", CHAR_UNION),
("Attributes", c_short)]
def to_str(self):
return ''
class KEY_EVENT_RECORD(Structure):
_fields_ = [("bKeyDown", c_byte),
("pad2", c_byte),
('pad1', c_short),
("wRepeatCount", c_short),
("wVirtualKeyCode", c_short),
("wVirtualScanCode", c_short),
("uChar", CHAR_UNION),
("dwControlKeyState", c_int)]
def to_str(self):
return ''
class MOUSE_EVENT_RECORD(Structure):
_fields_ = [("dwMousePosition", COORD),
("dwButtonState", c_int),
("dwControlKeyState", c_int),
("dwEventFlags", c_int)]
def to_str(self):
return ''
class WINDOW_BUFFER_SIZE_RECORD(Structure):
_fields_ = [("dwSize", COORD)]
def to_str(self):
return ''
class MENU_EVENT_RECORD(Structure):
_fields_ = [("dwCommandId", c_uint)]
def to_str(self):
return ''
class FOCUS_EVENT_RECORD(Structure):
_fields_ = [("bSetFocus", c_byte)]
def to_str(self):
return ''
class INPUT_UNION(Union):
_fields_ = [("KeyEvent", KEY_EVENT_RECORD),
("MouseEvent", MOUSE_EVENT_RECORD),
("WindowBufferSizeEvent", WINDOW_BUFFER_SIZE_RECORD),
("MenuEvent", MENU_EVENT_RECORD),
("FocusEvent", FOCUS_EVENT_RECORD)]
def to_str(self):
return ''
class INPUT_RECORD(Structure):
_fields_ = [("EventType", c_short),
("Event", INPUT_UNION)]
def to_str(self):
return ''

View File

@ -1,646 +0,0 @@
*ConqueTerm* Plugin to run a shell inside a Vim buffer
The ConqueTerm plugin will turn a Vim buffer into a terminal emulator, allowing
you to run and interact with a shell or shell application inside the buffer.
1. Installation |conque-term-setup|
1.1 Requirements for Unix |conque-term-requirements|
1.2 Requirements for Windows |conque-term-windows|
1.3 Installation |conque-term-installation|
2. Usage |conque-term-usage|
2.1 General Usage |conque-term-gen-usage|
2.2 Special keys |conque-term-special-keys|
2.2.1 Send text to Conque |conque-term-send|
2.2.2 Toggle terminal input mode |conque-term-input-mode|
2.2.3 Sending the <Esc> key press |conque-term-esc|
3. Configuration |conque-term-options|
3.1 General |conque-config-general|
3.1.1 Python version |ConqueTerm_PyVersion|
3.1.2 Fast mode |ConqueTerm_FastMode|
3.1.3 Color support |ConqueTerm_Color|
3.1.4 Session Support |ConqueTerm_SessionSupport|
3.1.5 Keep updating terminal buffer |ConqueTerm_ReadUnfocused|
3.1.6 Insert mode when entering buffer |ConqueTerm_InsertOnEnter|
3.1.7 Close buffer when program exits |ConqueTerm_CloseOnEnd|
3.1.8 Hide start messages |ConqueTerm_StartMessages|
3.1.9 Regex for highlighting your prompt |ConqueTerm_PromptRegex|
3.1.10 Syntax type |ConqueTerm_Syntax|
3.2 Keyboard |conque-config-keyboard|
3.2.1 The <Esc> key |ConqueTerm_EscKey|
3.2.2 Toggle terminal input mode |ConqueTerm_ToggleKey|
3.2.3 Enable <C-w> in insert mode |ConqueTerm_CWInsert|
3.2.4 Execute current file in Conque |ConqueTerm_ExecFileKey|
3.2.5 Send current file contents to Conque|ConqueTerm_SendFileKey|
3.2.6 Send selected text to Conque |ConqueTerm_SendVisKey|
3.2.7 Function Keys |ConqueTerm_SendFunctionKeys|
3.3 Unix |conque-config-unix|
3.3.1 Choose your terminal type |ConqueTerm_TERM|
3.4 Windows |conque-config-windows|
3.4.1 Python executable |ConqueTerm_PyExe|
3.4.2 Windows character code page |ConqueTerm_CodePage|
3.4.3 Terminal color method |ConqueTerm_ColorMode|
4. VimScript API |conque-term-api|
4.1 conque_term#open() |conque-term-open|
4.2 conque_term#subprocess() |conque-term-subprocess|
4.3 conque_term#get_instance() |conque-term-get-instance|
4.4 CONQUE_OBJECT.write() |conque-term-write|
4.5 CONQUE_OBJECT.writeln() |conque-term-writeln|
4.6 CONQUE_OBJECT.read() |conque-term-read|
4.7 CONQUE_OBJECT.set_callback() |conque-term-set-callback|
4.8 CONQUE_OBJECT.close() |conque-term-close|
4.9 Registering functions |conque-term-events|
5. Misc |conque-term-misc|
5.1 Known bugs |conque-term-bugs|
5.2 Contribute |conque-term-contribute|
5.3 Feedback |conque-term-feedback|
==============================================================================
1. Installation *conque-term-setup*
Conque is designed for both Unix and Windows operating systems, however the
requirements are slightly different. Please check section below corresponding
to your installed OS.
1.1 Requirements for Unix *conque-term-requirements*
* [G]Vim 7.0+ with +python and/or +python3
* Python 2.3+ and/or 3.x
* Unix-like OS: Linux, OS X, Solaris, Cygwin, etc
The most common stumbling block is getting a version of Vim which has the
python interface enabled. Most all software package managers will have a copy
of Vim with Python support, so that is often the easiest way to get it. If
you're compiling Vim from source, be sure to use the --enable-pythoninterp
option, or --enable-python3interp for Python 3. On OS X the best option is
MacVim, which installs with Python support by default.
1.2 Requirements for Windows *conque-term-windows*
* [G]Vim 7.3 with +python and/or +python3
* Python 2.7 and/or 3.1
* Modern Windows OS (XP or later)
Conque only officially supports the latest GVim 7.3 Windows installer
available at www.vim.org. If you are currently using Vim 7.2 or earlier you
will need to upgrade to 7.3 for Windows support. The Windows installer already
has the +python/+python3 interface built in.
The official 7.3 release of Vim for Windows only works with Python versions
2.7 and/or 3.1. You can download and install Python from their website
http://www.python.org/download
If you are compiling Vim + Python from source on Windows, the requirements
become only Vim 7.3+ and Python 2.7+.
1.3 Installation *conque-term-installation*
Download the latest vimball from http://conque.googlecode.com
Open the .vba file with Vim and run the following commands:
>
:so %
:q
<
That's it! The :ConqueTerm command will be available the next time you start
Vim. You can delete the .vba file when you've verified Conque was successfully
installed.
==============================================================================
2. Usage *conque-term-usage*
2.1 General Usage *conque-term-gen-usage*
Type :ConqueTerm <command> to launch an application in the current buffer. Eg:
>
:ConqueTerm bash
:ConqueTerm mysql -h localhost -u joe_lunchbox Menu
:ConqueTerm Powershell.exe
<
Use :ConqueTermSplit or :ConqueTermVSplit to open Conque in a new horizontal
or vertical buffer. Use :ConqueTermTab to open Conque in a new tab.
In insert mode you can interact with the shell as you would expect in a
normal terminal. All key presses will be sent to the terminal, including
control characters. See |conque-term-special-keys| for more information,
particularly regarding the <Esc> key.
In normal mode you can use Vim commands to browse your terminal output and
scroll back through the history. Most all Vim functionality will work, such
as searching, yanking or highlighting text.
2.2 Special keys *conque-term-special-keys*
There are several keys which can be configured to have special behavior with
Conque.
2.2.1 Send text to Conque *conque-term-send*
Conque gives you three different commands to send text from a different
buffer, probably a source code file, to the Conque terminal buffer. All three
are configurable to use your choice of key combinations.
To send a visually selected range of text to an existing terminal buffer,
press the <F9> key.
To send the entire contents of the file you are editing to an existing
terminal buffer, press the <F10> key.
Finally, to execute the current file in a new terminal buffer press the <F11>
key. This will split the screen with a new Conque buffer. The file you are
editing must be executable for this command to work.
See |conque-term-options| for information about configuring these commands.
2.2.2 Toggle terminal input mode *conque-term-input-mode*
If you want to use insert mode to edit the terminal screen, press <F8>. You
will now be able to edit the terminal output freely without your cursor
jumping the the active prompt line. This may be useful if you want to reformat
terminal output for readability.
While the terminal is paused new output will not be displayed on the screen
until you press <F8> again to resume.
You can configure Conque to use a different key with the |ConqueTerm_ToggleKey|
option.
2.2.3 Sending the <Esc> key press *conque-term-esc*
By default if you press the <Esc> key in a Conque buffer you will leave insert
mode. But what if you want the <Esc> character to be sent to your terminal?
There are two options. By default, pressing <Esc> twice will send one <Esc>
character to the terminal and you will remain in insert mode, while pressing
it once will leave insert mode.
Alternatively you can use the |ConqueTerm_EscKey| option to choose a
different key for leaving insert mode. If a custom key is set, then all <Esc>
key presses will be sent to the terminal.
2.3 Registering functions *conque-term-register*
Conque allows you to write your own VimScript functions which will be called
at certain events. See the API section |conque-term-events| for more.
==============================================================================
3. Options *conque-term-options*
You can set the following options in your .vimrc (default values shown)
3.1 General *conque-config-general*
3.1.1 Python version *ConqueTerm_PyVersion*
Conque will work with either Python 2.x or 3.x, assuming the interfaces have
been installed. By default it will try to use Python 2 first, then will try
Python 3. If you want Conque to use Python 3, set this variable to 3.
Note: even if you set this to 3, if you don't have the python3 interface
Conque will fall back to using Python 2.
>
let g:ConqueTerm_PyVersion = 2
<
3.1.2 Fast Mode *ConqueTerm_FastMode*
Disable features which could make Conque run slowly. This includes most
terminal colors and some unicode support. Set this to 1 to enable fast mode.
>
let g:ConqueTerm_FastMode = 0
<
3.1.3 Color support *ConqueTerm_Color*
Terminal colors have the potential to slow down terminal screen rendering,
depending on how many colors are used and how fast the computer is. This
option allows you to choose how much color support will be enabled.
If set to 0, terminal colors will be disabled. This will allow the terminal to
render most quickly. Syntax highlighting will still work. For example
highlighting quoted strings or MySQL output.
If set to 1, terminal colors will be enabled, but only for the most recent 200
lines of terminal output. Older output will be periodically stripped of color
highlighting to keep the display responsive.
If set to 2, terminal colors will always be enabled. If your programs don't
use color output very frequently this is a good choice.
Note: Color support is automatically disabled in "fast mode".
>
let g:ConqueTerm_Color = 1
<
3.1.4 Session Support *ConqueTerm_SessionSupport*
Vim's :mksession command allows you to save your current buffer configuration
to a file, which can be loaded at a later time after you've closed Vim.
By default, Conque buffers are not restored. This is mostly for safety
reasons; you may not want Vim to automatically re-run a destructive command.
However, if you're not working with missile launch code, and want Vim to
restart your Conque buffers when you load a session file, set this variable
to 1. Note your original subprocess and shell output will not be restored, but
the same command will be started in your buffer.
>
let g:ConqueTerm_SessionSupport = 0
<
3.1.5 Keep updating terminal buffer *ConqueTerm_ReadUnfocused*
If set to 1 then your Conque buffers will continue to update after you've
switched to another buffer.
Note: Conque buffers may continue to update, but they will not scroll down as
new lines are added beyond the bottom of the visible buffer area. This is a
limitation of the Vim scripting language for which I haven't found a
workaround.
>
let g:ConqueTerm_ReadUnfocused = 1
<
3.1.6 Insert mode when entering buffer *ConqueTerm_InsertOnEnter*
If set to 1 then you will automatically go into insert mode when you enter the
buffer. This diverges from normal Vim behavior. If 0 you will still be in
normal mode.
>
let g:ConqueTerm_InsertOnEnter = 0
<
3.1.7 Close buffer when program exits *ConqueTerm_CloseOnEnd*
If you want your terminal buffer to be closed and permanently deleted when the
program running inside of it exits, set this option to 1. Otherwise the buffer
will become a simple text buffer after the program exits, and you can edit the
program output in insert mode.
>
let g:ConqueTerm_CloseOnEnd = 0
<
3.1.8 Show start messages *ConqueTerm_StartMessages*
Display warning messages when starting up ConqueTerm if your system is
configured incorrectly.
>
let g:ConqueTerm_StartMessages = 1
<
3.1.9 Regex for highlighting your prompt *ConqueTerm_PromptRegex*
Use this regular expression for sytax highlighting your terminal prompt. Your
terminal will generally run faster if you use Vim highlighting instead of
terminal colors for your prompt. You can also use it to do more advanced
syntax highlighting for the prompt line.
>
let g:ConqueTerm_PromptRegex = '^\w\+@[0-9A-Za-z_.-]\+:[0-9A-Za-z_./\~,:-]\+\$'
<
3.1.10 Choose Vim syntax type *ConqueTerm_Syntax*
Set the buffer syntax. The default 'conque' has highlighting for MySQL, but
not much else.
>
let g:ConqueTerm_Syntax = 'conque'
<
3.2 Keyboard *conque-config-keyboard*
3.2.1 The <Esc> key *ConqueTerm_EscKey*
If a custom key is set, then all <Esc> key presses will be sent to the
terminal and you must use this custom key to leave insert mode. If left to the
default value of '<Esc>' then you must press it twice to send the escape
character to the terminal, while pressing it once will leave insert mode.
Note: You cannot use a key which is internally coded with the escape
character. This includes the <F-> keys and often the <A-> and <M-> keys.
Picking a control key, such as <C-k> will be your best bet.
>
let g:ConqueTerm_EscKey = '<Esc>'
<
3.2.2 Toggle terminal input mode *ConqueTerm_ToggleKey*
Press this key to pause terminal input and output display. You will then be
able to edit the terminal screen as if it were a normal text buffer. Press
this key again to resume terminal mode.
>
let g:ConqueTerm_ToggleKey = '<F8>'
<
3.2.3 Enable <C-w> in insert mode *ConqueTerm_CWInsert*
If set to 1 then you can leave the Conque buffer using the <C-w> commands
while you're still in insert mode. If set to 0 then the <C-w> character will
be sent to the terminal. If both this option and ConqueTerm_InsertOnEnter are
set you can go in and out of the terminal buffer while never leaving insert
mode.
>
let g:ConqueTerm_CWInsert = 0
<
3.2.4 Execute current file in Conque *ConqueTerm_ExecFileKey*
Press this key to execute the file you're currently editing in a Conque
buffer. Is equivelent to running the command :ConqueTermSplit YOUR_FILE. Your
file must be executable for this command to work correctly.
>
let g:ConqueTerm_ExecFileKey = '<F11>'
<
3.2.5 Send current file contents to Conque *ConqueTerm_SendFileKey*
Press this key to send your entire file contents to the most recently opened
Conque buffer as keyboard input.
>
let g:ConqueTerm_SendFileKey = '<F10>'
<
3.2.6 Send selected text to Conque *ConqueTerm_SendVisKey*
Use this key to send the currently selected text to the most recently created
Conque buffer.
>
let g:ConqueTerm_SendVisKey = '<F9>'
<
3.2.7 Function Keys *ConqueTerm_SendFunctionKeys*
By default, function keys (the F1-F12 row at the top of your keyboard) are not
passed to the terminal. Set this option to 1 to send these key events.
Note: Unless you configured |ConqueTerm_SendVisKey| and |ConqueTerm_ToggleKey|
to use different keys, <F8> and <F9> will not be sent to the terminal even if
you set this option to 1.
>
let g:ConqueTerm_SendFunctionKeys = 0
<
3.3 Unix *conque-config-unix*
3.3.1 Choose your terminal type, Unix ONLY *ConqueTerm_TERM*
Use this option to tell Conque what type of terminal it should identify itself
as. Conque officially uses the more limited VT100 terminal type for
developement and testing, although it supports some more advanced features
such as colors and title strings.
You can change this setting to a more advanced type, namely 'xterm', but your
results may vary depending on which programs you're running.
>
let g:ConqueTerm_TERM = 'vt100'
<
3.4 Windows *conque-config-windows*
3.4.1 Python executable, Windows ONLY *ConqueTerm_PyExe*
The Windows version of Conque needs to know the path to the python.exe
executable for the version of Python Conque is using. If you installed Python
in the default location, or added the Python directory to your system path,
Conque should be able to find python.exe without you changing this variable.
For example, you might set this to 'C:\Program Files\Python27\python.exe'
>
let g:ConqueTerm_PyExe = ''
<
3.4.2 Windows character code page *ConqueTerm_CodePage*
Set the "code page" Windows will use for your console. Leave this value set to
zero to use the environment code page.
Note: Displaying unicode characters on Conque for Windows needs work.
>
let g:ConqueTerm_CodePage = 0
<
3.4.3 Terminal color method, Windows ONLY *ConqueTerm_ColorMode*
Vim syntax highlighting by coordinate (e.g. the 3-7th characters on the 42nd
line) can be very slow. If you set this variable to 'conceal', you can use
the new conceal feature to render terminal colors. Requires Vim 7.3 and only
works on the Windows version of Conque. This will make colors render faster,
however it will also add hidden characters to the screen, which may be
annoying if you're copying and pasting terminal output out of the Conque
buffer. Set this to an empty string '' to disable concealed highlighting.
>
let g:ConqueTerm_ColorMode = 'conceal'
<
==============================================================================
4. VimScript API (Beta) *conque-term-api*
The Conque scripting API allows you to create and interact with Conque
terminals with the VimScript language. This API is still in beta stage.
4.1 conque_term#open({command}, [buf_opts], [remain]) *conque-term-open*
The open() function will create a new terminal buffer and start your command.
The {command} must be an executable, either an absolute path or relative to
your system path.
You can pass in a list of vim commands [buf_opts] which will be executed after
the new buffer is created but before the command is started. These are
typically commands to alter the size, position or configuration of the buffer
window.
Note: If you don't pass in a command such as 'split', the terminal will open
in the current buffer.
If you don't want the new terminal buffer to become the new active buffer, set
[remain] to 1. Only works if you create a split screen using [options].
Returns a Conque terminal object.
Examples:
>
let my_terminal = conque_term#open('/bin/bash')
let my_terminal = conque_term#open('ipython', ['split', 'resize 20'], 1)
<
4.2 conque_term#subprocess({command}) *conque-term-subprocess*
Starts a new subprocess with your {command}, but no terminal buffer is ever
created. This may be useful if you need asynchronous interaction with a
subprocess, but want to handle the output on your own.
Returns a Conque terminal object.
Example:
>
let my_subprocess = conque_term#subprocess('tail -f /var/log/foo.log')
<
4.3 conque_term#get_instance( [terminal_number] ) *conque-term-get-instance*
Use the get_instance() function to retrieve an existing terminal object. The
terminal could have been created either with the user command :ConqueTerm or
with an API call to conque_term#open() or subprocess().
Use the optional [terminal_number] to retrieve a specific terminal instance.
Otherwise if the current buffer is a Conque terminal, it will be returned,
else the most recently created terminal. The terminal number is what you see
at the end of a terminal buffer name, e.g. "bash - 2".
Returns a Conque terminal object.
Example:
>
nnoremap <F4> :call conque_term#get_instance().writeln('clear')<CR>
<
4.4 CONQUE_OBJECT.write({text}) *conque-term-write*
Once you have a terminal object from open(), subprocess() or get_instance()
you can send text input to it with the write() method.
No return value.
Examples:
>
call my_terminal.write("whoami\n")
call my_terminal.write("\<C-c>")
<
4.5 CONQUE_OBJECT.writeln({text}) *conque-term-writeln*
The same as write() except adds a \n character to the end if your input.
Examples:
>
call my_subprocess.writeln('make')
<
4.6 CONQUE_OBJECT.read( [timeout], [update_buffer] ) *conque-term-read*
Read new output from a Conque terminal subprocess. New output will be returned
as a string, and the terminal buffer will also be updated by default.
If you are reading immediately after calling the write() method, you may want
to wait [timeout] milliseconds for output to be ready.
If you want to prevent the output from being displayed in the terminal buffer,
set [update_buffer] to 0. This option has no effect if the terminal was
created with the subprocess() function, since there never is a buffer to
update.
Returns output string.
Note: The terminal buffer will not automatically scroll down if the new output
extends beyond the bottom of the visible buffer. Vim doesn't allow "unfocused"
buffers to be scrolled at the current version, although hopefully this will
change.
Examples:
>
call my_terminal.writeln('whoami')
let output = my_terminal.read(500)
call my_terminal.writeln('ls -lha')
let output = my_terminal.read(1000, 1)
<
4.7 CONQUE_OBJECT.set_callback( {funcname} ) *conque-term-set-callback*
Register a callback function for this subprocess instance. This function will
automatically be called whenever new output is available. Only practical with
subprocess() objects.
Conque checkes for new subprocess output once a second when Vim is idle. If
new output is found your function will be called.
Pass in the callback function name {funcname} as a string.
No return value.
Note: this method requires the g:ConqueTerm_ReadUnfocused option to be set.
Note: this method is experimental, results may vary.
Example:
>
let sp = conque_term#subprocess('tail -f /home/joe/log/error_log')
function! MyErrorAlert(output)
echo a:output
endfunction
call sp.set_callback('MyErrorAlert')
<
4.8 CONQUE_OBJECT.close() *conque-term-close*
Kill your terminal subprocess. Sends the ABORT signal. You probably want to
close your subprocess in a more graceful manner with the write() method, but
this can be used when needed. Does not close the terminal buffer, if it
exists.
This method will be called on all existing Conque subprocesses when Vim exits.
Example:
>
let term = conque_term#open('ping google.com', ['belowright split'])
call term.read(5000)
call term.close()
<
4.9 Registering functions *conque-term-events*
Conque provides the option to register callback functions which will be
executed at several different events. The currently available events are:
after_startup After your application has loaded into the buffer.
buffer_enter When you switch to a Conque buffer.
buffer_leave When you leave a Conque buffer.
You may use the function conque_term#register_function(event, function_name)
to add additional hooks at a particular event. The second argument should be
the name of a callback function which has one parameter, the current
terminal object (see|conque-term-api|for more about terminal objects).
For example:
>
function MyConqueStartup(term)
" set buffer syntax using the name of the program currently running
let syntax_associations = { 'ipython': 'python', 'irb': 'ruby' }
if has_key(syntax_associations, a:term.program_name)
execute 'setlocal syntax=' . syntax_associations[a:term.program_name]
else
execute 'setlocal syntax=' . a:term.program_name
endif
" shrink window height to 10 rows
resize 10
" silly example of terminal api usage
if a:term.program_name == 'bash'
call a:term.writeln('svn up ~/projects/*')
endif
endfunction
call conque_term#register_function('after_startup', 'MyConqueStartup')
<
==============================================================================
5. Misc *conque-term-misc*
5.1 Known bugs *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 <Esc><Esc>x or <Esc><M-x> instead of <M-x> works in
most cases.
5.2 Contribute *conque-term-contribute*
The two contributions most in need are improvements to Vim itself. I currently
use hacks to capture key press input from the user, and to poll the terminal
for more output. 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.
5.3 Feedback *conque-term-feedback*
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/
vim:tw=78:ts=8:ft=help:norl:

View File

@ -1,73 +0,0 @@
" ViM autocommands for binary plist files
" Copyright (C) 2005 Moritz Heckscher
"
" Note: When a file changes externally and you answer no to vim's question if
" you want to write anyway, the autocommands (e.g. for BufWritePost) are still
" executed, it seems, which could have some unwanted side effects.
"
" This program is free software; you can redistribute it and/or modify
" it under the terms of the GNU General Public License as published by
" the Free Software Foundation; either version 2 of the License, or
" (at your option) any later version.
"
" This program is distributed in the hope that it will be useful,
" but WITHOUT ANY WARRANTY; without even the implied warranty of
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
" GNU General Public License for more details.
autocmd BufReadPre,FileReadPre *.plist set binary ft=plist syntax=xml
" ... and call it just after editing a file in a new buffer...
autocmd BufReadPost *.plist call MyBinaryPlistReadPost()
" ... or when reading a file into an existing buffer (in that case, don't
" save as binary later on).
autocmd FileReadPost *.plist call MyBinaryPlistReadPost() | let b:saveAsBinaryPlist = 0
autocmd BufWritePre,FileWritePre *.plist call MyBinaryPlistWritePre()
autocmd BufWritePost,FileWritePost *.plist call MyBinaryPlistWritePost()
" breaking lines etc; since setting this for normal plist files doesn't
" hurt and it's not yet known whether or not the file to be read is stored
" in binary format, set the option in any case to be sure).
" Do it before editing a file in a new buffer and before reading a file
" into in an existing buffer (using ':read foo.plist').
" Define a little function to convert binary files if necessary...
fun MyBinaryPlistReadPost()
" Check if the first line just read in indicates a binary plist
if getline("'[") =~ "^bplist"
" Filter lines read into buffer (convert to XML with plutil)
'[,']!plutil -convert xml1 /dev/stdin -o /dev/stdout
" Many people seem to want to save files originally stored
" in binary format as such after editing, so memorize format.
let b:saveAsBinaryPlist = 1
endif
" Yeah, plain text (finally or all the way through, either way...)!
set nobinary
" Trigger file type detection to get syntax coloring etc. according
" to file contents (alternative: 'setfiletype xml' to force xml).
filetype detect
endfun
" Define and use functions for conversion back to binary format
fun MyBinaryPlistWritePre()
if exists("b:saveAsBinaryPlist") && b:saveAsBinaryPlist
" Must set binary mode before conversion (for EOL settings)
set binary
" Convert buffer lines to be written to binary
silent '[,']!plutil -convert binary1 /dev/stdin -o /dev/stdout
" If there was a problem, e.g. when the file contains syntax
" errors, undo the conversion and go back to nobinary so the
" file will be saved in text format.
if v:shell_error | undo | set nobinary | endif
endif
endfun
fun MyBinaryPlistWritePost()
" If file was to be written in binary format and there was no error
" doing the conversion, ...
if exists("b:saveAsBinaryPlist") && b:saveAsBinaryPlist && !v:shell_error
" ... undo the conversion and go back to nobinary so the
" lines are shown as text again in vim.
undo
set nobinary
endif
endfun

View File

@ -1,160 +0,0 @@
# coding: utf-8
from mccabe.mccabe import get_module_complexity
from pyflakes import checker, messages
import _ast
from pep8 import pep8 as p8
from pep8.autopep8 import fix_file as pep8_fix, fix_lines as pep8_fix_lines
import os
class Pep8Options():
verbose = 0
diff = False
in_place = True
recursive = False
pep8_passes = 100
max_line_length = 79
ignore = ''
select = ''
aggressive = False
class MccabeOptions():
complexity = 10
flake_code_mapping = {
'W402': (messages.UnusedImport,),
'W403': (messages.ImportShadowedByLoopVar,),
'W404': (messages.ImportStarUsed,),
'W405': (messages.LateFutureImport,),
'W801': (messages.RedefinedWhileUnused,
messages.RedefinedInListComp,),
'W802': (messages.UndefinedName,),
'W803': (messages.UndefinedExport,),
'W804': (messages.UndefinedLocal,
messages.UnusedVariable,),
'W805': (messages.DuplicateArgument,),
'W806': (messages.Redefined,),
}
flake_class_mapping = dict(
(k, c) for (c, v) in flake_code_mapping.items() for k in v)
def fix_file(filename):
pep8_fix(filename, Pep8Options)
def fix_lines(lines):
return pep8_fix_lines(lines, Pep8Options)
def run_checkers(filename, checkers, ignore):
result = []
for c in checkers:
checker_fun = globals().get(c)
if not checker:
continue
try:
for e in checker_fun(filename):
e.update(
col=e.get('col') or 0,
text="{0} [{1}]".format(
e.get('text', '').strip(
).replace("'", "\"").splitlines()[0],
c),
filename=os.path.normpath(filename),
type=e.get('type') or 'W',
bufnr=0,
)
result.append(e)
except:
pass
result = filter(lambda e: _ignore_error(e, ignore), result)
return sorted(result, key=lambda x: x['lnum'])
def mccabe(filename):
return get_module_complexity(filename, min=MccabeOptions.complexity)
def pep8(filename):
style = PEP8 or _init_pep8()
return style.input_file(filename)
def pyflakes(filename):
codeString = file(filename, 'U').read() + '\n'
errors = []
try:
tree = compile(codeString, filename, "exec", _ast.PyCF_ONLY_AST)
except SyntaxError as e:
errors.append(dict(
lnum=e.lineno or 0,
col=e.offset or 0,
text=getattr(e, 'msg', None) or str(e),
type='E'
))
else:
w = checker.Checker(tree, filename)
w.messages.sort(lambda a, b: cmp(a.lineno, b.lineno))
for w in w.messages:
errors.append(dict(
lnum=w.lineno,
col=0,
text=u'{0} {1}'.format(
flake_class_mapping.get(w.__class__, ''),
w.message % w.message_args),
type='E'
))
return errors
PEP8 = None
def _init_pep8():
global PEP8
class _PEP8Report(p8.BaseReport):
def init_file(self, filename, lines, expected, line_offset):
super(_PEP8Report, self).init_file(
filename, lines, expected, line_offset)
self.errors = []
def error(self, line_number, offset, text, check):
code = super(_PEP8Report, self).error(
line_number, offset, text, check)
self.errors.append(dict(
text=text,
type=code,
col=offset + 1,
lnum=line_number,
))
def get_file_results(self):
return self.errors
PEP8 = p8.StyleGuide(reporter=_PEP8Report)
return PEP8
def _ignore_error(e, ignore):
for i in ignore:
if e['text'].startswith(i):
return False
return True
if __name__ == '__main__':
for r in run_checkers(
'/home/andrew/devel/vim/bundle/flake8-vim/ftplugin/python/flake8.py',
checkers=['mccabe', 'pyflakes', 'pep8'], ignore=[]):
print r

View File

@ -1,188 +0,0 @@
" Check python support
if !has('python')
echo "Error: PyFlake.vim required vim compiled with +python."
finish
endif
if !exists('g:PyFlakeRangeCommand')
let g:PyFlakeRangeCommand = 'Q'
endif
if !exists('b:PyFlake_initialized')
let b:PyFlake_initialized = 1
au BufWritePost <buffer> call flake8#on_write()
au CursorHold <buffer> call flake8#get_message()
au CursorMoved <buffer> call flake8#get_message()
" Commands
command! -buffer PyFlakeToggle :let b:PyFlake_disabled = exists('b:PyFlake_disabled') ? b:PyFlake_disabled ? 0 : 1 : 1
command! -buffer PyFlake :call flake8#run()
command! -buffer -range=% PyFlakeAuto :call flake8#auto(<line1>,<line2>)
" Keymaps
if g:PyFlakeRangeCommand != ''
exec 'vnoremap <buffer> <silent> ' . g:PyFlakeRangeCommand . ' :PyFlakeAuto<CR>'
endif
let b:showing_message = 0
" Signs definition
sign define W text=WW texthl=Todo
sign define C text=CC texthl=Comment
sign define R text=RR texthl=Visual
sign define E text=EE texthl=Error
endif
"Check for flake8 plugin is loaded
if exists("g:PyFlakeDirectory")
finish
endif
if !exists('g:PyFlakeOnWrite')
let g:PyFlakeOnWrite = 1
endif
" Init variables
let g:PyFlakeDirectory = expand('<sfile>:p:h')
if !exists('g:PyFlakeCheckers')
let g:PyFlakeCheckers = 'pep8,mccabe,pyflakes'
endif
if !exists('g:PyFlakeDefaultComplexity')
let g:PyFlakeDefaultComplexity=10
endif
if !exists('g:PyFlakeDisabledMessages')
let g:PyFlakeDisabledMessages = 'E501'
endif
if !exists('g:PyFlakeCWindow')
let g:PyFlakeCWindow = 6
endif
if !exists('g:PyFlakeSigns')
let g:PyFlakeSigns = 1
endif
if !exists('g:PyFlakeMaxLineLength')
let g:PyFlakeMaxLineLength = 100
endif
python << EOF
import sys
import json
import vim
sys.path.insert(0, vim.eval("g:PyFlakeDirectory"))
from flake8 import run_checkers, fix_lines, Pep8Options, MccabeOptions
def flake8_check():
checkers=vim.eval('g:PyFlakeCheckers').split(',')
ignore=vim.eval('g:PyFlakeDisabledMessages').split(',')
MccabeOptions.complexity=int(vim.eval('g:PyFlakeDefaultComplexity'))
Pep8Options.max_line_length=int(vim.eval('g:PyFlakeMaxLineLength'))
filename=vim.current.buffer.name
parse_result(run_checkers(filename, checkers, ignore))
def parse_result(result):
vim.command('let g:qf_list = {}'.format(json.dumps(result, ensure_ascii=False)))
EOF
function! flake8#on_write()
if !g:PyFlakeOnWrite || exists("b:PyFlake_disabled") && b:PyFlake_disabled
return
endif
call flake8#check()
endfunction
function! flake8#run()
if &modifiable && &modified
write
endif
call flake8#check()
endfun
function! flake8#check()
py flake8_check()
let s:matchDict = {}
for err in g:qf_list
let s:matchDict[err.lnum] = err.text
endfor
call setqflist(g:qf_list, 'r')
" Place signs
if g:PyFlakeSigns
call flake8#place_signs()
endif
" Open cwindow
if g:PyFlakeCWindow
cclose
if len(g:qf_list)
let l:winsize = len(g:qf_list) > g:PyFlakeCWindow ? g:PyFlakeCWindow : len(g:qf_list)
exec l:winsize . 'cwindow'
endif
endif
endfunction
function! flake8#auto(l1, l2) "{{{
cclose
sign unplace *
let s:matchDict = {}
call setqflist([])
python << EOF
start, end = int(vim.eval('a:l1'))-1, int(vim.eval('a:l2'))
enc = vim.eval('&enc')
lines = fix_lines(vim.current.buffer[start:end]).splitlines()
res = [ln.encode(enc, 'replace') for ln in lines]
vim.current.buffer[start:end] = res
EOF
endfunction "}}}
function! flake8#place_signs()
"first remove all sings
sign unplace *
"now we place one sign for every quickfix line
let l:id = 1
for item in getqflist()
execute(':sign place '.l:id.' name='.l:item.type.' line='.l:item.lnum.' buffer='.l:item.bufnr)
let l:id = l:id + 1
endfor
endfunction
" keep track of whether or not we are showing a message
" WideMsg() prints [long] message up to (&columns-1) length
" guaranteed without "Press Enter" prompt.
function! flake8#wide_msg(msg)
let x=&ruler | let y=&showcmd
set noruler noshowcmd
redraw
echo strpart(a:msg, 0, &columns-1)
let &ruler=x | let &showcmd=y
endfun
function! flake8#get_message()
let s:cursorPos = getpos(".")
" Bail if RunPyflakes hasn't been called yet.
if !exists('s:matchDict')
return
endif
" if there's a message for the line the cursor is currently on, echo
" it to the console
if has_key(s:matchDict, s:cursorPos[1])
let s:pyflakesMatch = get(s:matchDict, s:cursorPos[1])
call flake8#wide_msg(s:pyflakesMatch)
let b:showing_message = 1
return
endif
" otherwise, if we're showing a message, clear it
if b:showing_message == 1
echo
let b:showing_message = 0
endif
endfunction

View File

@ -1,446 +0,0 @@
" -*- vim -*-
" FILE: python.vim
" LAST MODIFICATION: 2008-05-17 6:29pm
" (C) Copyright 2001-2005 Mikael Berthe <bmikael@lists.lilotux.net>
" Maintained by Jon Franklin <jvfranklin@gmail.com>
" Version: 1.12
" USAGE:
"
" Save this file to $VIMFILES/ftplugin/python.vim. You can have multiple
" python ftplugins by creating $VIMFILES/ftplugin/python and saving your
" ftplugins in that directory. If saving this to the global ftplugin
" directory, this is the recommended method, since vim ships with an
" ftplugin/python.vim file already.
" You can set the global variable "g:py_select_leading_comments" to 0
" if you don't want to select comments preceding a declaration (these
" are usually the description of the function/class).
" You can set the global variable "g:py_select_trailing_comments" to 0
" if you don't want to select comments at the end of a function/class.
" If these variables are not defined, both leading and trailing comments
" are selected.
" Example: (in your .vimrc) "let g:py_select_leading_comments = 0"
" You may want to take a look at the 'shiftwidth' option for the
" shift commands...
"
" REQUIREMENTS:
" vim (>= 7)
"
" Shortcuts:
" ]t -- Jump to beginning of block
" ]e -- Jump to end of block
" ]v -- Select (Visual Line Mode) block
" ]< -- Shift block to left
" ]> -- Shift block to right
" ]# -- Comment selection
" ]u -- Uncomment selection
" ]c -- Select current/previous class
" ]d -- Select current/previous function
" ]<up> -- Jump to previous line with the same/lower indentation
" ]<down> -- Jump to next line with the same/lower indentation
" Only do this when not done yet for this buffer
if exists("b:loaded_py_ftplugin")
finish
endif
let b:loaded_py_ftplugin = 1
map ]t :PBoB<CR>
vmap ]t :<C-U>PBOB<CR>m'gv``
map ]e :PEoB<CR>
vmap ]e :<C-U>PEoB<CR>m'gv``
map ]v ]tV]e
map ]< ]tV]e<
vmap ]< <
map ]> ]tV]e>
vmap ]> >
map ]# :call PythonCommentSelection()<CR>
vmap ]# :call PythonCommentSelection()<CR>
map ]u :call PythonUncommentSelection()<CR>
vmap ]u :call PythonUncommentSelection()<CR>
map ]c :call PythonSelectObject("class")<CR>
map ]d :call PythonSelectObject("function")<CR>
map ]<up> :call PythonNextLine(-1)<CR>
map ]<down> :call PythonNextLine(1)<CR>
" You may prefer use <s-up> and <s-down>... :-)
" jump to previous class
map ]J :call PythonDec("class", -1)<CR>
vmap ]J :call PythonDec("class", -1)<CR>
" jump to next class
map ]j :call PythonDec("class", 1)<CR>
vmap ]j :call PythonDec("class", 1)<CR>
" jump to previous function
map ]F :call PythonDec("function", -1)<CR>
vmap ]F :call PythonDec("function", -1)<CR>
" jump to next function
map ]f :call PythonDec("function", 1)<CR>
vmap ]f :call PythonDec("function", 1)<CR>
" Menu entries
nmenu <silent> &Python.Update\ IM-Python\ Menu
\:call UpdateMenu()<CR>
nmenu &Python.-Sep1- :
nmenu <silent> &Python.Beginning\ of\ Block<Tab>[t
\]t
nmenu <silent> &Python.End\ of\ Block<Tab>]e
\]e
nmenu &Python.-Sep2- :
nmenu <silent> &Python.Shift\ Block\ Left<Tab>]<
\]<
vmenu <silent> &Python.Shift\ Block\ Left<Tab>]<
\]<
nmenu <silent> &Python.Shift\ Block\ Right<Tab>]>
\]>
vmenu <silent> &Python.Shift\ Block\ Right<Tab>]>
\]>
nmenu &Python.-Sep3- :
vmenu <silent> &Python.Comment\ Selection<Tab>]#
\]#
nmenu <silent> &Python.Comment\ Selection<Tab>]#
\]#
vmenu <silent> &Python.Uncomment\ Selection<Tab>]u
\]u
nmenu <silent> &Python.Uncomment\ Selection<Tab>]u
\]u
nmenu &Python.-Sep4- :
nmenu <silent> &Python.Previous\ Class<Tab>]J
\]J
nmenu <silent> &Python.Next\ Class<Tab>]j
\]j
nmenu <silent> &Python.Previous\ Function<Tab>]F
\]F
nmenu <silent> &Python.Next\ Function<Tab>]f
\]f
nmenu &Python.-Sep5- :
nmenu <silent> &Python.Select\ Block<Tab>]v
\]v
nmenu <silent> &Python.Select\ Function<Tab>]d
\]d
nmenu <silent> &Python.Select\ Class<Tab>]c
\]c
nmenu &Python.-Sep6- :
nmenu <silent> &Python.Previous\ Line\ wrt\ indent<Tab>]<up>
\]<up>
nmenu <silent> &Python.Next\ Line\ wrt\ indent<Tab>]<down>
\]<down>
:com! PBoB execute "normal ".PythonBoB(line('.'), -1, 1)."G"
:com! PEoB execute "normal ".PythonBoB(line('.'), 1, 1)."G"
:com! UpdateMenu call UpdateMenu()
" Go to a block boundary (-1: previous, 1: next)
" If force_sel_comments is true, 'g:py_select_trailing_comments' is ignored
function! PythonBoB(line, direction, force_sel_comments)
let ln = a:line
let ind = indent(ln)
let mark = ln
let indent_valid = strlen(getline(ln))
let ln = ln + a:direction
if (a:direction == 1) && (!a:force_sel_comments) &&
\ exists("g:py_select_trailing_comments") &&
\ (!g:py_select_trailing_comments)
let sel_comments = 0
else
let sel_comments = 1
endif
while((ln >= 1) && (ln <= line('$')))
if (sel_comments) || (match(getline(ln), "^\\s*#") == -1)
if (!indent_valid)
let indent_valid = strlen(getline(ln))
let ind = indent(ln)
let mark = ln
else
if (strlen(getline(ln)))
if (indent(ln) < ind)
break
endif
let mark = ln
endif
endif
endif
let ln = ln + a:direction
endwhile
return mark
endfunction
" Go to previous (-1) or next (1) class/function definition
function! PythonDec(obj, direction)
if (a:obj == "class")
let objregexp = "^\\s*class\\s\\+[a-zA-Z0-9_]\\+"
\ . "\\s*\\((\\([a-zA-Z0-9_,. \\t\\n]\\)*)\\)\\=\\s*:"
else
let objregexp = "^\\s*def\\s\\+[a-zA-Z0-9_]\\+\\s*(\\_[^:#]*)\\s*:"
endif
let flag = "W"
if (a:direction == -1)
let flag = flag."b"
endif
let res = search(objregexp, flag)
endfunction
" Comment out selected lines
" commentString is inserted in non-empty lines, and should be aligned with
" the block
function! PythonCommentSelection() range
let commentString = "#"
let cl = a:firstline
let ind = 1000 " I hope nobody use so long lines! :)
" Look for smallest indent
while (cl <= a:lastline)
if strlen(getline(cl))
let cind = indent(cl)
let ind = ((ind < cind) ? ind : cind)
endif
let cl = cl + 1
endwhile
if (ind == 1000)
let ind = 1
else
let ind = ind + 1
endif
let cl = a:firstline
execute ":".cl
" Insert commentString in each non-empty line, in column ind
while (cl <= a:lastline)
if strlen(getline(cl))
execute "normal ".ind."|i".commentString
endif
execute "normal \<Down>"
let cl = cl + 1
endwhile
endfunction
" Uncomment selected lines
function! PythonUncommentSelection() range
" commentString could be different than the one from CommentSelection()
" For example, this could be "# \\="
let commentString = "#"
let cl = a:firstline
while (cl <= a:lastline)
let ul = substitute(getline(cl),
\"\\(\\s*\\)".commentString."\\(.*\\)$", "\\1\\2", "")
call setline(cl, ul)
let cl = cl + 1
endwhile
endfunction
" Select an object ("class"/"function")
function! PythonSelectObject(obj)
" Go to the object declaration
normal $
call PythonDec(a:obj, -1)
let beg = line('.')
if !exists("g:py_select_leading_comments") || (g:py_select_leading_comments)
let decind = indent(beg)
let cl = beg
while (cl>1)
let cl = cl - 1
if (indent(cl) == decind) && (getline(cl)[decind] == "#")
let beg = cl
else
break
endif
endwhile
endif
if (a:obj == "class")
let eod = "\\(^\\s*class\\s\\+[a-zA-Z0-9_]\\+\\s*"
\ . "\\((\\([a-zA-Z0-9_,. \\t\\n]\\)*)\\)\\=\\s*\\)\\@<=:"
else
let eod = "\\(^\\s*def\\s\\+[a-zA-Z0-9_]\\+\\s*(\\_[^:#]*)\\s*\\)\\@<=:"
endif
" Look for the end of the declaration (not always the same line!)
call search(eod, "")
" Is it a one-line definition?
if match(getline('.'), "^\\s*\\(#.*\\)\\=$", col('.')) == -1
let cl = line('.')
execute ":".beg
execute "normal V".cl."G"
else
" Select the whole block
execute "normal \<Down>"
let cl = line('.')
execute ":".beg
execute "normal V".PythonBoB(cl, 1, 0)."G"
endif
endfunction
" Jump to the next line with the same (or lower) indentation
" Useful for moving between "if" and "else", for example.
function! PythonNextLine(direction)
let ln = line('.')
let ind = indent(ln)
let indent_valid = strlen(getline(ln))
let ln = ln + a:direction
while((ln >= 1) && (ln <= line('$')))
if (!indent_valid) && strlen(getline(ln))
break
else
if (strlen(getline(ln)))
if (indent(ln) <= ind)
break
endif
endif
endif
let ln = ln + a:direction
endwhile
execute "normal ".ln."G"
endfunction
function! UpdateMenu()
" delete menu if it already exists, then rebuild it.
" this is necessary in case you've got multiple buffers open
" a future enhancement to this would be to make the menu aware of
" all buffers currently open, and group classes and functions by buffer
if exists("g:menuran")
aunmenu IM-Python
endif
let restore_fe = &foldenable
set nofoldenable
" preserve disposition of window and cursor
let cline=line('.')
let ccol=col('.') - 1
norm H
let hline=line('.')
" create the menu
call MenuBuilder()
" restore disposition of window and cursor
exe "norm ".hline."Gzt"
let dnscroll=cline-hline
exe "norm ".dnscroll."j".ccol."l"
let &foldenable = restore_fe
endfunction
function! MenuBuilder()
norm gg0
let currentclass = -1
let classlist = []
let parentclass = ""
while line(".") < line("$")
" search for a class or function
if match ( getline("."), '^\s*class\s\+[_a-zA-Z].*:\|^\s*def\s\+[_a-zA-Z].*:' ) != -1
norm ^
let linenum = line('.')
let indentcol = col('.')
norm "nye
let classordef=@n
norm w"nywge
let objname=@n
let parentclass = FindParentClass(classlist, indentcol)
if classordef == "class"
call AddClass(objname, linenum, parentclass)
else " this is a function
call AddFunction(objname, linenum, parentclass)
endif
" We actually created a menu, so lets set the global variable
let g:menuran=1
call RebuildClassList(classlist, [objname, indentcol], classordef)
endif " line matched
norm j
endwhile
endfunction
" classlist contains the list of nested classes we are in.
" in most cases it will be empty or contain a single class
" but where a class is nested within another, it will contain 2 or more
" this function adds or removes classes from the list based on indentation
function! RebuildClassList(classlist, newclass, classordef)
let i = len(a:classlist) - 1
while i > -1
if a:newclass[1] <= a:classlist[i][1]
call remove(a:classlist, i)
endif
let i = i - 1
endwhile
if a:classordef == "class"
call add(a:classlist, a:newclass)
endif
endfunction
" we found a class or function, determine its parent class based on
" indentation and what's contained in classlist
function! FindParentClass(classlist, indentcol)
let i = 0
let parentclass = ""
while i < len(a:classlist)
if a:indentcol <= a:classlist[i][1]
break
else
if len(parentclass) == 0
let parentclass = a:classlist[i][0]
else
let parentclass = parentclass.'\.'.a:classlist[i][0]
endif
endif
let i = i + 1
endwhile
return parentclass
endfunction
" add a class to the menu
function! AddClass(classname, lineno, parentclass)
if len(a:parentclass) > 0
let classstring = a:parentclass.'\.'.a:classname
else
let classstring = a:classname
endif
exe 'menu IM-Python.classes.'.classstring.' :call <SID>JumpToAndUnfold('.a:lineno.')<CR>'
endfunction
" add a function to the menu, grouped by member class
function! AddFunction(functionname, lineno, parentclass)
if len(a:parentclass) > 0
let funcstring = a:parentclass.'.'.a:functionname
else
let funcstring = a:functionname
endif
exe 'menu IM-Python.functions.'.funcstring.' :call <SID>JumpToAndUnfold('.a:lineno.')<CR>'
endfunction
function! s:JumpToAndUnfold(line)
" Go to the right line
execute 'normal '.a:line.'gg'
" Check to see if we are in a fold
let lvl = foldlevel(a:line)
if lvl != 0
" and if so, then expand the fold out, other wise, ignore this part.
execute 'normal 15zo'
endif
endfunction
"" This one will work only on vim 6.2 because of the try/catch expressions.
" function! s:JumpToAndUnfoldWithExceptions(line)
" try
" execute 'normal '.a:line.'gg15zo'
" catch /^Vim\((\a\+)\)\=:E490:/
" " Do nothing, just consume the error
" endtry
"endfunction
" vim:set et sts=2 sw=2:

View File

@ -1,122 +0,0 @@
" Vim folding file
" Language: Python
" Author: Jorrit Wiersma (foldexpr), Max Ischenko (foldtext), Robert
" Ames (line counts)
" Last Change: 2005 Jul 14
" Version: 2.3
" Bug fix: Drexler Christopher, Tom Schumm, Geoff Gerrietts
setlocal foldmethod=expr
setlocal foldexpr=GetPythonFold(v:lnum)
setlocal foldtext=PythonFoldText()
function! PythonFoldText()
let line = getline(v:foldstart)
let nnum = nextnonblank(v:foldstart + 1)
let nextline = getline(nnum)
if nextline =~ '^\s\+"""$'
let line = line . getline(nnum + 1)
elseif nextline =~ '^\s\+"""'
let line = line . ' ' . matchstr(nextline, '"""\zs.\{-}\ze\("""\)\?$')
elseif nextline =~ '^\s\+"[^"]\+"$'
let line = line . ' ' . matchstr(nextline, '"\zs.*\ze"')
elseif nextline =~ '^\s\+pass\s*$'
let line = line . ' pass'
endif
let size = 1 + v:foldend - v:foldstart
if size < 10
let size = " " . size
endif
if size < 100
let size = " " . size
endif
if size < 1000
let size = " " . size
endif
return size . " lines: " . line
endfunction
function! GetPythonFold(lnum)
" Determine folding level in Python source
"
let line = getline(a:lnum)
let ind = indent(a:lnum)
" Ignore blank lines
if line =~ '^\s*$'
return "="
endif
" Ignore triple quoted strings
if line =~ "(\"\"\"|''')"
return "="
endif
" Ignore continuation lines
if line =~ '\\$'
return '='
endif
" Support markers
if line =~ '{{{'
return "a1"
elseif line =~ '}}}'
return "s1"
endif
" Classes and functions get their own folds
if line =~ '^\s*\(class\|def\)\s'
return ">" . (ind / &sw + 1)
endif
let pnum = prevnonblank(a:lnum - 1)
if pnum == 0
" Hit start of file
return 0
endif
" If the previous line has foldlevel zero, and we haven't increased
" it, we should have foldlevel zero also
if foldlevel(pnum) == 0
return 0
endif
" The end of a fold is determined through a difference in indentation
" between this line and the next.
" So first look for next line
let nnum = nextnonblank(a:lnum + 1)
if nnum == 0
return "="
endif
" First I check for some common cases where this algorithm would
" otherwise fail. (This is all a hack)
let nline = getline(nnum)
if nline =~ '^\s*\(except\|else\|elif\)'
return "="
endif
" Python programmers love their readable code, so they're usually
" going to have blank lines at the ends of functions or classes
" If the next line isn't blank, we probably don't need to end a fold
if nnum == a:lnum + 1
return "="
endif
" If next line has less indentation we end a fold.
" This ends folds that aren't there a lot of the time, and this sometimes
" confuses vim. Luckily only rarely.
let nind = indent(nnum)
if nind < ind
return "<" . (nind / &sw + 1)
endif
" If none of the above apply, keep the indentation
return "="
endfunction

View File

@ -1,293 +0,0 @@
""" Meager code path measurement tool.
Ned Batchelder
http://nedbatchelder.com/blog/200803/python_code_complexity_microtool.html
MIT License.
"""
try:
from compiler import parse # NOQA
iter_child_nodes = None # NOQA
except ImportError:
from ast import parse, iter_child_nodes # NOQA
import optparse
import sys
from collections import defaultdict
WARNING_CODE = "W901"
class ASTVisitor:
VERBOSE = 0
def __init__(self):
self.node = None
self._cache = {}
def default(self, node, *args):
if hasattr(node, 'getChildNodes'):
children = node.getChildNodes()
else:
children = iter_child_nodes(node)
for child in children:
self.dispatch(child, *args)
def dispatch(self, node, *args):
self.node = node
klass = node.__class__
meth = self._cache.get(klass)
if meth is None:
className = klass.__name__
meth = getattr(self.visitor, 'visit' + className, self.default)
self._cache[klass] = meth
return meth(node, *args)
def preorder(self, tree, visitor, *args):
"""Do preorder walk of tree using visitor"""
self.visitor = visitor
visitor.visit = self.dispatch
self.dispatch(tree, *args) # XXX *args make sense?
class PathNode:
def __init__(self, name, look="circle"):
self.name = name
self.look = look
def to_dot(self):
print('node [shape=%s,label="%s"] %d;' % \
(self.look, self.name, self.dot_id()))
def dot_id(self):
return id(self)
class PathGraph:
def __init__(self, name, entity, lineno):
self.name = name
self.entity = entity
self.lineno = lineno
self.nodes = defaultdict(list)
def connect(self, n1, n2):
self.nodes[n1].append(n2)
def to_dot(self):
print('subgraph {')
for node in self.nodes:
node.to_dot()
for node, nexts in self.nodes.items():
for next in nexts:
print('%s -- %s;' % (node.dot_id(), next.dot_id()))
print('}')
def complexity(self):
""" Return the McCabe complexity for the graph.
V-E+2
"""
num_edges = sum([len(n) for n in self.nodes.values()])
num_nodes = len(self.nodes)
return num_edges - num_nodes + 2
class PathGraphingAstVisitor(ASTVisitor):
""" A visitor for a parsed Abstract Syntax Tree which finds executable
statements.
"""
def __init__(self):
ASTVisitor.__init__(self)
self.classname = ""
self.graphs = {}
self.reset()
def reset(self):
self.graph = None
self.tail = None
def visitFunction(self, node):
if self.classname:
entity = '%s%s' % (self.classname, node.name)
else:
entity = node.name
name = '%d:1: %r' % (node.lineno, entity)
if self.graph is not None:
# closure
pathnode = self.appendPathNode(name)
self.tail = pathnode
self.default(node)
bottom = PathNode("", look='point')
self.graph.connect(self.tail, bottom)
self.graph.connect(pathnode, bottom)
self.tail = bottom
else:
self.graph = PathGraph(name, entity, node.lineno)
pathnode = PathNode(name)
self.tail = pathnode
self.default(node)
self.graphs["%s%s" % (self.classname, node.name)] = self.graph
self.reset()
visitFunctionDef = visitFunction
def visitClass(self, node):
old_classname = self.classname
self.classname += node.name + "."
self.default(node)
self.classname = old_classname
def appendPathNode(self, name):
if not self.tail:
return
pathnode = PathNode(name)
self.graph.connect(self.tail, pathnode)
self.tail = pathnode
return pathnode
def visitSimpleStatement(self, node):
if node.lineno is None:
lineno = 0
else:
lineno = node.lineno
name = "Stmt %d" % lineno
self.appendPathNode(name)
visitAssert = visitAssign = visitAssTuple = visitPrint = \
visitPrintnl = visitRaise = visitSubscript = visitDecorators = \
visitPass = visitDiscard = visitGlobal = visitReturn = \
visitSimpleStatement
def visitLoop(self, node):
name = "Loop %d" % node.lineno
if self.graph is None:
# global loop
self.graph = PathGraph(name, name, node.lineno)
pathnode = PathNode(name)
self.tail = pathnode
self.default(node)
self.graphs["%s%s" % (self.classname, name)] = self.graph
self.reset()
else:
pathnode = self.appendPathNode(name)
self.tail = pathnode
self.default(node.body)
bottom = PathNode("", look='point')
self.graph.connect(self.tail, bottom)
self.graph.connect(pathnode, bottom)
self.tail = bottom
# TODO: else clause in node.else_
visitFor = visitWhile = visitLoop
def visitIf(self, node):
name = "If %d" % node.lineno
pathnode = self.appendPathNode(name)
if not pathnode:
return # TODO: figure out what to do with if's outside def's.
loose_ends = []
for t, n in node.tests:
self.tail = pathnode
self.default(n)
loose_ends.append(self.tail)
if node.else_:
self.tail = pathnode
self.default(node.else_)
loose_ends.append(self.tail)
else:
loose_ends.append(pathnode)
bottom = PathNode("", look='point')
for le in loose_ends:
self.graph.connect(le, bottom)
self.tail = bottom
# TODO: visitTryExcept
# TODO: visitTryFinally
# TODO: visitWith
# XXX todo: determine which ones can add to the complexity
# py2
# TODO: visitStmt
# TODO: visitAssName
# TODO: visitCallFunc
# TODO: visitConst
# py3
# TODO: visitStore
# TODO: visitCall
# TODO: visitLoad
# TODO: visitNum
# TODO: visitarguments
# TODO: visitExpr
def get_code_complexity(code, min=7, filename='stdin'):
complex = []
try:
ast = parse(code)
except AttributeError:
e = sys.exc_info()[1]
sys.stderr.write("Unable to parse %s: %s\n" % (filename, e))
return 0
visitor = PathGraphingAstVisitor()
visitor.preorder(ast, visitor)
for graph in visitor.graphs.values():
if graph is None:
# ?
continue
if graph.complexity() >= min:
complex.append(dict(
type = 'W',
lnum = graph.lineno,
text = '%s %r is too complex (%d)' % (
WARNING_CODE,
graph.entity,
graph.complexity(),
)
))
return complex
def get_module_complexity(module_path, min=7):
"""Returns the complexity of a module"""
code = open(module_path, "rU").read() + '\n\n'
return get_code_complexity(code, min, filename=module_path)
def main(argv):
opar = optparse.OptionParser()
opar.add_option("-d", "--dot", dest="dot",
help="output a graphviz dot file", action="store_true")
opar.add_option("-m", "--min", dest="min",
help="minimum complexity for output", type="int",
default=2)
options, args = opar.parse_args(argv)
text = open(args[0], "rU").read() + '\n\n'
ast = parse(text)
visitor = PathGraphingAstVisitor()
visitor.preorder(ast, visitor)
if options.dot:
print('graph {')
for graph in visitor.graphs.values():
if graph.complexity() >= options.min:
graph.to_dot()
print('}')
else:
for graph in visitor.graphs.values():
if graph.complexity() >= options.min:
print(graph.name, graph.complexity())
if __name__ == '__main__':
main(sys.argv[1:])

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +0,0 @@
__version__ = '0.6.1'

View File

@ -1,130 +0,0 @@
"""
API for the command-line I{pyflakes} tool.
"""
import sys
import os
import _ast
from pyflakes import checker
from pyflakes import reporter as modReporter
__all__ = ['check', 'checkPath', 'checkRecursive', 'iterSourceCode', 'main']
def check(codeString, filename, reporter=None):
"""
Check the Python source given by C{codeString} for flakes.
@param codeString: The Python source to check.
@type codeString: C{str}
@param filename: The name of the file the source came from, used to report
errors.
@type filename: C{str}
@param reporter: A L{Reporter} instance, where errors and warnings will be
reported.
@return: The number of warnings emitted.
@rtype: C{int}
"""
if reporter is None:
reporter = modReporter._makeDefaultReporter()
# First, compile into an AST and handle syntax errors.
try:
tree = compile(codeString, filename, "exec", _ast.PyCF_ONLY_AST)
except SyntaxError:
value = sys.exc_info()[1]
msg = value.args[0]
(lineno, offset, text) = value.lineno, value.offset, value.text
# If there's an encoding problem with the file, the text is None.
if text is None:
# Avoid using msg, since for the only known case, it contains a
# bogus message that claims the encoding the file declared was
# unknown.
reporter.unexpectedError(filename, 'problem decoding source')
else:
reporter.syntaxError(filename, msg, lineno, offset, text)
return 1
except Exception:
reporter.unexpectedError(filename, 'problem decoding source')
return 1
else:
# Okay, it's syntactically valid. Now check it.
w = checker.Checker(tree, filename)
w.messages.sort(key=lambda m: m.lineno)
for warning in w.messages:
reporter.flake(warning)
return len(w.messages)
def checkPath(filename, reporter=None):
"""
Check the given path, printing out any warnings detected.
@param reporter: A L{Reporter} instance, where errors and warnings will be
reported.
@return: the number of warnings printed
"""
if reporter is None:
reporter = modReporter._makeDefaultReporter()
try:
f = open(filename, 'U')
try:
return check(f.read() + '\n', filename, reporter)
finally:
f.close()
except UnicodeError:
reporter.unexpectedError(filename, 'problem decoding source')
except IOError:
msg = sys.exc_info()[1]
reporter.unexpectedError(filename, msg.args[1])
return 1
def iterSourceCode(paths):
"""
Iterate over all Python source files in C{paths}.
@param paths: A list of paths. Directories will be recursed into and
any .py files found will be yielded. Any non-directories will be
yielded as-is.
"""
for path in paths:
if os.path.isdir(path):
for dirpath, dirnames, filenames in os.walk(path):
for filename in filenames:
if filename.endswith('.py'):
yield os.path.join(dirpath, filename)
else:
yield path
def checkRecursive(paths, reporter):
"""
Recursively check all source files in C{paths}.
@param paths: A list of paths to Python source files and directories
containing Python source files.
@param reporter: A L{Reporter} where all of the warnings and errors
will be reported to.
@return: The number of warnings found.
"""
warnings = 0
for sourcePath in iterSourceCode(paths):
warnings += checkPath(sourcePath, reporter)
return warnings
def main():
args = sys.argv[1:]
reporter = modReporter._makeDefaultReporter()
if args:
warnings = checkRecursive(args, reporter)
else:
warnings = check(sys.stdin.read(), '<stdin>', reporter)
raise SystemExit(warnings > 0)

View File

@ -1,723 +0,0 @@
# -*- test-case-name: pyflakes -*-
# (c) 2005-2010 Divmod, Inc.
# See LICENSE file for details
import os.path
try:
import builtins
PY2 = False
except ImportError:
import __builtin__ as builtins
PY2 = True
try:
import ast
iter_child_nodes = ast.iter_child_nodes
except (ImportError, AttributeError): # Python 2.5
import _ast as ast
def iter_child_nodes(node, astcls=ast.AST):
"""
Yield all direct child nodes of *node*, that is, all fields that are nodes
and all items of fields that are lists of nodes.
"""
for name in node._fields:
field = getattr(node, name, None)
if isinstance(field, astcls):
yield field
elif isinstance(field, list):
for item in field:
yield item
# Python >= 3.3 uses ast.Try instead of (ast.TryExcept + ast.TryFinally)
if hasattr(ast, 'Try'):
ast_TryExcept = ast.Try
ast_TryFinally = ()
else:
ast_TryExcept = ast.TryExcept
ast_TryFinally = ast.TryFinally
from pyflakes import messages
class Binding(object):
"""
Represents the binding of a value to a name.
The checker uses this to keep track of which names have been bound and
which names have not. See L{Assignment} for a special type of binding that
is checked with stricter rules.
@ivar used: pair of (L{Scope}, line-number) indicating the scope and
line number that this binding was last used
"""
def __init__(self, name, source):
self.name = name
self.source = source
self.used = False
def __str__(self):
return self.name
def __repr__(self):
return '<%s object %r from line %r at 0x%x>' % (self.__class__.__name__,
self.name,
self.source.lineno,
id(self))
class UnBinding(Binding):
"""Created by the 'del' operator."""
class Importation(Binding):
"""
A binding created by an import statement.
@ivar fullName: The complete name given to the import statement,
possibly including multiple dotted components.
@type fullName: C{str}
"""
def __init__(self, name, source):
self.fullName = name
name = name.split('.')[0]
super(Importation, self).__init__(name, source)
class Argument(Binding):
"""
Represents binding a name as an argument.
"""
class Definition(Binding):
"""
A binding that defines a function or a class.
"""
class Assignment(Binding):
"""
Represents binding a name with an explicit assignment.
The checker will raise warnings for any Assignment that isn't used. Also,
the checker does not consider assignments in tuple/list unpacking to be
Assignments, rather it treats them as simple Bindings.
"""
class FunctionDefinition(Definition):
pass
class ClassDefinition(Definition):
pass
class ExportBinding(Binding):
"""
A binding created by an C{__all__} assignment. If the names in the list
can be determined statically, they will be treated as names for export and
additional checking applied to them.
The only C{__all__} assignment that can be recognized is one which takes
the value of a literal list containing literal strings. For example::
__all__ = ["foo", "bar"]
Names which are imported and not otherwise used but appear in the value of
C{__all__} will not have an unused import warning reported for them.
"""
def names(self):
"""
Return a list of the names referenced by this binding.
"""
names = []
if isinstance(self.source, ast.List):
for node in self.source.elts:
if isinstance(node, ast.Str):
names.append(node.s)
return names
class Scope(dict):
importStarred = False # set to True when import * is found
usesLocals = False
def __repr__(self):
return '<%s at 0x%x %s>' % (self.__class__.__name__, id(self), dict.__repr__(self))
class ClassScope(Scope):
pass
class FunctionScope(Scope):
"""
I represent a name scope for a function.
@ivar globals: Names declared 'global' in this function.
"""
def __init__(self):
super(FunctionScope, self).__init__()
self.globals = {}
class ModuleScope(Scope):
pass
# Globally defined names which are not attributes of the builtins module, or
# are only present on some platforms.
_MAGIC_GLOBALS = ['__file__', '__builtins__', 'WindowsError']
def getNodeName(node):
# Returns node.id, or node.name, or None
if hasattr(node, 'id'): # One of the many nodes with an id
return node.id
if hasattr(node, 'name'): # a ExceptHandler node
return node.name
class Checker(object):
"""
I check the cleanliness and sanity of Python code.
@ivar _deferredFunctions: Tracking list used by L{deferFunction}. Elements
of the list are two-tuples. The first element is the callable passed
to L{deferFunction}. The second element is a copy of the scope stack
at the time L{deferFunction} was called.
@ivar _deferredAssignments: Similar to C{_deferredFunctions}, but for
callables which are deferred assignment checks.
"""
nodeDepth = 0
traceTree = False
builtIns = set(dir(builtins)) | set(_MAGIC_GLOBALS)
def __init__(self, tree, filename='(none)', builtins=None):
self._deferredFunctions = []
self._deferredAssignments = []
self.deadScopes = []
self.messages = []
self.filename = filename
if builtins:
self.builtIns = self.builtIns.union(builtins)
self.scopeStack = [ModuleScope()]
self.futuresAllowed = True
self.root = tree
self.handleChildren(tree)
self.runDeferred(self._deferredFunctions)
# Set _deferredFunctions to None so that deferFunction will fail
# noisily if called after we've run through the deferred functions.
self._deferredFunctions = None
self.runDeferred(self._deferredAssignments)
# Set _deferredAssignments to None so that deferAssignment will fail
# noisily if called after we've run through the deferred assignments.
self._deferredAssignments = None
del self.scopeStack[1:]
self.popScope()
self.checkDeadScopes()
def deferFunction(self, callable):
"""
Schedule a function handler to be called just before completion.
This is used for handling function bodies, which must be deferred
because code later in the file might modify the global scope. When
`callable` is called, the scope at the time this is called will be
restored, however it will contain any new bindings added to it.
"""
self._deferredFunctions.append((callable, self.scopeStack[:]))
def deferAssignment(self, callable):
"""
Schedule an assignment handler to be called just after deferred
function handlers.
"""
self._deferredAssignments.append((callable, self.scopeStack[:]))
def runDeferred(self, deferred):
"""
Run the callables in C{deferred} using their associated scope stack.
"""
for handler, scope in deferred:
self.scopeStack = scope
handler()
@property
def scope(self):
return self.scopeStack[-1]
def popScope(self):
self.deadScopes.append(self.scopeStack.pop())
def checkDeadScopes(self):
"""
Look at scopes which have been fully examined and report names in them
which were imported but unused.
"""
for scope in self.deadScopes:
export = isinstance(scope.get('__all__'), ExportBinding)
if export:
all = scope['__all__'].names()
if not scope.importStarred and os.path.basename(self.filename) != '__init__.py':
# Look for possible mistakes in the export list
undefined = set(all) - set(scope)
for name in undefined:
self.report(messages.UndefinedExport,
scope['__all__'].source.lineno, name)
else:
all = []
# Look for imported names that aren't used.
for importation in scope.values():
if isinstance(importation, Importation):
if not importation.used and importation.name not in all:
self.report(messages.UnusedImport,
importation.source.lineno, importation.name)
def pushFunctionScope(self):
self.scopeStack.append(FunctionScope())
def pushClassScope(self):
self.scopeStack.append(ClassScope())
def report(self, messageClass, *args, **kwargs):
self.messages.append(messageClass(self.filename, *args, **kwargs))
def hasParent(self, node, kind):
while hasattr(node, 'parent'):
node = node.parent
if isinstance(node, kind):
return True
def getCommonAncestor(self, lnode, rnode, stop=None):
if not stop:
stop = self.root
if lnode is rnode:
return lnode
if stop in (lnode, rnode):
return stop
if not hasattr(lnode, 'parent') or not hasattr(rnode, 'parent'):
return
if (lnode.level > rnode.level):
return self.getCommonAncestor(lnode.parent, rnode, stop)
if (rnode.level > lnode.level):
return self.getCommonAncestor(lnode, rnode.parent, stop)
return self.getCommonAncestor(lnode.parent, rnode.parent, stop)
def descendantOf(self, node, ancestors, stop=None):
for a in ancestors:
if self.getCommonAncestor(node, a, stop) not in (stop, None):
return True
return False
def onFork(self, parent, lnode, rnode, items):
return (self.descendantOf(lnode, items, parent) ^
self.descendantOf(rnode, items, parent))
def differentForks(self, lnode, rnode):
"""True, if lnode and rnode are located on different forks of IF/TRY"""
ancestor = self.getCommonAncestor(lnode, rnode)
if isinstance(ancestor, ast.If):
for fork in (ancestor.body, ancestor.orelse):
if self.onFork(ancestor, lnode, rnode, fork):
return True
elif isinstance(ancestor, ast_TryExcept):
body = ancestor.body + ancestor.orelse
for fork in [body] + [[hdl] for hdl in ancestor.handlers]:
if self.onFork(ancestor, lnode, rnode, fork):
return True
elif isinstance(ancestor, ast_TryFinally):
if self.onFork(ancestor, lnode, rnode, ancestor.body):
return True
return False
def addBinding(self, node, value, reportRedef=True):
"""
Called when a binding is altered.
- `node` is the statement responsible for the change
- `value` is the optional new value, a Binding instance, associated
with the binding; if None, the binding is deleted if it exists.
- if `reportRedef` is True (default), rebinding while unused will be
reported.
"""
redefinedWhileUnused = False
if not isinstance(self.scope, ClassScope):
for scope in self.scopeStack[::-1]:
existing = scope.get(value.name)
if (isinstance(existing, Importation)
and not existing.used
and (not isinstance(value, Importation) or value.fullName == existing.fullName)
and reportRedef
and not self.differentForks(node, existing.source)):
redefinedWhileUnused = True
self.report(messages.RedefinedWhileUnused,
node.lineno, value.name, existing.source.lineno)
existing = self.scope.get(value.name)
if not redefinedWhileUnused and self.hasParent(value.source, ast.ListComp):
if (existing and reportRedef
and not self.hasParent(existing.source, (ast.For, ast.ListComp))):
self.report(messages.RedefinedInListComp,
node.lineno, value.name, existing.source.lineno)
if isinstance(value, UnBinding):
try:
del self.scope[value.name]
except KeyError:
self.report(messages.UndefinedName, node.lineno, value.name)
elif (isinstance(existing, Definition)
and not existing.used
and not self.differentForks(node, existing.source)):
self.report(messages.RedefinedWhileUnused,
node.lineno, value.name, existing.source.lineno)
else:
self.scope[value.name] = value
def handleNodeLoad(self, node):
name = getNodeName(node)
if not name:
return
# try local scope
importStarred = self.scope.importStarred
try:
self.scope[name].used = (self.scope, node.lineno)
except KeyError:
pass
else:
return
# try enclosing function scopes
for scope in self.scopeStack[-2:0:-1]:
importStarred = importStarred or scope.importStarred
if not isinstance(scope, FunctionScope):
continue
try:
scope[name].used = (self.scope, node.lineno)
except KeyError:
pass
else:
return
# try global scope
importStarred = importStarred or self.scopeStack[0].importStarred
try:
self.scopeStack[0][name].used = (self.scope, node.lineno)
except KeyError:
if not importStarred and name not in self.builtIns:
if (os.path.basename(self.filename) == '__init__.py' and name == '__path__'):
# the special name __path__ is valid only in packages
pass
else:
self.report(messages.UndefinedName, node.lineno, name)
def handleNodeStore(self, node):
name = getNodeName(node)
if not name:
return
# if the name hasn't already been defined in the current scope
if isinstance(self.scope, FunctionScope) and name not in self.scope:
# for each function or module scope above us
for scope in self.scopeStack[:-1]:
if not isinstance(scope, (FunctionScope, ModuleScope)):
continue
# if the name was defined in that scope, and the name has
# been accessed already in the current scope, and hasn't
# been declared global
if (name in scope and scope[name].used and scope[name].used[0] is self.scope
and name not in self.scope.globals):
# then it's probably a mistake
self.report(messages.UndefinedLocal,
scope[name].used[1], name, scope[name].source.lineno)
break
parent = getattr(node, 'parent', None)
if isinstance(parent, (ast.For, ast.comprehension, ast.Tuple, ast.List)):
binding = Binding(name, node)
elif parent is not None and name == '__all__' and isinstance(self.scope, ModuleScope):
binding = ExportBinding(name, parent.value)
else:
binding = Assignment(name, node)
if name in self.scope:
binding.used = self.scope[name].used
self.addBinding(node, binding)
def handleNodeDelete(self, node):
name = getNodeName(node)
if not name:
return
if isinstance(self.scope, FunctionScope) and name in self.scope.globals:
del self.scope.globals[name]
else:
self.addBinding(node, UnBinding(name, node))
def handleChildren(self, tree):
for node in iter_child_nodes(tree):
self.handleNode(node, tree)
def isDocstring(self, node):
"""
Determine if the given node is a docstring, as long as it is at the
correct place in the node tree.
"""
return isinstance(node, ast.Str) or (isinstance(node, ast.Expr) and
isinstance(node.value, ast.Str))
def handleNode(self, node, parent):
if node is None:
return
node.parent = parent
if self.traceTree:
print(' ' * self.nodeDepth + node.__class__.__name__)
self.nodeDepth += 1
if self.futuresAllowed and not (isinstance(node, ast.ImportFrom) or
self.isDocstring(node)):
self.futuresAllowed = False
nodeType = node.__class__.__name__.upper()
node.level = self.nodeDepth
try:
handler = getattr(self, nodeType)
handler(node)
finally:
self.nodeDepth -= 1
if self.traceTree:
print(' ' * self.nodeDepth + 'end ' + node.__class__.__name__)
def ignore(self, node):
pass
# "stmt" type nodes
RETURN = DELETE = PRINT = WHILE = IF = WITH = WITHITEM = RAISE = \
TRYEXCEPT = TRYFINALLY = TRY = ASSERT = EXEC = EXPR = handleChildren
CONTINUE = BREAK = PASS = ignore
# "expr" type nodes
BOOLOP = BINOP = UNARYOP = IFEXP = DICT = SET = YIELD = YIELDFROM = \
COMPARE = CALL = REPR = ATTRIBUTE = SUBSCRIPT = LIST = TUPLE = \
STARRED = handleChildren
NUM = STR = BYTES = ELLIPSIS = ignore
# "slice" type nodes
SLICE = EXTSLICE = INDEX = handleChildren
# expression contexts are node instances too, though being constants
LOAD = STORE = DEL = AUGLOAD = AUGSTORE = PARAM = ignore
# same for operators
AND = OR = ADD = SUB = MULT = DIV = MOD = POW = LSHIFT = RSHIFT = \
BITOR = BITXOR = BITAND = FLOORDIV = INVERT = NOT = UADD = USUB = \
EQ = NOTEQ = LT = LTE = GT = GTE = IS = ISNOT = IN = NOTIN = ignore
# additional node types
COMPREHENSION = KEYWORD = handleChildren
def GLOBAL(self, node):
"""
Keep track of globals declarations.
"""
if isinstance(self.scope, FunctionScope):
self.scope.globals.update(dict.fromkeys(node.names))
NONLOCAL = GLOBAL
def LISTCOMP(self, node):
# handle generators before element
for gen in node.generators:
self.handleNode(gen, node)
self.handleNode(node.elt, node)
GENERATOREXP = SETCOMP = LISTCOMP
def DICTCOMP(self, node):
for gen in node.generators:
self.handleNode(gen, node)
self.handleNode(node.key, node)
self.handleNode(node.value, node)
def FOR(self, node):
"""
Process bindings for loop variables.
"""
vars = []
def collectLoopVars(n):
if isinstance(n, ast.Name):
vars.append(n.id)
elif isinstance(n, ast.expr_context):
return
else:
for c in iter_child_nodes(n):
collectLoopVars(c)
collectLoopVars(node.target)
for varn in vars:
if (isinstance(self.scope.get(varn), Importation)
# unused ones will get an unused import warning
and self.scope[varn].used):
self.report(messages.ImportShadowedByLoopVar,
node.lineno, varn, self.scope[varn].source.lineno)
self.handleChildren(node)
def NAME(self, node):
"""
Handle occurrence of Name (which can be a load/store/delete access.)
"""
if node.id == 'locals' and isinstance(node.parent, ast.Call):
# we are doing locals() call in current scope
self.scope.usesLocals = True
# Locate the name in locals / function / globals scopes.
if isinstance(node.ctx, (ast.Load, ast.AugLoad)):
self.handleNodeLoad(node)
elif isinstance(node.ctx, (ast.Store, ast.AugStore)):
self.handleNodeStore(node)
elif isinstance(node.ctx, ast.Del):
self.handleNodeDelete(node)
else:
# must be a Param context -- this only happens for names in function
# arguments, but these aren't dispatched through here
raise RuntimeError("Got impossible expression context: %r" % (node.ctx,))
def FUNCTIONDEF(self, node):
if not hasattr(node, 'decorator_list'): # Python 2.5
node.decorator_list = node.decorators
for deco in node.decorator_list:
self.handleNode(deco, node)
self.addBinding(node, FunctionDefinition(node.name, node))
self.LAMBDA(node)
def LAMBDA(self, node):
args = []
if PY2:
def addArgs(arglist):
for arg in arglist:
if isinstance(arg, ast.Tuple):
addArgs(arg.elts)
else:
if arg.id in args:
self.report(messages.DuplicateArgument,
node.lineno, arg.id)
args.append(arg.id)
addArgs(node.args.args)
defaults = node.args.defaults
else:
for arg in node.args.args + node.args.kwonlyargs:
if arg.arg in args:
self.report(messages.DuplicateArgument,
node.lineno, arg.arg)
args.append(arg.arg)
self.handleNode(arg.annotation, node)
if hasattr(node, 'returns'): # Only for FunctionDefs
for annotation in (node.args.varargannotation,
node.args.kwargannotation, node.returns):
self.handleNode(annotation, node)
defaults = node.args.defaults + node.args.kw_defaults
# vararg/kwarg identifiers are not Name nodes
for wildcard in (node.args.vararg, node.args.kwarg):
if not wildcard:
continue
if wildcard in args:
self.report(messages.DuplicateArgument, node.lineno, wildcard)
args.append(wildcard)
for default in defaults:
self.handleNode(default, node)
def runFunction():
self.pushFunctionScope()
for name in args:
self.addBinding(node, Argument(name, node), reportRedef=False)
if isinstance(node.body, list):
# case for FunctionDefs
for stmt in node.body:
self.handleNode(stmt, node)
else:
# case for Lambdas
self.handleNode(node.body, node)
def checkUnusedAssignments():
"""
Check to see if any assignments have not been used.
"""
for name, binding in self.scope.items():
if (not binding.used and name not in self.scope.globals
and not self.scope.usesLocals
and isinstance(binding, Assignment)):
self.report(messages.UnusedVariable,
binding.source.lineno, name)
self.deferAssignment(checkUnusedAssignments)
self.popScope()
self.deferFunction(runFunction)
def CLASSDEF(self, node):
"""
Check names used in a class definition, including its decorators, base
classes, and the body of its definition. Additionally, add its name to
the current scope.
"""
# no class decorator in Python 2.5
for deco in getattr(node, 'decorator_list', ''):
self.handleNode(deco, node)
for baseNode in node.bases:
self.handleNode(baseNode, node)
if not PY2:
for keywordNode in node.keywords:
self.handleNode(keywordNode, node)
self.pushClassScope()
for stmt in node.body:
self.handleNode(stmt, node)
self.popScope()
self.addBinding(node, ClassDefinition(node.name, node))
def ASSIGN(self, node):
self.handleNode(node.value, node)
for target in node.targets:
self.handleNode(target, node)
def AUGASSIGN(self, node):
self.handleNodeLoad(node.target)
self.handleNode(node.value, node)
self.handleNode(node.target, node)
def IMPORT(self, node):
for alias in node.names:
name = alias.asname or alias.name
importation = Importation(name, node)
self.addBinding(node, importation)
def IMPORTFROM(self, node):
if node.module == '__future__':
if not self.futuresAllowed:
self.report(messages.LateFutureImport,
node.lineno, [n.name for n in node.names])
else:
self.futuresAllowed = False
for alias in node.names:
if alias.name == '*':
self.scope.importStarred = True
self.report(messages.ImportStarUsed, node.lineno, node.module)
continue
name = alias.asname or alias.name
importation = Importation(name, node)
if node.module == '__future__':
importation.used = (self.scope, node.lineno)
self.addBinding(node, importation)
def EXCEPTHANDLER(self, node):
# 3.x: in addition to handling children, we must handle the name of
# the exception, which is not a Name node, but a simple string.
if isinstance(node.name, str):
self.handleNodeStore(node)
self.handleChildren(node)

View File

@ -1,113 +0,0 @@
# (c) 2005 Divmod, Inc. See LICENSE file for details
class Message(object):
message = ''
message_args = ()
def __init__(self, filename, lineno):
self.filename = filename
self.lineno = lineno
def __str__(self):
return '%s:%s: %s' % (self.filename, self.lineno, self.message % self.message_args)
class UnusedImport(Message):
message = '%r imported but unused'
def __init__(self, filename, lineno, name):
Message.__init__(self, filename, lineno)
self.message_args = (name,)
class RedefinedWhileUnused(Message):
message = 'redefinition of unused %r from line %r'
def __init__(self, filename, lineno, name, orig_lineno):
Message.__init__(self, filename, lineno)
self.message_args = (name, orig_lineno)
class RedefinedInListComp(Message):
message = 'list comprehension redefines %r from line %r'
def __init__(self, filename, lineno, name, orig_lineno):
Message.__init__(self, filename, lineno)
self.message_args = (name, orig_lineno)
class ImportShadowedByLoopVar(Message):
message = 'import %r from line %r shadowed by loop variable'
def __init__(self, filename, lineno, name, orig_lineno):
Message.__init__(self, filename, lineno)
self.message_args = (name, orig_lineno)
class ImportStarUsed(Message):
message = "'from %s import *' used; unable to detect undefined names"
def __init__(self, filename, lineno, modname):
Message.__init__(self, filename, lineno)
self.message_args = (modname,)
class UndefinedName(Message):
message = 'undefined name %r'
def __init__(self, filename, lineno, name):
Message.__init__(self, filename, lineno)
self.message_args = (name,)
class UndefinedExport(Message):
message = 'undefined name %r in __all__'
def __init__(self, filename, lineno, name):
Message.__init__(self, filename, lineno)
self.message_args = (name,)
class UndefinedLocal(Message):
message = "local variable %r (defined in enclosing scope on line %r) referenced before assignment"
def __init__(self, filename, lineno, name, orig_lineno):
Message.__init__(self, filename, lineno)
self.message_args = (name, orig_lineno)
class DuplicateArgument(Message):
message = 'duplicate argument %r in function definition'
def __init__(self, filename, lineno, name):
Message.__init__(self, filename, lineno)
self.message_args = (name,)
class Redefined(Message):
message = 'redefinition of %r from line %r'
def __init__(self, filename, lineno, name, orig_lineno):
Message.__init__(self, filename, lineno)
self.message_args = (name, orig_lineno)
class LateFutureImport(Message):
message = 'future import(s) %r after other statements'
def __init__(self, filename, lineno, names):
Message.__init__(self, filename, lineno)
self.message_args = (names,)
class UnusedVariable(Message):
"""
Indicates that a variable has been explicity assigned to but not actually
used.
"""
message = 'local variable %r is assigned to but never used'
def __init__(self, filename, lineno, names):
Message.__init__(self, filename, lineno)
self.message_args = (names,)

View File

@ -1,79 +0,0 @@
# (c) 2005-2012 Divmod, Inc.
# See LICENSE file for details
import sys
try:
u = unicode
except NameError:
u = str
class Reporter(object):
"""
Formats the results of pyflakes checks to users.
"""
def __init__(self, warningStream, errorStream):
"""
Construct a L{Reporter}.
@param warningStream: A file-like object where warnings will be
written to. The stream's C{write} method must accept unicode.
C{sys.stdout} is a good value.
@param errorStream: A file-like object where error output will be
written to. The stream's C{write} method must accept unicode.
C{sys.stderr} is a good value.
"""
self._stdout = warningStream
self._stderr = errorStream
def unexpectedError(self, filename, msg):
"""
An unexpected error occurred trying to process C{filename}.
@param filename: The path to a file that we could not process.
@ptype filename: C{unicode}
@param msg: A message explaining the problem.
@ptype msg: C{unicode}
"""
self._stderr.write(u("%s: %s\n") % (filename, msg))
def syntaxError(self, filename, msg, lineno, offset, text):
"""
There was a syntax errror in C{filename}.
@param filename: The path to the file with the syntax error.
@ptype filename: C{unicode}
@param msg: An explanation of the syntax error.
@ptype msg: C{unicode}
@param lineno: The line number where the syntax error occurred.
@ptype lineno: C{int}
@param offset: The column on which the syntax error occurred.
@ptype offset: C{int}
@param text: The source code containing the syntax error.
@ptype text: C{unicode}
"""
line = text.splitlines()[-1]
if offset is not None:
offset = offset - (len(text) - len(line))
self._stderr.write(u('%s:%d: %s\n') % (filename, lineno, msg))
self._stderr.write(u(line))
self._stderr.write(u('\n'))
if offset is not None:
self._stderr.write(u(" " * (offset + 1) + "^\n"))
def flake(self, message):
"""
pyflakes found something wrong with the code.
@param: A L{pyflakes.messages.Message}.
"""
self._stdout.write(u(message))
self._stdout.write(u('\n'))
def _makeDefaultReporter():
"""
Make a reporter that can be used when no reporter is specified.
"""
return Reporter(sys.stdout, sys.stderr)

3
gvimrc
View File

@ -32,9 +32,10 @@ if &background == "dark"
hi normal guibg=black
endif
colorscheme Tomorrow-Night-Eighties
" colorscheme railscasts
" colorscheme zenburn
colorscheme freya
" colorscheme freya
" colorscheme southwest-fog
" colorscheme moria
" colorscheme morning

View File

@ -1,38 +0,0 @@
" ---------------------------------------------------------------------
" getscriptPlugin.vim
" Author: Charles E. Campbell, Jr.
" Date: Jan 07, 2008
" Installing: :help glvs-install
" Usage: :help glvs
"
" GetLatestVimScripts: 642 1 :AutoInstall: getscript.vim
"
" (Rom 15:11 WEB) Again, "Praise the Lord, all you Gentiles! Let
" all the peoples praise Him."
" ---------------------------------------------------------------------
" Initialization: {{{1
" if you're sourcing this file, surely you can't be
" expecting vim to be in its vi-compatible mode
if &cp || exists("g:loaded_getscriptPlugin")
if &verbose
echo "GetLatestVimScripts is not vi-compatible; not loaded (you need to set nocp)"
endif
finish
endif
let g:loaded_getscriptPlugin = "v33"
let s:keepcpo = &cpo
set cpo&vim
" ---------------------------------------------------------------------
" Public Interface: {{{1
com! -nargs=0 GetLatestVimScripts call getscript#GetLatestVimScripts()
com! -nargs=0 GetScripts call getscript#GetLatestVimScripts()
silent! com -nargs=0 GLVS call getscript#GetLatestVimScripts()
" ---------------------------------------------------------------------
" Restore Options: {{{1
let &cpo= s:keepcpo
unlet s:keepcpo
" ---------------------------------------------------------------------
" vim: ts=8 sts=2 fdm=marker nowrap

View File

@ -1,113 +0,0 @@
" FILE: syntax/conque_term.vim {{{
" AUTHOR: Nico Raffo <nicoraffo@gmail.com>
" WEBSITE: http://conque.googlecode.com
" MODIFIED: 2011-08-12
" VERSION: 2.2, for Vim 7.0
" LICENSE:
" Conque - Vim terminal/console emulator
" Copyright (C) 2009-__YEAR__ 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.
" }}}
" *******************************************************************************************************************
" MySQL *************************************************************************************************************
" *******************************************************************************************************************
" TODO Move these to syntax which is only executed for mysql
"syn match MySQLTableBodyG "^\s*\w\+:\(.\+\)\=$" contains=MySQLTableHeadG,MySQLNullG,MySQLBool,MySQLNumberG,MySQLStorageClass oneline skipwhite skipnl
"syn match MySQLTableHeadG "^\s*\w\+:" contains=MySQLTableColon skipwhite contained
"syn match MySQLTableColon ":" contained
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\+\(\.\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 and interval is null on
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
if g:ConqueTerm_PromptRegex != ''
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
endif
" 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

3
vimrc
View File

@ -27,6 +27,7 @@ Plugin 'The-NERD-Tree'
Plugin 'open-terminal-filemanager'
Plugin 'Conque-Shell'
Plugin 'taglist-plus'
Plugin 'darfink/vim-plist'
Plugin 'vcscommand.vim'
Plugin 'TextFormat'
Plugin 'jsbeautify'
@ -36,6 +37,7 @@ Plugin 'vim-pandoc/vim-pandoc'
Plugin 'vim-pandoc/vim-pandoc-syntax'
Plugin 'bling/vim-airline'
Plugin 'saltstack/salt-vim'
Plugin 'andviro/flake8-vim'
call vundle#end() " required
@ -56,6 +58,7 @@ set expandtab
set softtabstop=4
" set autoindent
" set smartindent
let g:PyFlakeDisabledMessages = 'E128,E501,E116'
" Highlightinh in python:
let python_highlight_numbers = 1