5

I would like the ability to define new commands in the ranger file manager by typing something like:

:newcmd myarg

and run arbitrary code with it.

The command definition should also have access to the program's state, e.g., current directory and selected files.

Is there a way to do that?

Disclaimer: I've created this question and self-answered it because of the lack of good sources on this subject. Additional answers are more than welcome.

fixer1234
  • 27,064
  • 61
  • 75
  • 116
  • @fixer1234 thanks for feedback. Added a self answer disclaimer. But if it is too broad, close it, I don't think self-answering should make a difference. What I don't understand is why is it too broad, I believe I've seen several comparable questions in the past. I could have asked: how to create a new command to do X for 3 different X's I had in mind. But I felt the basics that allow basically any command to be written were coverable in an answer. If it closes I'll do that. – Ciro Santilli OurBigBook.com Mar 05 '16 at 08:01
  • @fixer1234 Maybe it also has to do with the quantity of existing answers: I imagine there's ton of information about Excel already, so anything that is not laser-like specific is likely useless. But Ranger is not there yet :-) – Ciro Santilli OurBigBook.com Mar 05 '16 at 08:02
  • We get a lot of Excel questions where the OP lays out a requirement and asks for people to hand them a solution. Those get the "too broad" treatment. Here, you've provided your own solution, and the disclaimer makes that clear, so I don't think you've got a problem. I'm guessing that whoever flagged this into the review queue was reacting to that. – fixer1234 Mar 05 '16 at 08:27

1 Answers1

4

Edit ~/.config/ranger/commands.py to contain something like:

from ranger.api.commands import *

class newcmd(Command):
    def execute(self):
        if not self.arg(1):
            self.fm.notify('Wrong number of arguments', bad=True)
            return
        # First argument. 0 is the command name.
        self.fm.notify(self.arg(1))
        # Current directory to status line.
        self.fm.notify(self.fm.thisdir)
        # Run a shell command.
        self.fm.run(['touch', 'newfile')

Now you can type:

:newcmd myarg

to run the defined command.

More options can be found at: https://github.com/hut/ranger/blob/9c585e48e14525f11d2405ea0bb9b5eba92e63e9/ranger/config/commands.py

You can then go one step further and define a map for it, e.g.: add to ~/.config/ranger/rc.conf:

map ,n console newcmd
map ,m newcmd default-arg 

And now you can just type:

  • ,n to write newcmd on the status line, and get ready for the user to input the first argument
  • ,m and run the command immediately with a default argument

Tested on ranger 1.6.1.