如何从 irb 历史记录中删除重复的命令?
How to remove duplicate commands from irb history?
我搜索了几个 questions/answers/blogs 都没有成功。如何remove/delete从 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
注意:Ruby2.4.1(或更新版本!)
这将在关闭 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
有什么改进建议吗?
AT_EXIT
挂钩是一种完全可以接受的方法。虽然不需要猴子补丁。 IRB 通过创建您自己的输入法提供了执行此操作的工具。
IRB 从 InputMethod
获取输入。历史由
ReadlineInputMethod
,这是一个子类。
InputMethod
附加到 Context
。在 irb
会话中输入 conf
将使您能够访问当前上下文。
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
returns 都将由 IRB 评估。通常它从 stdin
.
读取
要告诉 IRB 在启动时使用你的 InputMethod
,你可以设置 :SCRIPT
配置选项:
# .irbrc
IRB.conf[:SCRIPT] = MyInputMethod.new
IRB 将在creating a Context
时使用:SCRIPT
的值作为输入法。这可以设置为一个文件,以将其内容用作输入法。
默认情况下它是 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
my .irbrc
中定义的 InputMethod
允许设置 IRB_HISTCONTROL
或 IRB_HISTIGNORE
,就像您(或多或少)为 Bash 设置的那样:
IRB_HISTIGNORE=ignoreboth IRB_HISTCONTROL='\Aq!:foo' irb
这会执行以下操作:
- 以 space 开头的条目或重复(连续)条目将不会添加到历史记录中
- 以
q!
(a custom method of mine) 开头或包含 foo
的条目将不会添加到历史记录中
我搜索了几个 questions/answers/blogs 都没有成功。如何remove/delete从 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
注意:Ruby2.4.1(或更新版本!)
这将在关闭 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
有什么改进建议吗?
AT_EXIT
挂钩是一种完全可以接受的方法。虽然不需要猴子补丁。 IRB 通过创建您自己的输入法提供了执行此操作的工具。
IRB 从 InputMethod
获取输入。历史由
ReadlineInputMethod
,这是一个子类。
InputMethod
附加到 Context
。在 irb
会话中输入 conf
将使您能够访问当前上下文。
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
returns 都将由 IRB 评估。通常它从 stdin
.
要告诉 IRB 在启动时使用你的 InputMethod
,你可以设置 :SCRIPT
配置选项:
# .irbrc
IRB.conf[:SCRIPT] = MyInputMethod.new
IRB 将在creating a Context
时使用:SCRIPT
的值作为输入法。这可以设置为一个文件,以将其内容用作输入法。
默认情况下它是 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
my .irbrc
中定义的 InputMethod
允许设置 IRB_HISTCONTROL
或 IRB_HISTIGNORE
,就像您(或多或少)为 Bash 设置的那样:
IRB_HISTIGNORE=ignoreboth IRB_HISTCONTROL='\Aq!:foo' irb
这会执行以下操作:
- 以 space 开头的条目或重复(连续)条目将不会添加到历史记录中
- 以
q!
(a custom method of mine) 开头或包含foo
的条目将不会添加到历史记录中