troshka 0.0.1

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/bin/troshka ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../lib/troshka'
3
+
4
+ Troshka::App.new.start
5
+
@@ -0,0 +1,59 @@
1
+ module Troshka
2
+
3
+ class App
4
+ def initialize
5
+ @qt_app = Qt::Application.new []
6
+
7
+ @editor = Editor.new
8
+ @editor.app = self
9
+
10
+ @output = Output.new
11
+ @output.app = self
12
+
13
+ @detail = Detail.new
14
+ @detail.app = self
15
+
16
+ @splitterh = Qt::Splitter.new
17
+ @splitterv = Qt::Splitter.new
18
+ @shell = Shell.new
19
+ end
20
+
21
+ def complete(word, line)
22
+ Bond.agent.call word, line
23
+ end
24
+
25
+ def run(text)
26
+ out = @shell.run text
27
+ @editor.text = ""
28
+ out[:text] = text
29
+ @output.add out
30
+ @output.scrollToBottom
31
+ @detail.view out[:obj]
32
+ end
33
+
34
+ def replace_code(text)
35
+ @editor.text = text
36
+ @editor.move_to_end
37
+ @editor.setFocus
38
+ end
39
+
40
+ def start
41
+ Bond.start
42
+
43
+ @splitterv.set_orientation Qt::Horizontal
44
+ @splitterh.set_orientation Qt::Vertical
45
+ @splitterh.resize 600,400
46
+
47
+ @splitterh.add_widget @splitterv
48
+ @splitterv.add_widget @output
49
+ @splitterv.add_widget @detail
50
+
51
+ @splitterh.add_widget @editor
52
+ @editor.setFocus
53
+ @splitterh.show
54
+
55
+ @qt_app.exec
56
+ end
57
+ end
58
+
59
+ end
@@ -0,0 +1,25 @@
1
+ module Troshka
2
+
3
+ class Detail < Qt::StackedWidget
4
+ attr_accessor :app
5
+
6
+ def initialize
7
+ super
8
+ @w = [DetailArrayHash.new, DetailAnything.new]
9
+ @w.each {|i| addWidget i}
10
+ self.setCurrentIndex 1
11
+ end
12
+
13
+ def view(obj)
14
+ case obj
15
+ when Array, Hash
16
+ @w[0].view obj
17
+ self.setCurrentIndex 0
18
+ else
19
+ @w[1].view obj
20
+ self.setCurrentIndex 1
21
+ end
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,9 @@
1
+ module Troshka
2
+
3
+ class DetailAnything < Qt::TextEdit
4
+ def view(obj)
5
+ self.text = obj.to_s
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,86 @@
1
+ module Troshka
2
+
3
+ class DetailArrayHash < Qt::TreeWidget
4
+ attr_accessor :app
5
+
6
+ def initialize
7
+ super
8
+ self.setHeaderLabels ['Index', 'Value']
9
+ end
10
+
11
+ def view(obj)
12
+ self.clear
13
+ viewObject obj
14
+ end
15
+
16
+ private
17
+
18
+ def viewObject(obj, idx=nil, parent=nil)
19
+ case obj
20
+ when Array
21
+ viewArray obj, idx, parent
22
+ when Hash
23
+ viewHash obj, idx, parent
24
+ else
25
+ viewAnything obj, idx, parent
26
+ end
27
+ end
28
+
29
+ def insert(item, parent=nil)
30
+ if not parent.is_a? Qt::TreeWidgetItem
31
+ self.addTopLevelItem item
32
+ else
33
+ parent.insertChild parent.childCount, item
34
+ end
35
+ end
36
+
37
+ def viewArray(obj, idx, parent)
38
+ if parent.nil?
39
+ item = :root
40
+ else
41
+ item = Qt::TreeWidgetItem.new
42
+ item.setText 0, idx.to_s
43
+ item.setText 1, "Array #{obj.size} items"
44
+ item.setForeground 1, Qt::Brush.new(Qt::Color.new 128, 128, 128)
45
+ insert item, parent
46
+ end
47
+
48
+ obj.each_with_index do |o,idx|
49
+ viewObject o, idx, item
50
+ end
51
+
52
+ item
53
+ end
54
+
55
+ def viewHash(obj, idx, parent)
56
+ if parent.nil?
57
+ item = :root
58
+ else
59
+ item = Qt::TreeWidgetItem.new
60
+ item.setText 0, idx.to_s
61
+ item.setText 1, "Hash #{obj.size} items"
62
+ brush = Qt::Brush.new(Qt::Color.new 229, 229, 255)
63
+ item.setBackground 0, brush
64
+ item.setBackground 1, brush
65
+ insert item, parent
66
+ end
67
+
68
+ obj.each do |k,v|
69
+ viewObject v, k, item
70
+ end
71
+
72
+ item
73
+ end
74
+
75
+ def viewAnything(obj, idx, parent=nil)
76
+ item = Qt::TreeWidgetItem.new
77
+ item.setText 0, idx.to_s
78
+ item.setText 1, obj.to_s
79
+ item.setForeground 1, Qt::Brush.new(Qt::Color.new 0, 0, 229)
80
+ insert item, parent
81
+ item
82
+ end
83
+
84
+ end
85
+
86
+ end
@@ -0,0 +1,113 @@
1
+ module Troshka
2
+
3
+ class Editor < Qsci::Scintilla
4
+ attr_accessor :app
5
+
6
+ def initialize
7
+ super
8
+ build
9
+ end
10
+
11
+ def user_list_activated(&block)
12
+ connect(SIGNAL "userListActivated(int, const QString)") {|id, text| block.(self,text)}
13
+ end
14
+
15
+ def keyPressEvent(x)
16
+ if x.key==Qt::Key_Space && x.modifiers==Qt::Control_Modifier
17
+ pos = column
18
+ word = current_word
19
+ list = @app.complete(word[:word], current_line)
20
+ unless list.empty?
21
+ list.sort!
22
+
23
+ hint = list.first.dup
24
+ hint.chop! while current_line.rindex(hint).nil?
25
+ @auto = word[:word_end]+1-hint.size, word[:word_end]
26
+
27
+ setCursorPosition(line, word[:word_end]-hint.size)
28
+ show_user_list 1, list
29
+ setCursorPosition(line, pos)
30
+ end
31
+ elsif x.key==Qt::Key_Return && x.modifiers==Qt::Control_Modifier
32
+ @app.run text
33
+ else
34
+ super x
35
+ end
36
+ end
37
+
38
+ def position
39
+ # SCI_GETCURRENTPOS
40
+ SendScintilla(2008, 0, 0)
41
+ end
42
+
43
+ def line_end_position(line)
44
+ # SCI_GETLINEENDPOSITION
45
+ SendScintilla(2136, line, 0)
46
+ end
47
+
48
+ def move_to_end
49
+ setCursorPosition lines, line_end_position(lines)
50
+ end
51
+
52
+ def select_word
53
+ word = current_word
54
+ setSelection line, word[:word_begin], line, word[:word_end]+1
55
+ end
56
+
57
+ def select_auto
58
+ setSelection line, @auto.first, line, @auto.last + 1
59
+ end
60
+
61
+ def select_line
62
+ setSelection line, 0, line, lineLength(line)
63
+ end
64
+
65
+ def line
66
+ # SCI_LINEFROMPOSITION
67
+ SendScintilla(2166,position,0)
68
+ end
69
+
70
+ def column
71
+ # SCI_GETCOLUMN = 2129
72
+ SendScintilla(2129,position,0)
73
+ end
74
+
75
+ def insert_and_advance(text)
76
+ insert text
77
+ setCursorPosition(line, column + text.length)
78
+ end
79
+
80
+ def current_line
81
+ text line
82
+ end
83
+
84
+ def current_word
85
+ word_begin = current_line.rindex(word_separator, column-1)+1 rescue 0
86
+ word_end = current_line.index(word_separator, column)-1 rescue current_line.size-1
87
+
88
+ word = current_line[word_begin..word_end]
89
+ {word_begin: word_begin, word_end: word_end, word: word}
90
+ end
91
+
92
+ def word_separator
93
+ " "
94
+ end
95
+
96
+ def build
97
+ @lexer = Qsci::LexerRuby.new
98
+ self.setAutoIndent true
99
+ self.setIndentationGuides true
100
+ self.setIndentationWidth 2
101
+ self.setFolding Qsci::Scintilla::PlainFoldStyle
102
+ self.setLexer @lexer
103
+ self.setMarginWidth 1, 0
104
+
105
+ self.user_list_activated do |editor, text|
106
+ editor.select_auto
107
+ editor.replaceSelectedText text
108
+ end
109
+ end
110
+
111
+ end
112
+
113
+ end
@@ -0,0 +1,58 @@
1
+ module Troshka
2
+
3
+ class Output < Qt::ListWidget
4
+ attr_accessor :app
5
+
6
+ def initialize
7
+ super
8
+ build
9
+ end
10
+
11
+ def item_double_click(&block)
12
+ connect(SIGNAL "itemDoubleClicked(QListWidgetItem*)") {|item| block.(item)}
13
+ end
14
+
15
+ def add(obj)
16
+ iCode = Qt::ListWidgetItem.new
17
+ iCode.setText obj[:text]
18
+ iCode.setData Qt::UserRole, Qt::Variant.new("code")
19
+ iCode.setForeground Qt::Brush.new(Qt::Color.new 0, 0, 255)
20
+ self.addItem iCode
21
+
22
+ if obj[:exception]
23
+ iEx = Qt::ListWidgetItem.new
24
+ iEx.setText "#{obj[:exception].class}: #{obj[:exception].message}"
25
+ iEx.setData Qt::UserRole, Qt::Variant.new("exception")
26
+ iEx.setBackground Qt::Brush.new(Qt::Color.new 255, 0, 0)
27
+ self.addItem iEx
28
+ else
29
+ unless obj[:output].empty?
30
+ obj[:output].chop! if obj[:output][-1]=="\n"
31
+ iOut = Qt::ListWidgetItem.new
32
+ iOut.setText obj[:output]
33
+ iOut.setBackground Qt::Brush.new(Qt::Color.new 229, 229, 255)
34
+ iOut.setData Qt::UserRole, Qt::Variant.new("output")
35
+ self.addItem iOut
36
+ end
37
+
38
+ obj[:obj] = "nil" if obj[:obj].nil?
39
+ iObj = Qt::ListWidgetItem.new
40
+ iObj.setText obj[:obj].to_s
41
+ iObj.setData Qt::UserRole, Qt::Variant.new("obj")
42
+ iObj.setBackground Qt::Brush.new(Qt::Color.new 255, 255, 229)
43
+ self.addItem iObj
44
+ end
45
+
46
+ self.item(self.count-1).setSelected true
47
+ end
48
+
49
+ def build
50
+ item_double_click do |item|
51
+ if item.data(Qt::UserRole).toString == "code"
52
+ @app.replace_code item.text
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ end
@@ -0,0 +1,27 @@
1
+ module Troshka
2
+
3
+ class Shell
4
+ def initialize
5
+ @binding = TOPLEVEL_BINDING
6
+ $stdout = StringIO.new
7
+ end
8
+
9
+ def run(str)
10
+ obj = eval(str, @binding, "(girb)")
11
+ exception = nil
12
+
13
+ $stdout.rewind
14
+ output = $stdout.read
15
+ $stdout.truncate(0)
16
+ $stdout.rewind
17
+ rescue Exception => e
18
+ output = nil
19
+ obj = nil
20
+ exception = e
21
+ ensure
22
+ return {output: output, obj: obj, exception: exception}
23
+ end
24
+
25
+ end
26
+
27
+ end
data/lib/troshka.rb ADDED
@@ -0,0 +1,5 @@
1
+ %w{Qt4 qscintilla bond stringio}.each {|lib| require "#{lib}"}
2
+
3
+ %w{app detail detail_anything detail_array_hash editor output shell version}.each do |lib|
4
+ require_relative "./troshka/#{lib}"
5
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: troshka
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Patricio Ros
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bond
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: ! " Troshka is an GUI Ruby console. It's an alternative to irb and\n
31
+ \ other Ruby REPLs. \n Troshka is written in Ruby and GUI uses Qt bindings.\n"
32
+ email: patricioros.dev@gmail.com
33
+ executables:
34
+ - troshka
35
+ extensions: []
36
+ extra_rdoc_files: []
37
+ files:
38
+ - lib/troshka/output.rb
39
+ - lib/troshka/detail_anything.rb
40
+ - lib/troshka/detail.rb
41
+ - lib/troshka/editor.rb
42
+ - lib/troshka/app.rb
43
+ - lib/troshka/detail_array_hash.rb
44
+ - lib/troshka/shell.rb
45
+ - lib/troshka.rb
46
+ - bin/troshka
47
+ homepage: https://github.com/pmros/troshka
48
+ licenses: []
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: 1.9.0
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements:
66
+ - QtRuby
67
+ - QScintilla
68
+ rubyforge_project:
69
+ rubygems_version: 1.8.23
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: A GUI Ruby console
73
+ test_files: []