about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--ranger/gui/widgets/filelist.py24
-rw-r--r--ranger/gui/widgets/pager.py71
2 files changed, 88 insertions, 7 deletions
diff --git a/ranger/gui/widgets/filelist.py b/ranger/gui/widgets/filelist.py
index 95fcf8fe..d8fc1073 100644
--- a/ranger/gui/widgets/filelist.py
+++ b/ranger/gui/widgets/filelist.py
@@ -1,7 +1,9 @@
 """The FileList widget displays the contents of a directory or file."""
 from . import Widget
+from ..displayable import DisplayableContainer
+from .pager import Pager
 
-class FileList(Widget):
+class FileList(Widget, DisplayableContainer):
 	main_display = False
 	display_infostring = False
 	scroll_begin = 0
@@ -10,8 +12,14 @@ class FileList(Widget):
 	tagged_marker = '*'
 
 	def __init__(self, win, level):
-		Widget.__init__(self, win)
+		DisplayableContainer.__init__(self, win)
+		self.pager = Pager(win)
+		self.add_obj(self.pager)
 		self.level = level
+	
+	def resize(self, *args):
+		DisplayableContainer.resize(self, *args)
+		self.pager.resize(*args)
 
 	def click(self, event):
 		"""Handle a MouseEvent"""
@@ -66,6 +74,7 @@ class FileList(Widget):
 		from ranger.fsobject.file import File
 		from ranger.fsobject.directory import Directory
 
+		self.pager.visible = False
 		if self.target is None:
 			pass
 		elif type(self.target) == File:
@@ -73,6 +82,8 @@ class FileList(Widget):
 		elif type(self.target) == Directory:
 			self.draw_directory()
 
+		DisplayableContainer.draw(self)
+
 	def finalize(self):
 		if self.postpone_drawing:
 			self.target.load_content_if_outdated()
@@ -92,13 +103,12 @@ class FileList(Widget):
 			return
 		
 		try:
-			if self.target.size < 1024 * 20:
-				f = open(self.target.path, 'r')
-				for line in range(self.hei):
-					read = f.readline().expandtabs()
-					self.win.addnstr(self.y + line, self.x, read, self.wid)
+			f = open(self.target.path, 'r')
 		except:
 			pass
+		else:
+			self.pager.visible = True
+			self.pager.set_source(f)
 
 	def draw_directory(self):
 		"""Draw the contents of a directory"""
diff --git a/ranger/gui/widgets/pager.py b/ranger/gui/widgets/pager.py
new file mode 100644
index 00000000..7a93a2d6
--- /dev/null
+++ b/ranger/gui/widgets/pager.py
@@ -0,0 +1,71 @@
+"""
+The pager displays text and allows you to scroll inside it.
+"""
+from ranger import log
+from . import Widget
+
+class Pager(Widget):
+	source = None
+	source_is_stream = False
+	def __init__(self, win):
+		Widget.__init__(self, win)
+		self.scroll_begin = 0
+
+#		self.commandlist = CommandList()
+#		self.settings.keys.initialize_pager_commands( \
+#				self.commandlist)
+	
+	def draw(self):
+		line_gen = self._generate_lines(
+				starty=self.scroll_begin, startx=0)
+
+		for line, i in zip(line_gen, range(self.hei)):
+			y, x = self.y + i, self.x
+
+			try:
+				self.win.addstr(y, x, line)
+			except:
+				pass
+	
+	def set_source(self, source):
+		if self.source and self.source_is_stream:
+			self.source.close()
+
+		if hasattr(source, '__getitem__'):
+			self.source_is_stream = True
+			self.lines = source
+		elif hasattr(source, 'readline'):
+			self.source_is_stream = True
+			self.lines = []
+		else:
+			self.source = None
+			self.source_is_stream = False
+			return False
+
+		self.source = source
+		return True
+	
+	def _get_line(self, n, attempt_to_read=True):
+		try:
+			return self.lines[n]
+		except (KeyError, IndexError):
+			if attempt_to_read and self.source_is_stream:
+				for l in self.source:
+					self.lines.append(l)
+					if len(self.lines) > n:
+						break
+				return self._get_line(n, attempt_to_read=False)
+			return ""
+	
+	def _generate_lines(self, starty, startx):
+		i = starty
+		if not self.source:
+			raise StopIteration
+		while True:
+			try:
+				line = self._get_line(i).expandtabs(4)
+				line = line[startx:self.wid - 1 + startx].rstrip()
+				yield line
+			except IndexError:
+				raise StopIteration
+			i += 1