rbhex-core 1.0.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.
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