/config/

n> mirror of ranger - a simple, vim-like file managerakspecs <akspecs@tilde.institute>
about summary refs log blame commit diff stats
path: root/ranger/defaults/keys.py
blob: 92a141ef9ef405250f7ba7b89481455772471926 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
                       














                                                                       
   
                                                     
                                        
 
                                                                        
 
                                                              
 
                                            
                                 
                           
                                                               
                                                   

                                                               

                                                                             
                                                                          

                                                                  

                                                                      
 







                                                                      











                                                                            











                                                             
                          
                                                        
                   

                                                                         

   
                             
 


                                                                     
                                          


                                                                         
 
                         
                                               


                                                 

                                                                   

                         




                                         
                                                     
 
 


                                                                     
















                                               
 








                                                           
 
                                                                     
                                      
                                                                     
                                       

                      
                                   
 
                                                                   
                        
                                                    

                                                



                            
 









                                                                   
                                            
 
                                                                   

                              


                                   

                                                                
 


                                                             
                                                                   
                                                 
                        


                                                                   

                                                                    

                                                    
                                                          
                                                 
                                                             
                                                       
                                                            
                                                    
                                                    

                                                                   

                                                             






















                                                                      




                                                                   


                                                       
                                                     




















                                                                   



                                                                       
                      












                                                                   
                                                                    






                                                                   
                                                


                                                                   
                          
                           


                                                                   
                          













                                                                      

                                                 

                                           



                                                                     
                                         










                                                                   
                             










                                                                   
                                                                   


                                              
                                                                            





                                                                     

                      








                                                       





                                                                     
 

                                           



                                               
                                           



                                                             
                              




                                 

                                                           
                  
                                   
 





                                                   


                                             
# -*- coding: utf-8 -*-
# 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/>.

"""
This is the default key configuration file of ranger.
Syntax for binding keys: map(*keys, fnc)

Examples for keys: "x", "gg", "<C-J><A-4>", "<tab>", "<down><up><right>"

fnc is a function which is called with the CommandArgs object.

The CommandArgs object has these attributes:
arg.fm: the file manager instance
arg.wdg: the current widget
arg.n: the number typed before the key combination (if allowed)
arg.direction: the direction object (if applicable)
arg.keys: the string representation of the used key combination
arg.keybuffer: the keybuffer instance

Direction keys are special.  They must be mapped with: map.dir(*keys, **args)
where args is a dict of values such as up, down, to, absolute, relative...
Example: map.dir('gg', to=0)
Direction keys can be accessed in a mapping that contians "<dir>".
Other special keys are "<any>" which matches any single key and "<bg>"
which will run the function passively, without clearing the keybuffer.

Additionally, there are shortcuts for accessing methods of the current
file manager and widget instance:
map('xyz', fm.method(foo=bar))
will be translated to:
map('xyz', lamdba arg: arg.fm.method(foo=bar))
If possible, arg.n and arg.direction are automatically inserted.


Example scenario
----------------
If this keys are defined:
map("dd", "d<dir>", fm.cut(foo=bar))
map.dir("gg", to=0)

Type in the keys on the left and the function on the right will be executed:
dd        => fm.cut(foo=bar)
5dd       => fm.cut(foo=bar, narg=5)
dgg       => fm.cut(foo=bar, dirarg=Direction(to=0))
5dgg      => fm.cut(foo=bar, narg=5, dirarg=Direction(to=0))
5d3gg     => fm.cut(foo=bar, narg=5, dirarg=Direction(to=3))

Example ~/.ranger/keys.py
-------------------------
from ranger.api.keys import *

keymanager.map("browser", "d", fm.move(down=0.5, pages=True))

# Add less-like d/u keys to the "browser" context:
map = keymanager.get_context('browser')
map("d", fm.move(down=0.5, pages=True))
map("u", fm.move(up=0.5, pages=True))

# Add keys to all contexts
map = KeyMapWithDirections()  # create new empty keymap.
map("q", fm.exit())
map.dir("<down>", down=3)     # I'm quick, I want to move 3 at once!
keymanager.merge_all(map)     # merge the new map into all existing ones.
"""

from ranger.api.keys import *

# ===================================================================
# == Define keys for everywhere:
# ===================================================================
map = global_keys = KeyMapWithDirections()
map('Q', fm.exit())
map('<C-L>', fm.redraw_window())
map('<backspace2>', alias='<backspace>')  # Backspace is bugged sometimes

#map('<dir>', wdg.move())
@map('<dir>') # move around with direction keys
def move(arg):
	arg.wdg.move(narg=arg.n, **arg.direction)

# -------------------------------------------------- direction keys
map.dir('<down>', down=1)
map.dir('<up>', up=1)
map.dir('<left>', left=1)
map.dir('<right>', right=1)
map.dir('<home>', down=0, absolute=True)
map.dir('<end>', down=-1, absolute=True)
map.dir('<pagedown>', down=1, pages=True)
map.dir('<pageup>', down=-1, pages=True)
map.dir('%', down=50, percentage=True, absolute=True)


# ===================================================================
# == Define aliases
# ===================================================================
map = vim_aliases = KeyMapWithDirections()
map.dir('j', alias='<down>')
map.dir('k', alias='<up>')
map.dir('h', alias='<left>')
map.dir('l', alias='<right>')
map.dir('gg', alias='<home>')
map.dir('G', alias='<end>')
map.dir('<C-F>', alias='<pagedown>')
map.dir('<C-B>', alias='<pageup>')

map = readline_aliases = KeyMapWithDirections()
map.dir('<C-B>', alias='<left>')
map.dir('<C-F>', alias='<right>')
map.dir('<C-A>', alias='<home>')
map.dir('<C-E>', alias='<end>')
map.dir('<C-D>', alias='<delete>')
map.dir('<C-H>', alias='<backspace>')

map = midnight_commander_fkeys = KeyMapWithDirections()
map('<F1>', fm.display_help())
map('<F3>', fm.display_file())
map('<F4>', fm.edit_file())
map('<F5>', fm.copy())
map('<F6>', fm.cut())
map('<F7>', fm.open_console(cmode.COMMAND, 'mkdir '))
map('<F8>', fm.open_console(cmode.COMMAND, DELETE_WARNING))
map('<F10>', fm.exit())

# ===================================================================
# == Define keys in "browser" context:
# ===================================================================
map = keymanager.get_context('browser')
map.merge(global_keys)
map.merge(vim_aliases)
map.merge(midnight_commander_fkeys)

# -------------------------------------------------------- movement
map('gg', fm.move(to=0))
map('<enter>', wdg.move(right=0))  # run with mode=0
map('<C-D>', 'J', fm.move(down=0.5, pages=True))
map('<C-U>', 'K', fm.move(up=0.5, pages=True))
map(']', fm.move_parent(1))
map('[', fm.move_parent(-1))
map('}', fm.traverse())
map('{', fm.history_go(-1))

# --------------------------------------------------------- history
map('H', fm.history_go(-1))
map('L', fm.history_go(1))

# ----------------------------------------------- tagging / marking
map('t', fm.tag_toggle())
map('T', fm.tag_remove())

map(' ', fm.mark(toggle=True))
map('v', fm.mark(all=True, toggle=True))
map('V', 'uv', fm.mark(all=True, val=False))

# ------------------------------------------ file system operations
map('yy', 'y<dir>', fm.copy())
map('dd', 'd<dir>', fm.cut())
map('pp', fm.paste())
map('po', fm.paste(overwrite=True))
map('pl', fm.paste_symlink())
map('p<bg>', fm.hint('press *p* once again to confirm pasting' \
		', or *l* to create symlinks'))

map('u<bg>', fm.hint("un*y*ank, unbook*m*ark, unselect:*v*"))
map('ud', 'uy', fm.uncut())

# ---------------------------------------------------- run programs
map('S', fm.execute_command(os.environ['SHELL']))
map('E', fm.edit_file())
map('du', fm.execute_command('du --max-depth=1 -h | less'))

# -------------------------------------------------- toggle options
map('z<bg>', fm.hint("[*cdfhimpPs*] show_*h*idden *p*review_files "\
		"*P*review_dirs *f*ilter flush*i*nput *m*ouse"))
map('zh', fm.toggle_boolean_option('show_hidden'))
map('zp', fm.toggle_boolean_option('preview_files'))
map('zP', fm.toggle_boolean_option('preview_directories'))
map('zi', fm.toggle_boolean_option('flushinput'))
map('zd', fm.toggle_boolean_option('sort_directories_first'))
map('zc', fm.toggle_boolean_option('collapse_preview'))
map('zs', fm.toggle_boolean_option('sort_case_insensitive'))
map('zm', fm.toggle_boolean_option('mouse_enabled'))
map('zf', fm.open_console(cmode.COMMAND, 'filter '))

# ------------------------------------------------------------ sort
map('o<bg>', 'O<bg>', fm.hint("*s*ize *b*ase*n*ame *m*time" \
	" *t*ype *r*everse"))
sort_dict = {
	's': 'size',
	'b': 'basename',
	'n': 'basename',
	'm': 'mtime',
	't': 'type',
}

for key, val in sort_dict.items():
	for key, is_capital in ((key, False), (key.upper(), True)):
		# reverse if any of the two letters is capital
		map('o' + key, fm.sort(func=val, reverse=is_capital))
		map('O' + key, fm.sort(func=val, reverse=True))

map('or', 'Or', 'oR', 'OR', lambda arg: \
		arg.fm.sort(reverse=not arg.fm.settings.sort_reverse))

# ----------------------------------------------- console shortcuts
@map("A")
def append_to_filename(arg):
	command = 'rename ' + arg.fm.env.cf.basename
	arg.fm.open_console(cmode.COMMAND, command)

@map("I")
def insert_before_filename(arg):
	append_to_filename(arg)
	arg.fm.ui.console.move(right=len('rename '), absolute=True)

map('cw', fm.open_console(cmode.COMMAND, 'rename '))
map('cd', fm.open_console(cmode.COMMAND, 'cd '))
map('f', fm.open_console(cmode.COMMAND_QUICK, 'find '))
map('d<bg>', fm.hint('d*u* (disk usage) d*d* (cut)'))
map('@', fm.open_console(cmode.OPEN, '@'))
map('#', fm.open_console(cmode.OPEN, 'p!'))

# --------------------------------------------- jump to directories
map('gh', fm.cd('~'))
map('ge', fm.cd('/etc'))
map('gu', fm.cd('/usr'))
map('gd', fm.cd('/dev'))
map('gl', fm.cd('/lib'))
map('go', fm.cd('/opt'))
map('gv', fm.cd('/var'))
map('gr', 'g/', fm.cd('/'))
map('gm', fm.cd('/media'))
map('gn', fm.cd('/mnt'))
map('gs', fm.cd('/srv'))
map('gR', fm.cd(RANGERDIR))

# ------------------------------------------------------------ tabs
map('gc', '<C-W>', fm.tab_close())
map('gt', '<TAB>', fm.tab_move(1))
map('gT', '<S-TAB>', fm.tab_move(-1))
@map('gn', '<C-N>')
def newtab_and_gohome(arg):
	arg.fm.tab_new()
	arg.fm.cd('~')   # To return to the original directory, type ``
for n in range(1, 10):
	map('g' + str(n), fm.tab_open(n))
	map('<A-' + str(n) + '>', fm.tab_open(n))

# ------------------------------------------------------- searching
map('/', fm.open_console(cmode.SEARCH))

map('n', fm.search())
map('N', fm.search(forward=False))

map('ct', fm.search(order='tag'))
map('cc', fm.search(order='ctime'))
map('cm', fm.search(order='mimetype'))
map('cs', fm.search(order='size'))
map('c<bg>', fm.hint('*c*time *m*imetype *s*ize *t*ag  *w*:rename'))

# ------------------------------------------------------- bookmarks
for key in ALLOWED_BOOKMARK_KEYS:
	map("`" + key, "'" + key, fm.enter_bookmark(key))
	map("m" + key, fm.set_bookmark(key))
	map("um" + key, fm.unset_bookmark(key))
map("`<bg>", "'<bg>", "m<bg>", fm.draw_bookmarks())
map('um<bg>', fm.hint("delete which bookmark?"))

# ---------------------------------------------------- change views
map('i', fm.display_file())
map('W', fm.display_log())
map('?', fm.display_help())
map('w', lambda arg: arg.fm.ui.open_taskview())

# ------------------------------------------------ system functions
map('ZZ', 'ZQ', fm.exit())
map('<C-R>', fm.reset())
map('R', fm.reload_cwd())
@map('<C-C>')
def ctrl_c(arg):
	try:
		item = arg.fm.loader.queue[0]
	except:
		arg.fm.notify("Type Q or :quit<Enter> to exit Ranger")
	else:
		arg.fm.notify("Aborting: " + item.get_description())
		arg.fm.loader.remove(index=0)

map(':', ';', fm.open_console(cmode.COMMAND))
map('>', fm.open_console(cmode.COMMAND_QUICK))
map('!', fm.open_console(cmode.OPEN, prompt='!'))
map('s', fm.open_console(cmode.OPEN, prompt='$'))
map('r', fm.open_console(cmode.OPEN_QUICK))


# ===================================================================
# == Define keys for the pager
# ===================================================================
map = pager_keys = KeyMapWithDirections()
map.merge(global_keys)
map.merge(vim_aliases)

# -------------------------------------------------------- movement
map('<left>', wdg.move(left=4))
map('<right>', wdg.move(right=4))
map('<C-D>', 'd', wdg.move(down=0.5, pages=True))
map('<C-U>', 'u', wdg.move(up=0.5, pages=True))
map('<C-F>', 'f', '<pagedown>', wdg.move(down=1, pages=True))
map('<C-B>', 'b', '<pageup>', wdg.move(up=1, pages=True))
map('<space>', wdg.move(down=0.8, pages=True))
map('<cr>', wdg.move(down=1))

# ---------------------------------------------------------- others
map('E', fm.edit_file())
map('?', fm.display_help())

# --------------------------------------------------- bind the keys
# There are two different kinds of pagers, each have a different
# method for exiting:

map = keymanager.get_context('pager')
map.merge(pager_keys)
map('q', 'i', '<esc>', '<F3>', lambda arg: arg.fm.ui.close_pager())

map = keymanager.get_context('embedded_pager')
map.merge(pager_keys)
map('q', 'i', '<esc>', '<F3>', lambda arg: arg.fm.ui.close_embedded_pager())


# ===================================================================
# == Define keys for the taskview
# ===================================================================
map = keymanager.get_context('taskview')
map.merge(global_keys)
map.merge(vim_aliases)
map('K', wdg.task_move(0))
map('J', wdg.task_move(-1))
map('dd', wdg.task_remove())

map('?', fm.display_help())
map('w', 'q', ESC, ctrl('d'), ctrl('c'),
		lambda arg: arg.fm.ui.close_taskview())


# ===================================================================
# == Define keys for the console
# ===================================================================
map = keymanager.get_context('console')
map.merge(global_keys)
map.merge(readline_aliases)

map('<up>', '<C-P>', wdg.history_move(-1))
map('<down>', '<C-N>', wdg.history_move(1))
map('<home>', wdg.move(right=0, absolute=True))
map('<end>', wdg.move(right=-1, absolute=True))
map('<tab>', wdg.tab())
map('<s-tab>', wdg.tab(-1))
map('<C-C>', '<C-D>', '<ESC>', wdg.close())
map('<CR>', '<c-j>', wdg.execute())
map('<F1>', lambda arg: arg.fm.display_command_help(arg.wdg))

map('<backspace>', wdg.delete(-1))
map('<delete>', wdg.delete(0))
map('<C-W>', wdg.delete_word())
map('<C-K>', wdg.delete_rest(1))
map('<C-U>', wdg.delete_rest(-1))
map('<C-Y>', wdg.paste())

# Any key which is still undefined will simply be typed in.
@map('<any>')
def type_key(arg):
	arg.wdg.type_key(arg.match)

# Allow typing in numbers:
def type_chr(n):
	return lambda arg: arg.wdg.type_key(str(n))
for number in range(10):
	map(str(number), type_chr(number))

# Unmap some global keys so we can type them:
map.unmap('Q')
map.directions.unmap('%')