about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--ranger/api/commands.py4
-rw-r--r--ranger/config/commands.py58
-rw-r--r--ranger/config/rc.conf4
-rw-r--r--ranger/core/actions.py131
-rw-r--r--ranger/core/environment.py198
-rw-r--r--ranger/core/fm.py42
-rw-r--r--ranger/core/main.py7
-rw-r--r--ranger/core/tab.py140
-rw-r--r--ranger/fsobject/directory.py4
-rw-r--r--ranger/gui/displayable.py2
-rw-r--r--ranger/gui/ui.py6
-rw-r--r--ranger/gui/widgets/browsercolumn.py10
-rw-r--r--ranger/gui/widgets/browserview.py11
-rw-r--r--ranger/gui/widgets/statusbar.py29
-rw-r--r--ranger/gui/widgets/titlebar.py14
15 files changed, 369 insertions, 291 deletions
diff --git a/ranger/api/commands.py b/ranger/api/commands.py
index 97ef415c..aaadde5d 100644
--- a/ranger/api/commands.py
+++ b/ranger/api/commands.py
@@ -179,7 +179,7 @@ class Command(FileManagerAware):
 	def _tab_only_directories(self):
 		from os.path import dirname, basename, expanduser, join
 
-		cwd = self.fm.env.cwd.path
+		cwd = self.fm.thisdir.path
 
 		rel_dest = self.rest(1)
 
@@ -225,7 +225,7 @@ class Command(FileManagerAware):
 	def _tab_directory_content(self):
 		from os.path import dirname, basename, expanduser, join
 
-		cwd = self.fm.env.cwd.path
+		cwd = self.fm.thisdir.path
 
 		rel_dest = self.rest(1)
 
diff --git a/ranger/config/commands.py b/ranger/config/commands.py
index 88b50860..8579b019 100644
--- a/ranger/config/commands.py
+++ b/ranger/config/commands.py
@@ -54,16 +54,16 @@
 # self.fm.notify(string): Print the given string on the screen.
 # self.fm.notify(string, bad=True): Print the given string in RED.
 # self.fm.reload_cwd(): Reload the current working directory.
-# self.fm.env.cwd: The current working directory. (A File object.)
-# self.fm.env.cf: The current file. (A File object too.)
-# self.fm.env.cwd.get_selection(): A list of all selected files.
+# self.fm.thisdir: The current working directory. (A File object.)
+# self.fm.thisfile: The current file. (A File object too.)
+# self.fm.thistab.get_selection(): A list of all selected files.
 # self.fm.execute_console(string): Execute the string as a ranger command.
 # self.fm.open_console(string): Open the console with the given string
 #      already typed in for you.
 # self.fm.move(direction): Moves the cursor in the given direction, which
 #      can be something like down=3, up=5, right=1, left=1, to=6, ...
 #
-# File objects (for example self.fm.env.cf) have these useful attributes and
+# File objects (for example self.fm.thisfile) have these useful attributes and
 # methods:
 #
 # cf.path: The path to the file.
@@ -126,7 +126,7 @@ class cd(Command):
 	def tab(self):
 		from os.path import dirname, basename, expanduser, join
 
-		cwd = self.fm.env.cwd.path
+		cwd = self.fm.thisdir.path
 		rel_dest = self.rest(1)
 
 		bookmarks = [v.path for v in self.fm.bookmarks.dct.values()
@@ -222,7 +222,7 @@ class shell(Command):
 			return (start + program + ' ' for program \
 					in get_executables() if program.startswith(command))
 		if position_of_last_space == len(command) - 1:
-			selection = self.fm.env.get_selection()
+			selection = self.fm.thistab.get_selection()
 			if len(selection) == 1:
 				return self.line + selection[0].shell_escaped_basename + ' '
 			else:
@@ -230,14 +230,14 @@ class shell(Command):
 		else:
 			before_word, start_of_word = self.line.rsplit(' ', 1)
 			return (before_word + ' ' + file.shell_escaped_basename \
-					for file in self.fm.env.cwd.files \
+					for file in self.fm.thisdir.files \
 					if file.shell_escaped_basename.startswith(start_of_word))
 
 class open_with(Command):
 	def execute(self):
 		app, flags, mode = self._get_app_flags_mode(self.rest(1))
 		self.fm.execute_file(
-				files = [f for f in self.fm.env.cwd.get_selection()],
+				files = [f for f in self.fm.thistab.get_selection()],
 				app = app,
 				flags = flags,
 				mode = mode)
@@ -346,7 +346,7 @@ class find(Command):
 
 	def quick(self):
 		self.count = 0
-		cwd = self.fm.env.cwd
+		cwd = self.fm.thisdir
 		arg = self.rest(1)
 		if not arg:
 			return False
@@ -369,7 +369,7 @@ class find(Command):
 				self.count += 1
 				if self.count == 1:
 					cwd.move(to=(cwd.pointer + i) % len(cwd.files))
-					self.fm.env.cf = cwd.pointed_obj
+					self.fm.thisfile.cf = cwd.pointed_obj
 			if self.count > 1:
 				return False
 			i += 1
@@ -490,8 +490,8 @@ class delete(Command):
 			# user did not confirm deletion
 			return
 
-		cwd = self.fm.env.cwd
-		cf = self.fm.env.cf
+		cwd = self.fm.thisdir
+		cf = self.fm.thisfile.cf
 
 		if cwd.marked_items or (cf.is_directory and not cf.is_link \
 				and len(os.listdir(cf.path)) > 0):
@@ -513,7 +513,7 @@ class mark(Command):
 
 	def execute(self):
 		import re
-		cwd = self.fm.env.cwd
+		cwd = self.fm.thisdir
 		input = self.rest(1)
 		searchflags = re.UNICODE
 		if input.lower() == input: # "smartcase"
@@ -604,7 +604,7 @@ class mkdir(Command):
 		from os.path import join, expanduser, lexists
 		from os import mkdir
 
-		dirname = join(self.fm.env.cwd.path, expanduser(self.rest(1)))
+		dirname = join(self.fm.thisdir.path, expanduser(self.rest(1)))
 		if not lexists(dirname):
 			mkdir(dirname)
 		else:
@@ -621,7 +621,7 @@ class touch(Command):
 	def execute(self):
 		from os.path import join, expanduser, lexists
 
-		fname = join(self.fm.env.cwd.path, expanduser(self.rest(1)))
+		fname = join(self.fm.thisdir.path, expanduser(self.rest(1)))
 		if not lexists(fname):
 			open(fname, 'a').close()
 		else:
@@ -637,7 +637,7 @@ class edit(Command):
 
 	def execute(self):
 		if not self.arg(1):
-			self.fm.edit_file(self.fm.env.cf.path)
+			self.fm.edit_file(self.fm.thisfile.path)
 		else:
 			self.fm.edit_file(self.rest(1))
 
@@ -655,7 +655,7 @@ class eval_(Command):
 
 	Examples:
 	:eval fm
-	:eval len(fm.env.directories)
+	:eval len(fm.directories)
 	:eval p("Hello World!")
 	"""
 	name = 'eval'
@@ -702,16 +702,16 @@ class rename(Command):
 		if not new_name:
 			return self.fm.notify('Syntax: rename <newname>', bad=True)
 
-		if new_name == self.fm.env.cf.basename:
+		if new_name == self.fm.thisfile.basename:
 			return
 
 		if access(new_name, os.F_OK):
 			return self.fm.notify("Can't rename: file already exists!", bad=True)
 
-		self.fm.rename(self.fm.env.cf, new_name)
+		self.fm.rename(self.fm.thisfile, new_name)
 		f = File(new_name)
-		self.fm.env.cwd.pointed_obj = f
-		self.fm.env.cf = f
+		self.fm.thisdir.pointed_obj = f
+		self.fm.thisfile = f
 
 	def tab(self):
 		return self._tab_directory_content()
@@ -743,7 +743,7 @@ class chmod(Command):
 			self.fm.notify("Need an octal number between 0 and 777!", bad=True)
 			return
 
-		for file in self.fm.env.get_selection():
+		for file in self.fm.thistab.get_selection():
 			try:
 				os.chmod(file.path, mode)
 			except Exception as ex:
@@ -752,7 +752,7 @@ class chmod(Command):
 		try:
 			# reloading directory.  maybe its better to reload the selected
 			# files only.
-			self.fm.env.cwd.load_content()
+			self.fm.thisdir.load_content()
 		except:
 			pass
 
@@ -776,7 +776,7 @@ class bulkrename(Command):
 		py3 = sys.version > "3"
 
 		# Create and edit the file list
-		filenames = [f.basename for f in self.fm.env.get_selection()]
+		filenames = [f.basename for f in self.fm.thistab.get_selection()]
 		listfile = tempfile.NamedTemporaryFile()
 
 		if py3:
@@ -823,7 +823,7 @@ class relink(Command):
 		from ranger.fsobject import File
 
 		new_path = self.rest(1)
-		cf = self.fm.env.cf
+		cf = self.fm.thisfile
 
 		if not new_path:
 			return self.fm.notify('Syntax: relink <newpath>', bad=True)
@@ -841,12 +841,12 @@ class relink(Command):
 			self.fm.notify(err)
 
 		self.fm.reset()
-		self.fm.env.cwd.pointed_obj = cf
-		self.fm.env.cf = cf
+		self.fm.thisdir.pointed_obj = cf
+		self.fm.thisfile = cf
 
 	def tab(self):
 		if not self.rest(1):
-			return self.line+os.readlink(self.fm.env.cf.path)
+			return self.line+os.readlink(self.fm.thisfile.path)
 		else:
 			return self._tab_directory_content()
 
@@ -1009,5 +1009,5 @@ class grep(Command):
 		if self.rest(1):
 			action = ['grep', '--color=always', '--line-number']
 			action.extend(['-e', self.rest(1), '-r'])
-			action.extend(f.path for f in self.fm.env.get_selection())
+			action.extend(f.path for f in self.fm.thistab.get_selection())
 			self.fm.execute_command(action, flags='p')
diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf
index a347d116..1b802fd5 100644
--- a/ranger/config/rc.conf
+++ b/ranger/config/rc.conf
@@ -139,8 +139,8 @@ map yn shell -d echo -n %f    | xsel -i
 map =  chmod
 
 map cw console rename 
-map A  eval fm.open_console('rename ' + fm.env.cf.basename)
-map I  eval fm.open_console('rename ' + fm.env.cf.basename, position=7)
+map A  eval fm.open_console('rename ' + fm.thisfile.basename)
+map I  eval fm.open_console('rename ' + fm.thisfile.basename, position=7)
 
 map pp paste
 map po paste overwrite=True
diff --git a/ranger/core/actions.py b/ranger/core/actions.py
index da4c480c..bf2e84dd 100644
--- a/ranger/core/actions.py
+++ b/ranger/core/actions.py
@@ -40,9 +40,9 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 
 	def reset(self):
 		"""Reset the filemanager, clearing the directory buffer"""
-		old_path = self.env.cwd.path
+		old_path = self.thisdir.path
 		self.previews = {}
-		self.env.garbage_collect(-1, self.tabs)
+		self.garbage_collect(-1, self.tabs)
 		self.enter_dir(old_path)
 		self.change_mode('normal')
 
@@ -50,9 +50,9 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 		if mode == self.mode:
 			return
 		if mode == 'visual':
-			self._visual_start       = self.env.cwd.pointed_obj
-			self._visual_start_pos   = self.env.cwd.pointer
-			self._previous_selection = set(self.env.cwd.marked_items)
+			self._visual_start       = self.thisdir.pointed_obj
+			self._visual_start_pos   = self.thisdir.pointer
+			self._previous_selection = set(self.thisdir.marked_items)
 			self.mark_files(val=not self._visual_reverse, movedown=False)
 		elif mode == 'normal':
 			if self.mode == 'visual':
@@ -73,7 +73,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 
 	def reload_cwd(self):
 		try:
-			cwd = self.env.cwd
+			cwd = self.thisdir
 		except:
 			pass
 		cwd.unload()
@@ -102,7 +102,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 			self.loader.remove(index=0)
 
 	def get_cumulative_size(self):
-		for f in self.env.get_selection() or ():
+		for f in self.thistab.get_selection() or ():
 			f.look_up_cumulative_size()
 		self.ui.status.request_redraw()
 		self.ui.redraw_main_column()
@@ -168,13 +168,13 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 
 		macros['rangerdir'] = ranger.RANGERDIR
 
-		if self.fm.env.cf:
-			macros['f'] = self.fm.env.cf.basename
+		if self.fm.thisfile:
+			macros['f'] = self.fm.thisfile.basename
 		else:
 			macros['f'] = MACRO_FAIL
 
-		if self.fm.env.get_selection:
-			macros['s'] = [fl.basename for fl in self.fm.env.get_selection()]
+		if self.fm.thistab.get_selection:
+			macros['s'] = [fl.basename for fl in self.fm.thistab.get_selection()]
 		else:
 			macros['s'] = MACRO_FAIL
 
@@ -183,14 +183,14 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 		else:
 			macros['c'] = MACRO_FAIL
 
-		if self.fm.env.cwd.files:
-			macros['t'] = [fl.basename for fl in self.fm.env.cwd.files
+		if self.fm.thisdir.files:
+			macros['t'] = [fl.basename for fl in self.fm.thisdir.files
 					if fl.realpath in (self.fm.tags or [])]
 		else:
 			macros['t'] = MACRO_FAIL
 
-		if self.fm.env.cwd:
-			macros['d'] = self.fm.env.cwd.path
+		if self.fm.thisdir:
+			macros['d'] = self.fm.thisdir.path
 		else:
 			macros['d'] = '.'
 
@@ -272,11 +272,11 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 		# ranger can act as a file chooser when running with --choosefile=...
 		if mode == 0 and 'label' not in kw:
 			if ranger.arg.choosefile:
-				open(ranger.arg.choosefile, 'w').write(self.fm.env.cf.path)
+				open(ranger.arg.choosefile, 'w').write(self.fm.thisfile.path)
 
 			if ranger.arg.choosefiles:
 				open(ranger.arg.choosefiles, 'w').write("".join(
-					f.path + "\n" for f in self.fm.env.get_selection()))
+					f.path + "\n" for f in self.fm.thistab.get_selection()))
 
 			if ranger.arg.choosefile or ranger.arg.choosefiles:
 				raise SystemExit()
@@ -288,7 +288,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 
 		flags = kw.get('flags', '')
 		if 'c' in squash_flags(flags):
-			files = [self.fm.env.cf]
+			files = [self.fm.thisfile]
 
 		self.signal_emit('execute.before', keywords=kw)
 		filenames = [f.path for f in files]
@@ -318,7 +318,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 		self.move(to=2, pages=True)  # moves to page 2.
 		self.move(to=1, percentage=True)  # moves to 80%
 		"""
-		cwd = self.env.cwd
+		cwd = self.thisdir
 		direction = Direction(kw)
 		if 'left' in direction or direction.left() > 0:
 			steps = direction.left()
@@ -328,16 +328,16 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 				directory = os.path.join(*(['..'] * steps))
 			except:
 				return
-			self.env.enter_dir(directory)
+			self.thistab.enter_dir(directory)
 			self.change_mode('normal')
 		if cwd and cwd.accessible and cwd.content_loaded:
 			if 'right' in direction:
 				mode = 0
 				if narg is not None:
 					mode = narg
-				cf = self.env.cf
-				selection = self.env.get_selection()
-				if not self.env.enter_dir(cf) and selection:
+				cf = self.thisfile
+				selection = self.thistab.get_selection()
+				if not self.thistab.enter_dir(cf) and selection:
 					if self.execute_file(selection, mode=mode) is False:
 						self.open_console('open_with ')
 			elif direction.vertical() and cwd.files:
@@ -378,35 +378,36 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 		self.change_mode('normal')
 		if narg is not None:
 			n *= narg
-		parent = self.env.at_level(-1)
+		parent = self.thistab.at_level(-1)
 		if parent is not None:
 			if parent.pointer + n < 0:
 				n = 0 - parent.pointer
 			try:
-				self.env.enter_dir(parent.files[parent.pointer+n])
+				self.thistab.enter_dir(parent.files[parent.pointer+n])
 			except IndexError:
 				pass
 
 	def select_file(self, path):
 		path = path.strip()
 		if self.enter_dir(os.path.dirname(path)):
-			self.env.cwd.move_to_obj(path)
+			self.thisdir.move_to_obj(path)
 
 	def history_go(self, relative):
 		"""Move back and forth in the history"""
-		self.env.history_go(int(relative))
+		self.thistab.history_go(int(relative))
 
+	# TODO: remove this method since it is not used?
 	def scroll(self, relative):
 		"""Scroll down by <relative> lines"""
 		if self.ui.browser and self.ui.browser.main_column:
 			self.ui.browser.main_column.scroll(relative)
-			self.env.cf = self.env.cwd.pointed_obj
+			self.thisfile = self.thisdir.pointed_obj
 
 	def enter_dir(self, path, remember=False, history=True):
 		"""Enter the directory at the given path"""
-		cwd = self.env.cwd
-		result = self.env.enter_dir(path, history=history)
-		if cwd != self.env.cwd:
+		cwd = self.thisdir
+		result = self.thistab.enter_dir(path, history=history)
+		if cwd != self.thisdir:
 			if remember:
 				self.bookmarks.remember(cwd)
 			self.change_mode('normal')
@@ -418,14 +419,14 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 
 	def traverse(self):
 		self.change_mode('normal')
-		cf = self.env.cf
-		cwd = self.env.cwd
+		cf = self.thisfile
+		cwd = self.thisdir
 		if cf is not None and cf.is_directory:
 			self.enter_dir(cf.path)
 		elif cwd.pointer >= len(cwd) - 1:
 			while True:
 				self.move(left=1)
-				cwd = self.env.cwd
+				cwd = self.thisdir
 				if cwd.pointer < len(cwd) - 1:
 					break
 				if cwd.path == '/':
@@ -467,7 +468,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 	def edit_file(self, file=None):
 		"""Calls execute_file with the current file and label='editor'"""
 		if file is None:
-			file = self.env.cf
+			file = self.thisfile
 		elif isinstance(file, str):
 			file = File(os.path.expanduser(file))
 		if file is None:
@@ -476,23 +477,23 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 
 	def toggle_option(self, string):
 		"""Toggle a boolean option named <string>"""
-		if isinstance(self.env.settings[string], bool):
-			self.env.settings[string] ^= True
+		if isinstance(self.settings[string], bool):
+			self.settings[string] ^= True
 
 	def set_option(self, optname, value):
 		"""Set the value of an option named <optname>"""
-		self.env.settings[optname] = value
+		self.settings[optname] = value
 
 	def sort(self, func=None, reverse=None):
 		if reverse is not None:
-			self.env.settings['sort_reverse'] = bool(reverse)
+			self.settings['sort_reverse'] = bool(reverse)
 
 		if func is not None:
-			self.env.settings['sort'] = str(func)
+			self.settings['sort'] = str(func)
 
 	def set_filter(self, fltr):
 		try:
-			self.env.cwd.filter = fltr
+			self.thisdir.filter = fltr
 		except:
 			pass
 
@@ -506,10 +507,10 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 		val - mark or unmark?
 		"""
 
-		if self.env.cwd is None:
+		if self.thisdir is None:
 			return
 
-		cwd = self.env.cwd
+		cwd = self.thisdir
 
 		if not cwd.accessible:
 			return
@@ -543,7 +544,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 		self.ui.status.need_redraw = True
 
 	def mark_in_direction(self, val=True, dirarg=None):
-		cwd = self.env.cwd
+		cwd = self.thisdir
 		direction = Direction(dirarg)
 		pos, selected = direction.select(lst=cwd.files, current=cwd.pointer,
 				pagesize=self.ui.termsize[0])
@@ -562,7 +563,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 				text = re.compile(text, re.L | re.U | re.I)
 			except:
 				return False
-		self.env.last_search = text
+		self.thistab.last_search = text
 		self.search_next(order='search', offset=offset)
 
 	def search_next(self, order=None, offset=1, forward=True):
@@ -575,7 +576,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 
 		if order in ('search', 'tag'):
 			if order == 'search':
-				arg = self.env.last_search
+				arg = self.thistab.last_search
 				if arg is None:
 					return False
 				if hasattr(arg, 'search'):
@@ -585,10 +586,10 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 			elif order == 'tag':
 				fnc = lambda x: x.realpath in self.tags
 
-			return self.env.cwd.search_fnc(fnc=fnc, offset=offset, forward=forward)
+			return self.thisdir.search_fnc(fnc=fnc, offset=offset, forward=forward)
 
 		elif order in ('size', 'mimetype', 'ctime', 'mtime', 'atime'):
-			cwd = self.env.cwd
+			cwd = self.thisdir
 			if original_order is not None or not cwd.cycle_list:
 				lst = list(cwd.files)
 				if order == 'size':
@@ -621,7 +622,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 		if not self.tags:
 			return
 		if paths is None:
-			tags = tuple(x.realpath for x in self.env.get_selection())
+			tags = tuple(x.realpath for x in self.thistab.get_selection())
 		else:
 			tags = [realpath(path) for path in paths]
 		if value is True:
@@ -654,7 +655,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 		try:
 			self.bookmarks.update_if_outdated()
 			destination = self.bookmarks[str(key)]
-			cwd = self.env.cwd
+			cwd = self.thisdir
 			if destination.path != cwd.path:
 				self.bookmarks.enter(str(key))
 				self.bookmarks.remember(cwd)
@@ -664,7 +665,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 	def set_bookmark(self, key):
 		"""Set the bookmark with the name <key> to the current directory"""
 		self.bookmarks.update_if_outdated()
-		self.bookmarks[str(key)] = self.env.cwd
+		self.bookmarks[str(key)] = self.thisdir
 
 	def unset_bookmark(self, key):
 		"""Delete the bookmark with the name <key>"""
@@ -679,7 +680,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 
 	def draw_possible_programs(self):
 		try:
-			target = self.env.get_selection()[0]
+			target = self.thistab.get_selection()[0]
 		except:
 			self.ui.browser.draw_info = []
 			return
@@ -733,11 +734,11 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 			pager.set_source(["Message Log:", "No messages!"])
 
 	def display_file(self):
-		if not self.env.cf or not self.env.cf.is_file:
+		if not self.thisfile or not self.thisfile.is_file:
 			return
 
 		pager = self.ui.open_embedded_pager()
-		pager.set_source(self.env.cf.get_preview_source(pager.wid, pager.hei))
+		pager.set_source(self.thisfile.get_preview_source(pager.wid, pager.hei))
 
 	# --------------------------
 	# -- Previews
@@ -801,12 +802,12 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 						f.close()
 					else:
 						data[(-1, -1)] = None
-					if self.env.cf.realpath == path:
+					if self.thisfile.realpath == path:
 						self.ui.browser.need_redraw = True
 					data['loading'] = False
 					pager = self.ui.browser.pager
-					if self.env.cf and self.env.cf.is_file:
-						pager.set_source(self.env.cf.get_preview_source(
+					if self.thisfile and self.thisfile.is_file:
+						pager.set_source(self.thisfile.get_preview_source(
 							pager.wid, pager.hei))
 				def on_destroy(signal):
 					try:
@@ -830,6 +831,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 	# --------------------------
 	# This implementation of tabs is very simple and keeps track of
 	# directory paths only.
+	# TODO: Need to rewrite this to fit the new tab model
 
 	def tab_open(self, name, path=None):
 		tab_has_changed = name != self.current_tab
@@ -872,9 +874,6 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 		assert len(self.tabs) > 0, "There must be >=1 tabs at all times"
 		return sorted(self.tabs)
 
-	def _update_current_tab(self):
-		self.tabs[self.current_tab] = self.env.cwd.path
-
 	# --------------------------
 	# -- Overview of internals
 	# --------------------------
@@ -955,9 +954,9 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 	def copy(self, mode='set', narg=None, dirarg=None):
 		"""Copy the selected items.  Modes are: 'set', 'add', 'remove'."""
 		assert mode in ('set', 'add', 'remove')
-		cwd = self.env.cwd
+		cwd = self.thisdir
 		if not narg and not dirarg:
-			selected = (f for f in self.env.get_selection() if f in cwd.files)
+			selected = (f for f in self.thistab.get_selection() if f in cwd.files)
 		else:
 			if not dirarg and narg:
 				direction = Direction(down=1)
@@ -1038,7 +1037,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 			cwd = self.get_directory(original_path)
 			cwd.load_content()
 
-		cwd = self.env.cwd
+		cwd = self.thisdir
 		original_path = cwd.path
 		one_file = copied_files[0]
 		if overwrite:
@@ -1080,7 +1079,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 	def delete(self):
 		# XXX: warn when deleting mount points/unseen marked files?
 		self.notify("Deleting!")
-		selected = self.env.get_selection()
+		selected = self.thistab.get_selection()
 		self.copy_buffer -= set(selected)
 		if selected:
 			for f in selected:
@@ -1094,11 +1093,11 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 						os.remove(f.path)
 					except OSError as err:
 						self.notify(err)
-		self.env.ensure_correct_pointer()
+		self.thistab.ensure_correct_pointer()
 
 	def mkdir(self, name):
 		try:
-			os.mkdir(os.path.join(self.env.cwd.path, name))
+			os.mkdir(os.path.join(self.thisdir.path, name))
 		except OSError as err:
 			self.notify(err)
 
diff --git a/ranger/core/environment.py b/ranger/core/environment.py
index f04fc307..61bbb6b2 100644
--- a/ranger/core/environment.py
+++ b/ranger/core/environment.py
@@ -1,16 +1,17 @@
 # Copyright (C) 2009, 2010, 2011  Roman Zimbelmann <romanz@lavabit.com>
 # This software is distributed under the terms of the GNU GPL version 3.
 
-import os
-from os.path import abspath, normpath, join, expanduser, isdir
+# THIS WHOLE FILE IS OBSOLETE AND EXISTS FOR BACKWARDS COMPATIBILITIY
 
-from ranger.fsobject import Directory
-from ranger.container.history import History
+import os
 from ranger.ext.signals import SignalDispatcher
 from ranger.core.shared import SettingsAware, FileManagerAware
 
 # COMPAT
-class EnvironmentCompatibilityWrapper(object):
+class Environment(SettingsAware, FileManagerAware, SignalDispatcher):
+	def __init__(self, path):
+		SignalDispatcher.__init__(self)
+
 	def _get_copy(self): return self.fm.copy_buffer
 	def _set_copy(self, obj): self.fm.copy_buffer = obj
 	copy = property(_get_copy, _set_copy)
@@ -43,143 +44,68 @@ class EnvironmentCompatibilityWrapper(object):
 	def _set_get_directory(self, obj): self.fm.get_directory = obj
 	get_directory = property(_get_get_directory, _set_get_directory)
 
-	def _get_garbage_collect(self): return self.fm.thistab.garbage_collect
-	def _set_garbage_collect(self, obj): self.fm.thistab.garbage_collect = obj
+	def _get_garbage_collect(self): return self.fm.garbage_collect
+	def _set_garbage_collect(self, obj): self.fm.garbage_collect = obj
 	garbage_collect = property(_get_garbage_collect, _set_garbage_collect)
 
-class Environment(SettingsAware, FileManagerAware, SignalDispatcher,
-		EnvironmentCompatibilityWrapper):
-	"""
-	A collection of data which is relevant for more than one class.
-	"""
-
-	def __init__(self, path):
-		SignalDispatcher.__init__(self)
-		self.cwd = None  # Current Working Directory
-		self._cf = None  # Current File
-		self.history = History(self.settings.max_history_size, unique=False)
-		self.last_search = None
-		self.path = abspath(expanduser(path))
-		self.pathway = ()
-		self.signal_bind('move', self._set_cf_from_signal, priority=0.1,
-				weak=True)
-
-	def _set_cf_from_signal(self, signal):
-		self._cf = signal.new
-
-	def _set_cf(self, value):
-		if value is not self._cf:
-			previous = self._cf
-			self.signal_emit('move', previous=previous, new=value)
-
-	def _get_cf(self):
-		return self._cf
+	def _get_cwd(self): return self.fm.thisdir
+	def _set_cwd(self, obj): self.fm.thisdir = obj
+	cwd = property(_get_cwd, _set_cwd)
 
+	def _get_cf(self): return self.fm.thisfile
+	def _set_cf(self, obj): self.fm.thisfile = obj
 	cf = property(_get_cf, _set_cf)
 
-	def at_level(self, level):
-		"""
-		Returns the FileSystemObject at the given level.
-		level >0 => previews
-		level 0 => current file/directory
-		level <0 => parent directories
-		"""
-		if level <= 0:
-			try:
-				return self.pathway[level - 1]
-			except IndexError:
-				return None
-		else:
-			directory = self.cf
-			for i in range(level - 1):
-				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
-
-	def get_selection(self):
-		if self.cwd:
-			return self.cwd.get_selection()
-		return set()
+	def _get_history(self): return self.fm.thistab.history
+	def _set_history(self, obj): self.fm.thistab.history = obj
+	history = property(_get_history, _set_history)
+
+	def _get_last_search(self): return self.fm.thistab.last_search
+	def _set_last_search(self, obj): self.fm.thistab.last_search = obj
+	last_search = property(_get_last_search, _set_last_search)
+
+	def _get_path(self): return self.fm.thistab.path
+	def _set_path(self, obj): self.fm.thistab.path = obj
+	path = property(_get_path, _set_path)
+
+	def _get_pathway(self): return self.fm.thistab.pathway
+	def _set_pathway(self, obj): self.fm.thistab.pathway = obj
+	pathway = property(_get_pathway, _set_pathway)
+
+	def _get_enter_dir(self): return self.fm.thistab.enter_dir
+	def _set_enter_dir(self, obj): self.fm.thistab.enter_dir = obj
+	enter_dir = property(_get_enter_dir, _set_enter_dir)
+
+	def _get_at_level(self): return self.fm.thistab.at_level
+	def _set_at_level(self, obj): self.fm.thistab.at_level = obj
+	at_level = property(_get_at_level, _set_at_level)
+
+	def _get_get_selection(self): return self.fm.thistab.get_selection
+	def _set_get_selection(self, obj): self.fm.thistab.get_selection = obj
+	get_selection = property(_get_get_selection, _set_get_selection)
+
+	def _get_assign_cursor_positions_for_subdirs(self):
+		return self.fm.thistab.assign_cursor_positions_for_subdirs
+	def _set_assign_cursor_positions_for_subdirs(self, obj):
+		self.fm.thistab.assign_cursor_positions_for_subdirs = obj
+	assign_cursor_positions_for_subdirs = property(
+			_get_assign_cursor_positions_for_subdirs,
+			_set_assign_cursor_positions_for_subdirs)
+
+	def _get_ensure_correct_pointer(self):
+		return self.fm.thistab.ensure_correct_pointer
+	def _set_ensure_correct_pointer(self, obj):
+		self.fm.thistab.ensure_correct_pointer = obj
+	ensure_correct_pointer = property(_get_ensure_correct_pointer,
+			_set_ensure_correct_pointer)
+
+	def _get_history_go(self): return self.fm.thistab.history_go
+	def _set_history_go(self, obj): self.fm.thistab.history_go = obj
+	history_go = property(_get_history_go, _set_history_go)
+
+	def _set_cf_from_signal(self, signal):
+		self.fm._cf = signal.new
 
 	def get_free_space(self, path):
 		stat = os.statvfs(path)
 		return stat.f_bavail * stat.f_bsize
-
-	def assign_cursor_positions_for_subdirs(self):
-		"""Assign correct cursor positions for subdirectories"""
-		last_path = None
-		for path in reversed(self.pathway):
-			if last_path is None:
-				last_path = path
-				continue
-
-			path.move_to_obj(last_path)
-			last_path = path
-
-	def ensure_correct_pointer(self):
-		if self.cwd:
-			self.cwd.correct_pointer()
-
-	def history_go(self, relative):
-		"""Move relative in history"""
-		if self.history:
-			self.history.move(relative).go(history=False)
-
-	def enter_dir(self, path, history = True):
-		"""Enter given path"""
-		if path is None: return
-		path = str(path)
-
-		previous = self.cwd
-
-		# get the absolute path
-		path = normpath(join(self.path, expanduser(path)))
-
-		if not isdir(path):
-			return False
-		new_cwd = self.fm.get_directory(path)
-
-		try:
-			os.chdir(path)
-		except:
-			return True
-		self.path = path
-		self.cwd = new_cwd
-
-		self.cwd.load_content_if_outdated()
-
-		# build the pathway, a tuple of directory objects which lie
-		# on the path to the current directory.
-		if path == '/':
-			self.pathway = (self.fm.get_directory('/'), )
-		else:
-			pathway = []
-			currentpath = '/'
-			for dir in path.split('/'):
-				currentpath = join(currentpath, dir)
-				pathway.append(self.fm.get_directory(currentpath))
-			self.pathway = tuple(pathway)
-
-		self.assign_cursor_positions_for_subdirs()
-
-		# set the current file.
-		self.cwd.sort_directories_first = self.settings.sort_directories_first
-		self.cwd.sort_reverse = self.settings.sort_reverse
-		self.cwd.sort_if_outdated()
-		self.cf = self.cwd.pointed_obj
-
-		if history:
-			self.history.add(new_cwd)
-
-		self.signal_emit('cd', previous=previous, new=self.cwd)
-
-		return True
diff --git a/ranger/core/fm.py b/ranger/core/fm.py
index 814d16ba..34e761bd 100644
--- a/ranger/core/fm.py
+++ b/ranger/core/fm.py
@@ -16,6 +16,7 @@ import sys
 
 import ranger
 from ranger.core.actions import Actions
+from ranger.core.tab import Tab
 from ranger.container.tags import Tags
 from ranger.gui.ui import UI
 from ranger.container.bookmarks import Bookmarks
@@ -49,11 +50,11 @@ class FM(Actions, SignalDispatcher):
 		self.directories = dict()
 		self.log = deque(maxlen=20)
 		self.bookmarks = bookmarks
-		self.tags = tags
+		self.current_tab = 1
 		self.tabs = {}
+		self.tags = tags
 		self.py3 = sys.version_info >= (3, )
 		self.previews = {}
-		self.current_tab = 1
 		self.loader = Loader()
 		self.copy_buffer = set()
 		self.do_cut = False
@@ -76,6 +77,8 @@ class FM(Actions, SignalDispatcher):
 	def initialize(self):
 		"""If ui/bookmarks are None, they will be initialized here."""
 
+		self.thistab = Tab(".")
+		self.tabs[self.current_tab] = self.thistab
 		if not ranger.arg.clean and os.path.isfile(self.confpath('rifle.conf')):
 			rifleconf = self.confpath('rifle.conf')
 		else:
@@ -110,8 +113,6 @@ class FM(Actions, SignalDispatcher):
 			self.notify(text, bad=True)
 		self.run = Runner(ui=self.ui, logfunc=mylogfunc, fm=self)
 
-		self.env.signal_bind('cd', self._update_current_tab)
-
 		if self.settings.init_function:
 			self.settings.init_function(self)
 
@@ -130,6 +131,21 @@ class FM(Actions, SignalDispatcher):
 				if debug:
 					raise
 
+	def _get_thisfile(self):
+		return self.thistab.thisfile
+
+	def _set_thisfile(self, obj):
+		self.thistab.thisfile = obj
+
+	def _get_thisdir(self):
+		return self.thistab.thisdir
+
+	def _set_thisdir(self, obj):
+		self.thistab.thisdir = obj
+
+	thisfile = property(_get_thisfile, _set_thisfile)
+	thisdir  = property(_get_thisdir,  _set_thisdir)
+
 	def block_input(self, sec=0):
 		self.input_blocked = sec != 0
 		self.input_blocked_until = time() + sec
@@ -190,14 +206,13 @@ class FM(Actions, SignalDispatcher):
 			self.directories[path] = obj
 			return obj
 
-	def garbage_collect(self, age, tabs):
+	def garbage_collect(self, age, tabs=None):  # tabs=None is for COMPATibility
 		"""Delete unused directory objects"""
 		for key in tuple(self.directories):
 			value = self.directories[key]
 			if age != -1:
-				if not value.is_older_than(age) or value in self.pathway:
-					continue
-				if value in tabs.values():
+				if not value.is_older_than(age) \
+						or any(value in tab.pathway for tab in self.tabs.values()):
 					continue
 			del self.directories[key]
 			if value.is_directory:
@@ -215,7 +230,7 @@ class FM(Actions, SignalDispatcher):
 		5. after X loops: collecting unused directory objects
 		"""
 
-		self.env.enter_dir(self.env.path)
+		self.enter_dir(self.thistab.path)
 
 		gc_tick = 0
 
@@ -249,8 +264,7 @@ class FM(Actions, SignalDispatcher):
 				gc_tick += 1
 				if gc_tick > ranger.TICKS_BEFORE_COLLECTING_GARBAGE:
 					gc_tick = 0
-					self.garbage_collect(
-						ranger.TIME_BEFORE_FILE_BECOMES_GARBAGE, self.tabs)
+					self.garbage_collect(ranger.TIME_BEFORE_FILE_BECOMES_GARBAGE)
 
 		except KeyboardInterrupt:
 			# this only happens in --debug mode. By default, interrupts
@@ -258,9 +272,9 @@ class FM(Actions, SignalDispatcher):
 			raise SystemExit
 
 		finally:
-			if ranger.arg.choosedir and self.env.cwd and self.env.cwd.path:
+			if ranger.arg.choosedir and self.thisdir and self.thisdir.path:
 				# XXX: UnicodeEncodeError: 'utf-8' codec can't encode character
 				# '\udcf6' in position 42: surrogates not allowed
-				open(ranger.arg.choosedir, 'w').write(self.env.cwd.path)
-			self.bookmarks.remember(self.env.cwd)
+				open(ranger.arg.choosedir, 'w').write(self.thisdir.path)
+			self.bookmarks.remember(self.thisdir)
 			self.bookmarks.save()
diff --git a/ranger/core/main.py b/ranger/core/main.py
index 1d25c54f..b0ddc4d1 100644
--- a/ranger/core/main.py
+++ b/ranger/core/main.py
@@ -12,8 +12,7 @@ def main():
 	import locale
 	import ranger
 	import sys
-	from ranger.core.shared import (EnvironmentAware, FileManagerAware,
-			SettingsAware)
+	from ranger.core.shared import FileManagerAware, SettingsAware
 	from ranger.core.fm import FM
 
 	if not sys.stdin.isatty():
@@ -86,10 +85,8 @@ def main():
 	crash_traceback = None
 	try:
 		# Initialize objects
-		from ranger.core.environment import Environment
 		fm = FM()
 		FileManagerAware.fm = fm
-		EnvironmentAware.env = Environment(target)
 		fm.tabs = dict((n+1, os.path.abspath(path)) for n, path \
 				in enumerate(targets[:9]))
 		load_settings(fm, arg.clean)
@@ -141,7 +138,7 @@ def main():
 	finally:
 		if crash_traceback:
 			try:
-				filepath = fm.env.cf.path if fm.env.cf else "None"
+				filepath = fm.thisfile.path if fm.thisfile else "None"
 			except:
 				filepath = "None"
 		try:
diff --git a/ranger/core/tab.py b/ranger/core/tab.py
new file mode 100644
index 00000000..8157ac37
--- /dev/null
+++ b/ranger/core/tab.py
@@ -0,0 +1,140 @@
+# Copyright (C) 2009, 2010, 2011  Roman Zimbelmann <romanz@lavabit.com>
+# This software is distributed under the terms of the GNU GPL version 3.
+
+import os
+from os.path import abspath, normpath, join, expanduser, isdir
+
+from ranger.container.history import History
+from ranger.core.shared import FileManagerAware, SettingsAware
+from ranger.ext.signals import SignalDispatcher
+
+class Tab(FileManagerAware, SettingsAware):
+	def __init__(self, path):
+		self.thisdir = None  # Current Working Directory
+		self._thisfile = None  # Current File
+		self.history = History(self.settings.max_history_size, unique=False)
+		self.last_search = None
+		self.path = abspath(expanduser(path))
+		self.pathway = ()
+		self.fm.signal_bind('move', self._set_thisfile_from_signal, priority=0.1,
+				weak=True)
+
+	def _set_thisfile_from_signal(self, signal):
+		if self == self.fm.thistab:
+			self._thisfile = signal.new
+
+	def _set_thisfile(self, value):
+		if value is not self._thisfile:
+			previous = self._thisfile
+			self.fm.signal_emit('move', previous=previous, new=value)
+
+	def _get_thisfile(self):
+		return self._thisfile
+
+	thisfile = property(_get_thisfile, _set_thisfile)
+
+	def at_level(self, level):
+		"""
+		Returns the FileSystemObject at the given level.
+		level >0 => previews
+		level 0 => current file/directory
+		level <0 => parent directories
+		"""
+		if level <= 0:
+			try:
+				return self.pathway[level - 1]
+			except IndexError:
+				return None
+		else:
+			directory = self.thisfile
+			for i in range(level - 1):
+				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
+
+	def get_selection(self):
+		if self.thisdir:
+			return self.thisdir.get_selection()
+		return set()
+
+	def assign_cursor_positions_for_subdirs(self):
+		"""Assign correct cursor positions for subdirectories"""
+		last_path = None
+		for path in reversed(self.pathway):
+			if last_path is None:
+				last_path = path
+				continue
+
+			path.move_to_obj(last_path)
+			last_path = path
+
+	def ensure_correct_pointer(self):
+		if self.thisdir:
+			self.thisdir.correct_pointer()
+
+	def history_go(self, relative):
+		"""Move relative in history"""
+		if self.history:
+			self.history.move(relative).go(history=False)
+
+	def enter_dir(self, path, history = True):
+		"""Enter given path"""
+		if path is None: return
+		path = str(path)
+
+		previous = self.thisdir
+
+		# get the absolute path
+		path = normpath(join(self.path, expanduser(path)))
+
+		if not isdir(path):
+			return False
+		new_thisdir = self.fm.get_directory(path)
+
+		try:
+			os.chdir(path)
+		except:
+			return True
+		self.path = path
+		self.thisdir = new_thisdir
+
+		self.thisdir.load_content_if_outdated()
+
+		# build the pathway, a tuple of directory objects which lie
+		# on the path to the current directory.
+		if path == '/':
+			self.pathway = (self.fm.get_directory('/'), )
+		else:
+			pathway = []
+			currentpath = '/'
+			for dir in path.split('/'):
+				currentpath = join(currentpath, dir)
+				pathway.append(self.fm.get_directory(currentpath))
+			self.pathway = tuple(pathway)
+
+		self.assign_cursor_positions_for_subdirs()
+
+		# set the current file.
+		self.thisdir.sort_directories_first = self.fm.settings.sort_directories_first
+		self.thisdir.sort_reverse = self.fm.settings.sort_reverse
+		self.thisdir.sort_if_outdated()
+		self.thisfile = self.thisdir.pointed_obj
+
+		if history:
+			self.history.add(new_thisdir)
+
+		self.fm.signal_emit('cd', previous=previous, new=self.thisdir)
+
+		return True
+
+	def __repr__(self):
+		return "<Tab '%s'>" % self.thisdir
diff --git a/ranger/fsobject/directory.py b/ranger/fsobject/directory.py
index 70543351..a8088cb2 100644
--- a/ranger/fsobject/directory.py
+++ b/ranger/fsobject/directory.py
@@ -454,8 +454,8 @@ class Directory(FileSystemObject, Accumulator, Loadable, SettingsAware):
 		Accumulator.correct_pointer(self)
 
 		try:
-			if self == self.fm.env.cwd:
-				self.fm.env.cf = self.pointed_obj
+			if self == self.fm.thisdir:
+				self.fm.thisfile = self.pointed_obj
 		except:
 			pass
 
diff --git a/ranger/gui/displayable.py b/ranger/gui/displayable.py
index a70dd2ff..cbd77fe4 100644
--- a/ranger/gui/displayable.py
+++ b/ranger/gui/displayable.py
@@ -37,7 +37,7 @@ class Displayable(EnvironmentAware, FileManagerAware, CursesShortcuts):
 		win -- the own curses window object
 		parent -- the parent (DisplayableContainer) object or None
 		x, y, wid, hei -- absolute coordinates and boundaries
-		settings, fm, env -- inherited shared variables
+		settings, fm -- inherited shared variables
 	"""
 
 	def __init__(self, win, env=None, fm=None, settings=None):
diff --git a/ranger/gui/ui.py b/ranger/gui/ui.py
index 835c4cc0..cc7e985e 100644
--- a/ranger/gui/ui.py
+++ b/ranger/gui/ui.py
@@ -47,10 +47,7 @@ class UI(DisplayableContainer):
 		self._draw_title = os.environ["TERM"] in TERMINALS_WITH_TITLE
 		self.keybuffer = KeyBuffer()
 		self.keymaps = KeyMaps(self.keybuffer)
-		self.keymaps.use_keymap('browser')
 
-		if env is not None:
-			self.env = env
 		if fm is not None:
 			self.fm = fm
 
@@ -63,6 +60,7 @@ class UI(DisplayableContainer):
 				os.environ['TERM'] = 'linux'
 				self.win = curses.initscr()
 		self.termsize = self.win.getmaxyx()
+		self.keymaps.use_keymap('browser')
 		DisplayableContainer.__init__(self, None)
 
 	def initialize(self):
@@ -279,7 +277,7 @@ class UI(DisplayableContainer):
 		self.win.touchwin()
 		DisplayableContainer.draw(self)
 		if self._draw_title and self.settings.update_title:
-			cwd = self.fm.env.cwd.path
+			cwd = self.fm.thisdir.path
 			if cwd.startswith(self.fm.home_path):
 				cwd = '~' + cwd[len(self.fm.home_path):]
 			if self.settings.shorten_title:
diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py
index b94fd7e5..adf79e92 100644
--- a/ranger/gui/widgets/browsercolumn.py
+++ b/ranger/gui/widgets/browsercolumn.py
@@ -21,7 +21,7 @@ class BrowserColumn(Pager):
 	ellipsis = { False: '~', True: '…' }
 
 	old_dir = None
-	old_cf = None
+	old_thisfile = None
 
 	def __init__(self, win, level):
 		"""
@@ -75,7 +75,7 @@ class BrowserColumn(Pager):
 						if clicked_file.is_directory:
 							self.fm.enter_dir(clicked_file.path)
 						elif self.level == 0:
-							self.fm.env.cwd.move_to_obj(clicked_file)
+							self.fm.thisdir.move_to_obj(clicked_file)
 							self.fm.execute_file(clicked_file)
 					except:
 						pass
@@ -118,7 +118,7 @@ class BrowserColumn(Pager):
 
 	def poke(self):
 		Widget.poke(self)
-		self.target = self.env.at_level(self.level)
+		self.target = self.fm.thistab.at_level(self.level)
 
 	def draw(self):
 		"""Call either _draw_file() or _draw_directory()"""
@@ -131,9 +131,9 @@ class BrowserColumn(Pager):
 
 		if self.target and self.target.is_directory \
 				and (self.level <= 0 or self.settings.preview_directories):
-			if self.target.pointed_obj != self.old_cf:
+			if self.target.pointed_obj != self.old_thisfile:
 				self.need_redraw = True
-				self.old_cf = self.target.pointed_obj
+				self.old_thisfile = self.target.pointed_obj
 
 			if self.target.load_content_if_outdated() \
 			or self.target.sort_if_outdated() \
diff --git a/ranger/gui/widgets/browserview.py b/ranger/gui/widgets/browserview.py
index b539ad4b..3c45b7ca 100644
--- a/ranger/gui/widgets/browserview.py
+++ b/ranger/gui/widgets/browserview.py
@@ -36,7 +36,7 @@ class BrowserView(Widget, DisplayableContainer):
 			self.settings.signal_bind('setopt.' + option,
 					self._request_clear_if_has_borders, weak=True)
 
-		self.fm.env.signal_bind('move', self.request_clear)
+		self.fm.signal_bind('move', self.request_clear)
 		self.settings.signal_bind('setopt.column_ratios', self.request_clear)
 
 	def change_ratios(self, ratios):
@@ -87,11 +87,10 @@ class BrowserView(Widget, DisplayableContainer):
 			self.win.erase()
 			self.need_redraw = True
 			self.need_clear = False
-		for path in self.fm.tabs.values():
-			if path is not None:
-				directory = self.fm.get_directory(path)
-				directory.load_content_if_outdated()
-				directory.use()
+		for tab in self.fm.tabs.values():
+			directory = tab.thisdir
+			directory.load_content_if_outdated()
+			directory.use()
 		DisplayableContainer.draw(self)
 		if self.settings.draw_borders:
 			self._draw_borders()
diff --git a/ranger/gui/widgets/statusbar.py b/ranger/gui/widgets/statusbar.py
index 20bc7c60..bf5ee641 100644
--- a/ranger/gui/widgets/statusbar.py
+++ b/ranger/gui/widgets/statusbar.py
@@ -9,6 +9,7 @@ print for the current file.  The right side shows directory information
 such as the space used by all the files in this directory.
 """
 
+import os
 from pwd import getpwuid
 from grp import getgrgid
 from os import getuid, readlink
@@ -26,7 +27,7 @@ class StatusBar(Widget):
 	hint = None
 	msg = None
 
-	old_cf = None
+	old_thisfile = None
 	old_ctime = None
 	old_du = None
 	old_hint = None
@@ -69,10 +70,10 @@ class StatusBar(Widget):
 				self.msg = None
 				self.need_redraw = True
 
-		if self.env.cf:
-			self.env.cf.load_if_outdated()
+		if self.fm.thisfile:
+			self.fm.thisfile.load_if_outdated()
 			try:
-				ctime = self.env.cf.stat.st_ctime
+				ctime = self.fm.thisfile.stat.st_ctime
 			except:
 				ctime = -1
 		else:
@@ -81,12 +82,12 @@ class StatusBar(Widget):
 		if not self.result:
 			self.need_redraw = True
 
-		if self.old_du and not self.env.cwd.disk_usage:
-			self.old_du = self.env.cwd.disk_usage
+		if self.old_du and not self.fm.thisdir.disk_usage:
+			self.old_du = self.fm.thisdir.disk_usage
 			self.need_redraw = True
 
-		if self.old_cf != self.env.cf:
-			self.old_cf = self.env.cf
+		if self.old_thisfile != self.fm.thisfile:
+			self.old_thisfile = self.fm.thisfile
 			self.need_redraw = True
 
 		if self.old_ctime != ctime:
@@ -139,7 +140,7 @@ class StatusBar(Widget):
 				and self.column.target.is_directory:
 			target = self.column.target.pointed_obj
 		else:
-			target = self.env.at_level(0).pointed_obj
+			target = self.fm.thistab.at_level(0).pointed_obj
 		try:
 			stat = target.stat
 		except:
@@ -215,9 +216,9 @@ class StatusBar(Widget):
 		max_pos = len(target) - self.column.hei
 		base = 'scroll'
 
-		if self.env.cwd.filter:
+		if self.fm.thisdir.filter:
 			right.add(" f=", base, 'filter')
-			right.add(repr(self.env.cwd.filter), base, 'filter')
+			right.add(repr(self.fm.thisdir.filter), base, 'filter')
 			right.add(", ", "space")
 
 		if target.marked_items:
@@ -231,7 +232,7 @@ class StatusBar(Widget):
 		else:
 			right.add(human_readable(target.disk_usage, separator='') + " sum")
 			try:
-				free = self.env.get_free_space(target.mount_path)
+				free = get_free_space(target.mount_path)
 			except OSError:
 				pass
 			else:
@@ -265,6 +266,10 @@ class StatusBar(Widget):
 			self.addstr(str(part))
 		self.color_reset()
 
+def get_free_space(path):
+	stat = os.statvfs(path)
+	return stat.f_bavail * stat.f_bsize
+
 class Message(object):
 	elapse = None
 	text = None
diff --git a/ranger/gui/widgets/titlebar.py b/ranger/gui/widgets/titlebar.py
index fddf2e64..04fdb7b6 100644
--- a/ranger/gui/widgets/titlebar.py
+++ b/ranger/gui/widgets/titlebar.py
@@ -13,7 +13,7 @@ from . import Widget
 from ranger.gui.bar import Bar
 
 class TitleBar(Widget):
-	old_cf = None
+	old_thisfile = None
 	old_keybuffer = None
 	old_wid = None
 	result = None
@@ -30,12 +30,12 @@ class TitleBar(Widget):
 
 	def draw(self):
 		if self.need_redraw or \
-				self.env.cf != self.old_cf or\
+				self.fm.thisfile != self.old_thisfile or\
 				str(self.fm.ui.keybuffer) != str(self.old_keybuffer) or\
 				self.wid != self.old_wid:
 			self.need_redraw = False
 			self.old_wid = self.wid
-			self.old_cf = self.env.cf
+			self.old_thisfile = self.fm.thisfile
 			self._calc_bar()
 		self._print_result(self.result)
 		if self.wid > 2:
@@ -101,9 +101,9 @@ class TitleBar(Widget):
 		bar.add(self.fm.hostname, 'hostname', clr, fixed=True)
 		bar.add(':', 'hostname', clr, fixed=True)
 
-		pathway = self.env.pathway
+		pathway = self.fm.thistab.pathway
 		if self.settings.tilde_in_titlebar and \
-				self.fm.env.cwd.path.startswith(self.fm.home_path):
+				self.fm.thisdir.path.startswith(self.fm.home_path):
 			pathway = pathway[self.fm.home_path.count('/')+1:]
 			bar.add('~/', 'directory', fixed=True)
 
@@ -116,8 +116,8 @@ class TitleBar(Widget):
 			bar.add(path.basename, clr, directory=path)
 			bar.add('/', clr, fixed=True, directory=path)
 
-		if self.env.cf is not None:
-			bar.add(self.env.cf.basename, 'file')
+		if self.fm.thisfile is not None:
+			bar.add(self.fm.thisfile.basename, 'file')
 
 	def _get_right_part(self, bar):
 		# TODO: fix that pressed keys are cut off when chaining CTRL keys