Is it possible to configure the IRB prompt to change dynamically?
Asked Answered
S

6

5

I'd like to navigate around the filesystem in IRB and have the prompt change to reflect the current working directory, but I can't figure out how to make the prompt update after each command. Ultimately I'd like to use IRB in day to day work a lot more and let bash slip away. I tried this in my .irbrc:

require 'fileutils'
include FileUtils

IRB.conf[:PROMPT][:CUSTOM] = {
    :PROMPT_N => "\e[1m:\e[m ",
    :PROMPT_I => "\e[1m#{pwd} >\e[m ",
    :PROMPT_S => "FOO",
    :PROMPT_C => "\e[1m#{pwd} >\e[m ",
    :RETURN => ""
}
IRB.conf[:PROMPT_MODE] = :CUSTOM

But the IRB prompt is not updated:

julianmann@mango:~ > irb
/users/julianmann > puts pwd
/users/julianmann
/users/julianmann > cd 'dev'
/users/julianmann > puts pwd
/users/julianmann/dev
/users/julianmann > 

I'd really like the prompt to change.

Slackjawed answered 20/5, 2011 at 17:21 Comment(0)
D
8

Here's a quick hack to get the working dir. It's sort of fragile, but it worked on ruby 1.8.7 and 1.9.2.

Set your prompt string to something like this:

"%N(%m):%03n:%i %~> ".tap {|s| def s.dup; gsub('%~', Dir.pwd); end }

The "%~" directive is not understood by irb itself, so I used it to do the replacement. This hack relies on the fact that irb calls dup to generate the prompt.

Defelice answered 20/5, 2011 at 18:9 Comment(7)
I'm looking at the docs for Object#tap and not quite understanding it yet but it looks like a powerful way to redefine methods inline. Love it!Slackjawed
@julian-mann yep, tap is real useful. Careful though if you're using ruby < 1.8.7 without rails, because it doesn't have tap.Defelice
a.tap { |i| ... } is basically i = a; ... ; a = iKovar
@Kovar Not exactly. tap doesn't: 1. reassign a at the end; 2. define assign any local variables in the enclosing scope. Rather, these 2 are equivalent - Tap: s="a"; s2="b"; s2.tap{|s| p "Inside: #{s}" }; p [s, s2] / Lambda: s="a"; s2="b"; lambda {|s| p "Inside: #{s}" }.call(s2); p [s, s2]. Notice how the block variable s doesn't overwrite the existing s outside the block.Defelice
(I know it's an old thread) It lead me in the right direction, I made a new class class MyPrompt < String, then set the prompt to MyPrompt.new('some nice prompt'). And then I have a better control of the prompt and can override methods without disturbing the String class.Shew
@Shew That's a good idea. (Note that my solution doesn't disturb the String class either; it redefines a method on a single String instance.)Defelice
This doesn't work anymore with the latest IRB (v1.11.0 currently). I've posted another answer that works with the latest IRB: https://mcmap.net/q/1939273/-is-it-possible-to-configure-the-irb-prompt-to-change-dynamicallyRapt
W
3

Another option is to use fresh. It's based on the irb alternative ripl and also shows the current directory as its prompt :]

Wien answered 20/5, 2011 at 23:17 Comment(1)
Thanks! Downloaded and its really cool, just what I was looking for. I was tempted by Rush too, but the docs say it has no concept of a current directory, that and the syntax put me off. The nice thing about fresh is that when I have my bash head on it behaves as expected (mostly) - navigating around is easy. And I when I want to do some ruby its right there.Slackjawed
H
0

You have to run(alias) irb like so

irb --prompt custom

Or alternatively add IRB.conf[:PROMPT_MODE] = :CUSTOM to your .irbrc

P.S. This isn't an EXACT answer to your question. But you might try using RUSH.

It doesn't have the concept of a current working directory, but it is easily configurable.

Herrah answered 20/5, 2011 at 17:45 Comment(2)
sorry - I should have mentioned that I did have RB.conf[:PROMPT_MODE] = :CUSTOM in .irbrc - I'll edit the questionSlackjawed
RUSH does indeed look pretty cool I'll check it out. Thanks!!Slackjawed
H
0

Its kind of static though but have a look, it may help you IN Linux ( Ubuntu 14.04)

You can change the irritating prompt of the irb console just by following some simple steps

Open your terminal

goto the location /home/leapfrog/.rvm/scripts

$ cd ~/.rvm/scripts

Open the file ‘irbrc.rb’, use superuser power to over-write the

$ sudo gedit irbrc.rb

You can see a portion of code like this. Replace the former with latter codes

# Set up the prompt to be RVM specific.
#@prompt = {
# :PROMPT_I => "#{rvm_ruby_string} :%03n > ", # default prompt
# :PROMPT_S => "#{rvm_ruby_string} :%03n%l> ", # known continuation
# :PROMPT_C => "#{rvm_ruby_string} :%03n > ",
# :PROMPT_N => "#{rvm_ruby_string} :%03n?> ", # unknown continuation
# :RETURN => " => %s \n",
# :AUTO_INDENT => true
#}

@prompt = {
 :PROMPT_I => "ROR: %03n > ", # default prompt
 :PROMPT_S => "%03n%l> ", # known continuation
 :PROMPT_C => "%03n > ",
 :PROMPT_N => "%03n?> ", # unknown continuation
 :RETURN => " O/P => %s \n",
 :AUTO_INDENT => true
}

Just save the file and restart the irb console Further mode you can see this link https://cbabhusal.wordpress.com/2014/12/22/ruby-rvm-change-prompt-of-irb/

Humanize answered 24/12, 2014 at 3:28 Comment(0)
E
0

If it may serve to contribute to the discussion, albeit belatedly: It may be possible to change the prompt after the IRB environment is initialized, such as via some values on IRB.conf[:MAIN_CONTEXT]

For a binding of c = IRB.conf[:MAIN_CONTEXT] the fields affecting prompt formatting may include the following

  • c.prompt_c
  • c.prompt_i
  • c.prompt_n
  • c.prompt_s
  • c.return_format
  • c.auto_indent_mode
  • c.prompt_mode

An example in updating the prompt_i field directly:


irb(main):009:0> IRB.conf[:MAIN_CONTEXT].prompt_i="%N %m %i >>"
=> "%N %m %i >>"

irb main 0 >>

Outside of the set of formatting specifiers documented in the IRB module documentation (3.0.0) it may not be supported - at present - to use an expression that would be evaluated when the prompt is displayed, in IRB. Each of the prompt strings may be used as simply a literal format string.

With some limitations albeit, but it may be possible to update the IRB prompt after IRB is initialized.

Disclaimer: This is not guaranteed to update all state values related to the prompt, under IRB.conf[:MAIN_CONTEXT]

Executant answered 6/11, 2021 at 20:22 Comment(0)
R
0

Kelvin's clever "quick hack" answer, which relied on dup, doesn't work anymore with the latest version of IRB (v1.11.0 right now).

Here's an alternative that allows providing a dynamic IRB prompt, which takes advantage of the fact that main.to_s is provided as %m in the IRB prompt configs:

# Save this file as `.irbrc`.
#
# Put it in your home directory to make it your default,
# or in a particular directory where you want it.
#
# Note: If you have an `.irbrc` in your home directory it
#       will take precedence over a local `.irbrc`.

# define `main.to_s` to provide dynamic context info.
# `main.to_s` is `%m` in the IRB prompt.
# `%m` is included in the default IRB prompt.
def self.to_s
  "#{Dir.pwd}"
end

# This should be the default already, but adding this line
# ensures you use an IRB prompt config that includes `%m`.
IRB.conf[:PROMPT_MODE] = :DEFAULT
Rapt answered 4/1 at 15:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.