summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--ranger/core/fm.py10
-rw-r--r--ranger/core/loader.py27
-rw-r--r--ranger/ext/img_display.py17
-rw-r--r--ranger/fsobject/file.py4
-rw-r--r--ranger/gui/widgets/pager.py9
5 files changed, 56 insertions, 11 deletions
diff --git a/ranger/core/fm.py b/ranger/core/fm.py
index d29e446b..e9ffb888 100644
--- a/ranger/core/fm.py
+++ b/ranger/core/fm.py
@@ -167,12 +167,22 @@ class FM(Actions, SignalDispatcher):
             sys.stderr.write("refusing to copy config files in clean mode\n")
             return
         import shutil
+        from errno import EEXIST
         def copy(_from, to):
             if os.path.exists(self.confpath(to)):
                 sys.stderr.write("already exists: %s\n" % self.confpath(to))
             else:
                 sys.stderr.write("creating: %s\n" % self.confpath(to))
                 try:
+                    os.makedirs(ranger.arg.confdir)
+                except OSError as err:
+                    if err.errno != EEXIST:  # EEXIST means it already exists
+                        print("This configuration directory could not be created:")
+                        print(ranger.arg.confdir)
+                        print("To run ranger without the need for configuration")
+                        print("files, use the --clean option.")
+                        raise SystemExit()
+                try:
                     shutil.copy(self.relpath(_from), self.confpath(to))
                 except Exception as e:
                     sys.stderr.write("  ERROR: %s\n" % str(e))
diff --git a/ranger/core/loader.py b/ranger/core/loader.py
index d5a30caf..bae19e9e 100644
--- a/ranger/core/loader.py
+++ b/ranger/core/loader.py
@@ -121,22 +121,37 @@ class CommandLoader(Loadable, SignalDispatcher, FileManagerAware):
     """
     finished = False
     process = None
-    def __init__(self, args, descr, silent=False, read=False):
+    def __init__(self, args, descr, silent=False, read=False, input=None,
+            kill_on_pause=False):
         SignalDispatcher.__init__(self)
         Loadable.__init__(self, self.generate(), descr)
         self.args = args
         self.silent = silent
         self.read = read
         self.stdout_buffer = ""
+        self.input = input
+        self.kill_on_pause = kill_on_pause
 
     def generate(self):
-        null = open(os.devnull, 'r')
+        if self.input:
+            stdin = PIPE
+        else:
+            stdin = open(os.devnull, 'r')
         self.process = process = Popen(self.args,
-                stdout=PIPE, stderr=PIPE, stdin=null)
+                stdout=PIPE, stderr=PIPE, stdin=stdin)
         self.signal_emit('before', process=process, loader=self)
+        if self.input:
+            try:
+                process.stdin.write(self.input)
+            except IOError as e:
+                if e.errno != errno.EPIPE and e.errno != errno.EINVAL:
+                    raise
+            process.stdin.close()
         if self.silent and not self.read:
             while process.poll() is None:
                 yield
+                if self.finished:
+                    break
                 sleep(0.03)
         else:
             py3 = sys.version >= '3'
@@ -147,6 +162,8 @@ class CommandLoader(Loadable, SignalDispatcher, FileManagerAware):
                 selectlist.append(process.stderr)
             while process.poll() is None:
                 yield
+                if self.finished:
+                    break
                 try:
                     rd, _, __ = select.select(selectlist, [], [], 0.03)
                     if rd:
@@ -175,12 +192,14 @@ class CommandLoader(Loadable, SignalDispatcher, FileManagerAware):
                 if py3:
                     read = safeDecode(read)
                 self.stdout_buffer += read
-        null.close()
         self.finished = True
         self.signal_emit('after', process=process, loader=self)
 
     def pause(self):
         if not self.finished and not self.paused:
+            if self.kill_on_pause:
+                self.finished = True
+                return
             try:
                 self.process.send_signal(20)
             except:
diff --git a/ranger/ext/img_display.py b/ranger/ext/img_display.py
index 307c7b75..9dcd276b 100644
--- a/ranger/ext/img_display.py
+++ b/ranger/ext/img_display.py
@@ -43,9 +43,9 @@ def _w3mimgdisplay(commands):
 
     return output
 
-def draw(path, start_x, start_y, max_width, max_height):
+def generate_w3m_input(path, start_x, start_y, max_width, max_height):
     """
-    Draw an image file in the terminal.
+    Prepare the input string for w3mimgpreview
 
     start_x, start_y, max_height and max_width specify the drawing area.
     They are expressed in number of characters.
@@ -75,14 +75,21 @@ def draw(path, start_x, start_y, max_width, max_height):
         width = (width * max_height_pixels) // height
         height = max_height_pixels
 
-    # draw
-    cmd = "0;1;{x};{y};{w};{h};;;;;{filename}\n4;\n3;".format(
+    return "0;1;{x};{y};{w};{h};;;;;{filename}\n4;\n3;".format(
             x = start_x * fontw,
             y = start_y * fonth,
             w = width,
             h = height,
             filename = path)
-    _w3mimgdisplay(cmd)
+
+def draw(path, start_x, start_y, max_width, max_height):
+    """
+    Draw an image file in the terminal.
+
+    start_x, start_y, max_height and max_width specify the drawing area.
+    They are expressed in number of characters.
+    """
+    _w3mimgdisplay(generate_w3m_input(path, start_x, start_y, max_width, max_height))
 
 def clear(start_x, start_y, width, height):
     """
diff --git a/ranger/fsobject/file.py b/ranger/fsobject/file.py
index 8d75e740..2a287ff5 100644
--- a/ranger/fsobject/file.py
+++ b/ranger/fsobject/file.py
@@ -72,7 +72,9 @@ class File(FileSystemObject, SettingsAware):
         if self.fm.settings.preview_script and \
                 self.fm.settings.use_preview_script:
             return True
-        if self.image or self.container:
+        if self.image and self.fm.settings.preview_images:
+            return True
+        if self.container:
             return False
         if PREVIEW_WHITELIST.search(self.basename):
             return True
diff --git a/ranger/gui/widgets/pager.py b/ranger/gui/widgets/pager.py
index 4e8161a5..8bfdf42d 100644
--- a/ranger/gui/widgets/pager.py
+++ b/ranger/gui/widgets/pager.py
@@ -6,6 +6,7 @@
 The pager displays text and allows you to scroll inside it.
 """
 from . import Widget
+from ranger.core.loader import CommandLoader
 from ranger.gui import ansi
 from ranger.ext.direction import Direction
 import ranger.ext.img_display as img_display
@@ -83,7 +84,13 @@ class Pager(Widget):
             self.source = None
             self.need_redraw_image = False
             try:
-                img_display.draw(self.image, self.x, self.y, self.wid, self.hei)
+                cmd = CommandLoader([img_display.W3MIMGDISPLAY_PATH] +
+                            img_display.W3MIMGDISPLAY_OPTIONS,
+                        input=img_display.generate_w3m_input(self.image,
+                            self.x, self.y, self.wid, self.hei),
+                        descr="loading preview image",
+                        silent=True, kill_on_pause=True)
+                self.fm.loader.add(cmd)
             except img_display.ImgDisplayUnsupportedException:
                 self.fm.settings.preview_images = False
             except Exception as e: