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.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/CHANGELOG +2000 -0
- data/LICENSE +56 -0
- data/README.md +44 -0
- data/examples/abasiclist.rb +179 -0
- data/examples/alpmenu.rb +50 -0
- data/examples/app.sample +19 -0
- data/examples/atree.rb +100 -0
- data/examples/bline.rb +136 -0
- data/examples/common/file.rb +45 -0
- data/examples/data/README.markdown +9 -0
- data/examples/data/brew.txt +38 -0
- data/examples/data/color.2 +37 -0
- data/examples/data/gemlist.txt +60 -0
- data/examples/data/lotr.txt +12 -0
- data/examples/data/ports.txt +136 -0
- data/examples/data/table.txt +37 -0
- data/examples/data/tasks.csv +88 -0
- data/examples/data/tasks.txt +27 -0
- data/examples/data/todo.txt +10 -0
- data/examples/data/todo.txt.bak +10 -0
- data/examples/data/todocsv.csv +28 -0
- data/examples/data/unix1.txt +21 -0
- data/examples/data/unix2.txt +11 -0
- data/examples/dbdemo.rb +502 -0
- data/examples/dirtree.rb +94 -0
- data/examples/newtabbedwindow.rb +100 -0
- data/examples/newtesttabp.rb +92 -0
- data/examples/tabular.rb +146 -0
- data/examples/tasks.rb +178 -0
- data/examples/term2.rb +84 -0
- data/examples/testbuttons.rb +296 -0
- data/examples/testcombo.rb +102 -0
- data/examples/testfields.rb +195 -0
- data/examples/testkeypress.rb +72 -0
- data/examples/testlistbox.rb +170 -0
- data/examples/testmessagebox.rb +140 -0
- data/examples/testprogress.rb +116 -0
- data/examples/testree.rb +106 -0
- data/examples/testwsshortcuts.rb +66 -0
- data/examples/testwsshortcuts2.rb +128 -0
- data/lib/rbhex.rb +6 -0
- data/lib/rbhex/core/docs/index.txt +73 -0
- data/lib/rbhex/core/include/action.rb +80 -0
- data/lib/rbhex/core/include/actionmanager.rb +49 -0
- data/lib/rbhex/core/include/appmethods.rb +214 -0
- data/lib/rbhex/core/include/bordertitle.rb +48 -0
- data/lib/rbhex/core/include/chunk.rb +203 -0
- data/lib/rbhex/core/include/io.rb +553 -0
- data/lib/rbhex/core/include/listbindings.rb +74 -0
- data/lib/rbhex/core/include/listcellrenderer.rb +140 -0
- data/lib/rbhex/core/include/listeditable.rb +317 -0
- data/lib/rbhex/core/include/listscrollable.rb +663 -0
- data/lib/rbhex/core/include/listselectable.rb +271 -0
- data/lib/rbhex/core/include/multibuffer.rb +83 -0
- data/lib/rbhex/core/include/orderedhash.rb +77 -0
- data/lib/rbhex/core/include/ractionevent.rb +73 -0
- data/lib/rbhex/core/include/rchangeevent.rb +27 -0
- data/lib/rbhex/core/include/rhistory.rb +95 -0
- data/lib/rbhex/core/include/rinputdataevent.rb +47 -0
- data/lib/rbhex/core/include/vieditable.rb +172 -0
- data/lib/rbhex/core/include/widgetmenu.rb +66 -0
- data/lib/rbhex/core/system/colormap.rb +165 -0
- data/lib/rbhex/core/system/keyboard.rb +150 -0
- data/lib/rbhex/core/system/keydefs.rb +30 -0
- data/lib/rbhex/core/system/ncurses.rb +236 -0
- data/lib/rbhex/core/system/panel.rb +162 -0
- data/lib/rbhex/core/system/window.rb +913 -0
- data/lib/rbhex/core/util/ansiparser.rb +119 -0
- data/lib/rbhex/core/util/app.rb +1228 -0
- data/lib/rbhex/core/util/basestack.rb +410 -0
- data/lib/rbhex/core/util/bottomline.rb +1859 -0
- data/lib/rbhex/core/util/colorparser.rb +77 -0
- data/lib/rbhex/core/util/focusmanager.rb +31 -0
- data/lib/rbhex/core/util/padreader.rb +192 -0
- data/lib/rbhex/core/util/rcommandwindow.rb +604 -0
- data/lib/rbhex/core/util/rdialogs.rb +574 -0
- data/lib/rbhex/core/util/viewer.rb +149 -0
- data/lib/rbhex/core/util/widgetshortcuts.rb +506 -0
- data/lib/rbhex/core/version.rb +5 -0
- data/lib/rbhex/core/widgets/applicationheader.rb +103 -0
- data/lib/rbhex/core/widgets/box.rb +58 -0
- data/lib/rbhex/core/widgets/divider.rb +310 -0
- data/lib/rbhex/core/widgets/keylabelprinter.rb +194 -0
- data/lib/rbhex/core/widgets/rcombo.rb +253 -0
- data/lib/rbhex/core/widgets/rcontainer.rb +415 -0
- data/lib/rbhex/core/widgets/rlink.rb +30 -0
- data/lib/rbhex/core/widgets/rlist.rb +696 -0
- data/lib/rbhex/core/widgets/rmenu.rb +958 -0
- data/lib/rbhex/core/widgets/rmenulink.rb +22 -0
- data/lib/rbhex/core/widgets/rmessagebox.rb +387 -0
- data/lib/rbhex/core/widgets/rprogress.rb +118 -0
- data/lib/rbhex/core/widgets/rtabbedpane.rb +634 -0
- data/lib/rbhex/core/widgets/rtabbedwindow.rb +70 -0
- data/lib/rbhex/core/widgets/rtextarea.rb +960 -0
- data/lib/rbhex/core/widgets/rtextview.rb +739 -0
- data/lib/rbhex/core/widgets/rtree.rb +768 -0
- data/lib/rbhex/core/widgets/rwidget.rb +3277 -0
- data/lib/rbhex/core/widgets/scrollbar.rb +143 -0
- data/lib/rbhex/core/widgets/statusline.rb +113 -0
- data/lib/rbhex/core/widgets/tabular.rb +264 -0
- data/lib/rbhex/core/widgets/tabularwidget.rb +1142 -0
- data/lib/rbhex/core/widgets/textpad.rb +995 -0
- data/lib/rbhex/core/widgets/tree/treecellrenderer.rb +150 -0
- data/lib/rbhex/core/widgets/tree/treemodel.rb +428 -0
- data/rbhex-core.gemspec +32 -0
- 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
|