如何从irb历史中删除重复的命令?

问题描述 投票:1回答:2

我搜索了几个问题/答案/博客但没有成功。如何从irb历史中删除/删除重复的命令?

理想情况下,我想要为我的bash配置相同的行为。即:在执行命令后,删除历史中具有完全相同命令的每个其他条目。

但是当我关闭irb时,消除重复项已经很好了。

我目前的.irbrc

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

注意:Ruby 2.4.1(或更新!)

ruby irb
2个回答
0
投票

关闭IRB控制台后,这将消除重复。但它仅适用于使用Readline的IRB(mac用户警告)。

# ~/.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)

如果您的IRB使用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

有关如何改进它的任何建议?


0
投票

一个AT_EXIT钩是一个完全可以接受的方式来做到这一点。虽然不需要猴子补丁。 IRB通过创建自己的输入方法为此提供了便利。

IRB从InputMethod获得输入。历史由ReadlineInputMethod提供,InputMethod是一个子类。

Contexts附属于conf。在irb会话中输入irb将使您可以访问当前上下文。

io将根据当前上下文的irb [2.4.0] (screenstaring.com)$ conf.io => #<HistoryInputMethod:0x007fdc3403e180 @file_name="(line)", @line_no=3, @line=[nil, "4317.02 - 250 \n", "conf.id\n", "conf.io\n"], @eof=false, @stdin=#<IO:fd 0>, @stdout=#<IO:fd 1>, @prompt="irb [2.4.0] (screenstaring.com)$ ", @ignore_settings=[], @ignore_patterns=[]> 读取输入。例如:

my Bash-like history control class

使用conf.io(更多信息见下文)。

您可以将InputMethod设置为符合conf.io = MyInputMethod.new 界面的任何内容:

MyInputMethod#gets

无论stdin返回什么将由IRB评估。通常它从InputMethod读取。

要告诉IRB在启动时使用:SCRIPT,您可以设置# .irbrc IRB.conf[:SCRIPT] = MyInputMethod.new 配置选项:

:SCRIPT

creating a Context时,IRB将使用nil的值作为输入法。这可以设置为文件以使用其内容作为输入方法。默认情况下,它是stdin,导致Readline被使用(通过ReadlineInputMethod#gets,如果它可用)。

要创建忽略重复项的输入方法,请覆盖class MyInputMethod < IRB::ReadlineInputMethod def gets line = super # super adds line to HISTORY HISTORY.pop if HISTORY[-1] == HISTORY[-2] line end end

InputMethod

my .irbrc中定义的IRB_HISTCONTROL允许你像(或多或少)为Bash设置IRB_HISTIGNOREIRB_HISTIGNORE=ignoreboth IRB_HISTCONTROL='\Aq!:foo' irb

q!

这样做如下:

  • 以空格或副本(背对背)条目开头的条目不会添加到历史记录中
  • a custom method of minefoo)开头或包含qazxswpoi的作品将不会被添加到历史记录中
© www.soinside.com 2019 - 2024. All rights reserved.