summary refs log tree commit diff stats
path: root/ranger.py
Commit message (Collapse)AuthorAgeFilesLines
* Python 3 division: Import `division` from `__future__`nfnty2017-01-211-1/+1
|
* linting: Python 2 compat: Import from `__future__`nfnty2017-01-171-4/+6
|
* linting: pylint and flake8nfnty2017-01-171-7/+7
|
* Fix mktemp invocation to work on Mac OS X and LinuxJesse Byler2015-06-101-1/+1
| | | | | | | | | | | mktemp on Mac OS X (and probably all BSDs) just returns an error when invoked without any arguments. The -t option used in this change is interpreted differently on Mac OS X and Linux, and is deprecated on Linux, but this invocation works as expected on both. See discussion at https://unix.stackexchange.com/questions/30091 Another alternative would be to use Python's tempfile module: https://docs.python.org/2/library/tempfile.html
* ranger.py: fixed issues with $tempfile in embedded shellEiichi Sato2015-03-281-2/+2
| | | | | | | | | | | | Previously, $tempfile (namely, /tmp/chosendir) was not cleaned up correctly when the ranger process quit in `pwd` without moving to other directory. This causes permission errors in multi-user environments trying to overwrite $tempfile created by a different user. This commit solves the problem in two ways: - Correctly clean up temporary files - Avoid writing to the same temporary by using mktemp(1)
* Neater copyright headerhut2015-03-191-3/+2
|
* update email addresshut2014-12-111-1/+1
|
* Changed email address in source codehut2013-08-081-1/+1
| | | | | Since lavabit.com ceased providing email services, I had to change my address from hut lavabit com to hut lepus uberspace de.
* updated rest of the copyright noticeshut2013-02-221-1/+1
|
* update email address (romanz@lavabit.com -> hut@lavabit.com)hut2013-02-221-1/+1
|
* replaced tabs with 4 spaces in all python fileshut2013-02-101-3/+3
| | | | | | | | | PEP 8 (Style Guide for Python Code) suggests the use of 4 spaces: http://www.python.org/dev/peps/pep-0008/#indentation If you need to use tools like "git blame", you can use the -w option to ignore this commit entirely. Patches will continue to work if you substitute tabs with 4 spaces everywhere except in the Makefile.
* shorten all copyright messages for better readabilityhut2012-03-141-13/+1
|
* Updated copyright headershut2011-10-101-1/+1
| | | | As much as I hate this, it has to be done
* README: polished, removed INSTALLhut2011-10-051-5/+2
|
* ranger.py: made the argument optional in embedded bash scripthut2011-10-041-15/+16
|
* Fixed minor issue in ranger.pyhut2011-10-011-3/+3
|
* another correction of the bash wrapper scriptshut2011-09-281-1/+2
|
* shortened ranger.pyhut2011-09-281-6/+3
|
* sanitized bash wrapper scripts, reformulated BUGS section in manualhut2011-09-281-2/+2
|
* minor optimization in ranger.pyhut2011-09-281-6/+1
|
* improved bash wrappers in ranger.py and man pagehut2011-09-281-5/+7
|
* ranger.py: More reliable check for whether ./ranger.py is startedhut2011-05-071-1/+1
|
* ranger.py: minor change, more general exception handlinghut2011-04-051-1/+1
|
* improved ranger.pyhut2011-04-051-2/+10
|
* Polished ranger.pyhut2010-10-161-3/+3
|
* Small simplification of ranger.pyhut2010-09-291-3/+2
|
* Don't write any bytecode with --clean optionhut2010-09-291-0/+10
|
* ranger.py: Return 0 on success in embedded scripthut2010-09-221-1/+1
|
* simplify ranger.pyhut2010-09-221-25/+11
|
* ranger.py Fixed embedded shellscript (quotes for bash)hut2010-09-111-2/+2
|
* ranger.py: fixed escape in embedded shellscripthut2010-09-111-1/+1
|
* Changed default config dir to $XDG_CONFIG_HOME/rangerhut2010-08-281-1/+5
|
* main: catch SystemExit and return the exit valuehut2010-06-181-2/+3
|
* renamed "--fail-if-run" to the more accurate "--fail-unless-cd"hut2010-06-091-1/+1
| | | | The old name, --fail-if-run, is still valid and working.
* Reverted hashbang for ranger.py.hut2010-06-091-1/+1
| | | | | It causes an error here: /usr/bin/env: python -O: No such file or directory
* Changed hashbang line to "#!/usr/bin/env python"hut2010-06-091-1/+1
|
* Run python with flag "-O" by defaulthut2010-05-101-1/+1
| | | | | This will discard assert statements which are unnecessary for end users.
* Fixed bug #65 by adding flag "--fail-if-run"hut2010-04-261-1/+1
|
* ranger.py: removed whitespacehut2010-04-121-4/+0
|
* reverted a part of 45cf5174. Allow "source ranger ranger" againhut2010-04-011-8/+7
| | | | This is OK since it comes at almost no cost
* removed the cd-after-exit hackhut2010-03-291-13/+8
| | | | | | | | | Fear not. You still get the same functionality by using a function like: ranger() { $(which ranger) $@ && cd "$(grep \^\' ~/.ranger/bookmarks | cut -b3-)" }
* ranger.__init__: don't implicitly import ranger.__main__hut2010-03-261-1/+1
|
* Changed license to the GNU General Public Licensehut2010-02-281-12/+14
|
* ranger.py: fixed cd-after-exit with spaces in directoryhut2010-02-241-1/+1
|
* ranger.py: removed unnecessary codehut2010-02-151-1/+1
|
* ranger.py: reverted cd-after-exit to the old wayhut2010-02-141-10/+1
| | | | | | | | This breaks cd-after-exit after Ctrl+C again, but enables compatibility with zsh which I prefer over the former. If you only use bash, you can safely revert this commit unless future changes make it break.
* ranger.py: more simple '--debug' flag checkhut2010-02-141-1/+1
|
* ranger.py: improved handling of bad importhut2010-01-261-1/+2
|
* ranger.py: more fixeshut2010-01-121-2/+2
|
* ranger.py: cleanup/fixhut2010-01-111-9/+8
|
4'>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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227







                                                                           







                                                                  



                            
                                                            







                                      

                                                 

                                                                                      
                    

                                             
                            

                                                       



                                                















                                                                           


                                                                              


                                                       

                              







                                                                                 

                              



                                                                         

                              
                    
 








                                       

                                                              

                       
                                                                                  

                                           



                                                                  

                              








                                                      




                                              
 


                                                                                        
















                                                                                    







                                                                  


                                               
                       

                                                                




                                                                        



                                                  
                                                                        

























                                                                          
 


                                                                
                                                            
                                   





                                                            

                            

                                           
 




                                                                












                                                                  
from ranger.shared import FileManagerAware, EnvironmentAware, SettingsAware

class Displayable(EnvironmentAware, FileManagerAware, SettingsAware):
	focused = False
	visible = True
	win = None
	colorscheme = None

	def __init__(self, win, env=None, fm=None, settings=None):
		if env is not None:
			self.env = env
		if fm is not None:
			self.fm = fm
		if settings is not None:
			self.settings = settings

		self.x = 0
		self.y = 0
		self.wid = 0
		self.hei = 0
		self.colorscheme = self.settings.colorscheme

		if win is not None:
			self.win = win

	def __nonzero__(self):
		"""Always True"""
		return True

	def __contains__(self, item):
		"""Is item inside the boundaries?
		item can be an iterable like [y, x] or an object with x and y methods.
		"""
		try:
			y, x = item.y, item.x
		except AttributeError:
			try:
				y, x = item
			except (ValueError, TypeError):
				return False
		
		return self.contains_point(y, x)

	def color(self, keylist = None, *keys):
		"""Change the colors from now on."""
		keys = combine(keylist, keys)
		self.win.attrset(self.colorscheme.get_attr(*keys))

	def color_at(self, y, x, wid, keylist = None, *keys):
		"""Change the colors at the specified position"""
		keys = combine(keylist, keys)
		self.win.chgat(y, x, wid, self.colorscheme.get_attr(*keys))
	
	def color_reset(self):
		"""Change the colors to the default colors"""
		Displayable.color(self, 'reset')

	def draw(self):
		"""Draw the object. Called on every main iteration.
		Containers should call draw() on their contained objects here.
		Override this!
		"""

	def destroy(self):
		"""Called when the object is destroyed.
		Override this!
		"""

	def contains_point(self, y, x):
		"""Test if the point lies within the boundaries of this object"""
		return (x >= self.x and x < self.x + self.wid) and \
				(y >= self.y and y < self.y + self.hei)

	def click(self, event):
		"""Called when a mouse key is pressed and self.focused is True.
		Override this!
		"""
		pass

	def press(self, key):
		"""Called when a key is pressed and self.focused is True.
		Override this!
		"""
		pass

	def activate(self, boolean):
		boolean = bool(boolean)
		self.visible = boolean
		self.focused = boolean
	
	def show(self, boolean):
		boolean = bool(boolean)
		self.visible = boolean

	def poke(self):
		"""Called before drawing, even if invisible"""
	
	def draw(self):
		"""Draw displayable.  Called on every main iteration if the object
		is visible.  Override this!
		"""
		pass

	def finalize(self):
		"""Called after every displayable is done drawing.
		Override this!
		"""
		pass

	def resize(self, y, x, hei=None, wid=None):
		"""Resize the widget"""
		try:
			maxy, maxx = self.env.termsize
		except TypeError:
			pass
		else:
			if hei is None:
				hei = maxy - y

			if wid is None:
				wid = maxx - x

			if x < 0 or y < 0:
				raise OutOfBoundsException("Starting point below zero!")

			if x + wid > maxx and y + hei > maxy:
				raise OutOfBoundsException("X and Y out of bounds!")

			if x + wid > maxx:
				raise OutOfBoundsException("X out of bounds!")

			if y + hei > maxy:
				raise OutOfBoundsException("Y out of bounds!")

		self.x = x
		self.y = y
		self.wid = wid
		self.hei = hei


class DisplayableContainer(Displayable):
	container = None
	def __init__(self, win, env=None, fm=None, settings=None):
		if env is not None:
			self.env = env
		if fm is not None:
			self.fm = fm
		if settings is not None:
			self.settings = settings

		Displayable.__init__(self, win)
		self.container = []

	def poke(self):
		"""Recursively called on objects in container"""
		for displayable in self.container:
			displayable.poke()

	def draw(self):
		"""Recursively called on visible objects in container"""
		for displayable in self.container:
			if displayable.visible:
				displayable.draw()

	def finalize(self):
		"""Recursively called on visible objects in container"""
		for displayable in self.container:
			if displayable.visible:
				displayable.finalize()
	
	def get_focused_obj(self):
		"""Finds a focused displayable object in the container."""
		for displayable in self.container:
			if displayable.focused:
				return displayable
			try:
				obj = displayable.get_focused_obj()
			except AttributeError:
				pass
			else:
				if obj is not None:
					return obj
		return None

	def press(self, key):
		"""Recursively called on objects in container"""
		focused_obj = self.get_focused_obj()

		if focused_obj:
			focused_obj.press(key)
			return True
		return False

	def click(self, event):
		"""Recursively called on objects in container"""
		focused_obj = self.get_focused_obj()
		if focused_obj and focused_obj.click(event):
			return True

		for displayable in self.container:
			if event in displayable:
				if displayable.click(event):
					return True

		return False

	def add_obj(self, *objs):
		self.container.extend(objs)

	def destroy(self):
		"""Recursively called on objects in container"""
		for displayable in self.container:
			displayable.destroy()

class OutOfBoundsException(Exception):
	pass

def combine(seq, tup):
	"""Add seq and tup. Ensures that the result is a tuple."""
	try:
		if isinstance(seq, str): raise TypeError
		return tuple(tuple(seq) + tup)
	except TypeError:
		try:
			return tuple((seq, ) + tup)
		except:
			return ()