module ListEditable
Public Instance Methods
THIS ONE SHOULD BE IN TEXTVIEW ALSO
add given line or lines to kill_ring
# File lib/canis/core/include/listeditable.rb, line 143 def add_to_kill_ring list # directly referenceing kill_ring. We need to OO it a bit, so we can change internals w'o breaking all. # FIXME if $append_next_kill # user requested this kill to be appened to last kill, so it can be yanked as one #$kill_ring.last << list last = $kill_ring.pop $log.debug "YANK: addto : last= #{last} , list= #{list} " case list when Array #list.insert 0, last list.insert 0, *last # 2011-10-10 changed as it was wrong in textarea $kill_ring << list when String $kill_ring << [last, list] end else $kill_ring << list end $kill_ring_pointer = $kill_ring.size $append_next_kill = false $log.debug "YANK: kill_ring: #{$kill_ring} " end
# File lib/canis/core/include/listeditable.rb, line 265 def append_next_kill $append_next_kill = true end
open a new line and add chars to it. FIXME does not fire handler, thus won't undo
# File lib/canis/core/include/listeditable.rb, line 102 def append_row lineno=@current_index, chars="" $log.debug "append row sapce:#{chars}." @list.insert lineno+1, chars end
delete character/s on current line
# File lib/canis/core/include/listeditable.rb, line 108 def delete_at index=@curpos, howmany=1 return -1 if !@editable $log.debug "delete_at (characters) : #{@current_index} #{@buffer} #{index}" char = @buffer.slice!(@curpos,howmany) # changed added ,1 and take char for event # if no newline at end of this then bring up prev character/s till maxlen # NO WE DON'T DO THIS ANYLONGER 2008-12-26 21:09 lets see =begin if @buffer[-1,1]!="\r" @buffer[-1]=" " if @buffer[-1,1]=="\n" if !next_line.nil? and next_line.length > 0 move_chars_up end end =end set_modified true fire_handler :CHANGE, InputDataEvent.new(@curpos,@curpos+howmany, self, :DELETE, @current_index, char) # 2008-12-24 18:34 end
# File lib/canis/core/include/listeditable.rb, line 77 def delete_curr_char num=($multiplier == 0 ? 1 : $multiplier) return -1 unless @editable delete_at @curpos, num # changed so only one event, and one undo set_modified $multiplier = 0 end
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 Should be:
-
do not take cursor back by 1 (this is vims D behavior)
-
retain EOL, we need to evaluate at undo
-
if nothing coming in delete buffer then join next line here
-
if line is blank, it will go to delete line (i think).
Earlier, a C-k at pos 0 would blank the line and not delete it (copied from alpine). The next C-k would delete. emacs deletes if C-k at pos 0.
# File lib/canis/core/include/listeditable.rb, line 23 def delete_eol return -1 unless @editable pos = @curpos -1 # retain from 0 till prev char @delete_buffer = @buffer[@curpos..-1] # currently eol is there in delete_buff often. Should i maintain it ? 2010-03-08 18:29 UNDO #@delete_buffer.chomp! # new 2010-03-08 18:29 UNDO - this worked but hope does not have othe impact # if pos is 0, pos-1 becomes -1, end of line! @list[@current_index] = pos == -1 ? "" : @buffer[0..pos] $log.debug "delete EOL :pos=#{pos}, #{@delete_buffer}: row: #{@list[@current_index]}:" @buffer = @list[@current_index] if @delete_buffer == "" $log.debug " TA: DELETE going to join next " join_next_line # pull next line in end oldcur = @curpos #x cursor_backward if @curpos > 0 # this was vims behavior -- knoecked off #fire_handler :CHANGE, self # 2008-12-09 14:56 fire_handler :CHANGE, InputDataEvent.new(oldcur,oldcur+@delete_buffer.length, self, :DELETE, @current_index, @delete_buffer) # 2008-12-24 18:34 set_modified return @delete_buffer end
deletes forward till the occurence of a character it gets the char from the user Should we pass in the character (and accept it as a separate func) ???
# File lib/canis/core/include/listeditable.rb, line 293 def delete_forward return -1 unless @editable ch = @graphic.getchar return if ch < 0 || ch > 255 char = ch.chr $multiplier = 1 if !$multiplier || $multiplier == 0 line = @current_index pos = @curpos tmpbuf = "" # currently only look in current line $multiplier.times { found = @buffer.index(char, pos) break if !found #$log.debug " delete_forward: pos #{pos} found #{found} buff: #{@buffer} " # ideally do this in one shot outside loop, but its okay here for now tmpbuf << @buffer.slice!(pos..found) } return if tmpbuf == "" @delete_buffer = tmpbuf $log.debug " delete_forward: delbuff #{@delete_buffer} " add_to_kill_ring @delete_buffer fire_handler :CHANGE, InputDataEvent.new(@curpos,@curpos+@delete_buffer.length, self, :DELETE, line, @delete_buffer) # 2008-12-24 18:34 set_modified $multiplier = 0 end
deletes given line or current now fires DELETE_LINE so no guessing by undo manager
# File lib/canis/core/include/listeditable.rb, line 56 def delete_line line=@current_index return -1 unless @editable if !$multiplier || $multiplier == 0 @delete_buffer = @list.delete_at line else @delete_buffer = @list.slice!(line, $multiplier) end @curpos ||= 0 # rlist has no such var $multiplier = 0 add_to_kill_ring @delete_buffer @buffer = @list[@current_index] if @buffer.nil? up setrowcol @row + 1, nil # @form.col end # warning: delete buffer can now be an array fire_handler :CHANGE, InputDataEvent.new(@curpos,@curpos+@delete_buffer.length, self, :DELETE_LINE, line, @delete_buffer) # 2008-12-24 18:34 set_modified # next line being called from textarea which is old style and thus bombs fire_dimension_changed if respond_to? :fire_dimension_changed end
2010-03-08 23:30 does not seem to be working well when backspacing at first char of line FIXME should work as a unit, so one undo and one fire_handler, at least if on one line.
# File lib/canis/core/include/listeditable.rb, line 86 def delete_prev_char num=($multiplier == 0 ? 1 : $multiplier) return -1 if !@editable num.times do if @curpos <= 0 join_to_prev_line return end @curpos -= 1 if @curpos > 0 delete_at set_modified addcol -1 end $multiplier = 0 end
deletes count words on current line Does not at this point go beyond the line
# File lib/canis/core/include/listeditable.rb, line 270 def delete_word return -1 unless @editable $multiplier = 1 if !$multiplier || $multiplier == 0 line = @current_index pos = @curpos @delete_buffer = "" # currently only look in current line $multiplier.times { found = @buffer.index(/[[:punct:][:space:]]/, pos) break if !found $log.debug " delete_word: pos #{pos} found #{found} buff: #{@buffer} " @delete_buffer << @buffer.slice!(pos..found) } return if @delete_buffer == "" $log.debug " delete_word: delbuff #{@delete_buffer} " add_to_kill_ring @delete_buffer fire_handler :CHANGE, InputDataEvent.new(@curpos,@curpos+@delete_buffer.length, self, :DELETE, line, @delete_buffer) # 2008-12-24 18:34 set_modified end
# File lib/canis/core/include/listeditable.rb, line 45 def join_next_line # return if last line TODO buff = @list.delete_at(@current_index + 1) if buff $log.debug " TA: DELETE inside to join next #{buff} " fire_handler :CHANGE, InputDataEvent.new(0,0+buff.length, self, :DELETE_LINE, @current_index+1, buff) @buffer << buff end end
THIS ONE SHOULD BE IN TEXTVIEW ALSO
saves current or n lines into kill ring, appending to earlier contents Use yank (paste) or yank-pop to retrieve
# File lib/canis/core/include/listeditable.rb, line 131 def kill_ring_save pointer = @current_index list = [] repeatm { line = @list[pointer] list << line unless line.nil? pointer += 1 } add_to_kill_ring list end
# File lib/canis/core/include/listeditable.rb, line 9 def remove_all # don't create a new object, other dependents like selection model may suffer 2014-04-08 - 20:00 #@list = [] @list.clear set_modified # added 2009-02-13 22:28 so repaints end
# File lib/canis/core/include/listeditable.rb, line 125 def undo_handler(uh) @undo_handler = uh end
pastes recent (last) entry of kill_ring. This can be one or more lines. Please note that for us vimmer's yank means copy but for emacsers it seems to mean paste. Aargh!! earlier it was not +1, it was pasting before not after
# File lib/canis/core/include/listeditable.rb, line 171 def yank where=@current_index+1 return -1 if !@editable return if $kill_ring.empty? row = $kill_ring.last $log.debug "YANK: row #{row} " index = where case row when Array #index = @current_index row.each{ |r| @list.insert index, r.dup index += 1 } $kill_last_pop_size = row.size when String #@list[@current_index].insert row.dup #@list.insert @current_index, row.dup @list.insert index, row.dup $kill_last_pop_size = 1 else raise "textarea yank got uncertain datatype from kill_ring #{row.class} " end $kill_ring_pointer = $kill_ring.size - 1 $kill_ring_index = @current_index # pops will replace data in this row, never an insert @repaint_required = true @widget_scrolled = true # XXX not firing anything here, so i can't undo. yet, i don't know whether a yank will # be followed by a yank-pop, in which case it will not be undone. # object row can be string or array - time to use INSERT_LINE so we are clear # row.length can be array's size or string length - beware fire_handler :CHANGE, InputDataEvent.new(0,row.length, self, :INSERT_LINE, @current_index, row) return 0 # don't want a UNHANDLED or NO_BLOCK going back end
paste previous entries from kill ring I am not totally clear on this, not being an emacs user. but seems you have to do C-y once (yank) before you can do a yank pop.
# File lib/canis/core/include/listeditable.rb, line 208 def yank_pop return -1 if !@editable return if $kill_ring.empty? mapped_key = @current_key # we are mapped to this # checking that user has done a yank on this row. We only replace on the given row, never # insert. But what if user edited after yank, Sheesh ! XXX if $kill_ring_index != @current_index Ncurses.beep return # error message required that user must yank first end # the real reason i put this into a loop is so that i can properly undo the # action later if required. I only need to store the final selection. # This also ensures the user doesn't wander off in between and come back. row = nil while true # remove lines from last replace, then insert index = @current_index $kill_last_pop_size.times { del = @list.delete_at index } row = $kill_ring[$kill_ring_pointer-$multiplier] $multiplier = 0 index = @current_index case row when Array row.each{ |r| @list.insert index, r.dup index += 1 } $kill_last_pop_size = row.size when String @list.insert index, row.dup $kill_last_pop_size = 1 else raise "textarea yank_pop got uncertain datatype from kill_ring #{row.class} " end $kill_ring_pointer -= 1 if $kill_ring_pointer < 0 # should be size, but that'll give an error. need to find a way! $kill_ring_pointer = $kill_ring.size - 1 end @repaint_required = true @widget_scrolled = true my_win = @form || @parent_component.form # 2010-02-12 12:51 my_win.repaint ch = @graphic.getchar if ch != mapped_key @graphic.ungetch ch # seems to work fine return ch # XXX to be picked up by handle_key loop and processed end end # object row can be string or array - time to use INSERT_LINE so we are clear # row.length can be array's size or string length - beware fire_handler :CHANGE, InputDataEvent.new(0,row.length, self, :INSERT_LINE, @current_index, row) return 0 end