summary refs log blame commit diff stats
path: root/Makefile
blob: 1f75728c46f27c03d83be9c6a9a8cf5dd7dfdf18 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15














                                                                       
             
               

                   

                       
               

                                                                         


                                                
 
                
                                                            
 



                                  
                                          






                                                      

                                                        


                                                                    
                                                                          
                                             
 




























                                                                                  


                            
                                                                   
 
      
                           

                                                        
             
                                                    





                                                  
         
                                                    
                                                      
 
     
                         

   
                                       

         
                                                                                                    
 
                                                                
                                  
# Copyright (C) 2009, 2010  Roman Zimbelmann <romanz@lavabit.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

NAME = ranger
VERSION = 1.0.4
PYTHON ?= python
DOCDIR ?= doc/pydoc
PREFIX ?= /usr
MANPREFIX ?= /share/man
PYOPTIMIZE ?= 1
PYTHON_SITE_DEST ?= $(shell $(PYTHON) -c 'import sys; sys.stdout.write( \
	[p for p in sys.path if "site" in p][0])' 2> /dev/null)
BMCOUNT ?= 5  # how often to run the benchmarks?

CWD = $(shell pwd)

default: compile
	@echo 'Run `make options` for a list of all options'

options: help
	@echo
	@echo 'Options:'
	@echo 'PYTHON = $(PYTHON)'
	@echo 'PYOPTIMIZE = $(PYOPTIMIZE)'
	@echo 'PYTHON_SITE_DEST = $(PYTHON_SITE_DEST)'
	@echo 'PREFIX = $(PREFIX)'
	@echo 'MANPREFIX = $(MANPREFIX)'
	@echo 'DOCDIR = $(DOCDIR)'

help:
	@echo 'make: Compile $(NAME)'
	@echo 'make doc: Create the pydoc documentation'
	@echo 'make install: Install ranger'
	@echo 'make clean: Remove the compiled files (*.pyc, *.pyo)'
	@echo 'make cleandoc: Remove the pydoc documentation'
	@echo 'make uninstall: Uninstall ranger'
	@echo 'make snapshot: Create a tar.gz of the current git revision'
	@echo 'make test: Run all unittests.'

all: test compile install

install:
	@if [ '$(PYTHON_SITE_DEST)' == '' ]; then \
		echo -n 'Cannot find a suitable destination for the files.'; \
		echo '  Please install $(NAME) manually.'; \
		false; \
	fi
	@echo "Installing $(NAME) version $(VERSION)..."
	@mkdir -p $(PREFIX)/bin
	cp -f ranger.py $(PREFIX)/bin/ranger
	@mkdir -p $(PYTHON_SITE_DEST)
	cp -fruT ranger $(PYTHON_SITE_DEST)/ranger
	@chmod 755 $(PREFIX)/bin/ranger
	@chmod -R +rX $(PYTHON_SITE_DEST)/ranger
	@mkdir -p $(PREFIX)$(MANPREFIX)/man1
	cp -f doc/ranger.1 $(PREFIX)$(MANPREFIX)/man1/ranger.1
	@chmod 644 $(PREFIX)$(MANPREFIX)/man1/ranger.1

uninstall:
	rm -f $(PREFIX)/bin/ranger
	rm -f '$(PREFIX)$(MANPREFIX)/man1/ranger.1'
	@if [ '$(PYTHON_SITE_DEST)' == '' ]; then \
		echo 'Cannot find a possible location of rangers library files'; \
		false; \
	fi
	rm -rf '$(PYTHON_SITE_DEST)/ranger/*'
	@echo 'NOTE: By default, configuration files are stored at "~/.ranger".'
	@echo 'This script will not delete those.'

compile: clean
	@echo 'Compiling...'
	PYTHONOPTIMIZE=$(PYOPTIMIZE) python -m compileall -q ranger

clean:
	@echo 'Cleaning...'
	find . -regex .\*.py[co]\$$ -exec rm -f -- {} \;

doc: cleandoc
	@echo 'Creating pydoc html documentation...'
	mkdir -p $(DOCDIR)
	cd $(DOCDIR); \
		$(PYTHON) -c 'import pydoc, sys; \
		sys.path[0] = "$(CWD)"; \
		pydoc.writedocs("$(CWD)")'

cleandoc:
	@echo 'Removing pydoc html documentation...'
	test -d $(DOCDIR) && rm -f -- $(DOCDIR)/*.html

test:
	@./all_tests.py 1

bm:
	@./all_benchmarks.py $(BMCOUNT)

snapshot:
	git archive HEAD | gzip > $(NAME)-$(VERSION)-$(shell git rev-parse HEAD | cut -b 1-8).tar.gz

.PHONY: default options all compile clean doc cleandoc test bm \
	install uninstall snapshot
pan class="kr">then Text.insert_at_cursor('\t') save_to_disk(Lines, Filename) elseif chord == 'left' then assert(Lines[Cursor_line].mode == 'text') if Cursor_pos > 1 then Cursor_pos = Cursor_pos-1 else local new_cursor_line = Cursor_line while new_cursor_line > 1 do new_cursor_line = new_cursor_line-1 if Lines[new_cursor_line].mode == 'text' then Cursor_line = new_cursor_line Cursor_pos = #Lines[Cursor_line].data+1 break end end if Cursor_line < Screen_top_line then Screen_top_line = Cursor_line end end elseif chord == 'right' then assert(Lines[Cursor_line].mode == 'text') if Cursor_pos <= #Lines[Cursor_line].data then Cursor_pos = Cursor_pos+1 else local new_cursor_line = Cursor_line while new_cursor_line <= #Lines-1 do new_cursor_line = new_cursor_line+1 if Lines[new_cursor_line].mode == 'text' then Cursor_line = new_cursor_line Cursor_pos = 1 break end end if Cursor_line > Screen_bottom_line then Screen_top_line = Cursor_line end end elseif chord == 'home' then Cursor_pos = 1 elseif chord == 'end' then Cursor_pos = #Lines[Cursor_line].data+1 elseif chord == 'backspace' then if Cursor_pos > 1 then local byte_start = utf8.offset(Lines[Cursor_line].data, Cursor_pos-1) local byte_end = utf8.offset(Lines[Cursor_line].data, Cursor_pos) if byte_start then if byte_end then Lines[Cursor_line].data = string.sub(Lines[Cursor_line].data, 1, byte_start-1)..string.sub(Lines[Cursor_line].data, byte_end) else Lines[Cursor_line].data = string.sub(Lines[Cursor_line].data, 1, byte_start-1) end Cursor_pos = Cursor_pos-1 end elseif Cursor_line > 1 then if Lines[Cursor_line-1].mode == 'drawing' then table.remove(Lines, Cursor_line-1) else -- join lines Cursor_pos = utf8.len(Lines[Cursor_line-1].data)+1 Lines[Cursor_line-1].data = Lines[Cursor_line-1].data..Lines[Cursor_line].data table.remove(Lines, Cursor_line) end Cursor_line = Cursor_line-1 end save_to_disk(Lines, Filename) elseif chord == 'delete' then if Cursor_pos <= #Lines[Cursor_line].data then local byte_start = utf8.offset(Lines[Cursor_line].data, Cursor_pos) local byte_end = utf8.offset(Lines[Cursor_line].data, Cursor_pos+1) if byte_start then if byte_end then Lines[Cursor_line].data = string.sub(Lines[Cursor_line].data, 1, byte_start-1)..string.sub(Lines[Cursor_line].data, byte_end) else Lines[Cursor_line].data = string.sub(Lines[Cursor_line].data, 1, byte_start-1) end -- no change to Cursor_pos end elseif Cursor_line < #Lines then if Lines[Cursor_line+1].mode == 'drawing' then table.remove(Lines, Cursor_line+1) else -- join lines Lines[Cursor_line].data = Lines[Cursor_line].data..Lines[Cursor_line+1].data table.remove(Lines, Cursor_line+1) end end save_to_disk(Lines, Filename) elseif chord == 'up' then assert(Lines[Cursor_line].mode == 'text') local new_cursor_line = Cursor_line while new_cursor_line > 1 do new_cursor_line = new_cursor_line-1 if Lines[new_cursor_line].mode == 'text' then local old_x = Text.cursor_x(Lines[new_cursor_line].data, Cursor_pos) Cursor_line = new_cursor_line Cursor_pos = Text.nearest_cursor_pos(Lines[Cursor_line].data, old_x, Cursor_pos) break end end if Cursor_line < Screen_top_line then Screen_top_line = Cursor_line end elseif chord == 'down' then assert(Lines[Cursor_line].mode == 'text') local new_cursor_line = Cursor_line while new_cursor_line < #Lines do new_cursor_line = new_cursor_line+1 if Lines[new_cursor_line].mode == 'text' then local old_x = Text.cursor_x(Lines[new_cursor_line].data, Cursor_pos) Cursor_line = new_cursor_line Cursor_pos = Text.nearest_cursor_pos(Lines[Cursor_line].data, old_x, Cursor_pos) break end end if Cursor_line > Screen_bottom_line then Screen_top_line = Cursor_line end end end function Text.move_cursor_down_to_next_text_line_while_scrolling_again_if_necessary() while Cursor_line <= #Lines do if Lines[Cursor_line].mode == 'text' then break end Cursor_line = Cursor_line + 1 end -- hack: insert a text line at bottom of file if necessary if Cursor_line > #Lines then assert(Cursor_line == #Lines+1) table.insert(Lines, {mode='text', data=''}) end if Cursor_line > Screen_bottom_line then Screen_top_line = Cursor_line Text.scroll_up_while_cursor_on_screen() end end function Text.scroll_up_while_cursor_on_screen() local y = Screen_height - math.floor(15*Zoom) -- for Cursor_line while true do if Screen_top_line == 1 then break end y = y - math.floor(15*Zoom) if Lines[Screen_top_line].mode == 'drawing' then y = y - Drawing.pixels(Lines[Screen_top_line].h) end if y < math.floor(15*Zoom) then break end Screen_top_line = Screen_top_line - 1 end end function Text.in_line(line, x,y) if line.y == nil then return false end -- outside current page return x >= 16 and y >= line.y and y < line.y + math.floor(15*Zoom) end function Text.move_cursor(line_index, line, x) Cursor_line = line_index Cursor_pos = Text.nearest_cursor_pos(line.data, x) end function Text.nearest_cursor_pos(line, x, hint) if x == 0 then return 1 end local max_x = Text.cursor_x(line, #line+1) if x > max_x then return #line+1 end if hint then local currx = Text.cursor_x(line, hint) if currx > x-2 and currx < x+2 then return hint end end local left, right = 1, #line+1 if hint then if currx > x then right = hint else left = hint end end while left < right-1 do local curr = math.floor((left+right)/2) local currxmin = Text.cursor_x(line, curr) local currxmax = Text.cursor_x(line, curr+1) if currxmin <= x and x < currxmax then return curr end if currxmin > x then right = curr else left = curr end end return right end function Text.cursor_x(line_data, cursor_pos) local line_before_cursor = line_data:sub(1, cursor_pos-1) local text_before_cursor = love.graphics.newText(love.graphics.getFont(), line_before_cursor) return 25 + math.floor(text_before_cursor:getWidth()*Zoom) end return Text