rumacs 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -0
- data/LICENSE +19 -0
- data/README.md +6 -0
- data/Rakefile +135 -0
- data/bin/.directory +0 -0
- data/bin/rumacs +7 -0
- data/lib/.directory +0 -0
- data/lib/rumacs.rb +58 -0
- data/lib/rumacs/files.rb +19 -0
- data/lib/rumacs/screen.rb +225 -0
- data/lib/rumacs/screen/curses.rb +149 -0
- data/lib/rumacs/screen/curses_helper.rb +13 -0
- data/rumacs.gemspec +45 -0
- metadata +132 -0
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2012 Jashank Jeremy.
|
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 above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rake'
|
4
|
+
require 'rdoc'
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), *%w[lib]))
|
7
|
+
|
8
|
+
#############################################################################
|
9
|
+
#
|
10
|
+
# Helper functions
|
11
|
+
#
|
12
|
+
#############################################################################
|
13
|
+
|
14
|
+
def name
|
15
|
+
@name ||= Dir['*.gemspec'].first.split('.').first
|
16
|
+
end
|
17
|
+
|
18
|
+
def version
|
19
|
+
line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/]
|
20
|
+
line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
|
21
|
+
end
|
22
|
+
|
23
|
+
def date
|
24
|
+
Date.today.to_s
|
25
|
+
end
|
26
|
+
|
27
|
+
def rubyforge_project
|
28
|
+
name
|
29
|
+
end
|
30
|
+
|
31
|
+
def gemspec_file
|
32
|
+
"#{name}.gemspec"
|
33
|
+
end
|
34
|
+
|
35
|
+
def gem_file
|
36
|
+
"#{name}-#{version}.gem"
|
37
|
+
end
|
38
|
+
|
39
|
+
def replace_header(head, header_name)
|
40
|
+
head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
|
41
|
+
end
|
42
|
+
|
43
|
+
#############################################################################
|
44
|
+
#
|
45
|
+
# Standard tasks
|
46
|
+
#
|
47
|
+
#############################################################################
|
48
|
+
|
49
|
+
task :default => [:test]
|
50
|
+
|
51
|
+
require 'rake/testtask'
|
52
|
+
Rake::TestTask.new(:test) do |test|
|
53
|
+
test.libs << 'lib' << 'test'
|
54
|
+
test.pattern = 'test/**/test_*.rb'
|
55
|
+
test.verbose = true
|
56
|
+
end
|
57
|
+
|
58
|
+
desc "Generate RCov test coverage and open in your browser"
|
59
|
+
task :coverage do
|
60
|
+
require 'rcov'
|
61
|
+
sh "rm -fr coverage"
|
62
|
+
sh "rcov test/test_*.rb"
|
63
|
+
sh "open coverage/index.html"
|
64
|
+
end
|
65
|
+
|
66
|
+
require 'rdoc/task'
|
67
|
+
Rake::RDocTask.new do |rdoc|
|
68
|
+
rdoc.rdoc_dir = 'rdoc'
|
69
|
+
rdoc.title = "#{name} #{version}"
|
70
|
+
rdoc.rdoc_files.include('README*')
|
71
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
72
|
+
end
|
73
|
+
|
74
|
+
desc "Open an irb session preloaded with this library"
|
75
|
+
task :console do
|
76
|
+
sh "irb -rubygems -r ./lib/#{name}.rb"
|
77
|
+
end
|
78
|
+
|
79
|
+
#############################################################################
|
80
|
+
#
|
81
|
+
# Custom tasks (add your own tasks here)
|
82
|
+
#
|
83
|
+
#############################################################################
|
84
|
+
|
85
|
+
#############################################################################
|
86
|
+
#
|
87
|
+
# Packaging tasks
|
88
|
+
#
|
89
|
+
#############################################################################
|
90
|
+
|
91
|
+
task :release => :build do
|
92
|
+
unless `git branch` =~ /^\* master$/
|
93
|
+
puts "You must be on the master branch to release!"
|
94
|
+
exit!
|
95
|
+
end
|
96
|
+
sh "git commit --allow-empty -m 'Release #{version}'"
|
97
|
+
sh "git tag v#{version}"
|
98
|
+
sh "git push origin master"
|
99
|
+
sh "git push origin v#{version}"
|
100
|
+
sh "gem push pkg/#{name}-#{version}.gem"
|
101
|
+
end
|
102
|
+
|
103
|
+
task :build => :gemspec do
|
104
|
+
sh "mkdir -p pkg"
|
105
|
+
sh "gem build #{gemspec_file}"
|
106
|
+
sh "mv #{gem_file} pkg"
|
107
|
+
end
|
108
|
+
|
109
|
+
task :gemspec do
|
110
|
+
# read spec file and split out manifest section
|
111
|
+
spec = File.read(gemspec_file)
|
112
|
+
head, manifest, tail = spec.split(" # = MANIFEST =\n")
|
113
|
+
|
114
|
+
# replace name version and date
|
115
|
+
replace_header(head, :name)
|
116
|
+
replace_header(head, :version)
|
117
|
+
replace_header(head, :date)
|
118
|
+
#comment this out if your rubyforge_project has a different name
|
119
|
+
replace_header(head, :rubyforge_project)
|
120
|
+
|
121
|
+
# determine file list from git ls-files
|
122
|
+
files = `git ls-files`.
|
123
|
+
split("\n").
|
124
|
+
sort.
|
125
|
+
reject { |file| file =~ /^\./ }.
|
126
|
+
reject { |file| file =~ /^(rdoc|pkg|coverage)/ }.
|
127
|
+
map { |file| " #{file}" }.
|
128
|
+
join("\n")
|
129
|
+
|
130
|
+
# piece file back together and write
|
131
|
+
manifest = " s.files = %w[\n#{files}\n ]\n"
|
132
|
+
spec = [head, manifest, tail].join(" # = MANIFEST =\n")
|
133
|
+
File.open(gemspec_file, 'w') { |io| io.write(spec) }
|
134
|
+
puts "Updated #{gemspec_file}"
|
135
|
+
end
|
data/bin/.directory
ADDED
File without changes
|
data/bin/rumacs
ADDED
data/lib/.directory
ADDED
File without changes
|
data/lib/rumacs.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
module Rumacs
|
6
|
+
VERSION = '0.0.1'
|
7
|
+
|
8
|
+
def self.version
|
9
|
+
return VERSION
|
10
|
+
end
|
11
|
+
|
12
|
+
KNOWN_BACKENDS = [nil, :curses]
|
13
|
+
$backend = nil
|
14
|
+
|
15
|
+
def self.backend(new_backend)
|
16
|
+
if KNOWN_BACKENDS.include?(new_backend)
|
17
|
+
$backend = new_backend
|
18
|
+
load "rumacs/screen/#{$backend}.rb"
|
19
|
+
else
|
20
|
+
raise Exception "unknown backend #{new_backend}, known backends are #{KNOWN_BACKENDS}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.init()
|
25
|
+
backend(:curses)
|
26
|
+
$screen = Rumacs::Screen.new
|
27
|
+
$filemgr = Rumacs::Files.new
|
28
|
+
|
29
|
+
$screen.init_screen do
|
30
|
+
$filemgr.load_text(<<LOAD_TEXT
|
31
|
+
Welcome to Rumacs #{VERSION}!
|
32
|
+
========================
|
33
|
+
|
34
|
+
C-l :: backend.redraw
|
35
|
+
|
36
|
+
C-p, up :: point_move -1 0
|
37
|
+
C-n, down :: point_move 1 0
|
38
|
+
C-b, left :: point_move 0 -1
|
39
|
+
C-f, right :: point_move 0 1
|
40
|
+
|
41
|
+
C-a, home :: point_set nil 0
|
42
|
+
C-e, end:: point_set nil 0
|
43
|
+
|
44
|
+
C-x [...] :: compound_command_x
|
45
|
+
C-x C-c :: kill_rumacs
|
46
|
+
|
47
|
+
C-c [...] :: compound_command_c
|
48
|
+
|
49
|
+
[[other functionality to be implemented]]
|
50
|
+
LOAD_TEXT
|
51
|
+
)
|
52
|
+
$screen.key_loop
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
autoload :Screen, 'rumacs/screen'
|
57
|
+
autoload :Files, 'rumacs/files'
|
58
|
+
end
|
data/lib/rumacs/files.rb
ADDED
@@ -0,0 +1,225 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
module Rumacs
|
6
|
+
class Screen
|
7
|
+
attr_accessor :rows, :cols
|
8
|
+
attr_accessor :point_row, :point_col
|
9
|
+
attr_accessor :window_row, :window_col
|
10
|
+
attr_accessor :lines
|
11
|
+
attr_accessor :top_row
|
12
|
+
attr_accessor :backend
|
13
|
+
|
14
|
+
def initialize()
|
15
|
+
@rows = 0
|
16
|
+
@cols = 0
|
17
|
+
@point_row = 0
|
18
|
+
@point_col = 0
|
19
|
+
@window_row = 0
|
20
|
+
@window_col = 0
|
21
|
+
@lines = ['']
|
22
|
+
@top_row = 0
|
23
|
+
@backend = Rumacs::Screen::Backend.new(self)
|
24
|
+
|
25
|
+
@selected_keys = ""
|
26
|
+
end
|
27
|
+
|
28
|
+
def init_screen()
|
29
|
+
@backend.init_screen do
|
30
|
+
status_line()
|
31
|
+
yield
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def kill_rumacs()
|
36
|
+
@backend.clean_exit
|
37
|
+
exit 0
|
38
|
+
end
|
39
|
+
|
40
|
+
def point_move(row_offset, col_offset)
|
41
|
+
if (row_offset != 0) then
|
42
|
+
shunt_row(row_offset)
|
43
|
+
elsif (col_offset != 0) then
|
44
|
+
shunt_col(col_offset)
|
45
|
+
end
|
46
|
+
|
47
|
+
status_line()
|
48
|
+
end
|
49
|
+
|
50
|
+
def shunt_row(row_offset)
|
51
|
+
if (@point_row <= 0) && (row_offset < 0) then
|
52
|
+
minibuf(:error, "Beginning of buffer") { sleep 1 }
|
53
|
+
elsif (@point_row >= @lines.length) && (row_offset > 0) then
|
54
|
+
minibuf(:error, "End of buffer") { sleep 1 }
|
55
|
+
else
|
56
|
+
@point_row += row_offset
|
57
|
+
if @point_col > ((@lines[@point_row] || '').size) then
|
58
|
+
@point_col = (@lines[@point_row] || '').size
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
@window_row = @point_row
|
63
|
+
end
|
64
|
+
|
65
|
+
def shunt_col(col_offset)
|
66
|
+
prev_line_length = @lines[@point_row-1].size
|
67
|
+
this_line_length = (@lines[@point_row] || '').size
|
68
|
+
if (@point_col >= this_line_length) && (col_offset > 0) then
|
69
|
+
col_offset = ((@point_col + col_offset) - this_line_length) - 1
|
70
|
+
shunt_row( +1 )
|
71
|
+
@point_col = col_offset
|
72
|
+
elsif (@point_col <= 0) && (col_offset < 0) then
|
73
|
+
shunt_row( -1 )
|
74
|
+
col_offset = prev_line_length - (@point_col + col_offset + 1)
|
75
|
+
@point_col = col_offset
|
76
|
+
else
|
77
|
+
@point_col += col_offset
|
78
|
+
end
|
79
|
+
|
80
|
+
@window_col = @point_col
|
81
|
+
end
|
82
|
+
|
83
|
+
def point_set(row, col)
|
84
|
+
if row === true then
|
85
|
+
@point_row = @lines.size
|
86
|
+
else
|
87
|
+
@point_row = (row || @point_row)
|
88
|
+
end
|
89
|
+
|
90
|
+
if col === true then
|
91
|
+
@point_col = (@lines[@point_row] || 0).size
|
92
|
+
else
|
93
|
+
@point_col = (col || @point_col)
|
94
|
+
end
|
95
|
+
|
96
|
+
@window_col = @point_col
|
97
|
+
status_line()
|
98
|
+
end
|
99
|
+
|
100
|
+
def put_lines(lines)
|
101
|
+
@lines = lines
|
102
|
+
@lines.collect! {|line| line || ''}
|
103
|
+
draw_lines
|
104
|
+
end
|
105
|
+
|
106
|
+
def draw_lines()
|
107
|
+
(0..(@rows-2)).to_a.each do |i|
|
108
|
+
@backend.draw_line(i, 0, @lines[@top_row+i])
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def status_line()
|
113
|
+
status_string = "- rumacs - [#{@point_row},(#{@point_col}/#{(@lines[@point_row] || '').size}) inside #{@top_row}..#{@top_row + @rows - 2}] (#{@rows}:#{@cols}:#{$$}) "
|
114
|
+
@backend.draw_line_mode(@rows - 2, 0, status_string+("-" * (@cols - (status_string.size))), :statusbar)
|
115
|
+
@backend.jump_to_point()
|
116
|
+
end
|
117
|
+
|
118
|
+
def minibuf(type, str)
|
119
|
+
if (type == :warning) || (type == :error) then
|
120
|
+
@backend.notify
|
121
|
+
end
|
122
|
+
@backend.draw_line_mode(@rows - 1, 0, str, :minibuf)
|
123
|
+
@backend.jump_to_point()
|
124
|
+
@backend.redraw()
|
125
|
+
yield
|
126
|
+
@backend.draw_line_mode(@rows - 1, 0, " "*(@cols-1), :minibuf)
|
127
|
+
@backend.jump_to_point()
|
128
|
+
@backend.redraw()
|
129
|
+
end
|
130
|
+
|
131
|
+
$known_keys = {
|
132
|
+
# Redaw screen
|
133
|
+
:c_l => lambda {|i| i.backend.redraw },
|
134
|
+
|
135
|
+
# compound keys
|
136
|
+
:c_x => lambda {|i| i.compound_key_x },
|
137
|
+
:c_c => lambda {|i| i.compound_key_c },
|
138
|
+
|
139
|
+
# Point manipulation: screenful at a stroke (M-v and C-v)
|
140
|
+
:m_v => lambda {|i| i.point_move(-(@rows/2), 0) },
|
141
|
+
:pgup => :m_v,
|
142
|
+
:c_v => lambda {|i| i.point_move((@rows/2), 0) },
|
143
|
+
:pgdn => :c_v,
|
144
|
+
|
145
|
+
# Point manipulation: character at a stroke (C-p C-n C-b C-f)
|
146
|
+
:c_p => lambda {|i| i.point_move(-1, 0) },
|
147
|
+
:up => :c_p,
|
148
|
+
:c_n => lambda {|i| i.point_move( 1, 0) },
|
149
|
+
:down => :c_n,
|
150
|
+
:c_b => lambda {|i| i.point_move( 0, -1) },
|
151
|
+
:left => :c_b,
|
152
|
+
:c_f => lambda {|i| i.point_move( 0, 1) },
|
153
|
+
:right => :c_f,
|
154
|
+
|
155
|
+
# Point manipulation: jumps
|
156
|
+
:c_a => lambda {|i| i.point_set(nil, 0) },
|
157
|
+
:home => :c_a,
|
158
|
+
:c_e => lambda {|i| i.point_set(nil, true) },
|
159
|
+
:end => :c_e,
|
160
|
+
}
|
161
|
+
|
162
|
+
$known_compound_x = {
|
163
|
+
#:c_c => lambda {|i| i.compound_key_c },
|
164
|
+
:c_x => lambda {|i| i.compound_key_x },
|
165
|
+
|
166
|
+
:c_c => lambda {|i| i.kill_rumacs },
|
167
|
+
}
|
168
|
+
|
169
|
+
$known_compound_c = {
|
170
|
+
:c_c => lambda {|i| i.compound_key_c },
|
171
|
+
:c_x => lambda {|i| i.compound_key_x },
|
172
|
+
}
|
173
|
+
|
174
|
+
def unbound_key_warning(key)
|
175
|
+
minibuf(:warning, "'#{key.to_s}' is undefined.") { sleep 1 }
|
176
|
+
end
|
177
|
+
|
178
|
+
#
|
179
|
+
# This function is RECURSIVE! Do NOT refactor!
|
180
|
+
#
|
181
|
+
def call_key_in_table(key, table, rescuer)
|
182
|
+
if key.is_a? Symbol then
|
183
|
+
if table.key?(key) then
|
184
|
+
if table[key].is_a? Proc then
|
185
|
+
table[key].call(self)
|
186
|
+
elsif table[key].is_a? Symbol then
|
187
|
+
call_key_in_table(table[key], table, rescuer)
|
188
|
+
else
|
189
|
+
raise Exception.new("unknown type of known_key in #{key}")
|
190
|
+
end
|
191
|
+
else
|
192
|
+
unbound_key_warning(key)
|
193
|
+
end
|
194
|
+
else
|
195
|
+
rescuer.call(key)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def call_key(c)
|
200
|
+
call_key_in_table(c, $known_keys, lambda {|key| $filemgr.insert_character_at_point(key) })
|
201
|
+
end
|
202
|
+
|
203
|
+
def compound_key_x()
|
204
|
+
@selected_keys += "C-x "
|
205
|
+
minibuf(:notice, "#{@selected_keys}...") do
|
206
|
+
call_key_in_table(@backend.next_character, $known_compound_x, lambda {|key| abort_command })
|
207
|
+
end
|
208
|
+
@selected_keys = ""
|
209
|
+
end
|
210
|
+
|
211
|
+
def compound_key_c()
|
212
|
+
@selected_keys += "C-c "
|
213
|
+
minibuf(:notice, "#{@selected_keys}...") do
|
214
|
+
call_key_in_table(@backend.next_character, $known_compound_c, lambda {|key| abort_command })
|
215
|
+
end
|
216
|
+
@selected_keys = ""
|
217
|
+
end
|
218
|
+
|
219
|
+
def key_loop()
|
220
|
+
loop do
|
221
|
+
call_key(@backend.next_character)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'curses'
|
5
|
+
require 'io/console'
|
6
|
+
require 'colorize'
|
7
|
+
|
8
|
+
module Rumacs
|
9
|
+
class Screen
|
10
|
+
class Backend
|
11
|
+
def initialize(screen)
|
12
|
+
@screen = screen
|
13
|
+
rows, cols = $stdin.winsize
|
14
|
+
@screen.rows = rows
|
15
|
+
@screen.cols = cols
|
16
|
+
end
|
17
|
+
|
18
|
+
def init_screen()
|
19
|
+
Curses.init_screen
|
20
|
+
Curses.raw
|
21
|
+
Curses.noecho # do not show typed keys
|
22
|
+
Curses.stdscr.keypad(true) # enable arrow keys
|
23
|
+
|
24
|
+
# trap signals from kill; key strokes don't trigger anymore
|
25
|
+
for i in 1 .. 15 # SIGHUP .. SIGTERM
|
26
|
+
if trap(i, "SIG_IGN") != 0 then # 0 for SIG_IGN
|
27
|
+
trap(i) do |sig|
|
28
|
+
Curses.close_screen
|
29
|
+
puts "rumacs received an unexpected signal #{sig}."
|
30
|
+
exit sig
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
begin
|
36
|
+
yield
|
37
|
+
ensure
|
38
|
+
clean_exit
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def clean_exit()
|
43
|
+
Curses.close_screen
|
44
|
+
end
|
45
|
+
|
46
|
+
CHARACTER_MAP = {
|
47
|
+
Curses::Key::PPAGE => :pgup,
|
48
|
+
Curses::Key::NPAGE => :pgdn,
|
49
|
+
Curses::Key::UP => :up,
|
50
|
+
Curses::Key::DOWN => :down,
|
51
|
+
Curses::Key::LEFT => :left,
|
52
|
+
Curses::Key::RIGHT => :right,
|
53
|
+
Curses::Key::HOME => :home,
|
54
|
+
Curses::Key::END => :end,
|
55
|
+
Curses::Key::IC => :insert,
|
56
|
+
Curses::Key::BACKSPACE => :backspace,
|
57
|
+
127 => :backspace,
|
58
|
+
Curses::Key::DC => :delete,
|
59
|
+
Curses::Key::BTAB => :backtab,
|
60
|
+
|
61
|
+
265 => :f_1,
|
62
|
+
266 => :f_2,
|
63
|
+
267 => :f_3,
|
64
|
+
268 => :f_4,
|
65
|
+
269 => :f_5,
|
66
|
+
270 => :f_6,
|
67
|
+
271 => :f_7,
|
68
|
+
272 => :f_8,
|
69
|
+
273 => :f_9,
|
70
|
+
274 => :f_10,
|
71
|
+
275 => :f_11,
|
72
|
+
276 => :f_12,
|
73
|
+
|
74
|
+
1 => :c_a,
|
75
|
+
2 => :c_b,
|
76
|
+
3 => :c_c,
|
77
|
+
4 => :c_d,
|
78
|
+
5 => :c_e,
|
79
|
+
6 => :c_f,
|
80
|
+
7 => :c_g,
|
81
|
+
8 => :c_h,
|
82
|
+
9 => :c_i,
|
83
|
+
10 => :c_j,
|
84
|
+
11 => :c_k,
|
85
|
+
12 => :c_l,
|
86
|
+
13 => :c_m,
|
87
|
+
14 => :c_n,
|
88
|
+
15 => :c_o,
|
89
|
+
16 => :c_p,
|
90
|
+
17 => :c_q,
|
91
|
+
18 => :c_r,
|
92
|
+
19 => :c_s,
|
93
|
+
20 => :c_t,
|
94
|
+
21 => :c_u,
|
95
|
+
22 => :c_v,
|
96
|
+
23 => :c_w,
|
97
|
+
24 => :c_x,
|
98
|
+
25 => :c_y,
|
99
|
+
26 => :c_z,
|
100
|
+
|
101
|
+
27 => :c_3,
|
102
|
+
28 => :c_4,
|
103
|
+
29 => :c_5,
|
104
|
+
30 => :c_6,
|
105
|
+
31 => :c_7,
|
106
|
+
34 => :c_0,
|
107
|
+
}
|
108
|
+
|
109
|
+
def next_character
|
110
|
+
c = Curses.getch
|
111
|
+
|
112
|
+
if CHARACTER_MAP.include? c then
|
113
|
+
c = CHARACTER_MAP[c]
|
114
|
+
end
|
115
|
+
|
116
|
+
c
|
117
|
+
end
|
118
|
+
|
119
|
+
def redraw()
|
120
|
+
Curses.refresh
|
121
|
+
end
|
122
|
+
|
123
|
+
def jump_to_point()
|
124
|
+
Curses.setpos(@screen.point_row, @screen.point_col)
|
125
|
+
end
|
126
|
+
|
127
|
+
def draw_line(row, col, text)
|
128
|
+
Curses.setpos(row, col)
|
129
|
+
Curses.addstr((text || ''))
|
130
|
+
Curses.refresh
|
131
|
+
end
|
132
|
+
|
133
|
+
def notify()
|
134
|
+
Curses.beep
|
135
|
+
end
|
136
|
+
|
137
|
+
def draw_line_mode(row, col, text, mode)
|
138
|
+
curses_modes = {
|
139
|
+
:statusbar => Curses::A_REVERSE,
|
140
|
+
:minibuf => Curses::A_NORMAL,
|
141
|
+
}
|
142
|
+
|
143
|
+
Curses.attron(curses_modes[mode])
|
144
|
+
draw_line(row, col, text)
|
145
|
+
Curses.attroff(curses_modes[mode])
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
data/rumacs.gemspec
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'rumacs'
|
5
|
+
s.version = '0.0.1'
|
6
|
+
s.date = '2012-08-19'
|
7
|
+
|
8
|
+
s.summary = "Emacs-alike lightweight text editor, in Ruby"
|
9
|
+
s.description = "rumacs is a lightweight text editor functionally similar to the Emacs family of text editors."
|
10
|
+
|
11
|
+
s.authors = ["Jashank Jeremy"]
|
12
|
+
s.email = 'jashank@rulingia.com'
|
13
|
+
s.homepage = 'http://jashank.github.com/rumacs'
|
14
|
+
|
15
|
+
s.require_paths = %w[lib]
|
16
|
+
|
17
|
+
s.executables = ["rumacs"]
|
18
|
+
|
19
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
20
|
+
s.extra_rdoc_files = %w[README.md LICENSE]
|
21
|
+
|
22
|
+
s.add_development_dependency('rake', "~> 0.9")
|
23
|
+
s.add_development_dependency('rdoc', "~> 3.11")
|
24
|
+
|
25
|
+
s.add_runtime_dependency('activesupport', "~> 3.2.0")
|
26
|
+
s.add_runtime_dependency('colorize', "~> 0.5.0")
|
27
|
+
|
28
|
+
# = MANIFEST =
|
29
|
+
s.files = %w[
|
30
|
+
Gemfile
|
31
|
+
LICENSE
|
32
|
+
README.md
|
33
|
+
Rakefile
|
34
|
+
bin/.directory
|
35
|
+
bin/rumacs
|
36
|
+
lib/.directory
|
37
|
+
lib/rumacs.rb
|
38
|
+
lib/rumacs/files.rb
|
39
|
+
lib/rumacs/screen.rb
|
40
|
+
lib/rumacs/screen/curses.rb
|
41
|
+
lib/rumacs/screen/curses_helper.rb
|
42
|
+
rumacs.gemspec
|
43
|
+
]
|
44
|
+
# = MANIFEST =
|
45
|
+
end
|
metadata
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rumacs
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jashank Jeremy
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-08-19 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0.9'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.9'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rdoc
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '3.11'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '3.11'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: activesupport
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 3.2.0
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 3.2.0
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: colorize
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.5.0
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 0.5.0
|
78
|
+
description: rumacs is a lightweight text editor functionally similar to the Emacs
|
79
|
+
family of text editors.
|
80
|
+
email: jashank@rulingia.com
|
81
|
+
executables:
|
82
|
+
- rumacs
|
83
|
+
extensions: []
|
84
|
+
extra_rdoc_files:
|
85
|
+
- README.md
|
86
|
+
- LICENSE
|
87
|
+
files:
|
88
|
+
- Gemfile
|
89
|
+
- LICENSE
|
90
|
+
- README.md
|
91
|
+
- Rakefile
|
92
|
+
- bin/.directory
|
93
|
+
- bin/rumacs
|
94
|
+
- lib/.directory
|
95
|
+
- lib/rumacs.rb
|
96
|
+
- lib/rumacs/files.rb
|
97
|
+
- lib/rumacs/screen.rb
|
98
|
+
- lib/rumacs/screen/curses.rb
|
99
|
+
- lib/rumacs/screen/curses_helper.rb
|
100
|
+
- rumacs.gemspec
|
101
|
+
homepage: http://jashank.github.com/rumacs
|
102
|
+
licenses: []
|
103
|
+
post_install_message:
|
104
|
+
rdoc_options:
|
105
|
+
- --charset=UTF-8
|
106
|
+
require_paths:
|
107
|
+
- lib
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
110
|
+
requirements:
|
111
|
+
- - ! '>='
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
segments:
|
115
|
+
- 0
|
116
|
+
hash: 399386248576728796
|
117
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
|
+
none: false
|
119
|
+
requirements:
|
120
|
+
- - ! '>='
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
segments:
|
124
|
+
- 0
|
125
|
+
hash: 399386248576728796
|
126
|
+
requirements: []
|
127
|
+
rubyforge_project:
|
128
|
+
rubygems_version: 1.8.24
|
129
|
+
signing_key:
|
130
|
+
specification_version: 3
|
131
|
+
summary: Emacs-alike lightweight text editor, in Ruby
|
132
|
+
test_files: []
|