summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--ranger/__main__.py69
-rw-r--r--ranger/core/environment.py4
-rw-r--r--ranger/core/fm.py11
-rw-r--r--ranger/defaults/options.py7
-rw-r--r--ranger/fsobject/directory.py8
-rw-r--r--ranger/fsobject/fsobject.py47
-rw-r--r--ranger/gui/widgets/browsercolumn.py3
-rw-r--r--ranger/gui/widgets/browserview.py2
-rw-r--r--ranger/gui/widgets/console.py7
-rw-r--r--ranger/help/starting.py12
-rw-r--r--ranger/shared/settings.py21
11 files changed, 109 insertions, 82 deletions
diff --git a/ranger/__main__.py b/ranger/__main__.py
index 2aae6343..ae3f3221 100644
--- a/ranger/__main__.py
+++ b/ranger/__main__.py
@@ -18,7 +18,7 @@
 
 import os
 import sys
-
+import ranger
 
 def parse_arguments():
 	"""Parse the program arguments"""
@@ -46,18 +46,47 @@ def parse_arguments():
 	arg = OpenStruct(options.__dict__, targets=positional)
 	arg.confdir = os.path.expanduser(arg.confdir)
 
-	if not arg.clean:
+	return arg
+
+def load_settings(fm):
+	if not ranger.arg.clean:
 		try:
-			os.makedirs(arg.confdir)
+			os.makedirs(ranger.arg.confdir)
 		except OSError as err:
 			if err.errno != 17:  # 17 means it already exists
 				print("This configuration directory could not be created:")
-				print(arg.confdir)
-				print("To run ranger without the need for configuration files")
-				print("use the --clean option.")
+				print(ranger.arg.confdir)
+				print("To run ranger without the need for configuration")
+				print("files, use the --clean option.")
 				raise SystemExit()
-		sys.path.append(arg.confdir)
-	return arg
+
+		sys.path[0:0] = [ranger.arg.confdir]
+
+		try:
+			import commands
+		except ImportError:
+			from ranger.defaults import commands
+		try:
+			import apps
+		except ImportError:
+			from ranger.defaults import apps
+
+		from ranger import shared, api
+		from ranger.api import keys
+		keymanager = shared.EnvironmentAware.env.keymanager
+		keys.keymanager = keymanager
+		from ranger.defaults import keys
+		try:
+			import keys
+		except ImportError:
+			pass
+		del sys.path[0]
+	else:
+		from ranger.defaults import commands, keys, apps
+	fm.commands = commands
+	fm.keys = keys
+	fm.apps = apps.CustomApplications()
+
 
 def main():
 	"""initialize objects and run the filemanager"""
@@ -71,7 +100,6 @@ def main():
 	from signal import signal, SIGINT
 	from locale import getdefaultlocale, setlocale, LC_ALL
 
-	import ranger
 	from ranger.ext import curses_interrupt_handler
 	from ranger.core.fm import FM
 	from ranger.core.environment import Environment
@@ -105,7 +133,9 @@ def main():
 			sys.exit(1)
 		elif os.path.isfile(target):
 			thefile = File(target)
-			FM().execute_file(thefile, mode=arg.mode, flags=arg.flags)
+			fm = FM()
+			load_settings(fm)
+			fm.execute_file(thefile, mode=arg.mode, flags=arg.flags)
 			sys.exit(0)
 		else:
 			path = target
@@ -116,18 +146,21 @@ def main():
 	SettingsAware._setup_keys()
 
 	try:
-		my_ui = UI()
-		my_fm = FM(ui=my_ui)
-		FileManagerAware._assign(my_fm)
+		fm = FM()
+		load_settings(fm)
+		FileManagerAware._assign(fm)
+		fm.ui = UI()
 
 		# Run the file manager
-		my_fm.initialize()
-		my_ui.initialize()
-		my_fm.loop()
+		fm.initialize()
+		fm.ui.initialize()
+		fm.loop()
 	finally:
 		# Finish, clean up
-		if 'my_ui' in vars():
-			my_ui.destroy()
+		try:
+			fm.ui.destroy()
+		except (AttributeError, NameError):
+			pass
 
 if __name__ == '__main__':
 	top_dir = os.path.dirname(sys.path[0])
diff --git a/ranger/core/environment.py b/ranger/core/environment.py
index b712683a..49bc8a5c 100644
--- a/ranger/core/environment.py
+++ b/ranger/core/environment.py
@@ -195,6 +195,10 @@ class Environment(SettingsAware, SignalDispatcher):
 		self.cwd = new_cwd
 
 		self.cwd.load_content_if_outdated()
+		if self.cwd.files:
+			for dir in self.cwd.files:
+				if dir.is_directory and dir.infostring == 'unknown':
+					dir.determine_infostring()
 
 		# build the pathway, a tuple of directory objects which lie
 		# on the path to the current directory.
diff --git a/ranger/core/fm.py b/ranger/core/fm.py
index 495b9f13..ab418c89 100644
--- a/ranger/core/fm.py
+++ b/ranger/core/fm.py
@@ -50,12 +50,6 @@ class FM(Actions, SignalDispatcher):
 		self.tabs = {}
 		self.current_tab = 1
 		self.loader = Loader()
-		self.apps = self.settings.apps.CustomApplications()
-
-		def mylogfunc(text):
-			self.notify(text, bad=True)
-		self.run = Runner(ui=self.ui, apps=self.apps,
-				logfunc=mylogfunc)
 
 		self.log.append('Ranger {0} started! Process ID is {1}.' \
 				.format(__version__, os.getpid()))
@@ -93,6 +87,11 @@ class FM(Actions, SignalDispatcher):
 			self.ui = DefaultUI()
 			self.ui.initialize()
 
+		def mylogfunc(text):
+			self.notify(text, bad=True)
+		self.run = Runner(ui=self.ui, apps=self.apps,
+				logfunc=mylogfunc)
+
 		self.env.signal_bind('cd', self._update_current_tab)
 
 	def block_input(self, sec=0):
diff --git a/ranger/defaults/options.py b/ranger/defaults/options.py
index 0593bae3..2de8a230 100644
--- a/ranger/defaults/options.py
+++ b/ranger/defaults/options.py
@@ -39,16 +39,18 @@ hidden_filter = regexp(
 	r'lost\+found|^\.|~$|\.(:?pyc|pyo|bak|swp)$')
 show_hidden = False
 
+# Show dotfiles in the bookmark preview box?
+show_hidden_bookmarks = True
+
 # Which colorscheme to use?  These colorschemes are available by default:
 # default, default88, texas, jungle, snow
 # Snow is monochrome, texas and default88 use 88 colors.
 colorscheme = 'default'
 
 # Preview files on the rightmost column?
-# And collapse the last column if there is nothing to preview?
+# And collapse (shrink) the last column if there is nothing to preview?
 preview_files = True
 preview_directories = True
-max_filesize_for_preview = 300 * 1024  # 300kb
 collapse_preview = True
 
 # Save the console history on exit?
@@ -80,6 +82,7 @@ tilde_in_titlebar = True
 
 # How many directory-changes or console-commands should be kept in history?
 max_history_size = 20
+max_console_history_size = 20
 
 # Try to keep so much space between the top/bottom border when scrolling:
 scroll_offset = 2
diff --git a/ranger/fsobject/directory.py b/ranger/fsobject/directory.py
index c9ec5bf5..3cec1646 100644
--- a/ranger/fsobject/directory.py
+++ b/ranger/fsobject/directory.py
@@ -200,9 +200,13 @@ class Directory(FileSystemObject, Accumulator, SettingsAware):
 
 				self.scroll_offset = 0
 				self.filenames = filenames
-				self.infostring = ' %d' % len(self.filenames) # update the infostring
 				self.files = files
 
+				if self == self.fm.env.cwd:
+					for dir in self.files:
+						if dir.is_directory and dir.infostring == 'unknown':
+							dir.determine_infostring()
+
 				self._clear_marked_items()
 				for item in self.files:
 					if item.path in marked_paths:
@@ -220,8 +224,8 @@ class Directory(FileSystemObject, Accumulator, SettingsAware):
 			else:
 				self.filenames = None
 				self.files = None
-				self.infostring = BAD_INFO
 
+			self.determine_infostring()
 			self.cycle_list = None
 			self.content_loaded = True
 			self.last_update_time = time()
diff --git a/ranger/fsobject/fsobject.py b/ranger/fsobject/fsobject.py
index 94729b9a..4ebec3bc 100644
--- a/ranger/fsobject/fsobject.py
+++ b/ranger/fsobject/fsobject.py
@@ -156,6 +156,29 @@ class FileSystemObject(MimeTypeAware, FileManagerAware):
 		"""Called by directory.mark_item() and similar functions"""
 		self.marked = bool(boolean)
 
+	def determine_infostring(self):
+		if self.is_device:
+			self.infostring = 'dev'
+		elif self.is_fifo:
+			self.infostring = 'fifo'
+		elif self.is_socket:
+			self.infostring = 'sock'
+		elif self.is_link:
+			self.infostring = '->'
+		elif self.is_directory:
+			try:
+				self.size = len(os.listdir(self.path))
+				self.infostring = " %d" % self.size
+				self.accessible = True
+				self.runnable = True
+			except OSError:
+				self.size = 0
+				self.infostring = BAD_INFO
+				self.accessible = False
+		elif self.is_file:
+			self.size = self.stat.st_size
+			self.infostring = ' ' + human_readable(self.size)
+
 	def load(self):
 		"""
 		reads useful information about the filesystem-object from the
@@ -188,40 +211,18 @@ class FileSystemObject(MimeTypeAware, FileManagerAware):
 		if self.accessible and os.access(self.path, os.F_OK):
 			self.exists = True
 			self.accessible = True
-
 			if os.path.isdir(self.path):
 				self.type = T_DIRECTORY
-				try:
-					self.size = len(os.listdir(self.path))
-					self.infostring = ' %d' % self.size
-					self.runnable = True
-				except OSError:
-					self.infostring = BAD_INFO
-					self.runnable = False
-					self.accessible = False
 			elif os.path.isfile(self.path):
 				self.type = T_FILE
-				self.size = self.stat.st_size
-				self.infostring = ' ' + human_readable(self.stat.st_size)
 			else:
 				self.type = T_UNKNOWN
-				if self.is_device:
-					self.infostring = 'dev'
-				elif self.is_fifo:
-					self.infostring = 'fifo'
-				elif self.is_socket:
-					self.infostring = 'sock'
-				else:
-					self.infostring = BAD_INFO
 
 		else:
-			if self.is_link:
-				self.infostring = '->'
-			else:
-				self.infostring = None
 			self.type = T_NONEXISTANT
 			self.exists = False
 			self.runnable = False
+		self.determine_infostring()
 
 	def get_permission_string(self):
 		if self.permissions is not None:
diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py
index 61c74e63..d7dbac4f 100644
--- a/ranger/gui/widgets/browsercolumn.py
+++ b/ranger/gui/widgets/browsercolumn.py
@@ -179,9 +179,6 @@ class BrowserColumn(Pager):
 				and not target.stat.st_mode & stat.S_IFIFO):
 			return False
 
-		maxsize = self.settings.max_filesize_for_preview
-		if maxsize is not None and target.size > maxsize:
-			return False
 		if PREVIEW_WHITELIST.search(target.basename):
 			return True
 		if PREVIEW_BLACKLIST.search(target.basename):
diff --git a/ranger/gui/widgets/browserview.py b/ranger/gui/widgets/browserview.py
index 466e23eb..33418a2f 100644
--- a/ranger/gui/widgets/browserview.py
+++ b/ranger/gui/widgets/browserview.py
@@ -121,7 +121,7 @@ class BrowserView(Widget, DisplayableContainer):
 		self.need_clear = True
 
 		sorted_bookmarks = sorted(item for item in self.fm.bookmarks \
-				if '/.' not in item[1].path)
+			if self.settings.show_hidden_bookmarks or '/.' not in item[1].path)
 
 		def generator():
 			return zip(range(self.hei-1), sorted_bookmarks)
diff --git a/ranger/gui/widgets/console.py b/ranger/gui/widgets/console.py
index c81c66b5..36090bb5 100644
--- a/ranger/gui/widgets/console.py
+++ b/ranger/gui/widgets/console.py
@@ -24,7 +24,6 @@ import re
 from collections import deque
 
 from . import Widget
-from ranger.defaults import commands
 from ranger.gui.widgets.console_mode import is_valid_mode, mode_to_class
 from ranger import log, relpath_conf
 from ranger.core.runner import ALLOWED_FLAGS
@@ -70,7 +69,7 @@ class Console(Widget):
 			self.historypaths = [relpath_conf(x) for x in \
 				('history', 'history_search', 'history_qopen', 'history_open')]
 			for i, path in enumerate(self.historypaths):
-				hist = History(self.settings.max_history_size)
+				hist = History(self.settings.max_console_history_size)
 				self.histories.append(hist)
 				if ranger.arg.clean: continue
 				try: f = open(path, 'r')
@@ -347,7 +346,7 @@ class CommandConsole(ConsoleWithTab):
 			return command_class(self.line, self.mode)
 
 	def _get_cmd_class(self):
-		return commands.get_command(self.line.split()[0])
+		return self.fm.commands.get_command(self.line.split()[0])
 
 	def _get_tab(self):
 		if ' ' in self.line:
@@ -357,7 +356,7 @@ class CommandConsole(ConsoleWithTab):
 			else:
 				return None
 
-		return commands.command_generator(self.line)
+		return self.fm.commands.command_generator(self.line)
 
 
 class QuickCommandConsole(CommandConsole):
diff --git a/ranger/help/starting.py b/ranger/help/starting.py
index 29921ffc..8fd8b0da 100644
--- a/ranger/help/starting.py
+++ b/ranger/help/starting.py
@@ -66,7 +66,8 @@ in the class CustomApplications which starts with "app_" can be used
 as a program in the "open with" prompt.
 
 You're encouraged to add your own program definitions to the list.  Refer to
-documentation in ranger/applications.py for more information on this subject.
+the existing examples in the apps.py, it should be easy to adapt it for your
+purposes.
 
 
 ==============================================================================
@@ -75,8 +76,8 @@ documentation in ranger/applications.py for more information on this subject.
 Sometimes there are multiple variants to open a file.  For example, ranger
 gives you 2 ways of opening a video (by default):
 
-	0	fullscreen
-	1	windowed
+	0	windowed
+	1	fullscreen
 
 By specifying a mode, you can select one of those.  The "l" key will
 start a file in mode 0. "4l" will start the file in mode 4 etc.
@@ -92,12 +93,15 @@ For a list of all programs and modes, see ranger/defaults/apps.py
 Flags give you a way to modify the behaviour of the spawned process.
 
 	s	Silent mode.  Output will be discarded.
-	d	Detach the process.
+	d	Detach the process.  (Run in background)
 	p	Redirect output to the pager
 
 For example, "open with: p" will pipe the output of that process into
 the pager.
 
+An uppercase flag has the opposite effect.  If a program will be detached by
+default, use "open with: D" to not detach it.
+
 Note: Some combinations don't make sense, eg: "vim d" would open the file in
 vim and detach it.  Since vim is a console application, you loose grip
 of that process when you detach it.  It's up to you to do such sanity checks.
diff --git a/ranger/shared/settings.py b/ranger/shared/settings.py
index 01d4caf6..df97238f 100644
--- a/ranger/shared/settings.py
+++ b/ranger/shared/settings.py
@@ -19,6 +19,7 @@ from ranger.ext.openstruct import OpenStruct
 
 ALLOWED_SETTINGS = {
 	'show_hidden': bool,
+	'show_hidden_bookmarks': bool,
 	'show_cursor': bool,
 	'autosave_bookmarks': bool,
 	'save_console_history': bool,
@@ -35,8 +36,8 @@ ALLOWED_SETTINGS = {
 	'update_title': bool,
 	'shorten_title': int,  # Note: False is an instance of int
 	'tilde_in_titlebar': bool,
-	'max_filesize_for_preview': (int, type(None)),
 	'max_history_size': (int, type(None)),
+	'max_console_history_size': (int, type(None)),
 	'scroll_offset': int,
 	'preview_files': bool,
 	'preview_directories': bool,
@@ -169,22 +170,4 @@ class SettingsAware(object):
 				for setting in ALLOWED_SETTINGS), \
 				"Ensure that all options are defined in the defaults!"
 
-		try:
-			import apps
-		except ImportError:
-			from ranger.defaults import apps
-		settings._raw_set('apps', apps)
-
 		SettingsAware.settings = settings
-
-	@staticmethod
-	def _setup_keys():  # ugly! but works.
-		import ranger.api.keys
-		import ranger.shared
-		env = ranger.shared.EnvironmentAware.env
-		ranger.api.keys.keymanager = env.keymanager
-		from ranger.defaults import keys
-		try:
-			import keys
-		except ImportError:
-			pass