##// END OF EJS Templates
Intercept <esc> avoid closing websocket on Firefox...
Intercept <esc> avoid closing websocket on Firefox Closes #1031; closes #1032 (rebased and fixed tiny typo)

File last commit:

r4872:34c10438
r5389:a329ff02
Show More
console_widget.py
625 lines | 22.4 KiB | text/x-python | PythonLexer
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 # encoding: utf-8
"""
gvaroquaux
Docstrings tweaks.
r1296 A Wx widget to act as a console and input commands.
This widget deals with prompts and provides an edit buffer
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 restricted to after the last prompt.
"""
__docformat__ = "restructuredtext en"
#-------------------------------------------------------------------------------
# Copyright (C) 2008 The IPython Development Team
#
# Distributed under the terms of the BSD License. The full license is
# in the file COPYING, distributed as part of this software.
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# Imports
#-------------------------------------------------------------------------------
import wx
import wx.stc as stc
Gael Varoquaux
Update wx frontend.
r1349 from wx.py import editwindow
Gael Varoquaux
Make synchronous printing work better.
r1618 import time
gvaroquaux
Make the wx frontend well-behaved under windows.
r1436 import sys
Laurent Dufrechou
better style handling + cleanup
r1835 import string
gvaroquaux
Make the wx frontend well-behaved under windows.
r1436 LINESEP = '\n'
if sys.platform == 'win32':
LINESEP = '\n\r'
Gael Varoquaux
Update wx frontend.
r1349
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 import re
# FIXME: Need to provide an API for non user-generated display on the
# screen: this should not be editable by the user.
Laurent Dufrechou
Full patch for better user color tweaking + patch for 'enter' synchro bug
r1834 #-------------------------------------------------------------------------------
Bernardo B. Marques
remove all trailling spaces
r4872 # Constants
Laurent Dufrechou
Full patch for better user color tweaking + patch for 'enter' synchro bug
r1834 #-------------------------------------------------------------------------------
_COMPLETE_BUFFER_MARKER = 31
_ERROR_MARKER = 30
_INPUT_MARKER = 29
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295
gvaroquaux
Make the wx frontend well-behaved under windows.
r1436 _DEFAULT_SIZE = 10
gvaroquaux
Better fonts on MacOSX....
r1502 if sys.platform == 'darwin':
Gael Varoquaux
Fix the default size under MacOSX.
r1667 _DEFAULT_SIZE = 12
Gael Varoquaux
Update wx frontend.
r1349
_DEFAULT_STYLE = {
Laurent Dufrechou
better style handling + cleanup
r1835 #background definition
Gael Varoquaux
Update wx frontend.
r1349 'default' : 'size:%d' % _DEFAULT_SIZE,
Gael Varoquaux
Get matching parenthesis to display well.
r1491 'bracegood' : 'fore:#00AA00,back:#000000,bold',
'bracebad' : 'fore:#FF0000,back:#000000,bold',
Gael Varoquaux
Update wx frontend.
r1349
Gael Varoquaux
MERGE Laurent's tweaks. Clean up'
r1893 # Edge column: a number of None
'edge_column' : -1,
Gael Varoquaux
Update wx frontend.
r1349 # properties for the various Python lexer styles
Gael Varoquaux
Nice background color for already entered code....
r1374 'comment' : 'fore:#007F00',
'number' : 'fore:#007F7F',
'string' : 'fore:#7F007F,italic',
'char' : 'fore:#7F007F,italic',
'keyword' : 'fore:#00007F,bold',
'triple' : 'fore:#7F0000',
'tripledouble' : 'fore:#7F0000',
'class' : 'fore:#0000FF,bold,underline',
'def' : 'fore:#007F7F,bold',
Gael Varoquaux
Take in account remarks by Fernando on code review
r1947 'operator' : 'bold',
# Default colors
'trace' : '#FAFAF1', # Nice green
'stdout' : '#FDFFD3', # Nice yellow
'stderr' : '#FFF1F1', # Nice red
# Default scintilla settings
'antialiasing' : True,
'carret_color' : 'BLACK',
Bernardo B. Marques
remove all trailling spaces
r4872 'background_color' :'WHITE',
Gael Varoquaux
Take in account remarks by Fernando on code review
r1947
#prompt definition
'prompt_in1' : \
'\n\x01\x1b[0;34m\x02In [\x01\x1b[1;34m\x02$number\x01\x1b[0;34m\x02]: \x01\x1b[0m\x02',
'prompt_out': \
'\x01\x1b[0;31m\x02Out[\x01\x1b[1;31m\x02$number\x01\x1b[0;31m\x02]: \x01\x1b[0m\x02',
Gael Varoquaux
Update wx frontend.
r1349 }
# new style numbers
_STDOUT_STYLE = 15
_STDERR_STYLE = 16
_TRACE_STYLE = 17
Gael Varoquaux
Improve tab-completion.
r1373 # system colors
Gael Varoquaux
Usability tweaks. Better auto tab completion. Terminal size more...
r1380 #SYS_COLOUR_BACKGROUND = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BACKGROUND)
Gael Varoquaux
Improve tab-completion.
r1373
Bernardo B. Marques
remove all trailling spaces
r4872 # Translation table from ANSI escape sequences to color.
Gael Varoquaux
MERGE Laurent's tweaks. Clean up'
r1893 ANSI_STYLES = {'0;30': [0, 'BLACK'], '0;31': [1, 'RED'],
'0;32': [2, 'GREEN'], '0;33': [3, 'BROWN'],
'0;34': [4, 'BLUE'], '0;35': [5, 'PURPLE'],
'0;36': [6, 'CYAN'], '0;37': [7, 'LIGHT GREY'],
'1;30': [8, 'DARK GREY'], '1;31': [9, 'RED'],
'1;32': [10, 'SEA GREEN'], '1;33': [11, 'YELLOW'],
Bernardo B. Marques
remove all trailling spaces
r4872 '1;34': [12, 'LIGHT BLUE'], '1;35':
Gael Varoquaux
MERGE Laurent's tweaks. Clean up'
r1893 [13, 'MEDIUM VIOLET RED'],
'1;36': [14, 'LIGHT STEEL BLUE'], '1;37': [15, 'YELLOW']}
Brian Granger
ColorANSI.py -> utils/coloransi.py and all imports updated.
r2010 # XXX: Maybe one day we should factor this code with coloransi. Right now
# coloransi is hard to reuse and makes our code more complex.
Gael Varoquaux
Take in account remarks by Fernando on code review
r1947
Gael Varoquaux
MERGE Laurent's tweaks. Clean up'
r1893 #we define platform specific fonts
if wx.Platform == '__WXMSW__':
FACES = { 'times': 'Times New Roman',
'mono' : 'Courier New',
'helv' : 'Arial',
'other': 'Comic Sans MS',
'size' : 10,
'size2': 8,
}
elif wx.Platform == '__WXMAC__':
FACES = { 'times': 'Times New Roman',
'mono' : 'Monaco',
'helv' : 'Arial',
'other': 'Comic Sans MS',
'size' : 10,
'size2': 8,
}
else:
FACES = { 'times': 'Times',
'mono' : 'Courier',
'helv' : 'Helvetica',
'other': 'new century schoolbook',
'size' : 10,
'size2': 8,
}
Bernardo B. Marques
remove all trailling spaces
r4872
Gael Varoquaux
MERGE Laurent's tweaks. Clean up'
r1893
Brian Granger
More work addressing review comments for Fernando's branch....
r2499 #-----------------------------------------------------------------------------
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 # The console widget class
Brian Granger
More work addressing review comments for Fernando's branch....
r2499 #-----------------------------------------------------------------------------
Gael Varoquaux
Update wx frontend.
r1349 class ConsoleWidget(editwindow.EditWindow):
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 """ Specialized styled text control view for console-like workflow.
gvaroquaux
Docstrings tweaks.
r1296
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 This widget is mainly interested in dealing with the prompt and
keeping the cursor inside the editing line.
"""
gvaroquaux
Clean up code, names, and docstrings.
r1455 # This is where the title captured from the ANSI escape sequences are
# stored.
Gael Varoquaux
Capture Xterm title sequence.
r1359 title = 'Console'
Gael Varoquaux
MERGE Laurent's tweaks. Clean up'
r1893 # Last prompt printed
last_prompt = ''
gvaroquaux
More code reuse between GUI-independant frontend and Wx frontend: getting...
r1462 # The buffer being edited.
def _set_input_buffer(self, string):
self.SetSelection(self.current_prompt_pos, self.GetLength())
self.ReplaceSelection(string)
self.GotoPos(self.GetLength())
def _get_input_buffer(self):
""" Returns the text in current edit buffer.
"""
input_buffer = self.GetTextRange(self.current_prompt_pos,
self.GetLength())
input_buffer = input_buffer.replace(LINESEP, '\n')
return input_buffer
input_buffer = property(_get_input_buffer, _set_input_buffer)
Gael Varoquaux
Update wx frontend.
r1349 style = _DEFAULT_STYLE.copy()
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 # Translation table from ANSI escape sequences to color. Override
# this to specify your colors.
Gael Varoquaux
MERGE Laurent's tweaks. Clean up'
r1893 ANSI_STYLES = ANSI_STYLES.copy()
Bernardo B. Marques
remove all trailling spaces
r4872
Gael Varoquaux
MERGE Laurent's tweaks. Clean up'
r1893 # Font faces
faces = FACES.copy()
Bernardo B. Marques
remove all trailling spaces
r4872
Gael Varoquaux
Make synchronous printing work better.
r1618 # Store the last time a refresh was done
_last_refresh_time = 0
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 #--------------------------------------------------------------------------
# Public API
#--------------------------------------------------------------------------
Bernardo B. Marques
remove all trailling spaces
r4872
def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
gvaroquaux
Misspelling in a docstring.
r1630 size=wx.DefaultSize, style=wx.WANTS_CHARS, ):
Gael Varoquaux
Update wx frontend.
r1349 editwindow.EditWindow.__init__(self, parent, id, pos, size, style)
Laurent Dufrechou
better style handling + cleanup
r1835 self.configure_scintilla()
Gael Varoquaux
MERGE Laurent's tweaks. Clean up'
r1893 # Track if 'enter' key as ever been processed
# This variable will only be reallowed until key goes up
Bernardo B. Marques
remove all trailling spaces
r4872 self.enter_catched = False
Laurent Dufrechou
Full patch for better user color tweaking + patch for 'enter' synchro bug
r1834 self.current_prompt_pos = 0
Gael Varoquaux
Update wx frontend.
r1349
self.Bind(wx.EVT_KEY_DOWN, self._on_key_down)
Gael Varoquaux
History is now working. + misc keybindings.
r1358 self.Bind(wx.EVT_KEY_UP, self._on_key_up)
Bernardo B. Marques
remove all trailling spaces
r4872
Gael Varoquaux
Update wx frontend.
r1349
gvaroquaux
Make process execution work under windows.
r1449 def write(self, text, refresh=True):
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 """ Write given text to buffer, while translating the ansi escape
sequences.
"""
Bernardo B. Marques
remove all trailling spaces
r4872 # XXX: do not put print statements to sys.stdout/sys.stderr in
# this method, the print statements will call this method, as
Gael Varoquaux
First cut of subprocess execution with redirection of stdin/stdout.
r1437 # you will end up with an infinit loop
Gael Varoquaux
Capture Xterm title sequence.
r1359 title = self.title_pat.split(text)
Gael Varoquaux
Clean up the title-setting code.
r1393 if len(title)>1:
self.title = title[-2]
Gael Varoquaux
Capture Xterm title sequence.
r1359
text = self.title_pat.sub('', text)
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 segments = self.color_pat.split(text)
segment = segments.pop(0)
gvaroquaux
Make the wx frontend well-behaved under windows.
r1436 self.GotoPos(self.GetLength())
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 self.StartStyling(self.GetLength(), 0xFF)
Gael Varoquaux
Fix for Unicode characters when executing processes. Also fix typo in...
r1451 try:
self.AppendText(segment)
except UnicodeDecodeError:
# XXX: Do I really want to skip the exception?
pass
Bernardo B. Marques
remove all trailling spaces
r4872
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 if segments:
Gael Varoquaux
Correct styling of ANSI patterns.
r1386 for ansi_tag, text in zip(segments[::2], segments[1::2]):
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 self.StartStyling(self.GetLength(), 0xFF)
Gael Varoquaux
Fix for Unicode characters when executing processes. Also fix typo in...
r1451 try:
self.AppendText(text)
except UnicodeDecodeError:
# XXX: Do I really want to skip the exception?
pass
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295
Gael Varoquaux
Tweak magics.
r1424 if ansi_tag not in self.ANSI_STYLES:
Gael Varoquaux
Correct styling of ANSI patterns.
r1386 style = 0
else:
style = self.ANSI_STYLES[ansi_tag][0]
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295
Bernardo B. Marques
remove all trailling spaces
r4872 self.SetStyling(len(text), style)
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 self.GotoPos(self.GetLength())
gvaroquaux
Make process execution work under windows.
r1449 if refresh:
Gael Varoquaux
Make synchronous printing work better.
r1618 current_time = time.time()
if current_time - self._last_refresh_time > 0.03:
gvaroquaux
Another attempt at fixing raw_input/program execution under windows...
r1653 if sys.platform == 'win32':
wx.SafeYield()
else:
wx.Yield()
gvaroquaux
Tweak to have windows show tracebacks.
r1651 # self.ProcessEvent(wx.PaintEvent())
Bernardo B. Marques
remove all trailling spaces
r4872 self._last_refresh_time = current_time
gvaroquaux
Make the wx frontend well-behaved under windows.
r1436
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 def new_prompt(self, prompt):
""" Prints a prompt at start of line, and move the start of the
current block there.
gvaroquaux
Spelling
r1465 The prompt can be given with ascii escape sequences.
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 """
Gael Varoquaux
Add a banner.
r1495 self.write(prompt, refresh=False)
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 # now we update our cursor giving end of prompt
self.current_prompt_pos = self.GetLength()
self.current_prompt_line = self.GetCurrentLine()
Gael Varoquaux
Rework multiline input
r1361 self.EnsureCaretVisible()
Gael Varoquaux
MERGE Laurent's tweaks. Clean up'
r1893 self.last_prompt = prompt
Gael Varoquaux
Rework multiline input
r1361
Gael Varoquaux
MERGE Laurent's tweaks. Clean up'
r1893 def continuation_prompt(self):
Gael Varoquaux
ENH: Backspace now deletes continuation lines
r1894 """ Returns the current continuation prompt.
We need to implement this method here to deal with the
ascii escape sequences cleaning up.
Gael Varoquaux
MERGE Laurent's tweaks. Clean up'
r1893 """
# ASCII-less prompt
ascii_less = ''.join(self.color_pat.split(self.last_prompt)[2::2])
return "."*(len(ascii_less)-2) + ': '
Bernardo B. Marques
remove all trailling spaces
r4872
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295
gvaroquaux
Clean up code, names, and docstrings.
r1455 def scroll_to_bottom(self):
maxrange = self.GetScrollRange(wx.VERTICAL)
self.ScrollLines(maxrange)
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295
gvaroquaux
Clean up code, names, and docstrings.
r1455 def pop_completion(self, possibilities, offset=0):
""" Pops up an autocompletion menu. Offset is the offset
in characters of the position at which the menu should
appear, relativ to the cursor.
"""
self.AutoCompSetIgnoreCase(False)
self.AutoCompSetAutoHide(False)
self.AutoCompSetMaxHeight(len(possibilities))
self.AutoCompShow(offset, " ".join(possibilities))
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295
gvaroquaux
Abstract completion mechanism outside of wx-specific code.
r1463 def get_line_width(self):
""" Return the width of the line in characters.
"""
return self.GetSize()[0]/self.GetCharWidth()
Gael Varoquaux
ENH: Add continuation prompts
r1884
Laurent Dufrechou
better style handling + cleanup
r1835 def configure_scintilla(self):
Gael Varoquaux
Take in account remarks by Fernando on code review
r1947 """ Set up all the styling option of the embedded scintilla
widget.
"""
p = self.style.copy()
Bernardo B. Marques
remove all trailling spaces
r4872
Laurent Dufrechou
Full patch for better user color tweaking + patch for 'enter' synchro bug
r1834 # Marker for complete buffer.
self.MarkerDefine(_COMPLETE_BUFFER_MARKER, stc.STC_MARK_BACKGROUND,
Gael Varoquaux
Take in account remarks by Fernando on code review
r1947 background=p['trace'])
Laurent Dufrechou
better style handling + cleanup
r1835
Laurent Dufrechou
Full patch for better user color tweaking + patch for 'enter' synchro bug
r1834 # Marker for current input buffer.
self.MarkerDefine(_INPUT_MARKER, stc.STC_MARK_BACKGROUND,
Gael Varoquaux
Take in account remarks by Fernando on code review
r1947 background=p['stdout'])
Laurent Dufrechou
Full patch for better user color tweaking + patch for 'enter' synchro bug
r1834 # Marker for tracebacks.
self.MarkerDefine(_ERROR_MARKER, stc.STC_MARK_BACKGROUND,
Gael Varoquaux
Take in account remarks by Fernando on code review
r1947 background=p['stderr'])
gvaroquaux
Clean up code, names, and docstrings.
r1455
self.SetEOLMode(stc.STC_EOL_LF)
Bernardo B. Marques
remove all trailling spaces
r4872 # Ctrl"+" or Ctrl "-" can be used to zoomin/zoomout the text inside
gvaroquaux
Clean up code, names, and docstrings.
r1455 # the widget
self.CmdKeyAssign(ord('+'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
self.CmdKeyAssign(ord('-'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
Bernardo B. Marques
remove all trailling spaces
r4872 # Also allow Ctrl Shift "=" for poor non US keyboard users.
self.CmdKeyAssign(ord('='), stc.STC_SCMOD_CTRL|stc.STC_SCMOD_SHIFT,
gvaroquaux
Clean up code, names, and docstrings.
r1455 stc.STC_CMD_ZOOMIN)
Bernardo B. Marques
remove all trailling spaces
r4872
gvaroquaux
Clean up code, names, and docstrings.
r1455 # Keys: we need to clear some of the keys the that don't play
# well with a console.
self.CmdKeyClear(ord('D'), stc.STC_SCMOD_CTRL)
self.CmdKeyClear(ord('L'), stc.STC_SCMOD_CTRL)
self.CmdKeyClear(ord('T'), stc.STC_SCMOD_CTRL)
Gael Varoquaux
Add better keybindings.
r1498 self.CmdKeyClear(ord('A'), stc.STC_SCMOD_CTRL)
gvaroquaux
Clean up code, names, and docstrings.
r1455
self.SetEOLMode(stc.STC_EOL_CRLF)
self.SetWrapMode(stc.STC_WRAP_CHAR)
self.SetWrapMode(stc.STC_WRAP_WORD)
self.SetBufferedDraw(True)
Laurent Dufrechou
added antialiasing option
r1836
Gael Varoquaux
Take in account remarks by Fernando on code review
r1947 self.SetUseAntiAliasing(p['antialiasing'])
Laurent Dufrechou
added antialiasing option
r1836
gvaroquaux
Clean up code, names, and docstrings.
r1455 self.SetLayoutCache(stc.STC_CACHE_PAGE)
self.SetUndoCollection(False)
self.SetUseTabs(True)
self.SetIndent(4)
self.SetTabWidth(4)
Bernardo B. Marques
remove all trailling spaces
r4872 # we don't want scintilla's autocompletion to choose
gvaroquaux
Clean up code, names, and docstrings.
r1455 # automaticaly out of a single choice list, as we pop it up
# automaticaly
self.AutoCompSetChooseSingle(False)
self.AutoCompSetMaxHeight(10)
Gael Varoquaux
Better tab-completion when the autocomp menu is displayed.
r1493 # XXX: this doesn't seem to have an effect.
self.AutoCompSetFillUps('\n')
gvaroquaux
Clean up code, names, and docstrings.
r1455
self.SetMargins(3, 3) #text is moved away from border with 3px
# Suppressing Scintilla margins
self.SetMarginWidth(0, 0)
self.SetMarginWidth(1, 0)
self.SetMarginWidth(2, 0)
# Xterm escape sequences
self.color_pat = re.compile('\x01?\x1b\[(.*?)m\x02?')
self.title_pat = re.compile('\x1b]0;(.*?)\x07')
# styles
Bernardo B. Marques
remove all trailling spaces
r4872
Gael Varoquaux
Take in account remarks by Fernando on code review
r1947 self.SetCaretForeground(p['carret_color'])
Bernardo B. Marques
remove all trailling spaces
r4872
Gael Varoquaux
Take in account remarks by Fernando on code review
r1947 background_color = p['background_color']
Bernardo B. Marques
remove all trailling spaces
r4872
Laurent Dufrechou
Full patch for better user color tweaking + patch for 'enter' synchro bug
r1834 if 'default' in p:
Laurent Dufrechou
better style handling + cleanup
r1835 if 'back' not in p['default']:
Gael Varoquaux
MERGE Laurent's tweaks. Clean up'
r1893 p['default'] += ',back:%s' % background_color
Laurent Dufrechou
better style handling + cleanup
r1835 if 'size' not in p['default']:
Gael Varoquaux
MERGE Laurent's tweaks. Clean up'
r1893 p['default'] += ',size:%s' % self.faces['size']
Laurent Dufrechou
better style handling + cleanup
r1835 if 'face' not in p['default']:
Gael Varoquaux
MERGE Laurent's tweaks. Clean up'
r1893 p['default'] += ',face:%s' % self.faces['mono']
Bernardo B. Marques
remove all trailling spaces
r4872
Laurent Dufrechou
Full patch for better user color tweaking + patch for 'enter' synchro bug
r1834 self.StyleSetSpec(stc.STC_STYLE_DEFAULT, p['default'])
else:
Bernardo B. Marques
remove all trailling spaces
r4872 self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
"fore:%s,back:%s,size:%d,face:%s"
% (self.ANSI_STYLES['0;30'][1],
Gael Varoquaux
MERGE Laurent's tweaks. Clean up'
r1893 background_color,
self.faces['size'], self.faces['mono']))
Bernardo B. Marques
remove all trailling spaces
r4872
gvaroquaux
Clean up code, names, and docstrings.
r1455 self.StyleClearAll()
Bernardo B. Marques
remove all trailling spaces
r4872
# XXX: two lines below are usefull if not using the lexer
Laurent Dufrechou
Full patch for better user color tweaking + patch for 'enter' synchro bug
r1834 #for style in self.ANSI_STYLES.values():
Bernardo B. Marques
remove all trailling spaces
r4872 # self.StyleSetSpec(style[0], "bold,fore:%s" % style[1])
Laurent Dufrechou
Full patch for better user color tweaking + patch for 'enter' synchro bug
r1834
Gael Varoquaux
Take in account remarks by Fernando on code review
r1947 # prompt definition
self.prompt_in1 = p['prompt_in1']
self.prompt_out = p['prompt_out']
Laurent Dufrechou
better style handling + cleanup
r1835
self.output_prompt_template = string.Template(self.prompt_out)
self.input_prompt_template = string.Template(self.prompt_in1)
Gael Varoquaux
Take in account remarks by Fernando on code review
r1947 self.StyleSetSpec(_STDOUT_STYLE, p['stdout'])
self.StyleSetSpec(_STDERR_STYLE, p['stderr'])
self.StyleSetSpec(_TRACE_STYLE, p['trace'])
self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT, p['bracegood'])
self.StyleSetSpec(stc.STC_STYLE_BRACEBAD, p['bracebad'])
self.StyleSetSpec(stc.STC_P_COMMENTLINE, p['comment'])
self.StyleSetSpec(stc.STC_P_NUMBER, p['number'])
self.StyleSetSpec(stc.STC_P_STRING, p['string'])
self.StyleSetSpec(stc.STC_P_CHARACTER, p['char'])
self.StyleSetSpec(stc.STC_P_WORD, p['keyword'])
self.StyleSetSpec(stc.STC_P_WORD2, p['keyword'])
self.StyleSetSpec(stc.STC_P_TRIPLE, p['triple'])
self.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE, p['tripledouble'])
self.StyleSetSpec(stc.STC_P_CLASSNAME, p['class'])
self.StyleSetSpec(stc.STC_P_DEFNAME, p['def'])
self.StyleSetSpec(stc.STC_P_OPERATOR, p['operator'])
self.StyleSetSpec(stc.STC_P_COMMENTBLOCK, p['comment'])
edge_column = p['edge_column']
if edge_column is not None and edge_column > 0:
#we add a vertical line to console widget
self.SetEdgeMode(stc.STC_EDGE_LINE)
self.SetEdgeColumn(edge_column)
Bernardo B. Marques
remove all trailling spaces
r4872
Gael Varoquaux
ENH: Backspace now deletes continuation lines
r1894 #--------------------------------------------------------------------------
# EditWindow API
#--------------------------------------------------------------------------
def OnUpdateUI(self, event):
Bernardo B. Marques
remove all trailling spaces
r4872 """ Override the OnUpdateUI of the EditWindow class, to prevent
Gael Varoquaux
ENH: Backspace now deletes continuation lines
r1894 syntax highlighting both for faster redraw, and for more
consistent look and feel.
"""
Bernardo B. Marques
remove all trailling spaces
r4872
Laurent Dufrechou
better style handling + cleanup
r1835 #--------------------------------------------------------------------------
# Private API
#--------------------------------------------------------------------------
Bernardo B. Marques
remove all trailling spaces
r4872
Gael Varoquaux
Update wx frontend.
r1349 def _on_key_down(self, event, skip=True):
Bernardo B. Marques
remove all trailling spaces
r4872 """ Key press callback used for correcting behavior for
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 console-like interfaces: the cursor is constraint to be after
the last prompt.
Return True if event as been catched.
"""
Gael Varoquaux
Added "ctr-K" to delete current buffer.
r1363 catched = True
Gael Varoquaux
ENH: Enter adds lines at the right position
r1896 # XXX: Would the right way to do this be to have a
# dictionary at the instance level associating keys with
# callbacks? How would we deal with inheritance? And Do the
# different callbacks share local variables?
Gael Varoquaux
History is now working. + misc keybindings.
r1358 # Intercept some specific keys.
Gael Varoquaux
BUG: Make the frontend compatible with wxPython 2.6
r2001 key_code = event.GetKeyCode()
if key_code == ord('L') and event.ControlDown() :
Gael Varoquaux
Update wx frontend.
r1349 self.scroll_to_bottom()
Gael Varoquaux
BUG: Make the frontend compatible with wxPython 2.6
r2001 elif key_code == ord('K') and event.ControlDown() :
gvaroquaux
More code reuse between GUI-independant frontend and Wx frontend: getting...
r1462 self.input_buffer = ''
Gael Varoquaux
BUG: Make the frontend compatible with wxPython 2.6
r2001 elif key_code == ord('A') and event.ControlDown() :
Gael Varoquaux
Add better keybindings.
r1498 self.GotoPos(self.GetLength())
self.SetSelectionStart(self.current_prompt_pos)
self.SetSelectionEnd(self.GetCurrentPos())
catched = True
Gael Varoquaux
BUG: Make the frontend compatible with wxPython 2.6
r2001 elif key_code == ord('E') and event.ControlDown() :
Gael Varoquaux
Add better keybindings.
r1498 self.GotoPos(self.GetLength())
catched = True
Gael Varoquaux
BUG: Make the frontend compatible with wxPython 2.6
r2001 elif key_code == wx.WXK_PAGEUP:
Gael Varoquaux
History is now working. + misc keybindings.
r1358 self.ScrollPages(-1)
Gael Varoquaux
BUG: Make the frontend compatible with wxPython 2.6
r2001 elif key_code == wx.WXK_PAGEDOWN:
Gael Varoquaux
History is now working. + misc keybindings.
r1358 self.ScrollPages(1)
Gael Varoquaux
BUG: Make the frontend compatible with wxPython 2.6
r2001 elif key_code == wx.WXK_HOME:
Gael Varoquaux
ENH: Enter adds lines at the right position
r1896 self.GotoPos(self.GetLength())
Gael Varoquaux
BUG: Make the frontend compatible with wxPython 2.6
r2001 elif key_code == wx.WXK_END:
Gael Varoquaux
ENH: Enter adds lines at the right position
r1896 self.GotoPos(self.GetLength())
Gael Varoquaux
BUG: Make the frontend compatible with wxPython 2.6
r2001 elif key_code == wx.WXK_UP and event.ShiftDown():
Gael Varoquaux
Usability tweaks. Better auto tab completion. Terminal size more...
r1380 self.ScrollLines(-1)
Gael Varoquaux
BUG: Make the frontend compatible with wxPython 2.6
r2001 elif key_code == wx.WXK_DOWN and event.ShiftDown():
Gael Varoquaux
Minor bug.
r1389 self.ScrollLines(1)
Gael Varoquaux
Added "ctr-K" to delete current buffer.
r1363 else:
catched = False
Gael Varoquaux
Update wx frontend.
r1349
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 if self.AutoCompActive():
event.Skip()
else:
Gael Varoquaux
BUG: Make the frontend compatible with wxPython 2.6
r2001 if key_code in (13, wx.WXK_NUMPAD_ENTER):
# XXX: not catching modifiers, to be wx2.6-compatible
Gael Varoquaux
History is now working. + misc keybindings.
r1358 catched = True
Laurent Dufrechou
better style handling + cleanup
r1835 if not self.enter_catched:
Laurent Dufrechou
Full patch for better user color tweaking + patch for 'enter' synchro bug
r1834 self.CallTipCancel()
Gael Varoquaux
BUG: Make the frontend compatible with wxPython 2.6
r2001 if event.ShiftDown():
Gael Varoquaux
ENH: Enter adds lines at the right position
r1896 # Try to force execution
self.GotoPos(self.GetLength())
Bernardo B. Marques
remove all trailling spaces
r4872 self.write('\n' + self.continuation_prompt(),
Gael Varoquaux
ENH: Enter adds lines at the right position
r1896 refresh=False)
self._on_enter()
else:
self._on_enter()
Laurent Dufrechou
Full patch for better user color tweaking + patch for 'enter' synchro bug
r1834 self.enter_catched = True
Gael Varoquaux
History is now working. + misc keybindings.
r1358
Gael Varoquaux
BUG: Make the frontend compatible with wxPython 2.6
r2001 elif key_code == wx.WXK_HOME:
if not event.ShiftDown():
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 self.GotoPos(self.current_prompt_pos)
catched = True
Gael Varoquaux
BUG: Make the frontend compatible with wxPython 2.6
r2001 else:
Gael Varoquaux
History is now working. + misc keybindings.
r1358 # FIXME: This behavior is not ideal: if the selection
# is already started, it will jump.
Bernardo B. Marques
remove all trailling spaces
r4872 self.SetSelectionStart(self.current_prompt_pos)
Gael Varoquaux
History is now working. + misc keybindings.
r1358 self.SetSelectionEnd(self.GetCurrentPos())
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 catched = True
Gael Varoquaux
BUG: Make the frontend compatible with wxPython 2.6
r2001 elif key_code == wx.WXK_UP:
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 if self.GetCurrentLine() > self.current_prompt_line:
if self.GetCurrentLine() == self.current_prompt_line + 1 \
and self.GetColumn(self.GetCurrentPos()) < \
self.GetColumn(self.current_prompt_pos):
self.GotoPos(self.current_prompt_pos)
else:
event.Skip()
catched = True
Gael Varoquaux
BUG: Make the frontend compatible with wxPython 2.6
r2001 elif key_code in (wx.WXK_LEFT, wx.WXK_BACK):
Gael Varoquaux
ENH: Better handling of continuation lines
r1886 if not self._keep_cursor_in_buffer(self.GetCurrentPos() - 1):
event.Skip()
catched = True
Gael Varoquaux
BUG: Make the frontend compatible with wxPython 2.6
r2001 elif key_code == wx.WXK_RIGHT:
Gael Varoquaux
ENH: Better handling of continuation lines
r1886 if not self._keep_cursor_in_buffer(self.GetCurrentPos() + 1):
event.Skip()
catched = True
Gael Varoquaux
BUG: Make the frontend compatible with wxPython 2.6
r2001 elif key_code == wx.WXK_DELETE:
Gael Varoquaux
ENH: Better handling of continuation lines
r1886 if not self._keep_cursor_in_buffer(self.GetCurrentPos() - 1):
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 event.Skip()
catched = True
if skip and not catched:
gvaroquaux
Make the wx frontend well-behaved under windows.
r1436 # Put the cursor back in the edit region
Gael Varoquaux
ENH: Add continuation prompts
r1884 if not self._keep_cursor_in_buffer():
Gael Varoquaux
ENH: Better handling of continuation lines
r1886 if not (self.GetCurrentPos() == self.GetLength()
Gael Varoquaux
BUG: Make the frontend compatible with wxPython 2.6
r2001 and key_code == wx.WXK_DELETE):
Gael Varoquaux
ENH: Better handling of continuation lines
r1886 event.Skip()
catched = True
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295
return catched
Gael Varoquaux
History is now working. + misc keybindings.
r1358 def _on_key_up(self, event, skip=True):
""" If cursor is outside the editing region, put it back.
"""
Gael Varoquaux
ENH: Add continuation prompts
r1884 if skip:
event.Skip()
self._keep_cursor_in_buffer()
Gael Varoquaux
ENH: Backspace now deletes continuation lines
r1894 # XXX: I need to avoid the problem of having an empty glass;
Gael Varoquaux
ENH: Better handling of continuation lines
r1886 def _keep_cursor_in_buffer(self, pos=None):
Gael Varoquaux
ENH: Add continuation prompts
r1884 """ Checks if the cursor is where it is allowed to be. If not,
put it back.
Returns
-------
cursor_moved: Boolean
whether or not the cursor was moved by this routine.
Notes
------
WARNING: This does proper checks only for horizontal
movements.
"""
Gael Varoquaux
ENH: Better handling of continuation lines
r1886 if pos is None:
current_pos = self.GetCurrentPos()
else:
current_pos = pos
Gael Varoquaux
ENH: Add continuation prompts
r1884 if current_pos < self.current_prompt_pos:
Gael Varoquaux
History is now working. + misc keybindings.
r1358 self.GotoPos(self.current_prompt_pos)
Gael Varoquaux
ENH: Add continuation prompts
r1884 return True
Gael Varoquaux
ENH: Better handling of continuation lines
r1886 line_num = self.LineFromPosition(current_pos)
if not current_pos > self.GetLength():
line_pos = self.GetColumn(current_pos)
else:
line_pos = self.GetColumn(self.GetLength())
line = self.GetLine(line_num)
Gael Varoquaux
ENH: Add continuation prompts
r1884 # Jump the continuation prompt
continuation_prompt = self.continuation_prompt()
if ( line.startswith(continuation_prompt)
Gael Varoquaux
ENH: Backspace now deletes continuation lines
r1894 and line_pos < len(continuation_prompt)):
Gael Varoquaux
ENH: Add continuation prompts
r1884 if line_pos < 2:
# We are at the beginning of the line, trying to move
# forward: jump forward.
self.GotoPos(current_pos + 1 +
len(continuation_prompt) - line_pos)
else:
# Jump back up
Gael Varoquaux
ENH: Better handling of continuation lines
r1886 self.GotoPos(self.GetLineEndPosition(line_num-1))
return True
Bernardo B. Marques
remove all trailling spaces
r4872 elif ( current_pos > self.GetLineEndPosition(line_num)
and not current_pos == self.GetLength()):
Gael Varoquaux
ENH: Better handling of continuation lines
r1886 # Jump to next line
self.GotoPos(current_pos + 1 +
len(continuation_prompt))
Gael Varoquaux
ENH: Add continuation prompts
r1884 return True
Gael Varoquaux
History is now working. + misc keybindings.
r1358
Gael Varoquaux
Minor formatting.
r1897 # We re-allow enter event processing
Bernardo B. Marques
remove all trailling spaces
r4872 self.enter_catched = False
Gael Varoquaux
MERGE Laurent's tweaks. Clean up'
r1893 return False
Gael Varoquaux
History is now working. + misc keybindings.
r1358
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 if __name__ == '__main__':
# Some simple code to test the console widget.
class MainWindow(wx.Frame):
def __init__(self, parent, id, title):
Gael Varoquaux
MERGE Laurent's tweaks. Clean up'
r1893 wx.Frame.__init__(self, parent, id, title, size=(300, 250))
gvaroquaux
Start of Wx frontend. Console widget impemented....
r1295 self._sizer = wx.BoxSizer(wx.VERTICAL)
self.console_widget = ConsoleWidget(self)
self._sizer.Add(self.console_widget, 1, wx.EXPAND)
self.SetSizer(self._sizer)
self.SetAutoLayout(1)
self.Show(True)
app = wx.PySimpleApp()
w = MainWindow(None, wx.ID_ANY, 'ConsoleWidget')
w.SetSize((780, 460))
w.Show()
app.MainLoop()