From 7a0f5d2f25a807e80a691c1346043a993d9d2214 Mon Sep 17 00:00:00 2001 From: hut Date: Thu, 3 Jun 2010 21:15:18 +0200 Subject: added gui/ansi.py from David Barnetts branch --- ranger/gui/ansi.py | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/tc_ansi.py | 45 +++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 ranger/gui/ansi.py create mode 100644 test/tc_ansi.py diff --git a/ranger/gui/ansi.py b/ranger/gui/ansi.py new file mode 100644 index 00000000..7d5f2623 --- /dev/null +++ b/ranger/gui/ansi.py @@ -0,0 +1,66 @@ +# Copyright (C) 2010 David Barnett +# +# 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 3 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, see . + +import re + +ansi_re = re.compile('(\x1b' + r'\[\d+(?:;\d+)*?m)') + +def split_ansi_from_text(ansi_text): + return ansi_re.split(ansi_text) + +def text_with_fg_bg(ansi_text): + for chunk in split_ansi_from_text(ansi_text): + if chunk.startswith('\x1b'): + attr_text = re.match('\x1b' + r'\[(.*?)m', chunk).group(1) + fg, bg = -1, -1 + for attr in attr_text.split(';'): + m = re.match('^3(\d)$', attr) + if m: + fg = int(m.group(1)) + m = re.match('^4(\d)$', attr) + if m: + bg = int(m.group(1)) + yield (fg, bg) + else: + yield chunk + +def char_len(ansi_text): + return len(ansi_re.sub('', ansi_text)) + +def char_slice(ansi_text, start, end): + slice_chunks = [] + # skip to start + last_color = None + skip_len_left = start + len_left = end - start + for chunk in split_ansi_from_text(ansi_text): + m = ansi_re.match(chunk) + if m: + last_color = chunk + else: + if skip_len_left > len(chunk): + skip_len_left -= len(chunk) + else: # finished skipping to start + if skip_len_left > 0: + chunk = chunk[skip_len_left:] + chunk_left = chunk[:len_left] + if len(chunk_left): + if last_color is not None: + slice_chunks.append(last_color) + slice_chunks.append(chunk_left) + len_left -= len(chunk_left) + if len_left == 0: + break + return ''.join(slice_chunks) diff --git a/test/tc_ansi.py b/test/tc_ansi.py new file mode 100644 index 00000000..5fc4e53b --- /dev/null +++ b/test/tc_ansi.py @@ -0,0 +1,45 @@ +# Copyright (C) 2010 David Barnett +# +# 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 3 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, see . + +if __name__ == '__main__': from __init__ import init; init() + +import unittest +from ranger.gui import ansi + +class TestDisplayable(unittest.TestCase): + def setUp(self): + pass + + def tearDown(self): + pass + + def test_char_len(self): + ansi_string = "X" + self.assertEqual(ansi.char_len(ansi_string), 1) + + def test_char_len2(self): + ansi_string = "XY" + self.assertEqual(ansi.char_len(ansi_string), 2) + + def test_char_len3(self): + ansi_string = "XY" + self.assertEqual(ansi.char_len(ansi_string), 2) + + def test_char_slice(self): + ansi_string = "XY" + self.assertEqual(ansi.char_slice(ansi_string, 0, 1), "X") + +if __name__ == '__main__': + unittest.main() -- cgit 1.4.1-2-gfad0 From cfa5ab76e62d73af76f131cb82938faa069e332e Mon Sep 17 00:00:00 2001 From: hut Date: Thu, 3 Jun 2010 22:06:42 +0200 Subject: gui.ansi: some modifications/completions --- ranger/gui/ansi.py | 47 ++++++++++++++++++++++++++++++++++------------- test/tc_ansi.py | 9 ++------- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/ranger/gui/ansi.py b/ranger/gui/ansi.py index 7d5f2623..fe0753a1 100644 --- a/ranger/gui/ansi.py +++ b/ranger/gui/ansi.py @@ -1,4 +1,5 @@ # Copyright (C) 2010 David Barnett +# Copyright (C) 2010 Roman Zimbelmann # # 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,26 +14,45 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +from ranger.gui import color import re -ansi_re = re.compile('(\x1b' + r'\[\d+(?:;\d+)*?m)') +ansi_re = re.compile('(\033' + r'\[\d+(?:;\d+)*?[a-zA-Z])') def split_ansi_from_text(ansi_text): return ansi_re.split(ansi_text) def text_with_fg_bg(ansi_text): for chunk in split_ansi_from_text(ansi_text): - if chunk.startswith('\x1b'): - attr_text = re.match('\x1b' + r'\[(.*?)m', chunk).group(1) - fg, bg = -1, -1 - for attr in attr_text.split(';'): - m = re.match('^3(\d)$', attr) - if m: - fg = int(m.group(1)) - m = re.match('^4(\d)$', attr) - if m: - bg = int(m.group(1)) - yield (fg, bg) + if chunk[0] == '\033': + if chunk[-1] != 'm': + continue + match = re.match(r'^.\[(.*).$', chunk) + attr_args = match.group(1) + fg, bg, attr = -1, -1, 0 + + # Convert arguments to attributes/colors + for arg in attr_args.split(';'): + n = int(arg) + if n == 0: + fg, bg, attr = 0, 0, 0 + elif n == 1: + attr |= color.bold + elif n == 4: + attr |= color.underline + elif n == 7: + attr |= color.reverse + elif n == 8: + attr |= color.invisible + elif n >= 30 and n <= 37: + fg = n - 30 + elif n == 39: + fg = -1 + elif n >= 40 and n <= 47: + bg = n - 40 + elif n == 49: + bg = -1 + yield (fg, bg, attr) else: yield chunk @@ -48,7 +68,8 @@ def char_slice(ansi_text, start, end): for chunk in split_ansi_from_text(ansi_text): m = ansi_re.match(chunk) if m: - last_color = chunk + if chunk[-1] == 'm': + last_color = chunk else: if skip_len_left > len(chunk): skip_len_left -= len(chunk) diff --git a/test/tc_ansi.py b/test/tc_ansi.py index 5fc4e53b..0a6ad8b1 100644 --- a/test/tc_ansi.py +++ b/test/tc_ansi.py @@ -19,12 +19,6 @@ import unittest from ranger.gui import ansi class TestDisplayable(unittest.TestCase): - def setUp(self): - pass - - def tearDown(self): - pass - def test_char_len(self): ansi_string = "X" self.assertEqual(ansi.char_len(ansi_string), 1) @@ -39,7 +33,8 @@ class TestDisplayable(unittest.TestCase): def test_char_slice(self): ansi_string = "XY" - self.assertEqual(ansi.char_slice(ansi_string, 0, 1), "X") + expected = "X" + self.assertEqual(ansi.char_slice(ansi_string, 0, 1), expected) if __name__ == '__main__': unittest.main() -- cgit 1.4.1-2-gfad0 From 43e0f44a4788f3251d5f2ad7c1bfeff014353aba Mon Sep 17 00:00:00 2001 From: hut Date: Thu, 3 Jun 2010 23:01:49 +0200 Subject: added more code from David Barnett, previews work --- ranger/core/actions.py | 9 ++------- ranger/ext/preview.sh | 21 +++++++++++++++++++++ ranger/fsobject/file.py | 21 +++++++++++++++------ ranger/gui/ansi.py | 17 ++++++++++++----- ranger/gui/curses_shortcuts.py | 9 +++++++++ ranger/gui/widgets/pager.py | 20 +++++++++++++++++--- 6 files changed, 76 insertions(+), 21 deletions(-) create mode 100755 ranger/ext/preview.sh 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 +# Copyright (C) 2010 David Barnett # # 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 . +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 +# Copyright (C) 2010 David Barnett # # 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 -- cgit 1.4.1-2-gfad0 From dd7f4e5c27fc04cb2abb93e659c3ec1c4411a662 Mon Sep 17 00:00:00 2001 From: hut Date: Fri, 4 Jun 2010 16:52:30 +0200 Subject: added preview_script option --- ranger/api/options.py | 1 + ranger/defaults/options.py | 3 +++ ranger/fsobject/file.py | 15 +++++++++------ ranger/shared/settings.py | 1 + 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/ranger/api/options.py b/ranger/api/options.py index ee947b39..aee6150b 100644 --- a/ranger/api/options.py +++ b/ranger/api/options.py @@ -17,3 +17,4 @@ import re from re import compile as regexp from ranger.api import * from ranger.gui import color +from ranger import relpath, relpath_conf diff --git a/ranger/defaults/options.py b/ranger/defaults/options.py index 23752d97..feb02a58 100644 --- a/ranger/defaults/options.py +++ b/ranger/defaults/options.py @@ -39,6 +39,9 @@ hidden_filter = regexp( r'^\.|\.(?:pyc|pyo|bak|swp)$|~$|lost\+found') show_hidden = False +# Which script is used to generate file previews? +preview_script = relpath('ext/preview.sh') # relative to rangers path + # Show dotfiles in the bookmark preview box? show_hidden_bookmarks = True diff --git a/ranger/fsobject/file.py b/ranger/fsobject/file.py index 25902f57..cd5b37ff 100644 --- a/ranger/fsobject/file.py +++ b/ranger/fsobject/file.py @@ -92,10 +92,13 @@ class File(FileSystemObject): return True def get_preview_source(self): - try: - p = Popen([relpath('ext/preview.sh'), self.path], - stdout=PIPE, stderr=devnull) - if not p.poll(): + if self.fm.settings.preview_script: + try: + p = Popen([self.fm.settings.preview_script, self.path], + stdout=PIPE, stderr=devnull) + if p.poll(): # nonzero exit code + return None return p.stdout - except: - return open(self.path, 'r') + except: + pass + return open(self.path, 'r') diff --git a/ranger/shared/settings.py b/ranger/shared/settings.py index f5d8614f..24aea39c 100644 --- a/ranger/shared/settings.py +++ b/ranger/shared/settings.py @@ -41,6 +41,7 @@ ALLOWED_SETTINGS = { 'tilde_in_titlebar': bool, 'max_history_size': (int, type(None)), 'max_console_history_size': (int, type(None)), + 'preview_script': (str, type(None)), 'scroll_offset': int, 'preview_files': bool, 'preview_directories': bool, -- cgit 1.4.1-2-gfad0 From 1d895690f81f2cb3a308416c29b280e91e681e36 Mon Sep 17 00:00:00 2001 From: hut Date: Tue, 8 Jun 2010 00:40:43 +0200 Subject: preview: renamed script to "scripts/scope.sh" --- ranger/defaults/options.py | 2 +- ranger/ext/preview.sh | 21 --------------------- ranger/scripts/scope.sh | 22 ++++++++++++++++++++++ 3 files changed, 23 insertions(+), 22 deletions(-) delete mode 100755 ranger/ext/preview.sh create mode 100644 ranger/scripts/scope.sh diff --git a/ranger/defaults/options.py b/ranger/defaults/options.py index feb02a58..4ff774c6 100644 --- a/ranger/defaults/options.py +++ b/ranger/defaults/options.py @@ -40,7 +40,7 @@ hidden_filter = regexp( show_hidden = False # Which script is used to generate file previews? -preview_script = relpath('ext/preview.sh') # relative to rangers path +preview_script = relpath('scripts/scope.sh') # relative to rangers path # Show dotfiles in the bookmark preview box? show_hidden_bookmarks = True diff --git a/ranger/ext/preview.sh b/ranger/ext/preview.sh deleted file mode 100755 index 80186e4d..00000000 --- a/ranger/ext/preview.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/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/scripts/scope.sh b/ranger/scripts/scope.sh new file mode 100644 index 00000000..998476dc --- /dev/null +++ b/ranger/scripts/scope.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# This script is responsible to generate the previews for ranger. +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 -- cgit 1.4.1-2-gfad0 From 9a41e0fc3695c2c7f9b07a93c48f72ee9838c698 Mon Sep 17 00:00:00 2001 From: hut Date: Sat, 12 Jun 2010 02:33:24 +0200 Subject: scripts/scope: make it executable --- ranger/scripts/scope.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 ranger/scripts/scope.sh diff --git a/ranger/scripts/scope.sh b/ranger/scripts/scope.sh old mode 100644 new mode 100755 -- cgit 1.4.1-2-gfad0 From 6613bf4181f3d6d4b612e98e865192b73ebbe90c Mon Sep 17 00:00:00 2001 From: hut Date: Tue, 15 Jun 2010 11:32:02 +0200 Subject: widgets.pager: more efficient width calculation --- ranger/gui/widgets/pager.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ranger/gui/widgets/pager.py b/ranger/gui/widgets/pager.py index 58fcdfd1..5e761a0f 100644 --- a/ranger/gui/widgets/pager.py +++ b/ranger/gui/widgets/pager.py @@ -35,6 +35,7 @@ class Pager(Widget): old_source = None old_scroll_begin = 0 old_startx = 0 + max_width = None def __init__(self, win, embedded=False): Widget.__init__(self, win) self.embedded = embedded @@ -122,7 +123,7 @@ class Pager(Widget): self.startx = direction.move( direction=direction.right(), override=narg, - maximum=self._get_max_width(), + maximum=self.max_width, current=self.startx, pagesize=self.wid, offset=-self.wid + 1) @@ -201,6 +202,8 @@ class Pager(Widget): if attempt_to_read and self.source_is_stream: try: for l in self.source: + if len(l) > self.max_width: + self.max_width = len(l) self.lines.append(l) if len(self.lines) > n: break @@ -225,6 +228,3 @@ class Pager(Widget): except IndexError: raise StopIteration i += 1 - - def _get_max_width(self): - return max(len(line) for line in self.lines) -- cgit 1.4.1-2-gfad0 From d5ba00761ed55e9f5c18b71c7eae546eb4056844 Mon Sep 17 00:00:00 2001 From: hut Date: Tue, 22 Jun 2010 00:55:38 +0200 Subject: move scripts/scope.sh to data/scope.sh --- ranger/data/scope.sh | 22 ++++++++++++++++++++++ ranger/defaults/options.py | 2 +- ranger/scripts/scope.sh | 22 ---------------------- 3 files changed, 23 insertions(+), 23 deletions(-) create mode 100755 ranger/data/scope.sh delete mode 100755 ranger/scripts/scope.sh diff --git a/ranger/data/scope.sh b/ranger/data/scope.sh new file mode 100755 index 00000000..998476dc --- /dev/null +++ b/ranger/data/scope.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# This script is responsible to generate the previews for ranger. +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/defaults/options.py b/ranger/defaults/options.py index 4ff774c6..6e840e33 100644 --- a/ranger/defaults/options.py +++ b/ranger/defaults/options.py @@ -40,7 +40,7 @@ hidden_filter = regexp( show_hidden = False # Which script is used to generate file previews? -preview_script = relpath('scripts/scope.sh') # relative to rangers path +preview_script = relpath('data/scope.sh') # relative to rangers path # Show dotfiles in the bookmark preview box? show_hidden_bookmarks = True diff --git a/ranger/scripts/scope.sh b/ranger/scripts/scope.sh deleted file mode 100755 index 998476dc..00000000 --- a/ranger/scripts/scope.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -# This script is responsible to generate the previews for ranger. -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 -- cgit 1.4.1-2-gfad0 From 48a13dcdb31313d74e71028a32e19041f3a7f76c Mon Sep 17 00:00:00 2001 From: hut Date: Tue, 22 Jun 2010 01:42:53 +0200 Subject: main: copy scope.sh to ~/.ranger on first start --- ranger/__main__.py | 12 +++++++++++- ranger/defaults/options.py | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ranger/__main__.py b/ranger/__main__.py index ac6b2362..048e00b9 100644 --- a/ranger/__main__.py +++ b/ranger/__main__.py @@ -22,7 +22,7 @@ # convenient exception handling in ranger.py (ImportError) import locale -import os +import os.path import sys def parse_arguments(): @@ -60,6 +60,13 @@ def parse_arguments(): return arg +def copy_config_files(): + import shutil + from ranger import relpath, relpath_conf + if not os.path.exists(relpath_conf('scope.sh')): + shutil.copy(relpath('data', 'scope.sh'), relpath_conf('scope.sh')) + + def allow_access_to_confdir(confdir, allow): if allow: try: @@ -200,6 +207,9 @@ def main(): else: path = '.' + if not ranger.arg.clean: + copy_config_files() + crash_traceback = None try: # Initialize objects diff --git a/ranger/defaults/options.py b/ranger/defaults/options.py index 6e840e33..63b1e1a7 100644 --- a/ranger/defaults/options.py +++ b/ranger/defaults/options.py @@ -40,7 +40,7 @@ hidden_filter = regexp( show_hidden = False # Which script is used to generate file previews? -preview_script = relpath('data/scope.sh') # relative to rangers path +preview_script = relpath_conf('scope.sh') # relative to config directory # Show dotfiles in the bookmark preview box? show_hidden_bookmarks = True -- cgit 1.4.1-2-gfad0 From 356726c41d5f7a95fdf60ed867f05d2d10bff70a Mon Sep 17 00:00:00 2001 From: hut Date: Tue, 22 Jun 2010 01:44:48 +0200 Subject: data/scope.sh: improved, commented --- ranger/data/scope.sh | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/ranger/data/scope.sh b/ranger/data/scope.sh index 998476dc..ad14f5e5 100755 --- a/ranger/data/scope.sh +++ b/ranger/data/scope.sh @@ -1,21 +1,30 @@ #!/bin/bash -# This script is responsible to generate the previews for ranger. + +# This script is called whenever you preview a file. +# Its output is used as the preview. ANSI color codes are supported. + +# Meaning of exit codes: +# code | meaning | action of ranger +# -----+------------+------------------------------------------- +# 0 | success | display stdout as preview +# 1 | no preview | display no preview at all + + 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" +case "$mimetype" in + text/*) + highlight --ansi "$1" || cat "$1" || exit 1 exit 0;; - image) + image/*) img2txt "$1" || exit 1 exit 0;; esac case "$extension" in zip|gz) - atool -l "$1" + atool -l "$1" || exit 1 exit 0;; esac -- cgit 1.4.1-2-gfad0 From 3531f1e49d890a75fec3ca6a2ddc773832b1b6a5 Mon Sep 17 00:00:00 2001 From: hut Date: Tue, 22 Jun 2010 02:16:17 +0200 Subject: ranger.__init__: added relpath_script --- ranger/__init__.py | 12 ++++++++++++ ranger/api/options.py | 2 +- ranger/defaults/options.py | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/ranger/__init__.py b/ranger/__init__.py index 4fcc2ecf..54baa3c0 100644 --- a/ranger/__init__.py +++ b/ranger/__init__.py @@ -61,6 +61,18 @@ def relpath_conf(*paths): else: return os.path.join(arg.confdir, *paths) +def relpath_script(*paths): + """ + Returns the path relative to where scripts are stored. + + It's relpath('data', *paths) with the --clean flag and + relpath_conf(*paths) without --clean. + """ + if arg.clean: + return relpath('data', *paths) + else: + return relpath_conf(*paths) + def relpath(*paths): """returns the path relative to rangers library directory""" return os.path.join(RANGERDIR, *paths) diff --git a/ranger/api/options.py b/ranger/api/options.py index aee6150b..93da4df1 100644 --- a/ranger/api/options.py +++ b/ranger/api/options.py @@ -17,4 +17,4 @@ import re from re import compile as regexp from ranger.api import * from ranger.gui import color -from ranger import relpath, relpath_conf +from ranger import relpath, relpath_conf, relpath_script diff --git a/ranger/defaults/options.py b/ranger/defaults/options.py index 63b1e1a7..67009426 100644 --- a/ranger/defaults/options.py +++ b/ranger/defaults/options.py @@ -40,7 +40,7 @@ hidden_filter = regexp( show_hidden = False # Which script is used to generate file previews? -preview_script = relpath_conf('scope.sh') # relative to config directory +preview_script = relpath_script('scope.sh') # relative to config directory # Show dotfiles in the bookmark preview box? show_hidden_bookmarks = True -- cgit 1.4.1-2-gfad0 From 500cf2593322008c05afeed9117dcc5d35b6fa9b Mon Sep 17 00:00:00 2001 From: hut Date: Tue, 22 Jun 2010 10:59:44 +0200 Subject: README: added dependencies for scope.sh --- README | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README b/README index 562dfbdf..7a293b97 100644 --- a/README +++ b/README @@ -50,6 +50,11 @@ Optional: * The "file" program * A pager ("less" by default) +For scope.sh: (enhanced file previews) +* img2txt (from caca-utils) for previewing images +* highlight for syntax highlighting of code +* atool for previews of archives + Getting Started --------------- -- cgit 1.4.1-2-gfad0 From 2e386864912dd028774ffcd997f5ea686e955d0b Mon Sep 17 00:00:00 2001 From: hut Date: Tue, 22 Jun 2010 11:01:54 +0200 Subject: defaults.options: deactivate scope.sh by default --- ranger/defaults/options.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ranger/defaults/options.py b/ranger/defaults/options.py index 67009426..8f8ee830 100644 --- a/ranger/defaults/options.py +++ b/ranger/defaults/options.py @@ -40,7 +40,13 @@ hidden_filter = regexp( show_hidden = False # Which script is used to generate file previews? -preview_script = relpath_script('scope.sh') # relative to config directory +preview_script = None + +# Ranger ships with scope.sh, a script that calls external programs (see +# README for dependencies) to preview images, archives, etc. +# As of now, it's disabled by default because of poor performance. +# Uncomment this line to enable it: +#preview_script = relpath_script('scope.sh') # Show dotfiles in the bookmark preview box? show_hidden_bookmarks = True -- cgit 1.4.1-2-gfad0 From bf14a7e72e7c03673949388365744f26e227ec83 Mon Sep 17 00:00:00 2001 From: hut Date: Tue, 22 Jun 2010 11:27:21 +0200 Subject: data/scope.sh: added lynx --- README | 1 + ranger/data/scope.sh | 22 +++++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/README b/README index 7a293b97..d92543f7 100644 --- a/README +++ b/README @@ -54,6 +54,7 @@ For scope.sh: (enhanced file previews) * img2txt (from caca-utils) for previewing images * highlight for syntax highlighting of code * atool for previews of archives +* lynx or elinks for previews of html pages Getting Started diff --git a/ranger/data/scope.sh b/ranger/data/scope.sh index ad14f5e5..ef5f8ff4 100755 --- a/ranger/data/scope.sh +++ b/ranger/data/scope.sh @@ -13,19 +13,27 @@ mimetype=$(file --mime-type -Lb "$1") extension=$(echo "$1" | grep '\.' | grep -o '[^.]\+$') +case "$extension" in + # Archive extensions: + tar|gz|tgz|bz|tbz|bz2|tbz2|Z|tZ|lzo|tzo|lz|tlz|xz|txz|7z|t7z|\ + zip|jar|war|rar|lha|lzh|alz|ace|a|arj|arc|rpm|cab|lzma|rz|cpio) + atool -l "$1" || exit 1 + exit 0;; + # HTML Pages: + htm|html|xhtml) + lynx -dump "$1" || elinks -dump "$1" || exit 1 + exit 0;; +esac + case "$mimetype" in - text/*) + # Syntax highlight for text files: + text/* | */xml) highlight --ansi "$1" || cat "$1" || exit 1 exit 0;; + # Ascii-previews of images: image/*) img2txt "$1" || exit 1 exit 0;; esac -case "$extension" in - zip|gz) - atool -l "$1" || exit 1 - exit 0;; -esac - exit 1 -- cgit 1.4.1-2-gfad0 From dc7ee19fc15eee33c948d0ccd6c06df9682c0bf3 Mon Sep 17 00:00:00 2001 From: hut Date: Tue, 22 Jun 2010 14:25:03 +0200 Subject: fsobject.file: dynamic width of caca previews, cleanups --- ranger/core/actions.py | 2 +- ranger/data/scope.sh | 16 +++++++++++++--- ranger/fsobject/file.py | 8 +++----- ranger/gui/widgets/browsercolumn.py | 2 +- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/ranger/core/actions.py b/ranger/core/actions.py index 743d82c5..44061aca 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -471,7 +471,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): return pager = self.ui.open_embedded_pager() - pager.set_source(self.env.cf.get_preview_source()) + pager.set_source(self.env.cf.get_preview_source(pager)) # -------------------------- # -- Tabs diff --git a/ranger/data/scope.sh b/ranger/data/scope.sh index ef5f8ff4..80fd2ea7 100755 --- a/ranger/data/scope.sh +++ b/ranger/data/scope.sh @@ -3,12 +3,22 @@ # This script is called whenever you preview a file. # Its output is used as the preview. ANSI color codes are supported. -# Meaning of exit codes: +# NOTE: This is considered to be a configuration file. If you upgrade +# ranger, it will be left untouched. (You must update it yourself) + +# Meanings of arguments: +# name | meaning +# -----+-------------------------------------------------------- +# $1 | Full filename of the selected file +# $2 | Width of the preview pane (number of fitting characters) +# $3 | Height of the preview pane (number of fitting characters) + +# Meanings of exit codes: # code | meaning | action of ranger # -----+------------+------------------------------------------- # 0 | success | display stdout as preview # 1 | no preview | display no preview at all - +# 2 | plain text | display the plain content of the file mimetype=$(file --mime-type -Lb "$1") extension=$(echo "$1" | grep '\.' | grep -o '[^.]\+$') @@ -32,7 +42,7 @@ case "$mimetype" in exit 0;; # Ascii-previews of images: image/*) - img2txt "$1" || exit 1 + img2txt -W "$2" "$1" || exit 1 exit 0;; esac diff --git a/ranger/fsobject/file.py b/ranger/fsobject/file.py index 216b4754..4acad100 100644 --- a/ranger/fsobject/file.py +++ b/ranger/fsobject/file.py @@ -14,7 +14,6 @@ # along with this program. If not, see . import re -import zipfile from ranger.fsobject import FileSystemObject from subprocess import Popen, PIPE from ranger.core.runner import devnull @@ -35,8 +34,6 @@ PREVIEW_BLACKLIST = re.compile(r""" | vob | wav | mpc | flac | divx? | xcf | pdf # binary files: | torrent | class | so | img | py[co] | dmg - # containers: - | iso | rar | 7z | tar | gz | bz2 | tgz ) # ignore filetype-independent suffixes: (\.part|\.bak|~)? @@ -93,10 +90,11 @@ class File(FileSystemObject): return False return True - def get_preview_source(self): + def get_preview_source(self, widget): if self.fm.settings.preview_script: try: - p = Popen([self.fm.settings.preview_script, self.path], + p = Popen([self.fm.settings.preview_script, self.path, + str(widget.wid), str(widget.hei)], stdout=PIPE, stderr=devnull) if p.poll(): # nonzero exit code return None diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py index d617e64e..5585bccc 100644 --- a/ranger/gui/widgets/browsercolumn.py +++ b/ranger/gui/widgets/browsercolumn.py @@ -155,7 +155,7 @@ class BrowserColumn(Pager): return try: - f = self.target.get_preview_source() + f = self.target.get_preview_source(self) except: Pager.close(self) else: -- cgit 1.4.1-2-gfad0 From d56375f95f91b9670a2353ee8d8883eca5c35f1e Mon Sep 17 00:00:00 2001 From: hut Date: Thu, 7 Oct 2010 17:17:44 +0200 Subject: enable shope.sh by default --- ranger/defaults/options.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ranger/defaults/options.py b/ranger/defaults/options.py index 39046443..5ce617bc 100644 --- a/ranger/defaults/options.py +++ b/ranger/defaults/options.py @@ -40,13 +40,11 @@ hidden_filter = regexp( show_hidden = False # Which script is used to generate file previews? -preview_script = None +#preview_script = None # Ranger ships with scope.sh, a script that calls external programs (see # README for dependencies) to preview images, archives, etc. -# As of now, it's disabled by default because of poor performance. -# Uncomment this line to enable it: -#preview_script = relpath_script('scope.sh') +preview_script = relpath_script('scope.sh') # Show dotfiles in the bookmark preview box? show_hidden_bookmarks = True -- cgit 1.4.1-2-gfad0 From 3668fb2c70524a4f3e988cc4760e319500f9a4fb Mon Sep 17 00:00:00 2001 From: hut Date: Fri, 8 Oct 2010 18:25:37 +0200 Subject: core.loader: forgot cleaning up @ last commit --- ranger/core/loader.py | 1 - 1 file changed, 1 deletion(-) diff --git a/ranger/core/loader.py b/ranger/core/loader.py index cda578f2..7b074d60 100644 --- a/ranger/core/loader.py +++ b/ranger/core/loader.py @@ -36,7 +36,6 @@ class Loader(FileManagerAware): self.item = None self.load_generator = None self.throbber_status = 0 - self.status_generator = status_generator() self.rotate() self.old_item = None -- cgit 1.4.1-2-gfad0