Is it possible to configure the IRB prompt to change dynamically? - ruby

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.

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.

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

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.

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/

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]

Related

How to allow users to edit given string via $stdin in ruby

I'm searching to allows users to edit an existing string.
Edit the following string: Edit me
# After user delete and add characters
Edit the following string: Edit you
I thought to prepend some data to the $stdin but seems like it's not possible and anyway IMHO it's a too radical solution.
Someone told me to use GNU Readline's Ruby wrapper so I've taken a quick look and I found Readline#pre_input_hook which acts before Readline start taking the input.
I tried:
require 'readline'
Readline.pre_input_hook = -> { "Edit me" }
result = Readline.readline("Edit the following string: ")
puts result
But seems not work.
begin
system("stty raw -echo")
print (acc = "Edit me: ")
loop.each_with_object(acc) do |_,acc|
sym = $stdin.getc
case sym.ord
when 13 # carriage return
break acc
when 127 # backspace
print "\e[1D \e[1D"
acc.slice!(acc.length - 1) if acc.length > 0
else # regular symbol
print sym
acc << sym
end
end
ensure
system("stty -raw echo")
puts
puts "\e[0mEntered: |#{acc}|"
end
Here you go. More info on terminal control sequences. Also, ANSI terminal codes.
I found prompt.ask from tty-prompt fulfilled my need:
$ gem install tty-prompt
$ irb
irb(main):001:0> require "tty-prompt"
=> true
irb(main):002:0> prompt = TTY::Prompt.new
=> #<TTY::Prompt prefix="" quiet=false enabled_color=nil active_color=:green
error_color=:red help_color=:bright_black input=#<IO:<ST...
irb(main):003:0> prompt.ask("What is your name?", default: ENV["USER"])
What is your name? xxx
=> "xxx"
irb(main):004:0> prompt.ask("What is your name?", value: "Mike")
What is your name? Michael
=> "Michael"

How to change to color of the Command Prompt [duplicate]

Previously I was using Ruby 1.8 and my irb command prompt used to look like this:
Air ~: irb
>> a = 1
=> 1
>> b = 2
=> 2
>> a + b
=> 3
I installed rvm (and Ruby 1.9.2) and now my irb command prompt looks like this:
Air ~: irb
ruby-1.9.2-p180 :001 > a = 1
=> 1
ruby-1.9.2-p180 :002 > b = 2
=> 2
ruby-1.9.2-p180 :003 > a + b
=> 3
Is there a way to remove the ruby-1.9.2-p180 :001 from the command line?
The irb man page has a section on "Customizing prompt". Here's mine for example:
IRB.conf[:PROMPT][:CUSTOM] = {
:PROMPT_I => ">> ",
:PROMPT_S => "%l>> ",
:PROMPT_C => ".. ",
:PROMPT_N => ".. ",
:RETURN => "=> %s\n"
}
IRB.conf[:PROMPT_MODE] = :CUSTOM
IRB.conf[:AUTO_INDENT] = true
To use this, add it to your ~/.irbrc file (creating it if it doesn't exist.)
In your ~/.irbrc, simply add
IRB.conf[:PROMPT_MODE] = :SIMPLE
When you would usually run the irb command, try running irb --simple-prompt instead. That greatly shortens the prompt and makes it easier to understand.
irb --simple-prompt
saw this in Lynda.com
To avoid giving the prompt you wish on the command line all the time, you can configure the prompt via the ~/.irbrc config file:
$ echo "IRB.conf[:PROMPT_MODE] = :DEFAULT" > ~/.irbrc
$ irb
irb(main):001:0> quit
$ echo "IRB.conf[:PROMPT_MODE] = :SIMPLE" > ~/.irbrc
$ irb
>> quit
$
Whoever want to add a prompt timestamp, this isn't possible yet (check "special strings" section), so I implemented it in a monkey-patchy way:
module IrbTimePrompt
def prompt(prompt, ltype, indent, line_no)
# I used %T as time format, but you could use whatever you want to.
# Check https://apidock.com/ruby/Time/strftime for more options
p = prompt.dup.gsub(/%t/, Time.new.strftime('%T'))
super(p, ltype, indent, line_no)
end
end
module IRB
class Irb
prepend IrbTimePrompt
end
end
Now, add this to your lib/ project folder (in case is a Rails project, ensure lib/ is part of config.autoload_paths in config/application.rb) or in a more aggresive way (not recommended), look for lib/irb.rb file in your local ruby instance and in def prompt method, add a new when condition to the method, like:
when "t"
Time.now.strftime('%-d-%-m %T%Z')
then in your .irbrc file (it could be located in your home folder or root project folder) you could modify your prompt. I'm adding my current prompt, but please adjust it to your needs:
def rails_prompt
# This is my base prompt, displaying line number and time
def_prompt = '[%01n][%t]'
# Maybe you're only running as `irb` an not `rails console`, so check first
# if rails is available
if defined? Rails
app_env = Rails.env[0...4]
if Rails.env.production?
puts "\n\e[1m\e[41mWARNING: YOU ARE USING RAILS CONSOLE IN PRODUCTION!\n" \
"Changing data can cause serious data loss.\n" \
"Make sure you know what you're doing.\e[0m\e[22m\n\n"
app_env = "\e[31m#{app_env}\e[0m" # red
else
app_env = "\e[32m#{app_env}\e[0m" # green
end
def_prompt << "(\e[1m#{app_env}\e[22m)" # bold
end
IRB.conf[:PROMPT] ||= {}
IRB.conf[:PROMPT][:WITH_TIME] = {
PROMPT_I: "#{def_prompt}> ",
PROMPT_N: "#{def_prompt}| ",
PROMPT_C: "#{def_prompt}| ",
PROMPT_S: "#{def_prompt}%l ",
RETURN: "=> %s\n",
AUTO_INDENT: true,
}
IRB.conf[:PROMPT_MODE] = :WITH_TIME
end
rails_prompt
Then start irb or rails console and check the awesomeness:
[1][13:01:15](deve)> 'say hello to your new prompt'
=> "say hello to your new prompt"
[2][13:01:23](deve)>
See this note about IRB prompt in RVM.
Note that you can create a .irbrc file in your home folder for various settings for IRB.
For example, see "Configuring the Prompt" in this document
You can also puts IRB.conf[:PROMPT_MODE] or puts IRB.conf to see all the various settings currently in effect. For example, the :PROMPT_MODE is probably set to "RVM" in your case.

Programmatically Loading Libraries with a Ruby REPL

I've been trying to get load project libraries in a script, then start either IRB or ripl to allow the user to have quick interaction with project libraries. I've succeeded in doing this.
My issue is programmatically turning off command-line echo.
Manually, this is easy with a call to irb_context.echo = false, but this doesn't work programmatically since control is handed over to IRB at IRB.start and irb_context isn't available before the call to IRB.start
If you want IRB to write nothing when the user gives input, you can set the info manually:
IRB.conf[:PROMPT][:NO_REPLY] = {
:PROMPT_I => "%N(%m):%03n:%i> ",
:PROMPT_S => "%N(%m):%03n:%i%l ",
:PROMPT_C => "%N(%m):%03n:%i* ",
:RETURN => "\n" # used to printf
}
IRB.conf[:PROMPT_MODE] = :NO_REPLY
This way, the return value will be ignored by the REPL, that will print just a newline. For more info, see the official docs.

How to format irb command prompt

Previously I was using Ruby 1.8 and my irb command prompt used to look like this:
Air ~: irb
>> a = 1
=> 1
>> b = 2
=> 2
>> a + b
=> 3
I installed rvm (and Ruby 1.9.2) and now my irb command prompt looks like this:
Air ~: irb
ruby-1.9.2-p180 :001 > a = 1
=> 1
ruby-1.9.2-p180 :002 > b = 2
=> 2
ruby-1.9.2-p180 :003 > a + b
=> 3
Is there a way to remove the ruby-1.9.2-p180 :001 from the command line?
The irb man page has a section on "Customizing prompt". Here's mine for example:
IRB.conf[:PROMPT][:CUSTOM] = {
:PROMPT_I => ">> ",
:PROMPT_S => "%l>> ",
:PROMPT_C => ".. ",
:PROMPT_N => ".. ",
:RETURN => "=> %s\n"
}
IRB.conf[:PROMPT_MODE] = :CUSTOM
IRB.conf[:AUTO_INDENT] = true
To use this, add it to your ~/.irbrc file (creating it if it doesn't exist.)
In your ~/.irbrc, simply add
IRB.conf[:PROMPT_MODE] = :SIMPLE
When you would usually run the irb command, try running irb --simple-prompt instead. That greatly shortens the prompt and makes it easier to understand.
irb --simple-prompt
saw this in Lynda.com
To avoid giving the prompt you wish on the command line all the time, you can configure the prompt via the ~/.irbrc config file:
$ echo "IRB.conf[:PROMPT_MODE] = :DEFAULT" > ~/.irbrc
$ irb
irb(main):001:0> quit
$ echo "IRB.conf[:PROMPT_MODE] = :SIMPLE" > ~/.irbrc
$ irb
>> quit
$
Whoever want to add a prompt timestamp, this isn't possible yet (check "special strings" section), so I implemented it in a monkey-patchy way:
module IrbTimePrompt
def prompt(prompt, ltype, indent, line_no)
# I used %T as time format, but you could use whatever you want to.
# Check https://apidock.com/ruby/Time/strftime for more options
p = prompt.dup.gsub(/%t/, Time.new.strftime('%T'))
super(p, ltype, indent, line_no)
end
end
module IRB
class Irb
prepend IrbTimePrompt
end
end
Now, add this to your lib/ project folder (in case is a Rails project, ensure lib/ is part of config.autoload_paths in config/application.rb) or in a more aggresive way (not recommended), look for lib/irb.rb file in your local ruby instance and in def prompt method, add a new when condition to the method, like:
when "t"
Time.now.strftime('%-d-%-m %T%Z')
then in your .irbrc file (it could be located in your home folder or root project folder) you could modify your prompt. I'm adding my current prompt, but please adjust it to your needs:
def rails_prompt
# This is my base prompt, displaying line number and time
def_prompt = '[%01n][%t]'
# Maybe you're only running as `irb` an not `rails console`, so check first
# if rails is available
if defined? Rails
app_env = Rails.env[0...4]
if Rails.env.production?
puts "\n\e[1m\e[41mWARNING: YOU ARE USING RAILS CONSOLE IN PRODUCTION!\n" \
"Changing data can cause serious data loss.\n" \
"Make sure you know what you're doing.\e[0m\e[22m\n\n"
app_env = "\e[31m#{app_env}\e[0m" # red
else
app_env = "\e[32m#{app_env}\e[0m" # green
end
def_prompt << "(\e[1m#{app_env}\e[22m)" # bold
end
IRB.conf[:PROMPT] ||= {}
IRB.conf[:PROMPT][:WITH_TIME] = {
PROMPT_I: "#{def_prompt}> ",
PROMPT_N: "#{def_prompt}| ",
PROMPT_C: "#{def_prompt}| ",
PROMPT_S: "#{def_prompt}%l ",
RETURN: "=> %s\n",
AUTO_INDENT: true,
}
IRB.conf[:PROMPT_MODE] = :WITH_TIME
end
rails_prompt
Then start irb or rails console and check the awesomeness:
[1][13:01:15](deve)> 'say hello to your new prompt'
=> "say hello to your new prompt"
[2][13:01:23](deve)>
See this note about IRB prompt in RVM.
Note that you can create a .irbrc file in your home folder for various settings for IRB.
For example, see "Configuring the Prompt" in this document
You can also puts IRB.conf[:PROMPT_MODE] or puts IRB.conf to see all the various settings currently in effect. For example, the :PROMPT_MODE is probably set to "RVM" in your case.

What's the difference between the ruby irb prompt modes?

I can change the irb prompt mode with
irb --prompt prompt-mode
I can see what null and simple does, but I can't tell the difference between null and xmp and the difference between default/classic/inf-ruby. Can someone explain to me what these other modes do? It seems pointless to have multiple modes doing the same thing.
Once you read the article cldwalker posted above, you may want to design a custom prompt, here's mine for example:
IRB.conf[:PROMPT][:CUSTOM] = {
:PROMPT_I => ">> ",
:PROMPT_S => "%l>> ",
:PROMPT_C => ".. ",
:PROMPT_N => ".. ",
:RETURN => "=> %s\n"
}
IRB.conf[:PROMPT_MODE] = :CUSTOM
IRB.conf[:AUTO_INDENT] = true
The answer to those questions lie in IRB.conf[:PROMPT] which is a hash whose keys are the different prompts and whose values are the configurations for each prompt. Read this to a understand a prompt's configuration.
The difference between null and xmp is that xmp displays a result indented with an arrow:
$ irb --prompt xmp -f
2**10
==>1024
while null doesn't indent or display the arrow:
$ irb --prompt null -f
2**10
1024
You should be able to answer your second question once you read the above link and understand that prompts have different modes and different configurations for them.

Resources