# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # This is just a proof of concept! # # # # # # # # # DOES NOT WORK! DO NOT USE! # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # return; # Copyright 2007 EPIC Software Labs # # This is my attempt to port BlackJac's history script to ruby. # Just for fun! # # Settings: # set history [0|] # Controls the maximum number of entries to be stored in # the client's history buffer. Setting it to 0 purges the # history buffer and disables command history. # set history_circleq [on|off|toggle] # Controls the behavior of history browsing when you reach # the beginning or end of the buffer. If set to on, when # you reach the beginning of the buffer and press the # backward_history keybinding (defaulted to the up arrow) # again, the history will circle back to the end of the # buffer. In addition, when you reach the end of the # buffer and press the forward_history keybinding # (defaulted to the down arrow) again, the history will # circle back to the beginning of the buffer. # set history_persistent [on|off|toggle] # Controls whether the current session's history buffer # will be saved on exit and read back into memory the next # time the script is loaded. # set history_remove_dupes [on|off|toggle] # Controls whether history buffer entries that are exact # duplicates of the most recent entry are removed from the # buffer. # set history_save_file # Default filename to use when saving the current history # buffer or reading a previous buffer and adding it to the # current buffer. # set history_save_position [on|off|toggle] # Controls whether the backward_history or forward_history # keybindings will start scrolling through the history # buffer from the spot where a previous # /! match was found, or from the most # recent history buffer entry. # set history_timestamp [on|off|toggle] # Controls whether /history displays the timestamp of each # command. # # Commands: # /history [] # Returns a list of all commands in the history buffer, or # all commands up to . # /! # Retrieves history buffer entries and outputs them to the # input line. Use /! to retrieve or # /! to retrieve the most recent entry matching # . # # Functions: # $historyctl(add ) # Adds to the next available index number in the # history buffer. # Returns 0 if the history buffer is disabled. # Returns 1 if successful. # $historyctl(delete ) # Removes from the history buffer. # Returns -2 if the history buffer is disabled. # Returns -1 if does not exist. # Returns 0 if successful. # $historyctl(get ) # Returns the history buffer item if it exists, # or nothing. # $historyctl(index ) # Moves the history buffer scrollback pointer to item # . # Returns 0 if does not exist. # Returns 1 if successful. # $historyctl(read []) # Reads into the history buffer the contents of or # HISTORY_SAVE_FILE if none is specified. # Returns nothing if the read failed. # Returns > 0 if the read succeeds. # $historyctl(reset) # Clears the entire history buffer. # Returns -1 if the history buffer does not exist. # Returns 0 if successful. # $historyctl(save []) # Writes the current history buffer to or # HISTORY_SAVE_FILE if none is specified. # Returns nothing if the write failed. # Returns > 0 if the write succeeds. # $historyctl(set ) # Sets the size of the history buffer. Setting it to 0 # purges the history buffer and disables command history. # BEGIN { class HistoryItem @@index = 0 attr_reader :index, :timestamp, :stuff attr_writer :index, :timestamp, :stuff def initialize (stuff) @index = @@index++ @timestamp = Time.new @stuff = stuff end end class History def History.cmd(args) EPIC.say("Command History:") History.items.each { |x| str = "#{x.index}" if (EPIC.expr("history_timestamp") == 'on') str += " [#{x.timestamp}] " else str += ": " end str += x.stuff EPIC.echo(str) } end def History.add(str) if str.length == 0 return end if (EPIC.expr("history_remove_dupes") == 'on') History.items.reject! {|x| x.stuff == str} while (History.items.size >= EPIC.expr("history")) History.items.shift end History.items.push(str) History.index = nil; end end def History.erase History.index = nil; EPIC.cmd("parsekey reset_line") end def History.get_backward input = EPIC.expr("L") if (input.length > 0 && History.index == nil) History.add(input) History.index = History.items.length - 1 end if (History.index == 0) if (EPIC.expr("history.circleq") == 'on') History.index = History.items.length - 1 end else History.index = History.index - 1 end History.show(History.index) end def History.get_forward input = EPIC.expr("L") if (input.length > 0 && History.index == nil) History.add(input) end if (History.index == History.items.length - 1 || History.index == nil) if (EPIC.expr("history.circleq") == 'on') History.show(0) # Oldest entry! else History.erase # A blank line end elsif (History.index < History.items.length && History.index != nil) History.index = History.index + 1 History.show(History.index) end end def History.shove str = EPIC.expr("L") History.add(str) EPIC.cmd("parsekey reset_line") end def History.show(index) if (index == nil) return end History.index = index EPIC.cmd("parsekey reset_line #{History.items[History.index].stuff}") end def History.historyctl(args) [action, rest] = args.split(' ', 2) case $action when "add" if (History.max <= 0) return 0 end History.add(rest) return 1 when "delete" index = rest.to_i History.items.delete_at(index) return 1 when "get" index = rest.to_i return History.items[index].stuff when "index" index = rest.to_i History.index = index return 1 when "read" if (rest.length != 0) filename = rest else filename = save_file end File.foreach(filename) {|x| History.add(x) } when "reset" History.index = nil History.items.clear return 1 when "save" if (rest.length != 0) filename = rest else filename = save_file end f = File.open(filename, "w") History.items.each {|x| f.puts("#{x.timestamp} #{x.stuff}") } f.close return 1 when "set" History.sethistory(rest) return 1 else end end def History.sendline(str) if (str.length == 0) return end History.add(str) EPIC.cmd("//sendline #{str}") end # # This function is called when the user does /! # 1. If is a number, it should behave as though the # user had moved to the th most recent history item # 2. Otherwise, it should behave as though the user had hit BACKWARD_HISTORY # until an entry containing is found. # 3. If does not match, it should error and do nothing # (ie, leave the input line unchanged # def History.banghandler(str) >>> TODO >>> @ :find = after(! $0); if (isnumber($find)) { if (:found = getitem(array.history $find)) { xtype -l $restw(1 $found)${*1 ? [$1-] : []}; } else { xecho -b -c No such history entry: $find; }; } else if (:found = [$getmatches(array.history % /$find*) $getmatches(array.history % $find*)]) { @ :index = rightw(1 $numsort($found)); if (history_save_position == [on]) { @ history.index = index; }; xtype -l $restw(1 $getitem(array.history $index))${*1 ? [ $1-] : []}; } else { xecho -b -c No match; }; <<<< TODO <<<< end def History.sethistory(numstr) limit = numstr.to_i if (limit == 0) History.index = nil; History.items.clear EPIC.eval("^bind ^] nothing;"); EPIC.eval("^on #input 2 -*"); EPIC.eval{"^on #input 2 -/!*"); else while (limit > History.items.length) History.trim end EPIC.eval("^bind ^] shove_to_history") EPIC.eval("^on #-input 2 * {history.add $*}") EPIC.eval("^on #-input 2 /!* #") end end def History.setpersistent(boolstr) case boolstr when 'on' EPIC.eval("on #-exit 2 * {@ historyctl(save $history_save_file)}") when 'off' EPIC.eval("on #exit 2 -*") else EPIC.yell("Huh?") end end end dummy = <