summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/window.py186
1 files changed, 99 insertions, 87 deletions
diff --git a/src/window.py b/src/window.py
index 2bb3c133..6d8777a5 100644
--- a/src/window.py
+++ b/src/window.py
@@ -99,7 +99,10 @@ class UserList(Win):
self.win.addnstr(y, 0, " ", 1)
self.win.attroff(curses.color_pair(show_col))
self.win.attron(curses.color_pair(role_col))
- self.win.addnstr(y, 1, user.nick, self.width-1)
+ try:
+ self.win.addnstr(y, 1, user.nick, self.width-1)
+ except:
+ pass
self.win.attroff(curses.color_pair(role_col))
y += 1
if y == self.height:
@@ -323,7 +326,9 @@ class Input(Win):
self.visible = visible
self.history = []
self.text = u''
- self.pos = 0
+ self.pos = 0 # cursor position
+ self.line_pos = 0 # position (in self.text) of
+ # the first char to display on the screen
self.histo_pos = 0
self.hit_list = [] # current possible completion (normal)
self.last_key_tab = False # True if we are cycling through possible completion
@@ -338,16 +343,19 @@ class Input(Win):
self.win.addnstr(0, 0, self.text.encode('utf-8'), self.width-1)
def key_dc(self):
- """delete char"""
- if self.pos == len(self.text):
- return
+ """
+ delete char just after the cursor
+ """
self.reset_completion()
- (y, x) = self.win.getyx()
- self.text = self.text[:self.pos]+self.text[self.pos+1:]
- self.win.delch(y, x)
- self.refresh()
+ if self.pos + self.line_pos == len(self.text):
+ return # end of line, nothing to delete
+ self.text = self.text[:self.pos+self.line_pos]+self.text[self.pos+self.line_pos+1:]
+ self.rewrite_text()
def key_up(self):
+ """
+ Get the previous line in the history
+ """
if not len(self.history):
return
self.reset_completion()
@@ -355,14 +363,12 @@ class Input(Win):
if self.histo_pos >= 0:
self.histo_pos -= 1
self.text = self.history[self.histo_pos+1]
- if len(self.text) >= self.width-1:
- self.win.addstr(self.history[self.histo_pos+1][:self.width-1].encode('utf-8'))
- else:
- self.win.addstr(self.history[self.histo_pos+1].encode('utf-8'))
- self.pos = len(self.text)
- self.refresh()
+ self.key_end()
def key_down(self):
+ """
+ Get the next line in the history
+ """
if not len(self.history):
return
self.reset_completion()
@@ -370,78 +376,79 @@ class Input(Win):
if self.histo_pos < len(self.history)-1:
self.histo_pos += 1
self.text = self.history[self.histo_pos]
- if len(self.text) >= self.width-1:
- self.win.addstr(self.history[self.histo_pos][:self.width-1].encode('utf-8'))
- else:
- self.win.addstr(self.history[self.histo_pos].encode('utf-8'))
- self.pos = len(self.text)
+ self.key_end()
else:
self.histo_pos = len(self.history)-1
self.text = u''
self.pos = 0
- self.refresh()
+ self.line_pos = 0
+ self.rewrite_text()
def key_home(self):
+ """
+ Go to the begining of line
+ """
self.reset_completion()
self.pos = 0
- if len(self.text) >= self.width-1:
- txt = self.text[:self.width-1]
- self.clear_text()
- self.win.addstr(txt.encode('utf-8'))
- self.win.move(0, 0)
- self.refresh()
+ self.line_pos = 0
+ self.rewrite_text()
- def key_end(self):
- self.reset_completion()
- self.pos = len(self.text)
+ def key_end(self, reset=False):
+ """
+ Go to the end of line
+ """
+ if reset:
+ self.reset_completion()
if len(self.text) >= self.width-1:
- txt = self.text[-(self.width-1):]
- self.clear_text()
- self.win.addstr(txt.encode('utf-8'))
- self.win.move(0, self.width-1)
+ self.pos = self.width-1
+ self.line_pos = len(self.text)-self.pos
else:
- self.win.move(0, len(self.text))
- self.refresh()
+ self.pos = len(self.text)
+ self.line_pos = 0
+ self.rewrite_text()
def key_left(self):
+ """
+ Move the cursor one char to the left
+ """
self.reset_completion()
(y, x) = self.win.getyx()
- if self.pos > 0:
+ if self.pos == self.width-1 and self.line_pos > 0:
+ self.line_pos -= 1
+ elif self.pos >= 1:
self.pos -= 1
- if x == 0:
- txt = self.text[self.pos:self.pos+self.width-1]
- self.clear_text()
- self.win.addstr(txt.encode('utf-8'))
- self.win.move(y, 0)
- else:
- self.win.move(y, x-1)
- self.refresh()
+ self.rewrite_text()
def key_right(self):
+ """
+ Move the cursor one char to the right
+ """
self.reset_completion()
(y, x) = self.win.getyx()
- if self.pos < len(self.text):
+ if self.pos == self.width-1:
+ if self.line_pos + self.width-1 < len(self.text):
+ self.line_pos += 1
+ elif self.pos < len(self.text):
self.pos += 1
- if x == self.width-1:
- txt = self.text[self.pos-(self.width-1):self.pos]
- self.clear_text()
- self.win.addstr(txt.encode('utf-8'))
- self.win.move(y, self.width-1)
- else:
- self.win.move(y, x+1)
- self.refresh()
+ self.rewrite_text()
def key_backspace(self):
+ """
+ Delete the char just before the cursor
+ """
self.reset_completion()
(y, x) = self.win.getyx()
- if len(self.text) > 0 and self.pos != 0:
- self.text = self.text[:self.pos-1]+self.text[self.pos:]
- self.pos -= 1
- self.win.delch(y, x-1)
- self.refresh()
+ if self.pos == 0:
+ return
+ self.text = self.text[:self.pos+self.line_pos-1]+self.text[self.pos+self.line_pos:]
+ self.key_left()
+ self.rewrite_text()
def auto_completion(self, user_list):
- if self.pos != len(self.text) or len(self.text) == 0:
+ """
+ Complete the nickname
+ """
+ if self.pos+self.line_pos != len(self.text) or len(self.text) == 0:
return # we don't complete if cursor is not at the end of line
completion_type = config.get('completion', 'normal')
if completion_type == 'shell':
@@ -450,10 +457,16 @@ class Input(Win):
self.normal_completion(user_list)
def reset_completion(self):
+ """
+ Reset the completion list (called on ALL keys except tab)
+ """
self.hit_list = []
self.last_key_tab = False
def normal_completion(self, user_list):
+ """
+ Normal completion
+ """
if " " in self.text.strip():
after = " " # don't put the "," if it's not the begining of the sentence
else:
@@ -475,21 +488,15 @@ class Input(Win):
begin = self.text[:-len(after)].split()[-1].encode('utf-8').lower()
self.hit_list.append(self.hit_list.pop(0)) # rotate list
end = len(begin.decode('utf-8')) + len(after)
- x -= end
- try:
- self.win.move(y, x)
- except:
- pass
- # remove begin from the line
- self.win.clrtoeol()
self.text = self.text[:-end]
nick = self.hit_list[0] # take the first hit
self.text += nick.decode('utf-8') +after
- self.pos = len(self.text)
- self.win.addstr(nick+after)
- self.refresh()
+ self.key_end(False)
def shell_completion(self, user_list):
+ """
+ Shell-like completion
+ """
if " " in self.text.strip():
after = " " # don't put the "," if it's not the begining of the sentence
else:
@@ -524,39 +531,44 @@ class Input(Win):
if end:
nick = nick[:-1]
x -= len(begin.decode('utf-8'))
- self.win.move(y, x)
- # remove begin from the line
- self.win.clrtoeol()
self.text = self.text[:-len(begin.decode('utf-8'))]
self.text += nick.decode('utf-8')
- self.pos = len(self.text)
- self.win.addstr(nick)
- self.refresh()
+ self.key_end(False)
def do_command(self, key):
+ from common import debug
+
+ debug("%s\n" % (len(self.text)))
self.reset_completion()
+ self.text = self.text[:self.pos+self.line_pos]+key.decode('utf-8')+self.text[self.pos+self.line_pos:]
(y, x) = self.win.getyx()
if x == self.width-1:
- self.win.delch(0, 0)
- self.win.move(y, x-1)
- x -= 1
- try:
- self.text = self.text[:self.pos]+key.decode('utf-8')+self.text[self.pos:]
- self.win.insstr(key)
- except:
- return
- self.win.move(y, x+1)
- self.pos += 1
- self.refresh()
+ self.line_pos += 1
+ else:
+ self.pos += 1
+ self.rewrite_text()
def get_text(self):
+ """
+ Clear the input and return the text entered so far
+ """
txt = self.text
self.text = u''
self.pos = 0
+ self.line_pos = 0
self.history.append(txt)
self.histo_pos = len(self.history)-1
return txt.encode('utf-8')
+ def rewrite_text(self):
+ """
+ Refresh the line onscreen, from the pos and pos_line
+ """
+ self.clear_text()
+ self.win.addstr(self.text[self.line_pos:self.line_pos+self.width-1].encode('utf-8'))
+ self.win.move(0, self.pos)
+ self.refresh()
+
def refresh(self):
if not self.visible:
return