summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--doc/ranger.16
-rw-r--r--doc/ranger.pod5
-rw-r--r--ranger/config/commands.py4
-rw-r--r--ranger/config/rc.conf3
-rw-r--r--ranger/container/directory.py21
-rw-r--r--ranger/container/fsobject.py8
-rw-r--r--ranger/container/settings.py1
-rw-r--r--ranger/core/actions.py8
-rw-r--r--ranger/gui/widgets/titlebar.py2
9 files changed, 43 insertions, 15 deletions
diff --git a/doc/ranger.1 b/doc/ranger.1
index 41463478..42b32f70 100644
--- a/doc/ranger.1
+++ b/doc/ranger.1
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "RANGER 1"
-.TH RANGER 1 "ranger-1.6.1" "02/18/2015" "ranger manual"
+.TH RANGER 1 "ranger-1.6.1" "03/03/2015" "ranger manual"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -758,6 +758,10 @@ Sort directories first?
 .IP "sort_reverse [bool] <or>" 4
 .IX Item "sort_reverse [bool] <or>"
 Reverse the order of files?
+.IP "sort_unicode [bool]" 4
+.IX Item "sort_unicode [bool]"
+When sorting according to some string, should the unicode characters be
+compared, instead of looking at the raw character values to save time?
 .IP "sort [string] <oa>, <ob>, <oc>, <oe>, <om>, <on>, <ot>, <os>, <oz>" 4
 .IX Item "sort [string] <oa>, <ob>, <oc>, <oe>, <om>, <on>, <ot>, <os>, <oz>"
 Which sorting mechanism should be used?  Choose one of \fBatime\fR, \fBbasename\fR,
diff --git a/doc/ranger.pod b/doc/ranger.pod
index d19ddc0f..7b3354c4 100644
--- a/doc/ranger.pod
+++ b/doc/ranger.pod
@@ -765,6 +765,11 @@ Sort directories first?
 
 Reverse the order of files?
 
+=item sort_unicode [bool]
+
+When sorting according to some string, should the unicode characters be
+compared, instead of looking at the raw character values to save time?
+
 =item sort [string] <oa>, <ob>, <oc>, <oe>, <om>, <on>, <ot>, <os>, <oz>
 
 Which sorting mechanism should be used?  Choose one of B<atime>, B<basename>,
diff --git a/ranger/config/commands.py b/ranger/config/commands.py
index 6e2ba26d..60b5a26f 100644
--- a/ranger/config/commands.py
+++ b/ranger/config/commands.py
@@ -793,14 +793,12 @@ class bulkrename(Command):
     def execute(self):
         import sys
         import tempfile
-        from os.path import relpath
         from ranger.container.file import File
         from ranger.ext.shell_escape import shell_escape as esc
         py3 = sys.version_info[0] >= 3
 
         # Create and edit the file list
-        filenames = [relpath(f.path, start=self.fm.thisdir.path)
-                     for f in self.fm.thistab.get_selection()]
+        filenames = [f.relative_path for f in self.fm.thistab.get_selection()]
         listfile = tempfile.NamedTemporaryFile(delete=False)
         listpath = listfile.name
 
diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf
index 59237a59..0d8edaf8 100644
--- a/ranger/config/rc.conf
+++ b/ranger/config/rc.conf
@@ -29,7 +29,7 @@ set hidden_filter ^\.|\.(?:pyc|pyo|bak|swp)$|^lost\+found$|^__(py)?cache__$
 set show_hidden false
 
 # Ask for a confirmation when running the "delete" command?
-# Valid values are "always" (default), "never", "multiple"
+# Valid values are "always", "never", "multiple" (default)
 # With "multiple", ranger will ask only if you delete multiple files at once.
 set confirm_on_delete multiple
 
@@ -154,6 +154,7 @@ set sort natural
 set sort_reverse false
 set sort_case_insensitive true
 set sort_directories_first true
+set sort_unicode false
 
 # Enable this if key combinations with the Alt Key don't work for you.
 # (Especially on xterm)
diff --git a/ranger/container/directory.py b/ranger/container/directory.py
index 63502ce9..256dd729 100644
--- a/ranger/container/directory.py
+++ b/ranger/container/directory.py
@@ -1,6 +1,7 @@
 # Copyright (C) 2009-2013  Roman Zimbelmann <hut@hut.pm>
 # This software is distributed under the terms of the GNU GPL version 3.
 
+import locale
 import os.path
 import random
 import re
@@ -20,7 +21,7 @@ from ranger.container.settings import LocalSettings
 
 def sort_by_basename(path):
     """returns path.basename (for sorting)"""
-    return path.drawn_basename
+    return path.relative_path
 
 def sort_by_basename_icase(path):
     """returns case-insensitive path.basename (for sorting)"""
@@ -36,6 +37,17 @@ def sort_naturally(path):
 def sort_naturally_icase(path):
     return path.basename_natural_lower
 
+def sort_unicode_wrapper_string(old_sort_func):
+    def sort_unicode(path):
+        return locale.strxfrm(old_sort_func(path))
+    return sort_unicode
+
+def sort_unicode_wrapper_list(old_sort_func):
+    def sort_unicode(path):
+        return [locale.strxfrm(str(c)) for c in old_sort_func(path)]
+    return sort_unicode
+
+
 def accept_file(file, filters):
     """
     Returns True if file shall be shown, otherwise False.
@@ -414,6 +426,13 @@ class Directory(FileSystemObject, Accumulator, Loadable):
                 sort_func == sort_naturally:
             sort_func = sort_naturally_icase
 
+        # XXX Does not work with usermade sorting functions :S
+        if self.settings.sort_unicode:
+            if sort_func in (sort_naturally, sort_naturally_icase):
+                sort_func = sort_unicode_wrapper_list(sort_func)
+            elif sort_func in (sort_by_basename, sort_by_basename_icase):
+                sort_func = sort_unicode_wrapper_string(sort_func)
+
         self.files_all.sort(key = sort_func)
 
         if self.settings.sort_reverse:
diff --git a/ranger/container/fsobject.py b/ranger/container/fsobject.py
index 43499e15..f7cf7f97 100644
--- a/ranger/container/fsobject.py
+++ b/ranger/container/fsobject.py
@@ -96,11 +96,11 @@ class FileSystemObject(FileManagerAware, SettingsAware):
         self.basename_is_rel_to = basename_is_rel_to
         if basename_is_rel_to == None:
             self.basename = basename(path)
-            self.drawn_basename = self.basename
+            self.relative_path = self.basename
         else:
             self.basename = basename(path)
-            self.drawn_basename = relpath(path, basename_is_rel_to)
-        self.basename_lower = self.drawn_basename.lower()
+            self.relative_path = relpath(path, basename_is_rel_to)
+        self.basename_lower = self.relative_path.lower()
         self.extension = splitext(self.basename)[1].lstrip(extsep) or None
         self.dirname = dirname(path)
         self.preload = preload
@@ -144,7 +144,7 @@ class FileSystemObject(FileManagerAware, SettingsAware):
     @lazy_property
     def basename_natural(self):
         return [c if i % 3 == 1 else (int(c) if c else 0) for i, c in \
-            enumerate(_extract_number_re.split(self.drawn_basename))]
+            enumerate(_extract_number_re.split(self.relative_path))]
 
     @lazy_property
     def basename_natural_lower(self):
diff --git a/ranger/container/settings.py b/ranger/container/settings.py
index 55585029..ddcc7d14 100644
--- a/ranger/container/settings.py
+++ b/ranger/container/settings.py
@@ -47,6 +47,7 @@ ALLOWED_SETTINGS = {
     'sort_case_insensitive': bool,
     'sort_directories_first': bool,
     'sort_reverse': bool,
+    'sort_unicode': bool,
     'sort': str,
     'status_bar_on_top': bool,
     'tilde_in_titlebar': bool,
diff --git a/ranger/core/actions.py b/ranger/core/actions.py
index 6e0dc797..33903859 100644
--- a/ranger/core/actions.py
+++ b/ranger/core/actions.py
@@ -258,12 +258,12 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
         macros['rangerdir'] = ranger.RANGERDIR
 
         if self.fm.thisfile:
-            macros['f'] = self.fm.thisfile.basename
+            macros['f'] = self.fm.thisfile.relative_path
         else:
             macros['f'] = MACRO_FAIL
 
         if self.fm.thistab.get_selection:
-            macros['s'] = [fl.basename for fl in self.fm.thistab.get_selection()]
+            macros['s'] = [fl.relative_path for fl in self.fm.thistab.get_selection()]
         else:
             macros['s'] = MACRO_FAIL
 
@@ -273,7 +273,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
             macros['c'] = MACRO_FAIL
 
         if self.fm.thisdir.files:
-            macros['t'] = [fl.basename for fl in self.fm.thisdir.files
+            macros['t'] = [fl.relative_path for fl in self.fm.thisdir.files
                     if fl.realpath in (self.fm.tags or [])]
         else:
             macros['t'] = MACRO_FAIL
@@ -1290,7 +1290,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 
     def mkdir(self, name):
         try:
-            os.mkdir(os.path.join(self.thisdir.path, name))
+            os.mkdirs(os.path.join(self.thisdir.path, name))
         except OSError as err:
             self.notify(err)
 
diff --git a/ranger/gui/widgets/titlebar.py b/ranger/gui/widgets/titlebar.py
index 55cc25e6..52726b1c 100644
--- a/ranger/gui/widgets/titlebar.py
+++ b/ranger/gui/widgets/titlebar.py
@@ -117,7 +117,7 @@ class TitleBar(Widget):
 
         if self.fm.thisfile is not None and \
                 self.settings.show_selection_in_titlebar:
-            bar.add(self.fm.thisfile.drawn_basename, 'file')
+            bar.add(self.fm.thisfile.relative_path, 'file')
 
     def _get_right_part(self, bar):
         # TODO: fix that pressed keys are cut off when chaining CTRL keys