summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--TODO2
-rw-r--r--ranger/ext/shell_escape.py14
-rw-r--r--ranger/fsobject/fsobject.py9
-rw-r--r--ranger/gui/widgets/console.py4
4 files changed, 26 insertions, 3 deletions
diff --git a/TODO b/TODO
index d475f099..78aaeb97 100644
--- a/TODO
+++ b/TODO
@@ -61,7 +61,7 @@ Bugs
    (X) #41  10/01/17  capital file extensions are not recognized
    (X) #46  10/01/19  old username displayed after using su
    (X) #49  10/01/19  fix unit tests :'(
-   ( ) #52  10/01/23  special characters in tab completion
+   (X) #52  10/01/23  special characters in tab completion
    (X) #54  10/01/23  max_dirsize_for_autopreview not working
    ( ) #60  10/02/05  utf support improvable
    (X) #62  10/02/15  curs_set can raise an exception
diff --git a/ranger/ext/shell_escape.py b/ranger/ext/shell_escape.py
index 8a78fc53..682cd86f 100644
--- a/ranger/ext/shell_escape.py
+++ b/ranger/ext/shell_escape.py
@@ -16,5 +16,19 @@
 A function to escape metacharacters of arguments for shell commands.
 """
 
+META_CHARS = (' ', "'", '"', '`', '&', '|', ';',
+		'$', '!', '(', ')', '[', ']', '<', '>')
+META_DICT = dict([(mc, '\\' + mc) for mc in META_CHARS])
+
 def shell_escape(string):
+	"""Escapes by quoting"""
 	return "'" + str(string).replace("'", "'\\''") + "'"
+
+
+def shell_escape2(arg):
+	"""Escapes by adding backslashes"""
+	arg = str(arg)
+	arg = arg.replace('\\', '\\\\') # make sure this comes at the start
+	for k, v in META_DICT.items():
+		arg = arg.replace(k, v)
+	return arg
diff --git a/ranger/fsobject/fsobject.py b/ranger/fsobject/fsobject.py
index 3721aa54..4b734e8a 100644
--- a/ranger/fsobject/fsobject.py
+++ b/ranger/fsobject/fsobject.py
@@ -18,6 +18,8 @@ DOCUMENT_BASENAMES = 'README TODO LICENSE COPYING INSTALL'.split()
 
 from . import T_FILE, T_DIRECTORY, T_UNKNOWN, T_NONEXISTANT, BAD_INFO
 from ranger.shared import MimeTypeAware, FileManagerAware
+from ranger.ext.shell_escape import shell_escape2
+
 class FileSystemObject(MimeTypeAware, FileManagerAware):
 	is_file = False
 	is_directory = False
@@ -26,6 +28,7 @@ class FileSystemObject(MimeTypeAware, FileManagerAware):
 	path = None
 	basename = None
 	basename_lower = None
+	_shell_escaped_basename = None
 	dirname = None
 	extension = None
 	exists = False
@@ -76,6 +79,12 @@ class FileSystemObject(MimeTypeAware, FileManagerAware):
 		self.set_mimetype()
 		self.use()
 
+	@property
+	def shell_escaped_basename(self):
+		if self._shell_escaped_basename is None:
+			self._shell_escaped_basename = shell_escape2(self.basename)
+		return self._shell_escaped_basename
+
 	def get_description(self):
 		return "Loading " + str(self)
 
diff --git a/ranger/gui/widgets/console.py b/ranger/gui/widgets/console.py
index 5439b2a8..34c8abf5 100644
--- a/ranger/gui/widgets/console.py
+++ b/ranger/gui/widgets/console.py
@@ -413,9 +413,9 @@ class OpenConsole(ConsoleWithTab):
 			return self.line + '%s '
 		else:
 			before_word, start_of_word = self.line.rsplit(' ', 1)
-			return (before_word + ' ' + file.basename \
+			return (before_word + ' ' + file.shell_escaped_basename \
 					for file in self.fm.env.pwd.files \
-					if file.basename.startswith(start_of_word))
+					if file.shell_escaped_basename.startswith(start_of_word))
 
 	def _substitute_metachars(self, command):
 		dct = {}
8f6f7f94b3c0a1da2d8abb38cf23ca127dd28a4'>f8f6f7f9 ^
29028631 ^

176e8a68 ^
3ee05c16 ^

f8f6f7f9 ^
f8f6f7f9 ^
176e8a68 ^
f8f6f7f9 ^





f8f6f7f9 ^




7bf5f967 ^

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78