pyreadline-refactor: Added visible selection mode to emacs-mode.

This commit is contained in:
jstenar
2006-03-21 22:00:03 +00:00
parent 2130c2787c
commit b7b76cd69c
7 changed files with 215 additions and 70 deletions
+1
View File
@@ -1,5 +1,6 @@
2006-03-16 Jörgen Stenarson <jorgen.stenarson -at- bostream.nu>
* Added vi patch
* Added visible selection mode to emacs mode
2006-03-16 Jörgen Stenarson <jorgen.stenarson -at- bostream.nu>
* Refactored emacs mode
+16 -7
View File
@@ -4,16 +4,21 @@ set_mode("emacs") #will cause following bind_keys to bind to emacs mode
bind_exit_key("Control-d")
bind_exit_key("Control-z")
#Commands for moving
bind_key("Home", "beginning_of_line")
bind_key("End", "end_of_line")
bind_key("Left", "backward_char")
bind_key("Left", "backward_char")
bind_key("Control-b", "backward_char")
bind_key("Right", "forward_char")
bind_key("Control-f", "forward_char")
bind_key("Alt-f", "forward_word")
bind_key("Control-Right", "forward_word")
bind_key("Shift-Right", "forward_char_extend_selection")
bind_key("Shift-Left", "backward_char_extend_selection")
bind_key("Shift-Control-Right", "forward_word_extend_selection")
bind_key("Shift-Control-Left", "backward_word_extend_selection")
bind_key("Alt-b", "backward_word")
bind_key("Control-Left", "backward_word")
bind_key("Clear", "clear_screen")
bind_key("Control-l", "clear_screen")
bind_key("Control-a", "beginning_of_line")
@@ -21,7 +26,7 @@ bind_key("Control-e", "end_of_line")
#bind_key("Control-l", "redraw_current_line")
#Commands for Manipulating the History
bind_key("Return", "accept_line")
bind_key("Return", "accept_line")
bind_key("Control-p", "previous_history")
bind_key("Control-n", "next_history")
bind_key("Up", "history_search_backward")
@@ -37,12 +42,14 @@ bind_key("Alt-n", "non_incremental_forward_search_history")
bind_key("Delete", "delete_char")
bind_key("Control-d", "delete_char")
bind_key("BackSpace", "backward_delete_char")
bind_key("Control-Shift-v", "quoted_insert")
bind_key("Control-BackSpace", "backward_delete_word")
#bind_key("Control-Shift-v", "quoted_insert")
bind_key("Control-space", "self_insert")
#Killing and Yanking
bind_key("Control-k", "kill_line")
bind_key("Control-shift-k", "kill_whole_line")
bind_key("Escape", "kill_whole_line")
bind_key("Meta-d", "kill_word")
bind_key("Control-w", "unix_word_rubout")
bind_key("Meta-Delete", "backward_kill_word")
@@ -50,23 +57,25 @@ bind_key("Meta-Delete", "backward_kill_word")
#Copy paste
bind_key("Control-m", "set_mark")
bind_key("Control-q", "copy_region_to_clipboard")
bind_key("Control-x", "cut_selection_to_clipboard")
bind_key("Control-Shift-x", "copy_selection_to_clipboard")
bind_key("Control-v", "paste")
bind_key("Alt-v", "ipython_paste")
bind_key("Control-y", "paste")
bind_key("Control-z", "undo")
bind_key("Control-_", "undo")
bind_key('Control-Shift-v', "paste_mulitline_code")
#Unbinding keys:
#un_bind_key("Home")
#Other
bell_style("none") #modes: none, audible, visible(not implemented)
show_all_if_ambiguous("on")
mark_directories("on")
completer_delims(" \t\n\"\\'`@$><=;|&{(")
completer_delims(" \t\n\"\\'`@$><=;|&{(?")
debug_output("off")
history_filename("~/.pythonhistory")
history_length(200) #value of -1 means no limit
+87 -8
View File
@@ -17,8 +17,6 @@ def quote_char(c):
if ord(c)>0:
return c
############## Line positioner ########################
class LinePositioner(object):
@@ -358,44 +356,109 @@ class ReadLineTextBuffer(TextLine):
def __init__(self,txtstr,point=None,mark=None):
super(ReadLineTextBuffer,self).__init__(txtstr,point,mark)
self.enable_win32_clipboard=True
self.selection_mark=-1
self.enable_selection=True
def insert_text(self,char):
self.delete_selection()
self.selection_mark=-1
self._insert_text(char)
######### Movement
def beginning_of_line(self):
self.selection_mark=-1
self.point=StartOfLine
def end_of_line(self):
self.selection_mark=-1
self.point=EndOfLine
def forward_char(self):
self.selection_mark=-1
self.point=NextChar
def backward_char(self):
self.selection_mark=-1
self.point=PrevChar
def forward_word(self):
self.selection_mark=-1
self.point=NextWordStart
def backward_word(self):
self.selection_mark=-1
self.point=PrevWordStart
######### Movement select
def beginning_of_line_extend_selection(self):
if self.enable_selection and self.selection_mark<0:
self.selection_mark=self.point
self.point=StartOfLine
def end_of_line_extend_selection(self):
if self.enable_selection and self.selection_mark<0:
self.selection_mark=self.point
self.point=EndOfLine
def forward_char_extend_selection(self):
if self.enable_selection and self.selection_mark<0:
self.selection_mark=self.point
self.point=NextChar
def backward_char_extend_selection(self):
if self.enable_selection and self.selection_mark<0:
self.selection_mark=self.point
self.point=PrevChar
def forward_word_extend_selection(self):
if self.enable_selection and self.selection_mark<0:
self.selection_mark=self.point
self.point=NextWordStart
def backward_word_extend_selection(self):
if self.enable_selection and self.selection_mark<0:
self.selection_mark=self.point
self.point=PrevWordStart
######### delete
def delete_selection(self):
if self.enable_selection and self.selection_mark>0:
if self.selection_mark<self.point:
del self[self.selection_mark:self.point]
else:
del self[self.point:self.selection_mark]
return True
else:
return False
def delete_char(self):
del self[Point]
if not self.delete_selection():
del self[Point]
self.selection_mark=-1
def backward_delete_char(self):
self.backward_char()
self.delete_char()
if not self.delete_selection():
if self.point>0:
self.backward_char()
self.delete_char()
self.selection_mark=-1
def backward_delete_word(self):
if not self.delete_selection():
del self[PrevWordEnd:Point]
self.selection_mark=-1
def delete_current_word(self):
del self[CurrentWord]
if not self.delete_selection():
del self[CurrentWord]
self.selection_mark=-1
def delete_horizontal_space(self):
pass
if not self.delete_selection():
pass
self.selection_mark=-1
######### Case
def upcase_word(self):
@@ -488,6 +551,22 @@ class ReadLineTextBuffer(TextLine):
toclipboard="".join(self.line_buffer[begin:end])
clipboard.SetClipboardText(str(toclipboard))
def copy_selection_to_clipboard(self): # ()
'''Copy the text in the region to the windows clipboard.'''
if self.enable_win32_clipboard and self.enable_selection and self.selection_mark>0:
selection_mark=min(self.selection_mark,len(self.line_buffer))
cursor=min(self.point,len(self.line_buffer))
if self.selection_mark==-1:
return
begin=min(cursor,selection_mark)
end=max(cursor,selection_mark)
toclipboard="".join(self.line_buffer[begin:end])
clipboard.SetClipboardText(str(toclipboard))
def cut_selection_to_clipboard(self): # ()
self.copy_selection_to_clipboard()
self.delete_selection()
############## Paste
+93 -3
View File
@@ -6,12 +6,13 @@
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#*****************************************************************************
import os
import os,re
import pyreadline.logger as logger
from pyreadline.logger import log
from pyreadline.keysyms import key_text_to_keyinfo
import pyreadline.lineeditor.lineobj as lineobj
import pyreadline.lineeditor.history as history
import pyreadline.clipboard as clipboard
class BaseMode(object):
mode="base"
@@ -41,11 +42,12 @@ class BaseMode(object):
next_meta=property(*_gs("next_meta"))
first_prompt=property(*_gs("first_prompt"))
prompt=property(*_gs("prompt"))
paste_line_buffer=property(*_gs("paste_line_buffer"))
console=property(_g("console"))
insert_text=property(_g("insert_text"))
_print_prompt=property(_g("_print_prompt"))
_update_line=property(_g("_update_line"))
paste_line_buffer=property(_g("paste_line_buffer"))
add_history=property(_g("add_history"))
_bell=property(_g("_bell"))
_clear_after=property(_g("_clear_after"))
@@ -54,9 +56,11 @@ class BaseMode(object):
_update_prompt_pos=property(_g("_update_prompt_pos"))
_update_line=property(_g("_update_line"))
enable_win32_clipboard=property(_g("enable_win32_clipboard"))
enable_ipython_paste_list_of_lists=property(_g("enable_ipython_paste_list_of_lists"))
enable_ipython_paste_for_paths=property(_g("enable_ipython_paste_for_paths"))
_bell=property(_g("_bell"))
_history=property(_g("_history"))
def _readline_from_keyboard(self):
raise NotImplementedError
@@ -229,6 +233,37 @@ class BaseMode(object):
composed of letters and digits.'''
self.l_buffer.backward_word()
def beginning_of_line_extend_selection(self, e): #
'''Move to the start of the current line. '''
self.l_buffer.beginning_of_line_extend_selection()
def end_of_line_extend_selection(self, e): #
'''Move to the end of the line. '''
self.l_buffer.end_of_line_extend_selection()
def forward_char_extend_selection(self, e): #
'''Move forward a character. '''
self.l_buffer.forward_char_extend_selection()
def backward_char_extend_selection(self, e): #
'''Move back a character. '''
self.l_buffer.backward_char_extend_selection()
def forward_word_extend_selection(self, e): #
'''Move forward to the end of the next word. Words are composed of
letters and digits.'''
self.l_buffer.forward_word_extend_selection()
def backward_word_extend_selection(self, e): #
'''Move back to the start of the current or previous word. Words are
composed of letters and digits.'''
self.l_buffer.backward_word_extend_selection()
def clear_screen(self, e): # (C-l)
'''Clear the screen and redraw the current line, leaving the current
line at the top of the screen.'''
@@ -257,8 +292,63 @@ class BaseMode(object):
to kill the characters instead of deleting them.'''
self.l_buffer.backward_delete_char()
def backward_delete_word(self, e): # (Rubout)
'''Delete the character behind the cursor. A numeric argument means
to kill the characters instead of deleting them.'''
self.l_buffer.backward_delete_word()
def self_insert(self, e): # (a, b, A, 1, !, ...)
'''Insert yourself. '''
if ord(e.char)!=0: #don't insert null character in buffer, can happen with dead keys.
self.insert_text(e.char)
# Paste from clipboard
def paste(self,e):
'''Paste windows clipboard'''
if self.enable_win32_clipboard:
txt=clipboard.get_clipboard_text_and_convert(False)
self.insert_text(txt)
def paste_mulitline_code(self,e):
'''Paste windows clipboard'''
reg=re.compile("\r?\n")
if self.enable_win32_clipboard:
txt=clipboard.get_clipboard_text_and_convert(False)
t=reg.split(txt)
t=[row for row in t if row.strip()!=""] #remove empty lines
if t!=[""]:
self.insert_text(t[0])
self.add_history(self.l_buffer.copy())
self.paste_line_buffer=t[1:]
log("multi: %s"%self.paste_line_buffer)
return True
else:
return False
def ipython_paste(self,e):
'''Paste windows clipboard. If enable_ipython_paste_list_of_lists is
True then try to convert tabseparated data to repr of list of lists or
repr of array'''
if self.enable_win32_clipboard:
txt=clipboard.get_clipboard_text_and_convert(
self.enable_ipython_paste_list_of_lists)
if self.enable_ipython_paste_for_paths:
if len(txt)<300 and ("\t" not in txt) and ("\n" not in txt):
txt=txt.replace("\\","/").replace(" ",r"\ ")
self.insert_text(txt)
def copy_region_to_clipboard(self, e): # ()
'''Copy the text in the region to the windows clipboard.'''
self.l_buffer.copy_region_to_clipboard()
def copy_selection_to_clipboard(self, e): # ()
'''Copy the text in the region to the windows clipboard.'''
self.l_buffer.copy_selection_to_clipboard()
def cut_selection_to_clipboard(self, e): # ()
'''Copy the text in the region to the windows clipboard.'''
self.l_buffer.cut_selection_to_clipboard()
+3 -47
View File
@@ -52,6 +52,7 @@ class EmacsMode(basemode.BaseMode):
def readline(self, prompt=''):
'''Try to act like GNU readline.'''
# handle startup_hook
self.l_buffer.selection_mark=-1
if self.first_prompt:
self.first_prompt = False
if self.startup_hook:
@@ -76,7 +77,7 @@ class EmacsMode(basemode.BaseMode):
log("in readline: %s"%self.paste_line_buffer)
if len(self.paste_line_buffer)>0:
self.l_buffer=lineobj.ReadlineTextBuffer(self.paste_line_buffer[0])
self.l_buffer=lineobj.ReadLineTextBuffer(self.paste_line_buffer[0])
self._update_line()
self.paste_line_buffer=self.paste_line_buffer[1:]
c.write('\r\n')
@@ -307,18 +308,6 @@ class EmacsMode(basemode.BaseMode):
yanked right away. By default, this command is unbound.'''
pass
def copy_region_to_clipboard(self, e): # ()
'''Copy the text in the region to the windows clipboard.'''
if self.enable_win32_clipboard:
mark=min(self.l_buffer.mark,len(self.l_buffer.line_buffer))
cursor=min(self.l_buffer.point,len(self.l_buffer.line_buffer))
if self.l_buffer.mark==-1:
return
begin=min(cursor,mark)
end=max(cursor,mark)
toclipboard="".join(self.l_buffer.line_buffer[begin:end])
clipboard.SetClipboardText(str(toclipboard))
def copy_backward_word(self, e): # ()
'''Copy the word before point to the kill buffer. The word
boundaries are the same as backward-word. By default, this command
@@ -331,39 +320,6 @@ class EmacsMode(basemode.BaseMode):
unbound.'''
pass
def paste(self,e):
'''Paste windows clipboard'''
if self.enable_win32_clipboard:
txt=clipboard.get_clipboard_text_and_convert(False)
self.insert_text(txt)
def paste_mulitline_code(self,e):
'''Paste windows clipboard'''
reg=re.compile("\r?\n")
if self.enable_win32_clipboard:
txt=clipboard.get_clipboard_text_and_convert(False)
t=reg.split(txt)
t=[row for row in t if row.strip()!=""] #remove empty lines
if t!=[""]:
self.insert_text(t[0])
self.add_history(self.l_buffer.copy())
self.paste_line_buffer=t[1:]
log("multi: %s"%self.paste_line_buffer)
return True
else:
return False
def ipython_paste(self,e):
'''Paste windows clipboard. If enable_ipython_paste_list_of_lists is
True then try to convert tabseparated data to repr of list of lists or
repr of array'''
if self.enable_win32_clipboard:
txt=clipboard.get_clipboard_text_and_convert(
self.enable_ipython_paste_list_of_lists)
if self.enable_ipython_paste_for_paths:
if len(txt)<300 and ("\t" not in txt) and ("\n" not in txt):
txt=txt.replace("\\","/").replace(" ",r"\ ")
self.insert_text(txt)
def yank(self, e): # (C-y)
'''Yank the top of the kill ring into the buffer at point. '''
@@ -506,6 +462,7 @@ class EmacsMode(basemode.BaseMode):
def _bind_key(self, key, func):
'''setup the mapping from key to call the function.'''
# print key,func
keyinfo = key_text_to_keyinfo(key)
# print key,keyinfo,func.__name__
self.key_dispatch[keyinfo] = func
@@ -518,7 +475,6 @@ class EmacsMode(basemode.BaseMode):
def init_editing_mode(self, e): # (C-e)
'''When in vi command mode, this causes a switch to emacs editing
mode.'''
self._bind_exit_key('Control-d')
self._bind_exit_key('Control-z')
-1
View File
@@ -95,7 +95,6 @@ class ViMode(basemode.BaseMode):
def init_editing_mode(self, e): # (M-C-j)
'''Initialize vi editingmode'''
print "initing vi"
self.show_all_if_ambiguous = 'on'
self.key_dispatch = {}
self.__vi_insert_mode = None
+15 -4
View File
@@ -53,6 +53,7 @@ class Readline(object):
self.size = self.console.size()
self.prompt_color = None
self.command_color = None
self.selection_color =0x00f0
self.key_dispatch = {}
self.previous_func = None
self.first_prompt = True
@@ -89,7 +90,6 @@ class Readline(object):
self.paste_line_buffer=[]
#Below is for refactoring, raise errors when using old style attributes
#that should be refactored out
def _g(x):
@@ -306,7 +306,17 @@ class Readline(object):
c=self.console
c.pos(*self.prompt_end_pos)
ltext = self.l_buffer.quoted_text()
n = c.write_scrolling(ltext, self.command_color)
if self.l_buffer.enable_selection and self.l_buffer.selection_mark>0:
start=len(self.l_buffer[:self.l_buffer.selection_mark].quoted_text())
stop=len(self.l_buffer[:self.l_buffer.point].quoted_text())
if start>stop:
stop,start=start,stop
n = c.write_scrolling(ltext[:start], self.command_color)
n = c.write_scrolling(ltext[start:stop], self.selection_color)
n = c.write_scrolling(ltext[stop:], self.command_color)
else:
n = c.write_scrolling(ltext, self.command_color)
self._update_prompt_pos(n)
self._clear_after()
self._set_cursor()
@@ -321,8 +331,9 @@ class Readline(object):
def setmode(name):
self.mode=modes[name]
def bind_key(key,name):
if hasattr(self,name):
modes[mode]._bind_key(key,getattr(self,name))
if hasattr(modes[mode],name):
#print key,name
modes[mode]._bind_key(key,getattr(modes[mode],name))
def un_bind_key(key):
keyinfo = key_text_to_keyinfo(key)
if keyinfo in modes[mode].key_dispatch: