summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornfnty <git@nfnty.se>2017-02-05 08:56:06 +0100
committernfnty <git@nfnty.se>2017-02-05 08:58:57 +0100
commit3fe5f92984e1361d06170e3b6a420ec93a041aaa (patch)
tree940c855b3a8685e497627a8004af051276cb4cb3
parent2841f7b86b1d464eb5280a9c9e5c29c4f4fda249 (diff)
Add setting `wrap_scroll`: Visual mode
-rw-r--r--ranger/core/actions.py61
-rw-r--r--ranger/core/fm.py4
-rw-r--r--ranger/ext/direction.py7
3 files changed, 45 insertions, 27 deletions
diff --git a/ranger/core/actions.py b/ranger/core/actions.py
index d3bbce7c..597b3279 100644
--- a/ranger/core/actions.py
+++ b/ranger/core/actions.py
@@ -82,14 +82,14 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m
if mode == self.mode: # pylint: disable=access-member-before-definition
return
if mode == 'visual':
- self._visual_start = self.thisdir.pointed_obj
- self._visual_start_pos = self.thisdir.pointer
+ self._visual_pos_start = self.thisdir.pointer
+ self._visual_move_cycles = 0
self._previous_selection = set(self.thisdir.marked_items)
self.mark_files(val=not self._visual_reverse, movedown=False)
elif mode == 'normal':
if self.mode == 'visual': # pylint: disable=access-member-before-definition
- self._visual_start = None
- self._visual_start_pos = None
+ self._visual_pos_start = None
+ self._visual_move_cycles = None
self._previous_selection = None
else:
return
@@ -439,7 +439,8 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m
# -- Moving Around
# --------------------------
- def move(self, narg=None, **kw): # pylint: disable=too-many-locals,too-many-branches
+ def move(self, # pylint: disable=too-many-locals,too-many-branches,too-many-statements
+ narg=None, **kw):
"""A universal movement method.
Accepts these parameters:
@@ -479,37 +480,49 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m
if result in (False, ASK_COMMAND):
self.open_console('open_with ')
elif direction.vertical() and cwd.files:
- newpos = direction.move(
+ pos_new = direction.move(
direction=direction.down(),
override=narg,
maximum=len(cwd),
current=cwd.pointer,
pagesize=self.ui.browser.hei)
- cwd.move(to=newpos)
+ cwd.move(to=pos_new)
if self.mode == 'visual':
- try:
- startpos = cwd.files.index(self._visual_start)
- except ValueError:
- self._visual_start = None
- startpos = min(self._visual_start_pos, len(cwd))
- # The files between here and _visual_start_pos
- targets = set(cwd.files[min(startpos, newpos):(max(startpos, newpos) + 1)])
- # The selection before activating visual mode
- old = self._previous_selection
+ pos_start = min(self._visual_pos_start, (len(cwd.files) - 1))
+ self._visual_move_cycles += direction.move_cycles()
+
+ # Haven't cycled
+ if self._visual_move_cycles == 0:
+ targets = set(cwd.files[min(pos_start, pos_new):(max(pos_start, pos_new) + 1)])
+ # Cycled down once
+ elif self._visual_move_cycles == 1:
+ if pos_new >= pos_start:
+ targets = set(cwd.files)
+ else:
+ targets = set(cwd.files[:(pos_new + 1)] + cwd.files[pos_start:])
+ # Cycled up once
+ elif self._visual_move_cycles == -1:
+ if pos_new <= pos_start:
+ targets = set(cwd.files)
+ else:
+ targets = set(cwd.files[:(pos_start + 1)] + cwd.files[pos_new:])
+ # Cycled more than once
+ else:
+ targets = set(cwd.files)
+
# The current selection
current = set(cwd.marked_items)
-
# Set theory anyone?
- if not self._visual_reverse:
- for fobj in targets - current:
- cwd.mark_item(fobj, True)
- for fobj in current - old - targets:
- cwd.mark_item(fobj, False)
- else:
+ if self._visual_reverse:
for fobj in targets & current:
cwd.mark_item(fobj, False)
- for fobj in old - current - targets:
+ for fobj in self._previous_selection - current - targets:
cwd.mark_item(fobj, True)
+ else:
+ for fobj in targets - current:
+ cwd.mark_item(fobj, True)
+ for fobj in current - self._previous_selection - targets:
+ cwd.mark_item(fobj, False)
if self.ui.pager.visible:
self.display_file()
diff --git a/ranger/core/fm.py b/ranger/core/fm.py
index 9e703327..a879ffad 100644
--- a/ranger/core/fm.py
+++ b/ranger/core/fm.py
@@ -41,8 +41,8 @@ class FM(Actions, # pylint: disable=too-many-instance-attributes
_previous_selection = None
_visual_reverse = False
- _visual_start = None
- _visual_start_pos = None
+ _visual_pos_start = None
+ _visual_move_cycles = None
def __init__(self, ui=None, bookmarks=None, tags=None, paths=None):
"""Initialize FM."""
diff --git a/ranger/ext/direction.py b/ranger/ext/direction.py
index 2bc58395..bbb69c9b 100644
--- a/ranger/ext/direction.py
+++ b/ranger/ext/direction.py
@@ -140,9 +140,14 @@ class Direction(dict):
else:
pos += current
if self.cycle():
- return minimum + pos % (maximum + offset - minimum)
+ cycles, pos = divmod(pos, (maximum + offset - minimum))
+ self['_move_cycles'] = int(cycles)
+ return int(minimum + pos)
return int(max(min(pos, maximum + offset - 1), minimum))
+ def move_cycles(self):
+ return self.get('_move_cycles', 0)
+
def select(self, lst, current, pagesize, override=None, offset=1):
dest = self.move(direction=self.down(), override=override,
current=current, pagesize=pagesize, minimum=0, maximum=len(lst) + 1)