summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--TODO2
-rw-r--r--ranger/fsobject/file.py25
-rw-r--r--ranger/gui/widgets/browsercolumn.py25
3 files changed, 48 insertions, 4 deletions
diff --git a/TODO b/TODO
index b1089225..7da64db5 100644
--- a/TODO
+++ b/TODO
@@ -48,7 +48,7 @@ General
    ( ) #64  10/02/25  scroll in previews
    (X) #66  10/02/28  explain how colorschemes work
    ( ) #70  10/03/14  mouse handler for titlebar
-   ( ) #71  10/03/21  previews: black/whitelist + read file
+   (X) #71  10/03/21  previews: black/whitelist + read file
 
 
 Bugs
diff --git a/ranger/fsobject/file.py b/ranger/fsobject/file.py
index 86621095..15bfc18b 100644
--- a/ranger/fsobject/file.py
+++ b/ranger/fsobject/file.py
@@ -13,6 +13,31 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+control_characters = set(chr(n) for n in set(range(0, 9)) | set(range(14,32)))
+
 from .fsobject import FileSystemObject as SuperClass
 class File(SuperClass):
 	is_file = True
+
+	@property
+	def first4bytes(self):
+		try:
+			return self._first4bytes
+		except:
+			try:
+				f = open(self.path, 'r')
+				self._first4bytes = f.read(4)
+				f.close()
+				return self._first4bytes
+			except:
+				pass
+
+	def is_binary(self):
+		if not self.first4bytes:
+			return
+		if self.first4bytes == "\x7F\x45\x4C\x46":
+			return True
+		if control_characters & set(self.first4bytes):
+			return True
+		return False
+
diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py
index 238a4803..06a89627 100644
--- a/ranger/gui/widgets/browsercolumn.py
+++ b/ranger/gui/widgets/browsercolumn.py
@@ -41,6 +41,15 @@ PREVIEW_BLACKLIST = re.compile(r"""
 		$
 """, re.VERBOSE | re.IGNORECASE)
 
+PREVIEW_WHITELIST = re.compile(r"""
+		\.(
+			txt | py | c
+		)
+		# ignore filetype-independent suffixes:
+			(\.part|\.bak|~)?
+		$
+""", re.VERBOSE | re.IGNORECASE)
+
 class BrowserColumn(Pager):
 	main_column = False
 	display_infostring = False
@@ -149,10 +158,20 @@ class BrowserColumn(Pager):
 			self.last_redraw_time = time()
 
 	def _preview_this_file(self, target):
+		if not self.settings.preview_files:
+			return False
+		if not self.target or not self.target.is_file:
+			return False
 		maxsize = self.settings.max_filesize_for_preview
-		return self.settings.preview_files \
-				and not PREVIEW_BLACKLIST.search(target.basename) \
-				and (maxsize is None or maxsize >= target.size)
+		if maxsize is not None and target.size > maxsize:
+			return False
+		if PREVIEW_WHITELIST.search(target.basename):
+			return True
+		if PREVIEW_BLACKLIST.search(target.basename):
+			return False
+		if target.is_binary():
+			return False
+		return True
 
 	def _draw_file(self):
 		"""Draw a preview of the file, if the settings allow it"""