rbhex-core 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/CHANGELOG +2000 -0
  4. data/LICENSE +56 -0
  5. data/README.md +44 -0
  6. data/examples/abasiclist.rb +179 -0
  7. data/examples/alpmenu.rb +50 -0
  8. data/examples/app.sample +19 -0
  9. data/examples/atree.rb +100 -0
  10. data/examples/bline.rb +136 -0
  11. data/examples/common/file.rb +45 -0
  12. data/examples/data/README.markdown +9 -0
  13. data/examples/data/brew.txt +38 -0
  14. data/examples/data/color.2 +37 -0
  15. data/examples/data/gemlist.txt +60 -0
  16. data/examples/data/lotr.txt +12 -0
  17. data/examples/data/ports.txt +136 -0
  18. data/examples/data/table.txt +37 -0
  19. data/examples/data/tasks.csv +88 -0
  20. data/examples/data/tasks.txt +27 -0
  21. data/examples/data/todo.txt +10 -0
  22. data/examples/data/todo.txt.bak +10 -0
  23. data/examples/data/todocsv.csv +28 -0
  24. data/examples/data/unix1.txt +21 -0
  25. data/examples/data/unix2.txt +11 -0
  26. data/examples/dbdemo.rb +502 -0
  27. data/examples/dirtree.rb +94 -0
  28. data/examples/newtabbedwindow.rb +100 -0
  29. data/examples/newtesttabp.rb +92 -0
  30. data/examples/tabular.rb +146 -0
  31. data/examples/tasks.rb +178 -0
  32. data/examples/term2.rb +84 -0
  33. data/examples/testbuttons.rb +296 -0
  34. data/examples/testcombo.rb +102 -0
  35. data/examples/testfields.rb +195 -0
  36. data/examples/testkeypress.rb +72 -0
  37. data/examples/testlistbox.rb +170 -0
  38. data/examples/testmessagebox.rb +140 -0
  39. data/examples/testprogress.rb +116 -0
  40. data/examples/testree.rb +106 -0
  41. data/examples/testwsshortcuts.rb +66 -0
  42. data/examples/testwsshortcuts2.rb +128 -0
  43. data/lib/rbhex.rb +6 -0
  44. data/lib/rbhex/core/docs/index.txt +73 -0
  45. data/lib/rbhex/core/include/action.rb +80 -0
  46. data/lib/rbhex/core/include/actionmanager.rb +49 -0
  47. data/lib/rbhex/core/include/appmethods.rb +214 -0
  48. data/lib/rbhex/core/include/bordertitle.rb +48 -0
  49. data/lib/rbhex/core/include/chunk.rb +203 -0
  50. data/lib/rbhex/core/include/io.rb +553 -0
  51. data/lib/rbhex/core/include/listbindings.rb +74 -0
  52. data/lib/rbhex/core/include/listcellrenderer.rb +140 -0
  53. data/lib/rbhex/core/include/listeditable.rb +317 -0
  54. data/lib/rbhex/core/include/listscrollable.rb +663 -0
  55. data/lib/rbhex/core/include/listselectable.rb +271 -0
  56. data/lib/rbhex/core/include/multibuffer.rb +83 -0
  57. data/lib/rbhex/core/include/orderedhash.rb +77 -0
  58. data/lib/rbhex/core/include/ractionevent.rb +73 -0
  59. data/lib/rbhex/core/include/rchangeevent.rb +27 -0
  60. data/lib/rbhex/core/include/rhistory.rb +95 -0
  61. data/lib/rbhex/core/include/rinputdataevent.rb +47 -0
  62. data/lib/rbhex/core/include/vieditable.rb +172 -0
  63. data/lib/rbhex/core/include/widgetmenu.rb +66 -0
  64. data/lib/rbhex/core/system/colormap.rb +165 -0
  65. data/lib/rbhex/core/system/keyboard.rb +150 -0
  66. data/lib/rbhex/core/system/keydefs.rb +30 -0
  67. data/lib/rbhex/core/system/ncurses.rb +236 -0
  68. data/lib/rbhex/core/system/panel.rb +162 -0
  69. data/lib/rbhex/core/system/window.rb +913 -0
  70. data/lib/rbhex/core/util/ansiparser.rb +119 -0
  71. data/lib/rbhex/core/util/app.rb +1228 -0
  72. data/lib/rbhex/core/util/basestack.rb +410 -0
  73. data/lib/rbhex/core/util/bottomline.rb +1859 -0
  74. data/lib/rbhex/core/util/colorparser.rb +77 -0
  75. data/lib/rbhex/core/util/focusmanager.rb +31 -0
  76. data/lib/rbhex/core/util/padreader.rb +192 -0
  77. data/lib/rbhex/core/util/rcommandwindow.rb +604 -0
  78. data/lib/rbhex/core/util/rdialogs.rb +574 -0
  79. data/lib/rbhex/core/util/viewer.rb +149 -0
  80. data/lib/rbhex/core/util/widgetshortcuts.rb +506 -0
  81. data/lib/rbhex/core/version.rb +5 -0
  82. data/lib/rbhex/core/widgets/applicationheader.rb +103 -0
  83. data/lib/rbhex/core/widgets/box.rb +58 -0
  84. data/lib/rbhex/core/widgets/divider.rb +310 -0
  85. data/lib/rbhex/core/widgets/keylabelprinter.rb +194 -0
  86. data/lib/rbhex/core/widgets/rcombo.rb +253 -0
  87. data/lib/rbhex/core/widgets/rcontainer.rb +415 -0
  88. data/lib/rbhex/core/widgets/rlink.rb +30 -0
  89. data/lib/rbhex/core/widgets/rlist.rb +696 -0
  90. data/lib/rbhex/core/widgets/rmenu.rb +958 -0
  91. data/lib/rbhex/core/widgets/rmenulink.rb +22 -0
  92. data/lib/rbhex/core/widgets/rmessagebox.rb +387 -0
  93. data/lib/rbhex/core/widgets/rprogress.rb +118 -0
  94. data/lib/rbhex/core/widgets/rtabbedpane.rb +634 -0
  95. data/lib/rbhex/core/widgets/rtabbedwindow.rb +70 -0
  96. data/lib/rbhex/core/widgets/rtextarea.rb +960 -0
  97. data/lib/rbhex/core/widgets/rtextview.rb +739 -0
  98. data/lib/rbhex/core/widgets/rtree.rb +768 -0
  99. data/lib/rbhex/core/widgets/rwidget.rb +3277 -0
  100. data/lib/rbhex/core/widgets/scrollbar.rb +143 -0
  101. data/lib/rbhex/core/widgets/statusline.rb +113 -0
  102. data/lib/rbhex/core/widgets/tabular.rb +264 -0
  103. data/lib/rbhex/core/widgets/tabularwidget.rb +1142 -0
  104. data/lib/rbhex/core/widgets/textpad.rb +995 -0
  105. data/lib/rbhex/core/widgets/tree/treecellrenderer.rb +150 -0
  106. data/lib/rbhex/core/widgets/tree/treemodel.rb +428 -0
  107. data/rbhex-core.gemspec +32 -0
  108. metadata +172 -0
@@ -0,0 +1,74 @@
1
+ # ----------------------------------------------------------------------------- #
2
+ # File: listbindings.rb
3
+ # Description: bindings for multi-row widgets such as listbox, table, textview
4
+ # Author: rkumar http://github.com/rkumar/rbcurse/
5
+ # Date: 2011-12-11 - 12:58
6
+ # License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
7
+ # Last update: 2013-03-25 01:53
8
+ # ----------------------------------------------------------------------------- #
9
+ #
10
+ module RubyCurses
11
+ #
12
+ # bindings for multi-row widgets such as listbox, table, textview
13
+ #
14
+ module ListBindings
15
+ extend self
16
+ def bindings
17
+ $log.debug "XXX: INSIDE LISTBINDING FOR #{self.class} "
18
+ bind_key(Ncurses::KEY_LEFT, 'cursor backward'){ cursor_backward } if respond_to? :cursor_backward
19
+ bind_key(Ncurses::KEY_RIGHT, 'cursor_forward'){ cursor_forward } if respond_to? :cursor_forward
20
+ # very irritating when user pressed up arrow, commented off 2012-01-4 can be made optional
21
+ bind_key(Ncurses::KEY_UP, 'previous row'){ ret = up; } #get_window.ungetch(KEY_BTAB) if ret == :NO_PREVIOUS_ROW }
22
+ # the next was irritating if user wanted to add a row ! 2011-10-10
23
+ #bind_key(Ncurses::KEY_DOWN){ ret = down ; get_window.ungetch(KEY_TAB) if ret == :NO_NEXT_ROW }
24
+ bind_key(Ncurses::KEY_DOWN, 'next row'){ ret = down ; }
25
+
26
+ # this allows us to set on a component basis, or global basis
27
+ # Motivation was mainly for textarea which needs emacs keys
28
+ kmap = @key_map || $key_map || :both
29
+ if kmap == :emacs || kmap == :both
30
+ bind_key(?\C-v, 'scroll forward'){ scroll_forward }
31
+ # clashes with M-v for toggle one key selection, i guess you can set it as you like
32
+ bind_key(?\M-v, 'scroll backward'){ scroll_backward }
33
+ bind_key(?\C-s, 'ask search'){ ask_search() }
34
+ bind_key(?\C-n, 'next row'){ next_row() }
35
+ bind_key(?\C-p, 'previous row'){ previous_row() }
36
+ bind_key(?\M->, 'goto bottom'){ goto_bottom() }
37
+ bind_key(?\M-<, 'goto top'){ goto_top() }
38
+ bind_key([?\C-x, ?>], :scroll_right)
39
+ bind_key([?\C-x, ?<], :scroll_left)
40
+ end
41
+ if kmap == :vim || kmap == :both
42
+ # some of these will not have effect in textarea such as j k, gg and G, search
43
+ bind_key(?j, 'next row'){ next_row() }
44
+ bind_key(?k, 'previous row'){ previous_row() }
45
+ ## added 2013-03-04 - 17:52
46
+ bind_key(?w, 'forward_word'){ forward_word }
47
+ bind_key(?b, 'backward_word'){ backward_word }
48
+ bind_key(?\C-d, 'scroll forward'){ scroll_forward() }
49
+ bind_key(?\C-b, 'scroll backward'){ scroll_backward() }
50
+ bind_key([?g,?g], 'goto start'){ goto_start } # mapping double keys like vim
51
+ bind_key(?G, 'goto end'){ goto_bottom() }
52
+ bind_key([?',?'], 'goto last position'){ goto_last_position } # vim , goto last row position (not column)
53
+
54
+ bind_key(?/, :ask_search)
55
+ bind_key(?n, :find_more)
56
+ bind_key(?h, 'cursor backward'){ cursor_backward } if respond_to? :cursor_backward
57
+ bind_key(?l, 'cursor forward'){ cursor_forward } if respond_to? :cursor_forward
58
+ end
59
+ bind_key(?\C-a, 'start of line'){ cursor_bol } if respond_to? :cursor_bol
60
+ bind_key(?\C-e, 'end of line'){ cursor_eol } if respond_to? :cursor_eol
61
+ bind_key(?\M-l, :scroll_right)
62
+ bind_key(?\M-h, :scroll_left)
63
+
64
+ # save as and edit_external are only in textview and textarea
65
+ # save_as can be given to list's also and tables
66
+ # put them someplace so the code can be shared.
67
+ bind_key([?\C-x, ?\C-s], :saveas)
68
+ bind_key([?\C-x, ?e], :edit_external)
69
+
70
+ # textview also uses space for scroll_forward
71
+ end # def
72
+ end
73
+ end
74
+ include RubyCurses::ListBindings
@@ -0,0 +1,140 @@
1
+ require 'rbhex/core/widgets/rwidget'
2
+ module RubyCurses
3
+
4
+ ##
5
+ # 2010-09-27 11:06 : i have modified this quite a bit, to calculate some stuff
6
+ # once in the init, to reduce work in repaint
7
+ # This is a basic list cell renderer that will render the to_s value of anything.
8
+ # Using alignment one can use for numbers too.
9
+ # However, for booleans it will print true and false. If editing, you may want checkboxes
10
+ # NOTE: this class is being extended by many other classes. Careful while making
11
+ # sweeping changes.
12
+ class ListCellRenderer
13
+ include RubyCurses::ConfigSetup
14
+ include RubyCurses::Utils
15
+ dsl_accessor :justify # :right, :left, :center # added 2008-12-22 19:02
16
+ dsl_accessor :display_length # please give this to ensure the we only print this much
17
+ dsl_accessor :height # if you want a multiline label.
18
+ dsl_accessor :text # text of label
19
+ dsl_accessor :color, :bgcolor
20
+ dsl_accessor :row, :col
21
+ dsl_accessor :parent #usuall the table to get colors and other default info
22
+
23
+ def initialize text="", config={}, &block
24
+ @text = text
25
+ @editable = false
26
+ @focusable = false
27
+ config_setup config # @config.each_pair { |k,v| variable_set(k,v) }
28
+ instance_eval &block if block_given?
29
+ init_vars
30
+ end
31
+ # NOTE: please call super() if you override this
32
+ def init_vars #:nodoc:
33
+ # omg, some classes won't have justify !!
34
+ #@justify ||= (@parent.justify || :left)
35
+ unless @justify
36
+ if @parent.respond_to? :justify
37
+ @justify ||= (@parent.justify || :left)
38
+ else
39
+ @justify ||= :left
40
+ end
41
+ end
42
+ @format = @justify.to_sym == :right ? "%*s" : "%-*s"
43
+ @display_length ||= 10
44
+ # create color pairs once for this 2010-09-26 20:53
45
+ end
46
+ # creates pairs of colors at start
47
+ # since often classes are overriding init_vars, so not gettin created
48
+ def create_color_pairs
49
+ @color_pair = get_color $datacolor
50
+ @pairs = Hash.new(@color_pair)
51
+ @attrs = Hash.new(Ncurses::A_NORMAL)
52
+ color_pair = get_color $selectedcolor, @parent.selected_color, @parent.selected_bgcolor
53
+ @pairs[:normal] = @color_pair
54
+ @pairs[:selected] = color_pair
55
+ @pairs[:focussed] = @pairs[:normal]
56
+ @attrs[:selected] = $row_selected_attr
57
+ @attrs[:focussed] = $row_focussed_attr
58
+
59
+ end
60
+ def getvalue
61
+ @text
62
+ end
63
+ ##
64
+ # sets @color_pair and @attr
65
+ def select_colors focussed, selected
66
+ create_color_pairs unless @pairs
67
+ raise ArgumentError, "pairs hash is null. Changes have happened in listcellrenderer" unless @pairs
68
+ @color_pair = @pairs[:normal]
69
+ #@attr = $row_attr
70
+ @attr = @row_attr || $row_attr # changed 2011-10-15 since we seem to be ignoring row_attr changes
71
+ # give precedence to a selected row
72
+ if selected
73
+ @color_pair = @pairs[:selected]
74
+ @attr = @attrs[:selected]
75
+ elsif focussed
76
+ @color_pair = @pairs[:focussed]
77
+ @attr = @attrs[:focussed]
78
+ end
79
+ end
80
+
81
+ ##
82
+ # paint a list box cell
83
+ #
84
+ # @param [Buffer] window or buffer object used for printing
85
+ # @param [Fixnum] row
86
+ # @param [Fixnum] column
87
+ # @param [Fixnum] actual index into data, some lists may have actual data elsewhere and
88
+ # display data separate. e.g. rfe_renderer (directory listing)
89
+ # @param [String] text to print in cell
90
+ # @param [Boolean, cell focussed, not focussed
91
+ # @param [Boolean] cell selected or not
92
+ def repaint graphic, r=@row,c=@col, row_index=-1,value=@text, focussed=false, selected=false
93
+
94
+ select_colors focussed, selected
95
+ # if listboxes width is reduced, display_len remains the same
96
+ # XXX FIXME parent may not be the list but a container like rfe !!
97
+ # maybe caller should update at start of repain loop.
98
+ #@display_length = @parent.width - 2 - @parent.left_margin
99
+
100
+ value=value.to_s
101
+ if !@display_length.nil?
102
+ if value.length > @display_length
103
+ value = value[0..@display_length-1]
104
+ end
105
+ # added 2010-09-27 11:05 TO UNCOMMENT AND TEST IT OUT
106
+ if @justify == :center
107
+ value = value.center(@display_length)
108
+ end
109
+ end
110
+ len = @display_length || value.length
111
+ #$log.debug " XXX @display_length: #{@display_length}, #{value.length}, L:#{len}, pw:#{@parent.width} ::attr:: #{@attr} "
112
+ graphic.printstring r, c, @format % [len, value], @color_pair, @attr
113
+ end # repaint
114
+
115
+ # @deprecated
116
+ # only for older code that may have extended this.
117
+ def prepare_default_colors focussed, selected
118
+ @color_pair = get_color $datacolor
119
+ @attr = @row_attr || Ncurses::A_NORMAL
120
+
121
+
122
+ ## determine bg and fg and attr
123
+ if selected
124
+ @attr = Ncurses::A_BOLD if selected
125
+ @color_pair =get_color $selectedcolor, @parent.selected_color, @parent.selected_bgcolor unless @parent.nil?
126
+ end
127
+ case focussed
128
+ when :SOFT_FOCUS
129
+ @attr |= Ncurses::A_BOLD
130
+ when true
131
+ @attr |= Ncurses::A_REVERSE
132
+ when false
133
+ end
134
+ #if focussed
135
+ #@attr |= Ncurses::A_REVERSE
136
+ #end
137
+ end
138
+ end # class
139
+
140
+ end # module
@@ -0,0 +1,317 @@
1
+ # Some methods for manipulating lists
2
+ # Different components may bind different keys to these
3
+ # Currently will be called by TextArea and the editable version
4
+ # of TextView (vieditable).
5
+ #
6
+ require 'rbhex/core/include/rinputdataevent'
7
+ module ListEditable
8
+
9
+ def remove_all
10
+ @list = []
11
+ set_modified # added 2009-02-13 22:28 so repaints
12
+ end
13
+ # current behav is a mix of vim's D and C-k from alpine, i don;t know how i screwed it up like this
14
+ # Should be:
15
+ # 1. do not take cursor back by 1 (this is vims D behavior)
16
+ # 2. retain EOL, we need to evaluate at undo
17
+ # 3. if nothing coming in delete buffer then join next line here
18
+ # 4. if line is blank, it will go to delete line (i think).
19
+ # Earlier, a C-k at pos 0 would blank the line and not delete it (copied from alpine).
20
+ # The next C-k would delete. emacs deletes if C-k at pos 0.
21
+ def delete_eol
22
+ return -1 unless @editable
23
+ pos = @curpos -1 # retain from 0 till prev char
24
+ @delete_buffer = @buffer[@curpos..-1]
25
+ # currently eol is there in delete_buff often. Should i maintain it ? 2010-03-08 18:29 UNDO
26
+ #@delete_buffer.chomp! # new 2010-03-08 18:29 UNDO - this worked but hope does not have othe impact
27
+
28
+ # if pos is 0, pos-1 becomes -1, end of line!
29
+ @list[@current_index] = pos == -1 ? "" : @buffer[0..pos]
30
+ $log.debug "delete EOL :pos=#{pos}, #{@delete_buffer}: row: #{@list[@current_index]}:"
31
+ @buffer = @list[@current_index]
32
+ if @delete_buffer == ""
33
+ $log.debug " TA: DELETE going to join next "
34
+ join_next_line # pull next line in
35
+ end
36
+ oldcur = @curpos
37
+ #x cursor_backward if @curpos > 0 # this was vims behavior -- knoecked off
38
+ #fire_handler :CHANGE, self # 2008-12-09 14:56
39
+ fire_handler :CHANGE, InputDataEvent.new(oldcur,oldcur+@delete_buffer.length, self, :DELETE, @current_index, @delete_buffer) # 2008-12-24 18:34
40
+ set_modified
41
+ return @delete_buffer
42
+ end
43
+ def join_next_line
44
+ # return if last line TODO
45
+ buff = @list.delete_at(@current_index + 1)
46
+ if buff
47
+ $log.debug " TA: DELETE inside to join next #{buff} "
48
+ fire_handler :CHANGE, InputDataEvent.new(0,0+buff.length, self, :DELETE_LINE, @current_index+1, buff)
49
+ @buffer << buff
50
+ end
51
+ end
52
+ # deletes given line or current
53
+ # now fires DELETE_LINE so no guessing by undo manager
54
+ def delete_line line=@current_index
55
+ return -1 unless @editable
56
+ if !$multiplier || $multiplier == 0
57
+ @delete_buffer = @list.delete_at line
58
+ else
59
+ @delete_buffer = @list.slice!(line, $multiplier)
60
+ end
61
+ @curpos ||= 0 # rlist has no such var
62
+ $multiplier = 0
63
+ add_to_kill_ring @delete_buffer
64
+ @buffer = @list[@current_index]
65
+ if @buffer.nil?
66
+ up
67
+ setrowcol @row + 1, nil # @form.col
68
+ end
69
+ # warning: delete buffer can now be an array
70
+ fire_handler :CHANGE, InputDataEvent.new(@curpos,@curpos+@delete_buffer.length, self, :DELETE_LINE, line, @delete_buffer) # 2008-12-24 18:34
71
+ set_modified
72
+ @widget_scrolled = true
73
+ @repaint_required = true
74
+ end
75
+ def delete_curr_char num=($multiplier == 0 ? 1 : $multiplier)
76
+ return -1 unless @editable
77
+ delete_at @curpos, num # changed so only one event, and one undo
78
+ set_modified
79
+ $multiplier = 0
80
+ end
81
+ #
82
+ # 2010-03-08 23:30 does not seem to be working well when backspacing at first char of line
83
+ # FIXME should work as a unit, so one undo and one fire_handler, at least if on one line.
84
+ def delete_prev_char num=($multiplier == 0 ? 1 : $multiplier)
85
+ return -1 if !@editable
86
+ num.times do
87
+ if @curpos <= 0
88
+ join_to_prev_line
89
+ return
90
+ end
91
+ @curpos -= 1 if @curpos > 0
92
+ delete_at
93
+ set_modified
94
+ addcol -1
95
+ end
96
+ $multiplier = 0
97
+ end
98
+ # open a new line and add chars to it.
99
+ # FIXME does not fire handler, thus won't undo
100
+ def append_row lineno=@current_index, chars=""
101
+ $log.debug "append row sapce:#{chars}."
102
+ @list.insert lineno+1, chars
103
+ end
104
+ ##
105
+ # delete character/s on current line
106
+ def delete_at index=@curpos, howmany=1
107
+ return -1 if !@editable
108
+ $log.debug "delete_at (characters) : #{@current_index} #{@buffer} #{index}"
109
+ char = @buffer.slice!(@curpos,howmany) # changed added ,1 and take char for event
110
+ # if no newline at end of this then bring up prev character/s till maxlen
111
+ # NO WE DON'T DO THIS ANYLONGER 2008-12-26 21:09 lets see
112
+ =begin
113
+ if @buffer[-1,1]!="\r"
114
+ @buffer[-1]=" " if @buffer[-1,1]=="\n"
115
+ if !next_line.nil? and next_line.length > 0
116
+ move_chars_up
117
+ end
118
+ end
119
+ =end
120
+ set_modified true
121
+ fire_handler :CHANGE, InputDataEvent.new(@curpos,@curpos+howmany, self, :DELETE, @current_index, char) # 2008-12-24 18:34
122
+ end
123
+ def undo_handler(uh)
124
+ @undo_handler = uh
125
+ end
126
+ ## THIS ONE SHOULD BE IN TEXTVIEW ALSO
127
+ # saves current or n lines into kill ring, appending to earlier contents
128
+ # Use yank (paste) or yank-pop to retrieve
129
+ def kill_ring_save
130
+ pointer = @current_index
131
+ list = []
132
+ repeatm {
133
+ line = @list[pointer]
134
+ list << line unless line.nil?
135
+ pointer += 1
136
+ }
137
+ add_to_kill_ring list
138
+ end
139
+ ## THIS ONE SHOULD BE IN TEXTVIEW ALSO
140
+ # add given line or lines to kill_ring
141
+ def add_to_kill_ring list
142
+ # directly referenceing kill_ring. We need to OO it a bit, so we can change internals w'o breaking all.
143
+ # FIXME
144
+ if $append_next_kill
145
+ # user requested this kill to be appened to last kill, so it can be yanked as one
146
+ #$kill_ring.last << list
147
+ last = $kill_ring.pop
148
+ $log.debug "YANK: addto : last= #{last} , list= #{list} "
149
+ case list
150
+ when Array
151
+ #list.insert 0, last
152
+ list.insert 0, *last # 2011-10-10 changed as it was wrong in textarea
153
+ $kill_ring << list
154
+ when String
155
+ $kill_ring << [last, list]
156
+ end
157
+ else
158
+ $kill_ring << list
159
+ end
160
+ $kill_ring_pointer = $kill_ring.size
161
+ $append_next_kill = false
162
+ $log.debug "YANK: kill_ring: #{$kill_ring} "
163
+ end
164
+
165
+ # pastes recent (last) entry of kill_ring.
166
+ # This can be one or more lines. Please note that for us vimmer's yank means copy
167
+ # but for emacsers it seems to mean paste. Aargh!!
168
+ # earlier it was not +1, it was pasting before not after
169
+ def yank where=@current_index+1
170
+ return -1 if !@editable
171
+ return if $kill_ring.empty?
172
+ row = $kill_ring.last
173
+ $log.debug "YANK: row #{row} "
174
+ index = where
175
+ case row
176
+ when Array
177
+ #index = @current_index
178
+ row.each{ |r|
179
+ @list.insert index, r.dup
180
+ index += 1
181
+ }
182
+ $kill_last_pop_size = row.size
183
+ when String
184
+ #@list[@current_index].insert row.dup
185
+ #@list.insert @current_index, row.dup
186
+ @list.insert index, row.dup
187
+ $kill_last_pop_size = 1
188
+ else
189
+ raise "textarea yank got uncertain datatype from kill_ring #{row.class} "
190
+ end
191
+ $kill_ring_pointer = $kill_ring.size - 1
192
+ $kill_ring_index = @current_index # pops will replace data in this row, never an insert
193
+ @repaint_required = true
194
+ @widget_scrolled = true
195
+ # XXX not firing anything here, so i can't undo. yet, i don't know whether a yank will
196
+ # be followed by a yank-pop, in which case it will not be undone.
197
+ # object row can be string or array - time to use INSERT_LINE so we are clear
198
+ # row.length can be array's size or string length - beware
199
+ fire_handler :CHANGE, InputDataEvent.new(0,row.length, self, :INSERT_LINE, @current_index, row)
200
+ return 0 # don't want a UNHANDLED or NO_BLOCK going back
201
+ end
202
+
203
+ # paste previous entries from kill ring
204
+ # I am not totally clear on this, not being an emacs user. but seems you have to do C-y
205
+ # once (yank) before you can do a yank pop.
206
+ def yank_pop
207
+ return -1 if !@editable
208
+ return if $kill_ring.empty?
209
+ mapped_key = @current_key # we are mapped to this
210
+ # checking that user has done a yank on this row. We only replace on the given row, never
211
+ # insert. But what if user edited after yank, Sheesh ! XXX
212
+ if $kill_ring_index != @current_index
213
+ Ncurses.beep
214
+ return # error message required that user must yank first
215
+ end
216
+ # the real reason i put this into a loop is so that i can properly undo the
217
+ # action later if required. I only need to store the final selection.
218
+ # This also ensures the user doesn't wander off in between and come back.
219
+ row = nil
220
+ while true
221
+ # remove lines from last replace, then insert
222
+ index = @current_index
223
+ $kill_last_pop_size.times {
224
+ del = @list.delete_at index
225
+ }
226
+ row = $kill_ring[$kill_ring_pointer-$multiplier]
227
+ $multiplier = 0
228
+ index = @current_index
229
+ case row
230
+ when Array
231
+ row.each{ |r|
232
+ @list.insert index, r.dup
233
+ index += 1
234
+ }
235
+ $kill_last_pop_size = row.size
236
+ when String
237
+ @list.insert index, row.dup
238
+ $kill_last_pop_size = 1
239
+ else
240
+ raise "textarea yank_pop got uncertain datatype from kill_ring #{row.class} "
241
+ end
242
+
243
+ $kill_ring_pointer -= 1
244
+ if $kill_ring_pointer < 0
245
+ # should be size, but that'll give an error. need to find a way!
246
+ $kill_ring_pointer = $kill_ring.size - 1
247
+ end
248
+ @repaint_required = true
249
+ @widget_scrolled = true
250
+ my_win = @form || @parent_component.form # 2010-02-12 12:51
251
+ my_win.repaint
252
+ ch = @graphic.getchar
253
+ if ch != mapped_key
254
+ @graphic.ungetch ch # seems to work fine
255
+ return ch # XXX to be picked up by handle_key loop and processed
256
+ end
257
+ end
258
+ # object row can be string or array - time to use INSERT_LINE so we are clear
259
+ # row.length can be array's size or string length - beware
260
+ fire_handler :CHANGE, InputDataEvent.new(0,row.length, self, :INSERT_LINE, @current_index, row)
261
+ return 0
262
+ end
263
+ def append_next_kill
264
+ $append_next_kill = true
265
+ end
266
+ # deletes count words on current line
267
+ # Does not at this point go beyond the line
268
+ def delete_word
269
+ return -1 unless @editable
270
+ $multiplier = 1 if !$multiplier || $multiplier == 0
271
+ line = @current_index
272
+ pos = @curpos
273
+ @delete_buffer = ""
274
+ # currently only look in current line
275
+ $multiplier.times {
276
+ found = @buffer.index(/[[:punct:][:space:]]/, pos)
277
+ break if !found
278
+ $log.debug " delete_word: pos #{pos} found #{found} buff: #{@buffer} "
279
+ @delete_buffer << @buffer.slice!(pos..found)
280
+ }
281
+ return if @delete_buffer == ""
282
+ $log.debug " delete_word: delbuff #{@delete_buffer} "
283
+ add_to_kill_ring @delete_buffer
284
+ fire_handler :CHANGE, InputDataEvent.new(@curpos,@curpos+@delete_buffer.length, self, :DELETE, line, @delete_buffer) # 2008-12-24 18:34
285
+ set_modified
286
+ end
287
+ ##
288
+ # deletes forward till the occurence of a character
289
+ # it gets the char from the user
290
+ # Should we pass in the character (and accept it as a separate func) ???
291
+ def delete_forward
292
+ return -1 unless @editable
293
+ ch = @graphic.getchar
294
+ return if ch < 0 || ch > 255
295
+ char = ch.chr
296
+ $multiplier = 1 if !$multiplier || $multiplier == 0
297
+ line = @current_index
298
+ pos = @curpos
299
+ tmpbuf = ""
300
+ # currently only look in current line
301
+ $multiplier.times {
302
+ found = @buffer.index(char, pos)
303
+ break if !found
304
+ #$log.debug " delete_forward: pos #{pos} found #{found} buff: #{@buffer} "
305
+ # ideally do this in one shot outside loop, but its okay here for now
306
+ tmpbuf << @buffer.slice!(pos..found)
307
+ }
308
+ return if tmpbuf == ""
309
+ @delete_buffer = tmpbuf
310
+ $log.debug " delete_forward: delbuff #{@delete_buffer} "
311
+ add_to_kill_ring @delete_buffer
312
+ fire_handler :CHANGE, InputDataEvent.new(@curpos,@curpos+@delete_buffer.length, self, :DELETE, line, @delete_buffer) # 2008-12-24 18:34
313
+ set_modified
314
+ $multiplier = 0
315
+ end
316
+
317
+ end # end module