about summary refs log tree commit diff stats
path: root/ranger/container/environment.py
blob: 24257952bc930677e46ff7c38ec92caeb0ebd6ca (plain) (blame)
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
from os.path import abspath, normpath, join, expanduser, isdir
import os
from ranger.fsobject.directory import Directory, NoDirectoryGiven
from ranger.container import KeyBuffer, History
from ranger.shared import SettingsAware
import curses

class Environment(SettingsAware):
	"""A collection of data which is relevant for more than
	one class.
	"""

	pwd = None  # current directory
	cf = None  # current file
	copy = None
	cut = None
	termsize = None
	history = None
	directories = None
	last_search = None
	pathway = None
	path = None
	keybuffer = None

	def __init__(self, path):
		self.path = abspath(expanduser(path))
		self.pathway = ()
		self.directories = {}
		self.keybuffer = KeyBuffer()
		self.copy = set()
		self.history = History(self.settings.max_history_size)

		from ranger.shared import EnvironmentAware
		EnvironmentAware.env = self

	def key_append(self, key):
		"""Append a key to the keybuffer"""
		
		# special keys:
		if key == curses.KEY_RESIZE:
			self.keybuffer.clear()

		self.keybuffer.append(key)

	def key_clear(self):
		"""Clear the keybuffer"""
		self.keybuffer.clear()
	
	def at_level(self, level):
		"""Returns the FileSystemObject at the given level.
		level 1 => preview
		level 0 => current file/directory
		level <0 => parent directories"""
		if level <= 0:
			try:
				return self.pathway[level - 1]
			except IndexError:
				return None
		else:
			try:
				return self.directories[self.cf.path]
			except AttributeError:
				return None
			except KeyError:
				return self.cf

	def garbage_collect(self):
		"""Delete unused directory objects"""
		from ranger.fsobject.fsobject import FileSystemObject
		for key in tuple(self.directories.keys()):
			value = self.directories[key]
			if isinstance(value, FileSystemObject):
				if value.is_older_than(1200):
					del self.directories[key]
	
	def get_selection(self):
		if self.pwd:
			return self.pwd.get_selection()
		return set()
	
	def get_directory(self, path):
		"""Get the directory object at the given path"""
		path = abspath(path)
		try:
			return self.directories[path]
		except KeyError:
			obj = Directory(path)
			self.directories[path] = obj
			return obj

	def assign_correct_cursor_positions(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 history_go(self, relative):
		"""Move relative in history"""
		if self.history:
#			self.enter_dir(self.history.move(relative))
			self.history.move(relative).go()

	def enter_dir(self, path, history = True):
		"""Enter given path"""
		if path is None: return
		path = str(path)

		# get the absolute path
		path = normpath(join(self.path, expanduser(path)))

		if not isdir(path):
			return

		try:
			new_pwd = self.get_directory(path)
		except NoDirectoryGiven:
			return False

		self.path = path
		self.pwd = new_pwd
		os.chdir(path)

		self.pwd.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.get_directory('/'), )
		else:
			pathway = []
			currentpath = '/'
			for dir in path.split('/'):
				currentpath = join(currentpath, dir)
				pathway.append(self.get_directory(currentpath))
			self.pathway = tuple(pathway)

		self.assign_correct_cursor_positions()

		# set the current file.
		self.pwd.directories_first = self.settings.directories_first
		self.pwd.sort_if_outdated()
		self.cf = self.pwd.pointed_obj

		if history:
			self.history.add(new_pwd)

		return True