irb-history 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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: []