Search code examples
rubyirb

How to remove duplicate commands from irb history?


I have searched several questions/answers/blogs without success. How to remove/delete duplicate commands from irb history?

Ideally I want to have the same behavior I configured for my bash. That is: after I execute a command every other entry in the history with the exactly same command is deleted.

But it would already be good to eliminate duplicates when I close irb.

My current .irbrc:

require 'irb/ext/save-history'
IRB.conf[:SAVE_HISTORY] = 1000
IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb_history"
IRB.conf[:AUTO_INDENT] = true

Note: Ruby 2.4.1 (or newer!)


Solution

  • This will eliminate duplicates after closing IRB console. But it works only for IRBs using Readline (mac users warned).

    # ~/.irbrc
    require 'irb/ext/save-history'
    IRB.conf[:SAVE_HISTORY] = 1000
    IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb_history"
    
    deduplicate_history = Proc.new do
        history = Readline::HISTORY.to_a
        Readline::HISTORY.clear
        history.reverse!.uniq!
        history.reverse!.each{|entry| Readline::HISTORY << entry}
    end
    
    IRB.conf[:AT_EXIT].unshift(deduplicate_history)
    

    And this monkey patch will eliminate duplicates on the fly if your IRB is using Readline:

    require 'irb/ext/save-history'
    IRB.conf[:SAVE_HISTORY] = 1000
    IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb_history"
    
    class IRB::ReadlineInputMethod
        alias :default_gets :gets
        def gets
            if result = default_gets
                line = result.chomp
                history = HISTORY.to_a
                HISTORY.clear
                history.each{|entry| HISTORY << entry unless entry == line}
                HISTORY << line
            end
            result
        end
    end
    

    Any suggestion on how to improve it?