diff --git a/buffer.py b/buffer.py index 8bc3f1d..147300b 100644 --- a/buffer.py +++ b/buffer.py @@ -289,6 +289,14 @@ class Buffer(object): def overwrite_char(self, p, c, act=ACT_NORM, force=False): self.delete_char(p, act=act, force=force) self.insert_string(p, c, act=act, force=force) + def delete_line(self, y, act=ACT_NORM, force=False): + line = self.lines[y] + p1 = Point(0, y) + if y < len(self.lines) - 1: + p2 = Point(0, y + 1) + else: + p2 = Point(len(self.lines[-1]), y) + self.delete(p1, p2, act, force) # random def count_leading_whitespace(self, y): diff --git a/method.py b/method.py index fa18dfe..917dcc4 100644 --- a/method.py +++ b/method.py @@ -644,36 +644,50 @@ class UncommentRegion(Method): # wrapping/justifying/etc class WrapLine(Method): - '''Wrap the current line at 80 characters by word''' limit = 80 - prefix_re = None + def _token_len(self, tokens): + l = 0 + for t in tokens: + l += len(t) + return l + def _find_line_bounds(self, tokens): + if len(tokens[0]) > self.limit: + i = 1 + else: + i = 0 + while i < len(tokens) and self._token_len(tokens[:i+1]) <= self.limit: + i += 1 + while i > 1 and tokens and tokens[i-1].isspace(): + del tokens[i-1] + i -= 1 + return i + def _clear_preceeding_spaces(self, tokens): + while tokens and tokens[0].isspace(): + del tokens[0] def _execute(self, w, **vargs): cursor = w.logical_cursor() - old_cursor = cursor - i = cursor.y - move_old_cursor = old_cursor.x > self.limit + x, y = cursor.xy() - while len(w.buffer.lines[i]) > self.limit: - if ' ' in w.buffer.lines[i][:self.limit]: - j = w.buffer.lines[i][:self.limit].rindex(' ') - elif ' ' in w.buffer.lines[i][self.limit:]: - j = w.buffer.lines[i][self.limit:].index(' ') - else: - break - if move_old_cursor: - move_old_cursor = False - old_cursor.x -= j + 1 - old_cursor.y += 1 - w.goto(Point(j, i)) - w.right_delete() - w.insert_string_at_cursor('\n') - i += 1 + tokens = re.findall('[^ ]+| +', w.buffer.lines[y]) + if self._token_len(tokens) <= self.limit: + return - l = len(w.buffer.lines[old_cursor.y]) - if l > old_cursor.x: - w.goto(old_cursor) - else: - w.goto(Point(l, old_cursor.y)) + lines = [] + while tokens and self._token_len(tokens) > self.limit: + i = self._find_line_bounds(tokens) + s = ''.join(tokens[:i]) + lines.append(s) + if x > len(s): + y += 1 + x -= len(s) + del tokens[:i] + self._clear_preceeding_spaces(tokens) + if tokens: + lines.append(''.join(tokens)) + + w.buffer.delete_line(cursor.y) + w.buffer.insert_lines(Point(0, cursor.y), lines) + w.goto(Point(x, y)) class WrapParagraph(Method): limit = 80 wrapper = WrapLine