# -*- coding: utf-8 -*-
#
# move.py - move commander module
#
# Copyright (C) 2010 - Jesse van den Kieboom
#
# 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.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
import commander.commands as commands
from gi.repository import Gdk, Gtk
import re
__commander_module__ = True
def _move(view, what, num, modifier):
try:
num = int(num)
except:
raise commands.exceptions.Execute('Invalid number: ' + str(num))
view.emit('move-cursor', what, num, modifier & Gdk.EventMask.CONTROL_MASK)
return commands.result.HIDE
def word(view, modifier, num=1):
"""Move cursor per word: move.word <num>
Move the cursor per word (use negative num to move backwards)"""
return _move(view, Gtk.MovementStep.WORDS, num, modifier)
def line(view, modifier, num=1):
"""Move cursor per line: move.line <num>
Move the cursor per line (use negative num to move backwards)"""
return _move(view, Gtk.MovementStep.DISPLAY_LINES, num, modifier)
def char(view, modifier, num=1):
"""Move cursor per char: move.char <num>
Move the cursor per char (use negative num to move backwards)"""
return _move(view, Gtk.MovementStep.VISUAL_POSITIONS, num, modifier)
def paragraph(view, modifier, num=1):
"""Move cursor per paragraph: move.paragraph <num>
Move the cursor per paragraph (use negative num to move backwards)"""
return _move(view, Gtk.MovementStep.PARAGRAPHS, num, modifier)
def regex(view, modifier, regex, num=1):
"""Move cursor per regex: move.regex <num>
Move the cursor per regex (use negative num to move backwards)"""
try:
r = re.compile(regex, re.DOTALL | re.MULTILINE | re.UNICODE)
except Exception as e:
raise commands.exceptions.Execute('Invalid regular expression: ' + str(e))
try:
num = int(num)
except Exception as e:
raise commands.exceptions.Execute('Invalid number: ' + str(e))
buf = view.get_buffer()
start = buf.get_iter_at_mark(buf.get_insert())
if num > 0:
end = buf.get_end_iter()
else:
end = start.copy()
start = buf.get_start_iter()
text = start.get_text(end)
ret = list(r.finditer(text))
if num < 0:
ret.reverse()
idx = min(abs(num), len(ret))
if idx > 0:
found = ret[idx - 1]
start = buf.get_iter_at_mark(buf.get_insert())
if num < 0:
start.backward_char(len(text) - found.start(0))
else:
start.forward_chars(found.start(0))
if modifier & Gdk.EventMask.CONTROL_MASK:
buf.move_mark(buf.get_selection_bound(), start)
else:
buf.move_mark(buf.get_insert(), start)
buf.move_mark(buf.get_selection_bound(), start)
visible = view.get_visible_rect()
loc = view.get_iter_location(start)
# Scroll there if needed
if loc.y + loc.height < visible.y or loc.y > visible.y + visible.height:
view.scroll_to_mark(buf.get_insert(), 0.2, True, 0, 0.5)
return commands.result.HIDE
# ex:ts=4:et