summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--ranger/api/commands.py11
-rw-r--r--ranger/config/commands.py41
-rw-r--r--ranger/config/rc.conf2
-rw-r--r--ranger/core/fm.py6
-rw-r--r--ranger/core/tab.py11
-rw-r--r--ranger/ext/widestring.py6
-rw-r--r--ranger/fsobject/fsobject.py10
-rw-r--r--ranger/gui/ui.py1
8 files changed, 58 insertions, 30 deletions
diff --git a/ranger/api/commands.py b/ranger/api/commands.py
index 8e7e16ac..4a9688a0 100644
--- a/ranger/api/commands.py
+++ b/ranger/api/commands.py
@@ -271,6 +271,17 @@ class Command(FileManagerAware):
 			# manually type in the slash to advance into that directory
 			return (self.start(1) + join(rel_dirname, name) for name in names)
 
+	def _tab_through_executables(self):
+		from ranger.ext.get_executables import get_executables
+		programs = [program for program in get_executables() if \
+				program.startswith(self.rest(1))]
+		if not programs:
+			return
+		if len(programs) == 1:
+			return self.start(1) + programs[0]
+		programs.sort()
+		return (self.start(1) + program for program in programs)
+
 
 class FunctionCommand(Command):
 	_based_function = None
diff --git a/ranger/config/commands.py b/ranger/config/commands.py
index b283a71b..636a949e 100644
--- a/ranger/config/commands.py
+++ b/ranger/config/commands.py
@@ -76,11 +76,7 @@
 # of ranger.
 # ===================================================================
 
-import os
-
 from ranger.api.commands import *
-from ranger.ext.get_executables import get_executables
-from ranger.core.runner import ALLOWED_FLAGS
 
 class alias(Command):
 	"""
@@ -108,8 +104,8 @@ class cd(Command):
 	"""
 
 	def execute(self):
+		import os.path
 		if self.arg(1) == '-r':
-			import os.path
 			self.shift()
 			destination = os.path.realpath(self.rest(1))
 			if os.path.isfile(destination):
@@ -126,6 +122,7 @@ class cd(Command):
 			self.fm.cd(destination)
 
 	def tab(self):
+		import os
 		from os.path import dirname, basename, expanduser, join
 
 		cwd = self.fm.thisdir.path
@@ -205,13 +202,15 @@ class shell(Command):
 			flags = ''
 			command = self.rest(1)
 
-		if not command and 'p' in flags: command = 'cat %f'
+		if not command and 'p' in flags:
+			command = 'cat %f'
 		if command:
 			if '%' in command:
 				command = self.fm.substitute_macros(command)
 			self.fm.execute_command(command, flags=flags)
 
 	def tab(self):
+		from ranger.ext.get_executables import get_executables
 		if self.arg(1) and self.arg(1)[0] == '-':
 			command = self.rest(2)
 		else:
@@ -244,6 +243,9 @@ class open_with(Command):
 				flags = flags,
 				mode = mode)
 
+	def tab(self):
+		return self._tab_through_executables()
+
 	def _get_app_flags_mode(self, string):
 		"""
 		Extracts the application, flags and mode from a string.
@@ -321,6 +323,7 @@ class open_with(Command):
 		return not self._is_flags(arg) and not arg.isdigit()
 
 	def _is_flags(self, arg):
+		from ranger.core.runner import ALLOWED_FLAGS
 		return all(x in ALLOWED_FLAGS for x in arg)
 
 	def _is_mode(self, arg):
@@ -395,12 +398,12 @@ class set_(Command):
 		name, value, name_done = self.parse_setting_line()
 		settings = self.fm.settings
 		if not name:
-			return (self.firstpart + setting for setting in settings)
+			return sorted(self.firstpart + setting for setting in settings)
 		if not value and not name_done:
 			return (self.firstpart + setting for setting in settings \
 					if setting.startswith(name))
 		if not value:
-			return self.firstpart + repr(settings[name])
+			return self.firstpart + str(settings[name])
 		if bool in settings.types_of(name):
 			if 'true'.startswith(value.lower()):
 				return self.firstpart + 'True'
@@ -414,8 +417,9 @@ class setlocal(set_):
 
 	Gives an option a new value.
 	"""
-	PATH_RE=re.compile(r'^\s*path="?(.*?)"?\s*$')
+	PATH_RE = re.compile(r'^\s*path="?(.*?)"?\s*$')
 	def execute(self):
+		import os.path
 		match = self.PATH_RE.match(self.arg(1))
 		if match:
 			path = os.path.normpath(os.path.expanduser(match.group(1)))
@@ -472,6 +476,8 @@ class terminal(Command):
 	Spawns an "x-terminal-emulator" starting in the current directory.
 	"""
 	def execute(self):
+		import os
+		from ranger.ext.get_executables import get_executables
 		command = os.environ.get('TERMCMD', os.environ.get('TERM'))
 		if command not in get_executables():
 			command = 'x-terminal-emulator'
@@ -491,15 +497,13 @@ class delete(Command):
 	use the "current file" (where the cursor is)
 
 	When attempting to delete non-empty directories or multiple
-	marked files, it will require a confirmation: The last word in
-	the line has to start with a 'y'.  This may look like:
-	:delete yes
-	:delete seriously? yeah!
+	marked files, it will require a confirmation.
 	"""
 
 	allow_abbrev = False
 
 	def execute(self):
+		import os
 		if self.rest(1):
 			self.fm.notify("Error: delete takes no arguments! It deletes "
 					"the selected file(s).", bad=True)
@@ -507,6 +511,9 @@ class delete(Command):
 
 		cwd = self.fm.thisdir
 		cf = self.fm.thisfile
+		if not cwd or not cf:
+			self.fm.notify("Error: no file selected for deletion!", bad=True)
+			return
 
 		confirm = self.fm.settings.confirm_on_delete
 		many_files = (cwd.marked_items or (cf.is_directory and not cf.is_link \
@@ -667,6 +674,9 @@ class mkdir(Command):
 		else:
 			self.fm.notify("file/directory exists!", bad=True)
 
+	def tab(self):
+		return self._tab_directory_content()
+
 
 class touch(Command):
 	"""
@@ -684,6 +694,9 @@ class touch(Command):
 		else:
 			self.fm.notify("file/directory exists!", bad=True)
 
+	def tab(self):
+		return self._tab_directory_content()
+
 
 class edit(Command):
 	"""
@@ -935,7 +948,7 @@ class copymap(Command):
 
 	def execute(self):
 		if not self.arg(1) or not self.arg(2):
-			return self.notify("Not enough arguments", bad=True)
+			return self.fm.notify("Not enough arguments", bad=True)
 
 		for arg in self.args[2:]:
 			self.fm.ui.keymaps.copy(self.context, self.arg(1), arg)
diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf
index 82dc1379..f4d2955d 100644
--- a/ranger/config/rc.conf
+++ b/ranger/config/rc.conf
@@ -206,7 +206,7 @@ map <F4> edit
 map <F5> copy
 map <F6> cut
 map <F7> console mkdir 
-map <F8> console delete seriously? 
+map <F8> console delete
 map <F10> exit
 
 # In case you work on a keyboard with dvorak layout
diff --git a/ranger/core/fm.py b/ranger/core/fm.py
index 3c100532..0cd3cb5c 100644
--- a/ranger/core/fm.py
+++ b/ranger/core/fm.py
@@ -186,7 +186,11 @@ class FM(Actions, SignalDispatcher):
 			copy('data/scope.sh', 'scope.sh')
 			os.chmod(self.confpath('scope.sh'),
 				os.stat(self.confpath('scope.sh')).st_mode | stat.S_IXUSR)
-		if which not in ('all', 'rifle', 'scope', 'commands', 'rc'):
+		if which in ('all', 'rifle', 'scope', 'commands', 'rc'):
+			sys.stderr.write("\nPlease note that configuration files may "
+				"change as ranger evolves.\nIt's completely up to you to keep "
+				"them up to date.\n")
+		else:
 			sys.stderr.write("Unknown config file `%s'\n" % which)
 
 	def confpath(self, *paths):
diff --git a/ranger/core/tab.py b/ranger/core/tab.py
index 8ae74141..443b2037 100644
--- a/ranger/core/tab.py
+++ b/ranger/core/tab.py
@@ -61,20 +61,15 @@ class Tab(FileManagerAware, SettingsAware):
 			except IndexError:
 				return None
 		else:
-			directory = self.thisfile
-			for i in range(level - 1):
+			directory = self.thisdir
+			for i in range(level):
 				if directory is None:
 					return None
 				if directory.is_directory:
 					directory = directory.pointed_obj
 				else:
 					return None
-			try:
-				return self.fm.directories[directory.path]
-			except AttributeError:
-				return None
-			except KeyError:
-				return directory
+			return directory
 
 	def get_selection(self):
 		if self.thisdir:
diff --git a/ranger/ext/widestring.py b/ranger/ext/widestring.py
index 44972c9c..fbd84b0d 100644
--- a/ranger/ext/widestring.py
+++ b/ranger/ext/widestring.py
@@ -88,6 +88,8 @@ class WideString(object):
 		"""
 		>>> WideString("asdf")[1:3]
 		<WideString 'sd'>
+		>>> WideString("asdf")[1:-100]
+		<WideString ''>
 		>>> WideString("モヒカン")[2:4]
 		<WideString 'ヒ'>
 		>>> WideString("モヒカン")[2:5]
@@ -107,6 +109,10 @@ class WideString(object):
 		"""
 		if z is None or z > len(self.chars):
 			z = len(self.chars)
+		if z < 0:
+			z = len(self.chars) + z
+		if z < 0:
+			return WideString("")
 		if a is None or a < 0:
 			a = 0
 		if z < len(self.chars) and self.chars[z] == '':
diff --git a/ranger/fsobject/fsobject.py b/ranger/fsobject/fsobject.py
index 073da74f..0417e8d3 100644
--- a/ranger/fsobject/fsobject.py
+++ b/ranger/fsobject/fsobject.py
@@ -210,8 +210,8 @@ class FileSystemObject(FileManagerAware):
 		else:
 			try:
 				new_stat = lstat(path)
-				is_link = new_stat.st_mode & 0o170000 == 0o120000
-				if is_link:
+				self.is_link = new_stat.st_mode & 0o170000 == 0o120000
+				if self.is_link:
 					new_stat = stat(path)
 				self.exists = True
 			except:
@@ -242,10 +242,8 @@ class FileSystemObject(FileManagerAware):
 			else:
 				self.size = 0
 				self.infostring = '?'
-		if is_link:
-			self.is_link = True
-			if not self.is_directory:
-				self.infostring = '->' + self.infostring
+		if self.is_link and not self.is_directory:
+			self.infostring = '->' + self.infostring
 
 		self.stat = new_stat
 
diff --git a/ranger/gui/ui.py b/ranger/gui/ui.py
index 78dab9de..f01b7b17 100644
--- a/ranger/gui/ui.py
+++ b/ranger/gui/ui.py
@@ -88,6 +88,7 @@ class UI(DisplayableContainer):
 
 		if self.settings.update_tmux_title:
 			sys.stdout.write("\033kranger\033\\")
+			sys.stdout.flush()
 
 	def suspend(self):
 		"""Turn off curses"""