diff options
-rw-r--r-- | ranger/core/actions.py | 9 | ||||
-rwxr-xr-x | ranger/ext/preview.sh | 21 | ||||
-rw-r--r-- | ranger/fsobject/file.py | 21 | ||||
-rw-r--r-- | ranger/gui/ansi.py | 17 | ||||
-rw-r--r-- | ranger/gui/curses_shortcuts.py | 9 | ||||
-rw-r--r-- | ranger/gui/widgets/pager.py | 20 |
6 files changed, 76 insertions, 21 deletions
diff --git a/ranger/core/actions.py b/ranger/core/actions.py index 14f862c7..2db749cd 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -468,13 +468,8 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): if not hasattr(self.ui, 'open_embedded_pager'): return - try: - f = open(self.env.cf.path, 'r') - except: - pass - else: - pager = self.ui.open_embedded_pager() - pager.set_source(f) + pager = self.ui.open_embedded_pager() + pager.set_source(self.env.cf.get_preview_source()) # -------------------------- # -- Tabs diff --git a/ranger/ext/preview.sh b/ranger/ext/preview.sh new file mode 100755 index 00000000..80186e4d --- /dev/null +++ b/ranger/ext/preview.sh @@ -0,0 +1,21 @@ +#!/bin/bash +mimetype=$(file --mime-type -Lb "$1") +basetype=$(echo "$mimetype" | grep -o '^[^/]\+') +extension=$(echo "$1" | grep '\.' | grep -o '[^.]\+$') + +case "$basetype" in + text) + highlight --ansi "$1" || cat "$1" + exit 0;; + image) + img2txt "$1" || exit 1 + exit 0;; +esac + +case "$extension" in + zip|gz) + atool -l "$1" + exit 0;; +esac + +exit 1 diff --git a/ranger/fsobject/file.py b/ranger/fsobject/file.py index 2619fa35..25902f57 100644 --- a/ranger/fsobject/file.py +++ b/ranger/fsobject/file.py @@ -16,6 +16,9 @@ import re import zipfile from ranger.fsobject import FileSystemObject +from subprocess import Popen, PIPE +from ranger.core.runner import devnull +from ranger import relpath N_FIRST_BYTES = 20 control_characters = set(chr(n) for n in @@ -28,8 +31,8 @@ PREVIEW_BLACKLIST = re.compile(r""" # one character extensions: [oa] # media formats: - | avi | [mj]pe?g | mp\d | og[gmv] | wm[av] | mkv | flv - | png | bmp | vob | wav | mpc | flac | divx? | xcf | pdf + | avi | mpe?g | mp\d | og[gmv] | wm[av] | mkv | flv + | vob | wav | mpc | flac | divx? | xcf | pdf # binary files: | torrent | class | so | img | py[co] | dmg # containers: @@ -78,15 +81,21 @@ class File(FileSystemObject): return False if not self.accessible or self.is_fifo or self.is_device: return False + if self.image or self.container: + return True if PREVIEW_WHITELIST.search(self.basename): return True if PREVIEW_BLACKLIST.search(self.basename): return False - if self.extension not in ('zip',) and self.is_binary(): + if self.is_binary(): return False return True def get_preview_source(self): - if self.extension == 'zip': - return '\n'.join(zipfile.ZipFile(self.path).namelist()) - return open(self.path, 'r') + try: + p = Popen([relpath('ext/preview.sh'), self.path], + stdout=PIPE, stderr=devnull) + if not p.poll(): + return p.stdout + except: + return open(self.path, 'r') diff --git a/ranger/gui/ansi.py b/ranger/gui/ansi.py index fe0753a1..a9b37665 100644 --- a/ranger/gui/ansi.py +++ b/ranger/gui/ansi.py @@ -17,14 +17,15 @@ from ranger.gui import color import re -ansi_re = re.compile('(\033' + r'\[\d+(?:;\d+)*?[a-zA-Z])') +ansi_re = re.compile('(\033' + r'\[\d*(?:;\d+)*?[a-zA-Z])') +reset = '\033[0m' def split_ansi_from_text(ansi_text): return ansi_re.split(ansi_text) -def text_with_fg_bg(ansi_text): +def text_with_fg_bg_attr(ansi_text): for chunk in split_ansi_from_text(ansi_text): - if chunk[0] == '\033': + if chunk and chunk[0] == '\033': if chunk[-1] != 'm': continue match = re.match(r'^.\[(.*).$', chunk) @@ -33,9 +34,15 @@ def text_with_fg_bg(ansi_text): # Convert arguments to attributes/colors for arg in attr_args.split(';'): - n = int(arg) + try: + n = int(arg) + except: + if arg == '': + n = 0 + else: + continue if n == 0: - fg, bg, attr = 0, 0, 0 + fg, bg, attr = -1, -1, 0 elif n == 1: attr |= color.bold elif n == 4: diff --git a/ranger/gui/curses_shortcuts.py b/ranger/gui/curses_shortcuts.py index 3df45700..42f9dada 100644 --- a/ranger/gui/curses_shortcuts.py +++ b/ranger/gui/curses_shortcuts.py @@ -1,4 +1,5 @@ # Copyright (C) 2009, 2010 Roman Zimbelmann <romanz@lavabit.com> +# Copyright (C) 2010 David Barnett <davidbarnett2@gmail.com> # # 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 @@ -13,9 +14,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +import curses import _curses from ranger.ext.iter_tools import flatten +from ranger.gui.color import get_color from ranger.shared import SettingsAware def ascii_only(string): @@ -95,6 +98,12 @@ class CursesShortcuts(SettingsAware): except _curses.error: pass + def set_fg_bg_attr(self, fg, bg, attr): + try: + self.win.attrset(curses.color_pair(get_color(fg, bg)) | attr) + except _curses.error: + pass + def color_reset(self): """Change the colors to the default colors""" CursesShortcuts.color(self, 'reset') diff --git a/ranger/gui/widgets/pager.py b/ranger/gui/widgets/pager.py index c0bc98b4..58fcdfd1 100644 --- a/ranger/gui/widgets/pager.py +++ b/ranger/gui/widgets/pager.py @@ -1,4 +1,5 @@ # Copyright (C) 2009, 2010 Roman Zimbelmann <romanz@lavabit.com> +# Copyright (C) 2010 David Barnett <davidbarnett2@gmail.com> # # 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 @@ -18,6 +19,7 @@ The pager displays text and allows you to scroll inside it. """ import re from . import Widget +from ranger.gui import ansi from ranger.ext.direction import Direction from ranger.container.keymap import CommandArgs @@ -106,6 +108,13 @@ class Pager(Widget): if TITLE_REGEXP.match(line): self.color_at(i, 0, -1, 'title', *baseclr) + elif self.markup == 'ansi': + self.win.move(i, 0) + for chunk in ansi.text_with_fg_bg_attr(line): + if isinstance(chunk, tuple): + self.set_fg_bg_attr(*chunk) + else: + self.addstr(chunk) def move(self, narg=None, **kw): direction = Direction(kw) @@ -158,12 +167,13 @@ class Pager(Widget): if isinstance(source, str): self.source_is_stream = False - self.lines = source.split('\n') + self.lines = source.splitlines() elif hasattr(source, '__getitem__'): self.source_is_stream = False self.lines = source elif hasattr(source, 'readline'): self.source_is_stream = True + self.markup = 'ansi' self.lines = [] else: self.source = None @@ -206,8 +216,12 @@ class Pager(Widget): while True: try: line = self._get_line(i).expandtabs(4) - line = line[startx:self.wid + startx].rstrip() - yield line + if self.markup is 'ansi': + line = ansi.char_slice(line, startx, self.wid + startx) \ + + ansi.reset + else: + line = line[startx:self.wid + startx] + yield line.rstrip() except IndexError: raise StopIteration i += 1 |