rbpad 3.1.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.
- checksums.yaml +7 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +48 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/rbpad +3 -0
- data/lib/rbpad/blockmatch.rb +136 -0
- data/lib/rbpad/config/actions_menubar.xml +166 -0
- data/lib/rbpad/config/actions_menubar_template.xml +126 -0
- data/lib/rbpad/config/actions_menubar_toggle.xml +27 -0
- data/lib/rbpad/config/find_next.xpm +196 -0
- data/lib/rbpad/config/find_prev.xpm +196 -0
- data/lib/rbpad/config/menu.xml +63 -0
- data/lib/rbpad/config/messages.xml +64 -0
- data/lib/rbpad/config/platform.xml +41 -0
- data/lib/rbpad/config/run.xpm +44 -0
- data/lib/rbpad/config/sourceview.xml +132 -0
- data/lib/rbpad/config.rb +216 -0
- data/lib/rbpad/editor.rb +141 -0
- data/lib/rbpad/error_jp.rb +176 -0
- data/lib/rbpad/input.rb +27 -0
- data/lib/rbpad/output.rb +51 -0
- data/lib/rbpad/pad.rb +656 -0
- data/lib/rbpad/page.rb +257 -0
- data/lib/rbpad/util.rb +30 -0
- data/lib/rbpad/version.rb +3 -0
- data/lib/rbpad.rb +32 -0
- data/rbpad.gemspec +43 -0
- data/rbpad3_en.png +0 -0
- data/rbpad3_jp.png +0 -0
- metadata +95 -0
data/lib/rbpad/page.rb
ADDED
@@ -0,0 +1,257 @@
|
|
1
|
+
|
2
|
+
require 'gtk3'
|
3
|
+
require 'gtksourceview3'
|
4
|
+
require 'uri'
|
5
|
+
|
6
|
+
require 'rbpad/blockmatch'
|
7
|
+
|
8
|
+
|
9
|
+
module Rbpad
|
10
|
+
|
11
|
+
class Page < Gtk::ScrolledWindow
|
12
|
+
attr_reader :status, :dirname, :basename
|
13
|
+
|
14
|
+
def initialize(conf, status_area)
|
15
|
+
super()
|
16
|
+
|
17
|
+
language = GtkSource::LanguageManager.new.get_language('ruby')
|
18
|
+
buffer = GtkSource::Buffer.new(language)
|
19
|
+
buffer.highlight_syntax = true # syntax highlight
|
20
|
+
|
21
|
+
@conf = conf
|
22
|
+
schememgr = GtkSource::StyleSchemeManager.new.set_search_path([@conf.sourceview])
|
23
|
+
#p schememgr.scheme_ids
|
24
|
+
#p schememgr.search_path
|
25
|
+
|
26
|
+
scheme = schememgr.get_scheme("rbpad")
|
27
|
+
buffer.set_style_scheme(scheme)
|
28
|
+
|
29
|
+
@view = GtkSource::View.new(buffer)
|
30
|
+
@view.override_font(Pango::FontDescription.new("#{@conf.platform[:font][:page]}"))
|
31
|
+
@view.left_margin = 6
|
32
|
+
@view.pixels_above_lines = 1
|
33
|
+
@view.pixels_below_lines = 1
|
34
|
+
@view.accepts_tab = false # 'TAB' is used for moving focus
|
35
|
+
@view.editable = true # editable
|
36
|
+
@view.cursor_visible = true # show cursor
|
37
|
+
@view.show_line_numbers = true # show line number
|
38
|
+
@view.auto_indent = true # auto indent
|
39
|
+
@view.highlight_current_line = true # show current line with highlight
|
40
|
+
|
41
|
+
self.add(@view)
|
42
|
+
|
43
|
+
@status = :EMPTY
|
44
|
+
@dirname = nil
|
45
|
+
@basename = nil
|
46
|
+
@status_area = status_area
|
47
|
+
|
48
|
+
attr = {
|
49
|
+
color: scheme.get_style("def:comment").foreground.downcase,
|
50
|
+
bold: scheme.get_style("def:comment").bold?,
|
51
|
+
italic: scheme.get_style("def:comment").italic?
|
52
|
+
}
|
53
|
+
@bm = BlockMatch.new(@view, attr)
|
54
|
+
|
55
|
+
_display_status # show status
|
56
|
+
|
57
|
+
@view.drag_dest_set(Gtk::DestDefaults::MOTION |
|
58
|
+
Gtk::DestDefaults::HIGHLIGHT |
|
59
|
+
Gtk::DestDefaults::DROP,
|
60
|
+
[["text/uri-list", :other_app, 49334]],
|
61
|
+
Gdk::DragAction::COPY |
|
62
|
+
Gdk::DragAction::MOVE)
|
63
|
+
|
64
|
+
@view.signal_connect(:drag_data_received) do |widget, context, x, y, data, info, time|
|
65
|
+
# decode the data which is uri encoded,
|
66
|
+
# and process each file from multi files list
|
67
|
+
if @last_received_time != time # [BUG?] Signal is sent dupulicate including last time data since 2nd operation, isn't it ?
|
68
|
+
data.uris.each do |uri|
|
69
|
+
dec_uri = URI.decode(uri)
|
70
|
+
if /cygwin|mingw|mswin/ === RUBY_PLATFORM and /file:\/\/\/[A-Z]:/ === dec_uri # UNC is formatted like file://host/path/file
|
71
|
+
filename = dec_uri.sub('file:///', '') # Windows : e.g. file:/// (file:///C:/foo/bar.rb --> C:/foo/bar.rb)
|
72
|
+
else
|
73
|
+
filename = dec_uri.sub('file://', '') # Linux, macOS : e.g. file:// (file:///home/foo/bar.rb --> /home/foo/bar.rb)
|
74
|
+
end
|
75
|
+
self.parent.load(filename)
|
76
|
+
end
|
77
|
+
@last_received_time = time
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
@view.signal_connect(:button_release_event) do
|
82
|
+
# by pointing mouse cursor
|
83
|
+
_display_status
|
84
|
+
@bm.scan if @block_match
|
85
|
+
false # if true, event about selecting range by mouse pointer is happend
|
86
|
+
end
|
87
|
+
|
88
|
+
@view.signal_connect_after(:move_cursor) do |widget, step, count, extend_selection|
|
89
|
+
_display_status
|
90
|
+
@bm.scan if @block_match
|
91
|
+
end
|
92
|
+
|
93
|
+
@view.buffer.signal_connect(:changed) do |widget|
|
94
|
+
@status = :UNSAVED # update status of editing
|
95
|
+
_display_status
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def destroy
|
100
|
+
self.instance_variables.each do |v|
|
101
|
+
remove_instance_variable(v)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def undo
|
106
|
+
@view.signal_emit(:undo)
|
107
|
+
end
|
108
|
+
|
109
|
+
def redo
|
110
|
+
@view.signal_emit(:redo)
|
111
|
+
end
|
112
|
+
|
113
|
+
def cut
|
114
|
+
@view.signal_emit(:cut_clipboard)
|
115
|
+
end
|
116
|
+
|
117
|
+
def copy
|
118
|
+
@view.signal_emit(:copy_clipboard)
|
119
|
+
end
|
120
|
+
|
121
|
+
def paste
|
122
|
+
@view.signal_emit(:paste_clipboard) # scroll till bottom of pasted line
|
123
|
+
end
|
124
|
+
|
125
|
+
def select_all
|
126
|
+
@view.signal_emit(:select_all, true)
|
127
|
+
end
|
128
|
+
|
129
|
+
def set_draw_spaces(status)
|
130
|
+
if status
|
131
|
+
@view.draw_spaces = GtkSource::DrawSpacesFlags::SPACE # show space character
|
132
|
+
else
|
133
|
+
@view.draw_spaces = 0
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def set_block_match(status)
|
138
|
+
@block_match = status
|
139
|
+
if status
|
140
|
+
@bm.scan
|
141
|
+
else
|
142
|
+
@bm.clear
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def find_and_select(word, direction)
|
147
|
+
return true unless word
|
148
|
+
@view.set_focus(true)
|
149
|
+
iter = @view.buffer.get_iter_at(mark: @view.buffer.get_mark("insert"))
|
150
|
+
if direction == :forward
|
151
|
+
if @view.buffer.get_iter_at(mark: @view.buffer.get_mark("selection_bound")).offset > @view.buffer.get_iter_at(mark: @view.buffer.get_mark("insert")).offset
|
152
|
+
# avoid duplicate hits of the same word
|
153
|
+
# when reversing the search direction
|
154
|
+
iter = @view.buffer.get_iter_at(mark: @view.buffer.get_mark("selection_bound"))
|
155
|
+
end
|
156
|
+
match_iters = iter.forward_search(word, :text_only)
|
157
|
+
next_iter = [match_iters[1], match_iters[0]] if match_iters
|
158
|
+
else
|
159
|
+
if @view.buffer.get_iter_at(mark: @view.buffer.get_mark("selection_bound")).offset < @view.buffer.get_iter_at(mark: @view.buffer.get_mark("insert")).offset
|
160
|
+
# avoid duplicate hits of the same word
|
161
|
+
# when reversing the search direction
|
162
|
+
iter = @view.buffer.get_iter_at(mark: @view.buffer.get_mark("selection_bound"))
|
163
|
+
end
|
164
|
+
match_iters = iter.backward_search(word, :text_only)
|
165
|
+
next_iter = match_iters if match_iters
|
166
|
+
end
|
167
|
+
if match_iters
|
168
|
+
@view.buffer.place_cursor(next_iter[0])
|
169
|
+
@view.scroll_mark_onscreen(@view.buffer.get_mark("insert"))
|
170
|
+
@view.buffer.move_mark(@view.buffer.get_mark("selection_bound"), next_iter[1])
|
171
|
+
_display_status
|
172
|
+
@bm.scan if @block_match
|
173
|
+
true
|
174
|
+
else
|
175
|
+
false
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
# insert text block with indent at cursor place
|
180
|
+
def insert_block(text, cursor = nil)
|
181
|
+
mark = @view.buffer.selection_bound # get mark of cursor place
|
182
|
+
iter = @view.buffer.get_iter_at(mark: mark) # get iter from mark
|
183
|
+
text.gsub!("\n", "\n#{" " * iter.line_offset}") # adjust indent of text (add space after line-feed)
|
184
|
+
@view.buffer.insert_at_cursor(text) # insert text
|
185
|
+
@view.scroll_to_mark(mark, 0, false, 0, 1) # move to mark
|
186
|
+
if cursor == :start
|
187
|
+
@view.buffer.place_cursor(@view.buffer.start_iter)
|
188
|
+
end
|
189
|
+
_display_status
|
190
|
+
end
|
191
|
+
|
192
|
+
# save file
|
193
|
+
def save(filename, temporary = false)
|
194
|
+
content = @view.buffer.text
|
195
|
+
File.open(filename, "wb:utf-8") do |fp|
|
196
|
+
fp.puts content
|
197
|
+
end
|
198
|
+
|
199
|
+
unless temporary
|
200
|
+
@status = :SAVED
|
201
|
+
@dirname = File.dirname(filename)
|
202
|
+
@basename = File.basename(filename)
|
203
|
+
end
|
204
|
+
_display_status
|
205
|
+
end
|
206
|
+
|
207
|
+
# load file
|
208
|
+
def load(filename, template = false)
|
209
|
+
begin
|
210
|
+
File.open(filename, "rb:utf-8") do |file|
|
211
|
+
# replace incorrect bytes to 'U+FFFD'
|
212
|
+
content = file.read.scrub
|
213
|
+
@view.buffer.insert(@view.buffer.end_iter, content)
|
214
|
+
end
|
215
|
+
|
216
|
+
if template
|
217
|
+
@status = :UNSAVED
|
218
|
+
else
|
219
|
+
@status = :SAVED
|
220
|
+
@dirname = File.dirname(filename)
|
221
|
+
@basename = File.basename(filename)
|
222
|
+
end
|
223
|
+
|
224
|
+
@view.buffer.place_cursor(@view.buffer.start_iter)
|
225
|
+
_display_status
|
226
|
+
true
|
227
|
+
rescue
|
228
|
+
# when has read binary file, etc
|
229
|
+
false
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
# set focus
|
234
|
+
def set_focus
|
235
|
+
@view.set_focus(true)
|
236
|
+
end
|
237
|
+
|
238
|
+
# show information
|
239
|
+
def display_status
|
240
|
+
_display_status
|
241
|
+
end
|
242
|
+
|
243
|
+
# show information at status area (line, columun, saving status)
|
244
|
+
private def _display_status(movement_step = nil, count = 0)
|
245
|
+
mark = @view.buffer.selection_bound # get the mark at the cursor position
|
246
|
+
iter = @view.buffer.get_iter_at(mark: mark)
|
247
|
+
|
248
|
+
stat = @conf.messages[:status_saved]
|
249
|
+
stat = @conf.messages[:status_unsaved] if @status == :UNSAVED
|
250
|
+
# e.g. "%5L%4C (UNSAVED)"
|
251
|
+
format = "%5d#{@conf.messages[:status_pos_l]}%4d#{@conf.messages[:status_pos_c]} %-10s"
|
252
|
+
@status_area.text = format % [iter.line + 1, iter.line_offset + 1, stat]
|
253
|
+
end
|
254
|
+
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
data/lib/rbpad/util.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
|
2
|
+
module Rbpad
|
3
|
+
|
4
|
+
module Utility
|
5
|
+
module_function def get_uniqname
|
6
|
+
# generate a random 8-character string
|
7
|
+
(1..8).map {
|
8
|
+
[*'A'..'Z', *'a'..'z', *'0'..'9'].sample
|
9
|
+
}.join
|
10
|
+
end
|
11
|
+
|
12
|
+
module_function def get_os
|
13
|
+
(
|
14
|
+
host_os = RbConfig::CONFIG['host_os']
|
15
|
+
case host_os
|
16
|
+
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
17
|
+
:windows
|
18
|
+
when /darwin|mac os/
|
19
|
+
:mac
|
20
|
+
when /linux/
|
21
|
+
:linux
|
22
|
+
else
|
23
|
+
:unknown
|
24
|
+
end
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
data/lib/rbpad.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
=begin
|
2
|
+
'rbpad'
|
3
|
+
Copyright (c) 2018 Koki Kitamura
|
4
|
+
Released under the MIT license
|
5
|
+
https://opensource.org/licenses/mit-license.php
|
6
|
+
=end
|
7
|
+
|
8
|
+
require 'gtk3'
|
9
|
+
require 'optparse'
|
10
|
+
|
11
|
+
require 'rbpad/pad'
|
12
|
+
|
13
|
+
Encoding.default_external = 'UTF-8'
|
14
|
+
|
15
|
+
opts = ARGV.getopts('ex')
|
16
|
+
|
17
|
+
lang = (opts['e'] ? :en : :jp) # :jp or :en
|
18
|
+
|
19
|
+
if opts['x']
|
20
|
+
pad = Rbpad::Pad.new(lang, 0, 0) # maximized
|
21
|
+
else
|
22
|
+
if ARGV.size >= 2
|
23
|
+
w = ARGV[0].to_i
|
24
|
+
h = ARGV[1].to_i
|
25
|
+
pad = Rbpad::Pad.new(lang, w, h) # specified
|
26
|
+
else
|
27
|
+
pad = Rbpad::Pad.new(lang) # default
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
Gtk.main
|
32
|
+
|
data/rbpad.gemspec
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "rbpad/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rbpad"
|
8
|
+
spec.version = Rbpad::VERSION
|
9
|
+
spec.authors = ["Koki Kitamura"]
|
10
|
+
spec.email = ["spool.kitamura@nifty.ne.jp"]
|
11
|
+
|
12
|
+
spec.summary = %q{programming editor for Ruby using Ruby/GTK3 and Ruby/GtkSourceView3}
|
13
|
+
spec.description = %q{'rbpad' is a programming editor for Ruby using Ruby/GTK3 and Ruby/GtkSourceView3}
|
14
|
+
spec.homepage = "https://github.com/spoolkitamura/rbpad3"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
|
+
#if spec.respond_to?(:metadata)
|
20
|
+
# spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
21
|
+
#
|
22
|
+
# spec.metadata["homepage_uri"] = spec.homepage
|
23
|
+
# spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
|
24
|
+
# spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
|
25
|
+
#else
|
26
|
+
# raise "RubyGems 2.0 or newer is required to protect against " \
|
27
|
+
# "public gem pushes."
|
28
|
+
#end
|
29
|
+
|
30
|
+
# Specify which files should be added to the gem when it is released.
|
31
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
32
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
33
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
34
|
+
end
|
35
|
+
spec.bindir = "exe"
|
36
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
37
|
+
spec.require_paths = ["lib"]
|
38
|
+
|
39
|
+
spec.add_runtime_dependency "gtksourceview3", "~> 3.3", ">= 3.3.1"
|
40
|
+
|
41
|
+
#spec.add_development_dependency "bundler", "~> 1.17"
|
42
|
+
#spec.add_development_dependency "rake", "~> 10.0"
|
43
|
+
end
|
data/rbpad3_en.png
ADDED
Binary file
|
data/rbpad3_jp.png
ADDED
Binary file
|
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rbpad
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 3.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Koki Kitamura
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-08-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: gtksourceview3
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.3'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 3.3.1
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.3'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 3.3.1
|
33
|
+
description: "'rbpad' is a programming editor for Ruby using Ruby/GTK3 and Ruby/GtkSourceView3"
|
34
|
+
email:
|
35
|
+
- spool.kitamura@nifty.ne.jp
|
36
|
+
executables:
|
37
|
+
- rbpad
|
38
|
+
extensions: []
|
39
|
+
extra_rdoc_files: []
|
40
|
+
files:
|
41
|
+
- Gemfile
|
42
|
+
- LICENSE.txt
|
43
|
+
- README.md
|
44
|
+
- Rakefile
|
45
|
+
- bin/console
|
46
|
+
- bin/setup
|
47
|
+
- exe/rbpad
|
48
|
+
- lib/rbpad.rb
|
49
|
+
- lib/rbpad/blockmatch.rb
|
50
|
+
- lib/rbpad/config.rb
|
51
|
+
- lib/rbpad/config/actions_menubar.xml
|
52
|
+
- lib/rbpad/config/actions_menubar_template.xml
|
53
|
+
- lib/rbpad/config/actions_menubar_toggle.xml
|
54
|
+
- lib/rbpad/config/find_next.xpm
|
55
|
+
- lib/rbpad/config/find_prev.xpm
|
56
|
+
- lib/rbpad/config/menu.xml
|
57
|
+
- lib/rbpad/config/messages.xml
|
58
|
+
- lib/rbpad/config/platform.xml
|
59
|
+
- lib/rbpad/config/run.xpm
|
60
|
+
- lib/rbpad/config/sourceview.xml
|
61
|
+
- lib/rbpad/editor.rb
|
62
|
+
- lib/rbpad/error_jp.rb
|
63
|
+
- lib/rbpad/input.rb
|
64
|
+
- lib/rbpad/output.rb
|
65
|
+
- lib/rbpad/pad.rb
|
66
|
+
- lib/rbpad/page.rb
|
67
|
+
- lib/rbpad/util.rb
|
68
|
+
- lib/rbpad/version.rb
|
69
|
+
- rbpad.gemspec
|
70
|
+
- rbpad3_en.png
|
71
|
+
- rbpad3_jp.png
|
72
|
+
homepage: https://github.com/spoolkitamura/rbpad3
|
73
|
+
licenses:
|
74
|
+
- MIT
|
75
|
+
metadata: {}
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubygems_version: 3.0.3
|
92
|
+
signing_key:
|
93
|
+
specification_version: 4
|
94
|
+
summary: programming editor for Ruby using Ruby/GTK3 and Ruby/GtkSourceView3
|
95
|
+
test_files: []
|