irb-history 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/LICENSE ADDED
@@ -0,0 +1,16 @@
1
+ Copyright (c) 2005 Sam Stephenson
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16
+ SOFTWARE.
data/README ADDED
@@ -0,0 +1,63 @@
1
+ = irb-history
2
+
3
+ irb-history gives IRB <b>persistent, shared Readline history</b> by way of
4
+ Distributed Ruby (DRb). What does that mean?
5
+
6
+ ==== Persistent
7
+
8
+ <tt>irb-history-server</tt> stores its history in YAML in a file of your
9
+ choice (the default is <tt>~/.irb_history</tt>).
10
+
11
+ ==== Shared
12
+
13
+ Load the irb-history client in your <tt>~/.irbrc</tt>, and you'll instantly
14
+ have access to the irb-history store. Every line you type is sent to the
15
+ server and will appear in other clients' histories immediately.
16
+
17
+ Because irb-history uses DRb, you can share your history with other IRB
18
+ sessions:
19
+
20
+ * on the same computer
21
+ * on other computers on your local network
22
+ * on computers connected to the Internet (fun, but not recommended :))
23
+
24
+ === Installation and usage
25
+
26
+ It's a simple process:
27
+
28
+ 1. <b>Install the gem</b>.
29
+ $ gem install irb-history
30
+
31
+ 2. <b>Start a history server</b> listening on <tt>127.0.0.1</tt>,
32
+ port <tt>26501</tt> (see the {irb-history-server
33
+ documentation}[link:files/bin/irb-history-server.html] for more options).
34
+ $ irb-history-server -d
35
+
36
+ Note: If you wish to use irb-history on a network, you'll need to pass
37
+ the <tt>-h</tt> flag with an appropriate address to listen on.
38
+
39
+ 3. <b>Add three lines to your <tt>~/.irbrc</tt></b>.
40
+ require 'rubygems'
41
+ require 'irb/history'
42
+ IRB::History.start_client
43
+ This connects to the history server on <tt>127.0.0.1</tt>, port
44
+ <tt>26501</tt>. If you need to specify a different host and/or port, just
45
+ pass a DRb URI to <tt>start_client</tt>. For example:
46
+ IRB::History.start_client 'druby://galt:4000'
47
+ connects to the history server on host <tt>galt</tt>, port <tt>4000</tt>.
48
+
49
+ === Source code
50
+
51
+ Check out the darcs[http://darcs.net/] repository:
52
+
53
+ $ darcs get http://dev.conio.net/repos/irb-history
54
+
55
+ === License
56
+
57
+ irb-history is freely distributable under the terms of a {MIT-style
58
+ license}[link:files/LICENSE.html].
59
+
60
+ === Author
61
+
62
+ Sam Stephenson <{sam@conio.net}[mailto:sam@conio.net]>
63
+
@@ -0,0 +1,61 @@
1
+ require 'rake'
2
+ require 'rake/rdoctask'
3
+ require 'rake/gempackagetask'
4
+
5
+ class String
6
+ def unquote
7
+ self.gsub /^(['"])(.*)\1$/, '\2'
8
+ end
9
+ end
10
+
11
+ PKG_NAME = 'irb-history'
12
+ PKG_VERSION = '1.0.0'
13
+ PKG_DESCRIPTION = 'Persistent, shared IRB Readline history'
14
+ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
15
+ PKG_DESTINATION = "pkg/#{PKG_NAME}"
16
+ PKG_AUTHOR = 'Sam Stephenson'
17
+ PKG_AUTHOR_EMAIL = 'sam@conio.net'
18
+ PKG_DOC_DIR = 'rdoc'
19
+
20
+ task :default => [:rdoc, :package]
21
+
22
+ SOURCE_FILES = FileList[
23
+ '[A-Z]*',
24
+ 'bin/**',
25
+ 'lib/**/*.rb'
26
+ ].to_a
27
+
28
+ RDOC_FILES = SOURCE_FILES - %w(Rakefile)
29
+
30
+ desc 'Generate documentation'
31
+ rdoc = Rake::RDocTask.new do |rd|
32
+ rd.main = 'README'
33
+ rd.title = PKG_NAME
34
+ rd.rdoc_dir = PKG_DOC_DIR
35
+ rd.options += %w(--inline-source --line-numbers)
36
+ rd.rdoc_files.include RDOC_FILES
37
+ end
38
+
39
+ spec = Gem::Specification.new do |s|
40
+ s.name = PKG_NAME
41
+ s.version = PKG_VERSION
42
+ s.summary = PKG_DESCRIPTION
43
+ s.description = PKG_DESCRIPTION
44
+ s.author = PKG_AUTHOR
45
+ s.email = PKG_AUTHOR_EMAIL
46
+
47
+ s.files = SOURCE_FILES
48
+ s.bindir = 'bin'
49
+ s.require_path = 'lib'
50
+ s.executables = %w(irb-history-server)
51
+
52
+ s.has_rdoc = true
53
+ s.rdoc_options = rdoc.option_list.map {|o| o.unquote}
54
+ s.extra_rdoc_files = RDOC_FILES
55
+ end
56
+
57
+ Rake::GemPackageTask.new(spec) do |pkg|
58
+ end
59
+
60
+ desc 'Removes documentation and package files'
61
+ task :clean => [:clobber_rdoc, :clobber_package]
data/THANKS ADDED
@@ -0,0 +1,5 @@
1
+ Many thanks, as always, go to:
2
+
3
+ * Scott Barron -- http://scott.elitists.net/
4
+ * Mikael Brockman -- http://www.deepwood.net/~mikael/tumblelog/
5
+ * Marcel Molina, Jr -- http://vernix.org/marcel/
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # = irb-history-server
4
+ #
5
+ # Manages an irb-history YAML store and starts a DRb service for irb-history
6
+ # clients.
7
+ #
8
+ # Usage: <tt>irb-history-server [options]</tt>
9
+ #
10
+ # -p, --port=port listen on the specified port
11
+ # (default: 26501)
12
+ # -h, --host=host bind to the specified host
13
+ # (default: "127.0.0.1")
14
+ # -f, --filename=filename use the specified history file
15
+ # (default: ~/.irb_history)
16
+ # -d, --daemon make irb-history-server run as a daemon
17
+
18
+ begin
19
+ require 'rubygems'
20
+ require 'irb/history'
21
+ rescue LoadError
22
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
23
+ require 'irb/history'
24
+ end
25
+
26
+ require 'optparse'
27
+
28
+ OPTIONS = {
29
+ :port => IRB::History::DEFAULT_PORT,
30
+ :host => IRB::History::DEFAULT_HOST,
31
+ :file => IRB::History::DEFAULT_FILE,
32
+ :fork => false
33
+ }
34
+
35
+ SCRIPT_NAME = File.basename(__FILE__)
36
+
37
+ ARGV.options do |opts|
38
+ opts.banner = "Usage: #{SCRIPT_NAME} [options]"
39
+
40
+ opts.separator ''
41
+
42
+ opts.on('-p', '--port=port', Integer,
43
+ "listen on the specified port",
44
+ "(default: #{OPTIONS[:port]})") {|OPTIONS[:port]|}
45
+ opts.on('-h', '--host=host', String,
46
+ "bind to the specified host",
47
+ "(default: #{OPTIONS[:host].inspect})") {|OPTIONS[:host]|}
48
+ opts.on('-f', '--filename=filename', String,
49
+ "use the specified history file",
50
+ "(default: #{OPTIONS[:file]})") {|OPTIONS[:file]|}
51
+ opts.on('-d', '--daemon',
52
+ "make #{SCRIPT_NAME} run as a daemon") {|OPTIONS[:fork]|}
53
+
54
+ opts.separator ''
55
+
56
+ opts.on(nil, '--help', 'show this help message') {puts opts; exit}
57
+
58
+ opts.parse!
59
+ end
60
+
61
+ uri = "druby://#{OPTIONS[:host]}:#{OPTIONS[:port]}"
62
+ puts "*** #{SCRIPT_NAME} starting on #{uri}"
63
+ puts "*** history file: #{OPTIONS[:file]}"
64
+
65
+ if OPTIONS[:fork]
66
+ exit if fork
67
+ Process.setsid
68
+ exit if fork
69
+ Dir.chdir '/'
70
+ [STDIN, STDOUT, STDERR].each {|io| io.reopen('/dev/null', 'r+')}
71
+ else
72
+ trap :INT do
73
+ puts "*** #{SCRIPT_NAME} exiting"
74
+ exit!
75
+ end
76
+ end
77
+
78
+ IRB::History.start_server uri, OPTIONS[:file]
79
+ DRb.thread.join
@@ -0,0 +1,5 @@
1
+ require 'irb'
2
+
3
+ %w(client server).each do |filename|
4
+ require File.join(File.dirname(__FILE__), 'history', filename)
5
+ end
@@ -0,0 +1,26 @@
1
+ module IRB #:nododc:
2
+ module History
3
+ DEFAULT_HOST = '127.0.0.1'
4
+ DEFAULT_PORT = 26501
5
+ DEFAULT_URI = "druby://#{DEFAULT_HOST}:#{DEFAULT_PORT}"
6
+ DEFAULT_FILE = '~/.irb_history'
7
+ end
8
+ end
9
+
10
+ module Kernel
11
+ # A Ruby-ized realization of the K combinator, courtesy of Mikael Brockman.
12
+ #
13
+ # def foo
14
+ # returning values = [] do
15
+ # values << 'bar'
16
+ # values << 'baz'
17
+ # end
18
+ # end
19
+ #
20
+ # foo # => ['bar', 'baz']
21
+ #
22
+ def returning(value)
23
+ yield
24
+ value
25
+ end
26
+ end
@@ -0,0 +1,36 @@
1
+ require File.join(File.dirname(__FILE__), 'base')
2
+
3
+ module IRB #:nodoc:
4
+ module History
5
+ # Reconfigures a running IRB session to use the given remote history
6
+ # service specified by +uri+, initially retrieving +lines_to_recall+
7
+ # lines of history.
8
+ #
9
+ # Note: This method overrides +gets+ in IRB::ReadlineInputMethod; it
10
+ # can't be "stopped," and you shouldn't call it more than once.
11
+ #
12
+ def self.start_client(uri = DEFAULT_URI, lines_to_recall = 100)
13
+ require 'drb'
14
+
15
+ DRb.start_service
16
+ history = DRbObject.new nil, uri
17
+
18
+ IRB::ReadlineInputMethod.instance_eval do
19
+ alias_method :old_gets, :gets
20
+
21
+ define_method :gets do
22
+ returning old_gets do
23
+ line = Readline::HISTORY[-1]
24
+ history.remember line unless @eof rescue nil
25
+ end
26
+ end
27
+ end
28
+
29
+ Readline::HISTORY.push *history.recall(lines_to_recall)
30
+
31
+ at_exit {history.unsubscribe_from Readline::HISTORY} if
32
+ history.subscribe_to Readline::HISTORY
33
+ rescue
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,95 @@
1
+ require 'drb'
2
+ require 'yaml'
3
+
4
+ require File.join(File.dirname(__FILE__), 'base')
5
+
6
+ module IRB #:nodoc:
7
+ module History
8
+ class Server
9
+ attr_accessor :service
10
+
11
+ # Creates a new Server with the YAML history store file specified
12
+ # by +filename+.
13
+ def initialize(filename)
14
+ @filename = File.expand_path(filename)
15
+ @subscriptions = []
16
+ @mutex = Mutex.new
17
+ load
18
+ end
19
+
20
+ # Returns the number of lines in the history store.
21
+ def length
22
+ @store.length
23
+ end
24
+
25
+ # Stores the given +values+ in the history store, saves the history
26
+ # store to disk, and notifies any subscribers of the added lines.
27
+ def remember(*values)
28
+ @mutex.synchronize do
29
+ @store += values
30
+ notify_subscriptions_with *values
31
+ save
32
+ end
33
+ end
34
+
35
+ # Returns the last +limit+ history lines from the history store. If
36
+ # +limit+ is 0 (the default value), a copy of the entire history
37
+ # store is returned.
38
+ def recall(limit = 0)
39
+ @mutex.synchronize do
40
+ limit = length if limit > length
41
+ @store[-limit..-1] || []
42
+ end
43
+ end
44
+
45
+ # Subscribes to the given +readline_history+ (which can be any object
46
+ # that responds to +push+, but is intended to be used with the
47
+ # Readline::HISTORY object). When new history lines are added, they'll
48
+ # be pushed onto subscriptions.
49
+ def subscribe_to(readline_history)
50
+ @subscriptions |= [readline_history]
51
+ true
52
+ end
53
+
54
+ # Removes the given +readline_history+ object from the subscription
55
+ # list. This should be called from +at_exit+ in history clients.
56
+ def unsubscribe_from(readline_history)
57
+ @subscriptions -= [readline_history]
58
+ true
59
+ end
60
+
61
+ protected
62
+ def load
63
+ @store = YAML.load_file(@filename) rescue []
64
+ end
65
+
66
+ def save
67
+ File.open(@filename, 'w+') {|file| file << YAML.dump(@store)}
68
+ end
69
+
70
+ def notify_subscriptions_with(*values)
71
+ @subscriptions.each do |readline_history|
72
+ Thread.new do
73
+ readline_history.push *values rescue nil or
74
+ unsubscribe_from readline_history
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ # Starts a Server on the given +uri+ and using the YAML history
81
+ # file specified by +store_path+. The Server object is instantiated,
82
+ # a DRb service is started on it, and the Server object is returned.
83
+ # The DRb service object is accessible via Server#service.
84
+ def self.start_server(uri = DEFAULT_URI, store_path = DEFAULT_FILE)
85
+ returning server = Server.new(store_path) do
86
+ server.service = DRb.start_service uri, server
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ if __FILE__ == $0
93
+ IRB::History.start_server *ARGV
94
+ DRb.thread.join
95
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.10
3
+ specification_version: 1
4
+ name: irb-history
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.0.0
7
+ date: 2005-06-17
8
+ summary: "Persistent, shared IRB Readline history"
9
+ require_paths:
10
+ - lib
11
+ email: sam@conio.net
12
+ homepage:
13
+ rubyforge_project:
14
+ description: "Persistent, shared IRB Readline history"
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ -
22
+ - ">"
23
+ - !ruby/object:Gem::Version
24
+ version: 0.0.0
25
+ version:
26
+ platform: ruby
27
+ authors:
28
+ - Sam Stephenson
29
+ files:
30
+ - LICENSE
31
+ - Rakefile
32
+ - README
33
+ - THANKS
34
+ - bin/irb-history-server
35
+ - lib/irb/history.rb
36
+ - lib/irb/history/server.rb
37
+ - lib/irb/history/client.rb
38
+ - lib/irb/history/base.rb
39
+ test_files: []
40
+ rdoc_options:
41
+ - "--inline-source"
42
+ - "--line-numbers"
43
+ - "--main"
44
+ - README
45
+ - "--title"
46
+ - irb-history
47
+ - "-T"
48
+ - html
49
+ extra_rdoc_files:
50
+ - LICENSE
51
+ - README
52
+ - THANKS
53
+ - bin/irb-history-server
54
+ - lib/irb/history.rb
55
+ - lib/irb/history/server.rb
56
+ - lib/irb/history/client.rb
57
+ - lib/irb/history/base.rb
58
+ executables:
59
+ - irb-history-server
60
+ extensions: []
61
+ requirements: []
62
+ dependencies: []