module ListEditable

Public Instance Methods

add_to_kill_ring(list) click to toggle source
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
append_next_kill() click to toggle source
# File lib/canis/core/include/listeditable.rb, line 265
def append_next_kill
  $append_next_kill = true
end
append_row(lineno=@current_index, chars="") click to toggle source

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_at(index=@curpos, howmany=1) click to toggle source

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
delete_curr_char(num=($multiplier == 0 ? 1 : $multiplier)) click to toggle source
# 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
delete_eol() click to toggle source

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:

  1. do not take cursor back by 1 (this is vims D behavior)

  2. retain EOL, we need to evaluate at undo

  3. if nothing coming in delete buffer then join next line here

  4. 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
delete_forward() click to toggle source

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
delete_line(line=@current_index) click to toggle source

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
delete_prev_char(num=($multiplier == 0 ? 1 : $multiplier)) click to toggle source

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
delete_word() click to toggle source

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
join_next_line() click to toggle source
# 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
kill_ring_save() click to toggle source
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
remove_all() click to toggle source
# 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
undo_handler(uh) click to toggle source
# File lib/canis/core/include/listeditable.rb, line 125
def undo_handler(uh)
  @undo_handler = uh
end
yank(where=@current_index+1) click to toggle source

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
yank_pop() click to toggle source

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