ranger v.1.7.2
==============
[![Build Status](https://travis-ci.org/ranger/ranger.svg?branch=master)](https://travis-ci.org/ranger/ranger)
ranger is a console file manager with VI key bindings. It provides a
minimalistic and nice curses interface with a view on the directory hierarchy.
It ships with "rifle", a file launcher that is good at automatically finding
out which program to use for what file type.
![screenshot](https://raw.githubusercontent.com/ranger/ranger-assets/master/screenshots/screenshot.png)
This file describes ranger and how to get it to run. For instructions on the
usage, please read the man page. See HACKING.md for development specific
information. For configuration, check the files in ranger/config/ or copy the
default config to ~/.config/ranger with ranger's --copy-config option. The
examples/ directory contains several scripts and plugins that demonstrate how
ranger can be extended or combined with other programs. These files can be
found in the git repository or in /usr/share/doc/ranger.
A note to packagers: Versions meant for packaging are listed in the changelog
on the website.
About
-----
* Authors: see "AUTHORS" file
* License: GNU General Public License Version 3
* Website: http://ranger.nongnu.org/
* Download: http://ranger.nongnu.org/ranger-stable.tar.gz
* Bug reports: https://github.com/hut/ranger/issues
* git clone http://git.sv.gnu.org/r/ranger.git
Design Goals
------------
* An easily maintainable file manager in a high level language
* A quick way to switch directories and browse the file system
* Keep it small but useful, do one thing and do it well
* Console based, with smooth integration into the unix shell
Features
--------
* UTF-8 Support (if your python copy supports it)
* Multi-column display
* Preview of the selected file/directory
* Common file operations (create/chmod/copy/delete/...)
* Renaming multiple files at once
* VIM-like console and hotkeys
* Automatically determine file types and run them with correct programs
* Change the directory of your shell after exiting ranger
* Tabs, Bookmarks, Mouse support
Dependencies
------------
* Python (tested with version 2.6, 2.7, 3.1-3.5) with the "curses" module
# Null-terminated vs length-prefixed ascii strings.
#
# By default we create strings with a 4-byte length prefix rather than a null suffix.
# However we still need null-prefixed strings when interacting with the Linux
# kernel in a few places. This layer implements a function for comparing
# a null-terminated 'kernel string' with a length-prefixed 'SubX string'.
#
# To run (from the subx directory):
# $ ./subx translate examples/ex11.subx -o examples/ex11
# $ ./subx run examples/ex11 # runs a series of tests
# ...... # all tests pass
#
# (We can't yet run the tests when given a "test" commandline argument,
# because checking for it would require the function being tested! Breakage
# would cause tests to not run, rather than to fail as we'd like.)
== code 0x09000000
# instruction effective address register displacement immediate
# . op subop mod rm32 base index scale r32
# . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
Entry: # run all tests
e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'.
# syscall(exit, EAX)
89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX
b8/copy-to-EAX 1/imm32/exit
cd/syscall 0x80/imm8
# compare a null-terminated ascii string with a more idiomatic length-prefixed byte array
# reason for the name: the only place we should have null-terminated ascii strings is from commandline args
kernel-string-equal?: # s : null-terminated ascii string, benchmark : length-prefixed ascii string -> EAX : boolean
# pseudocode:
# n = benchmark->length
# s1 = s
# s2 = benchmark->data
# i = 0
# while i < n
# c1 = *s1
# c2 = *s2
# if (c1 == 0) return false
# if (c1 != c2) return false
# ++s1, ++s2, ++i
# return *s1 == 0
#
# registers:
# i: ECX
# n: EDX
# s1: EDI
# s2: ESI
# c1: EAX
# c2: EBX
#
# . prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
# . save registers
51/push-ECX
52/push-EDX
53/push-EBX
56/push-ESI
57/push-EDI
# s1/EDI = s
8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 7/r32/EDI 8/disp8 . # copy *(EBP+8) to EDI
# n/EDX = benchmark->length
8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 2/r32/EDX 0xc/disp8 . # copy *(EBP+12) to EDX
8b/copy 0/mod/indirect 2/rm32/EDX . . . 2/r32/EDX . . # copy *EDX to EDX
# s2/ESI = benchmark->data
8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 0xc/disp8 . # copy *(EBP+12) to ESI
81 0/subop/add 3/mod/direct 6/rm32/ESI . . . . . 4/imm32 # add to ESI
# i/ECX = c1/EAX = c2/EBX = 0
b9/copy-to-ECX 0/imm32/exit
b8/copy-to-EAX 0/imm32
bb/copy-to-EBX 0/imm32
$kernel-string-equal?:loop:
# if (i >= n) break
39/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare ECX with EDX
7d/jump-if-greater-or-equal $kernel-string-equal?:break/disp8
# c1 = *s1
8a/copy-byte 0/mod/indirect 7/rm32/EDI . . . 0/r32/AL . . # copy byte at *EDI to AL
# c2 = *s2
8a/copy-byte 0/mod/indirect 6/rm32/ESI . . . 3/r32/BL . . # copy byte at *ESI to BL
# if (c1 == 0) return false
3d/compare-EAX-and 0/imm32
74/jump-if-equal $kernel-string-equal?:false/disp8
# if (c1 != c2) return false
39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX and EBX
75/jump-if-not-equal $kernel-string-equal?:false/disp8
# ++i
41/increment-ECX
# ++s1
47/increment-EDI
# ++s2
46/increment-ESI
eb/jump $kernel-string-equal?:loop/disp8
$kernel-string-equal?:break:
# return *s1 == 0
8a/copy-byte 0/mod/indirect 7/rm32/EDI . . . 0/r32/AL . . # copy byte at *EDI to AL
3d/compare-EAX-and 0/imm32
75/jump-if-not-equal $kernel-string-equal?:false/disp8
$kernel-string-equal?:true:
b8/copy-to-EAX 1/imm32
eb/jump $kernel-string-equal?:end/disp8
$kernel-string-equal?:false:
b8/copy-to-EAX 0/imm32
$kernel-string-equal?:end:
# . restore registers
5f/pop-to-EDI
5e/pop-to-ESI
5b/pop-to-EBX
5a/pop-to-EDX
59/pop-to-ECX
# . epilog
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
5d/pop-to-EBP
c3/return
# - tests
test-compare-null-kernel-string-with-empty-array:
# EAX = kernel-string-equal?(Null-kernel-string, "")
# . . push args
68/push ""/imm32
68/push Null-kernel-string/imm32
# . . call
e8/call kernel-string-equal?/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# check-ints-equal(EAX, 1, msg)
# . . push args
68/push "F - test-compare-null-kernel-string-with-empty-array"/imm32
68/push 1/imm32/true
50/push-EAX
# . . call
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
test-compare-null-kernel-string-with-non-empty-array:
# EAX = kernel-string-equal?(Null-kernel-string, "Abc")
# . . push args
68/push "Abc"/imm32
68/push Null-kernel-string/imm32
# . . call
e8/call kernel-string-equal?/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# check-ints-equal(EAX, 0, msg)
# . . push args
68/push "F - test-compare-null-kernel-string-with-non-empty-array"/imm32
68/push 0/imm32/false
50/push-EAX
# . . call
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
test-compare-kernel-string-with-equal-array:
# EAX = kernel-string-equal?(_test-Abc-kernel-string, "Abc")
# . . push args
68/push "Abc"/imm32
68/push _test-Abc-kernel-string/imm32
# . . call
e8/call kernel-string-equal?/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# check-ints-equal(EAX, 1, msg)
# . . push args
68/push "F - test-compare-kernel-string-with-equal-array"/imm32
68/push 1/imm32/true
50/push-EAX
# . . call
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
test-compare-kernel-string-with-inequal-array:
# EAX = kernel-string-equal?(_test-Abc-kernel-string, "Adc")
# . . push args
68/push "Adc"/imm32
68/push _test-Abc-kernel-string/imm32
# . . call
e8/call kernel-string-equal?/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# check-ints-equal(EAX, 0, msg)
# . . push args
68/push "F - test-compare-kernel-string-with-equal-array"/imm32
68/push 0/imm32/false
50/push-EAX
# . . call
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
test-compare-kernel-string-with-empty-array:
# EAX = kernel-string-equal?(_test-Abc-kernel-string, "")
# . . push args
68/push ""/imm32
68/push _test-Abc-kernel-string/imm32
# . . call
e8/call kernel-string-equal?/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# check-ints-equal(EAX, 0, msg)
# . . push args
68/push "F - test-compare-kernel-string-with-equal-array"/imm32
68/push 0/imm32/false
50/push-EAX
# . . call
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
test-compare-kernel-string-with-shorter-array:
# EAX = kernel-string-equal?(_test-Abc-kernel-string, "Ab")
# . . push args
68/push "Ab"/imm32
68/push _test-Abc-kernel-string/imm32
# . . call
e8/call kernel-string-equal?/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# check-ints-equal(EAX, 0, msg)
# . . push args
68/push "F - test-compare-kernel-string-with-shorter-array"/imm32
68/push 0/imm32/false
50/push-EAX
# . . call
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
test-compare-kernel-string-with-longer-array:
# EAX = kernel-string-equal?(_test-Abc-kernel-string, "Abcd")
# . . push args
68/push "Abcd"/imm32
68/push _test-Abc-kernel-string/imm32
# . . call
e8/call kernel-string-equal?/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# check-ints-equal(EAX, 0, msg)
# . . push args
68/push "F - test-compare-kernel-string-with-longer-array"/imm32
68/push 0/imm32/false
50/push-EAX
# . . call
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
# - helpers
# print msg to stderr if a != b, otherwise print "."
check-ints-equal: # (a : int, b : int, msg : (address array byte)) -> boolean
# . prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
# . save registers
51/push-ECX
53/push-EBX
# load args into EAX, EBX and ECX
8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 0/r32/EAX 8/disp8 . # copy *(EBP+8) to EAX
8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 3/r32/EBX 0xc/disp8 . # copy *(EBP+12) to EBX
# if (EAX == b/EBX) print('.') and return
39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX and EBX
75/jump-if-unequal $check-ints-equal:else/disp8
# . write-stderr('.')
# . . push args
68/push "."/imm32
# . . call
e8/call write-stderr/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# . return
eb/jump $check-ints-equal:end/disp8
# otherwise print(msg)
$check-ints-equal:else:
# copy msg into ECX
8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 1/r32/ECX 0x10/disp8 . # copy *(EBP+16) to ECX
# print(ECX)
# . . push args
51/push-ECX
# . . call
e8/call write-stderr/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# print newline
# . . push args
68/push Newline/imm32
# . . call
e8/call write-stderr/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
$check-ints-equal:end:
# . restore registers
5b/pop-to-EBX
59/pop-to-ECX
# end
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
5d/pop-to-EBP
c3/return
write-stderr: # s : (address array byte) -> <void>
# . prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
# . save registers
50/push-EAX
51/push-ECX
52/push-EDX
53/push-EBX
# syscall(write, 2/stderr, (data) s+4, (size) *s)
# . . fd = 2 (stderr)
bb/copy-to-EBX 2/imm32
# . . x = s+4
8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 1/r32/ECX 8/disp8 . # copy *(EBP+8) to ECX
81 0/subop/add 3/mod/direct 1/rm32/ECX . . . . . 4/imm32 # add to ECX
# . . size = *s
8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 2/r32/EDX 8/disp8 . # copy *(EBP+8) to EDX
8b/copy 0/mod/indirect 2/rm32/EDX . . . 2/r32/EDX . . # copy *EDX to EDX
# . . syscall
b8/copy-to-EAX 4/imm32/write
cd/syscall 0x80/imm8
# . restore registers
5b/pop-to-EBX
5a/pop-to-EDX
59/pop-to-ECX
58/pop-to-EAX
# . end
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
5d/pop-to-EBP
c3/return
== data 0x0a000000
Newline:
# size
1/imm32
# data
0a/newline
# for kernel-string-equal tests
Null-kernel-string:
00/null
_test-Abc-kernel-string:
41/A 62/b 63/c 00/null
# . . vim:nowrap:textwidth=0