Funny IO.select behaviour

I’ve been debugging my full screen console ruby editor.

Suddenly, for no apparent reason, I’m starting to get

(a) random quits while typing. espically when pressing “t”.

(b) Select:Interrupt while typing.

This didn’t used to happen. The line it is dying at is…

if select(@in_io],nil,nil,1)

very strange, and frustrating! This is on linux…

ruby version…

1.8.6 (2007-09-24 patchlevel 111) [i686-linux]

I’m willing to post the whole thing, as long as I don’t get too much
abuse for it not being very well coded. It’s a work in progress.

Hi,

In message “Re: Funny IO.select behaviour”
on Tue, 25 May 2010 22:15:45 +0900, Dennis N.
[email protected] writes:

|This didn’t used to happen. The line it is dying at is…
|
| if select(@in_io],nil,nil,1)
|
|very strange, and frustrating! This is on linux…

I feel sympathy, but above code snippet help us nothing. If you need
help from the list, you’d better disclose everything, to reproduce the
problem, no matter how bad your code is right now.

          matz.

Dennis N. wrote:

1.8.6 (2007-09-24 patchlevel 111) [i686-linux]

Can you try upgrading to the latest 1.8.6 or 1.8.7? IIRC there were a
lot of changes to threading somewhere in the 1.8.6 patchlevels. Or it
could be something else…

On Tue, May 25, 2010 at 5:23 PM, Joel VanderWerf
[email protected] wrote:

Dennis N. wrote:

1.8.6 (2007-09-24 patchlevel 111) [i686-linux]

Can you try upgrading to the latest 1.8.6 or 1.8.7? IIRC there were a lot of
changes to threading somewhere in the 1.8.6 patchlevels. Or it could be
something else…

I thought about that. I’m kind of nervous about doing that, because
the ruby BBS I wrote didn’t like 1.8.7. It used to get segfaults.

I think you might be on to something. I don’t think I’m doing
something wrong, it just ain’t pretty.


I know a mouse
And he hasn’t got a house
I don’t know why
I call him Gerald
He’s getting rather old
But he’s a good mouse

  • Syd Barrett

On Tue, May 25, 2010 at 8:57 PM, Dennis N. [email protected]
wrote:

On Tue, May 25, 2010 at 5:23 PM, Joel VanderWerf

Can you try upgrading to the latest 1.8.6 or 1.8.7? IIRC there were a lot of
changes to threading somewhere in the 1.8.6 patchlevels. Or it could be
something else…

Martin (my partner in crime) has tried it for me on 1.8.7 and 1.9.1
and it doesn’t work right on those either.

What’s odd is, I haven’t changed that part of the program, and it
worked fine before.

I know a mouse
And he hasn’t got a house
I don’t know why
I call him Gerald
He’s getting rather old
But he’s a good mouse

  • Syd Barrett

No takers I guess. Code must be worse than I thought… (;


I know a mouse
And he hasn’t got a house
I don’t know why
I call him Gerald
He’s getting rather old
But he’s a good mouse

  • Syd Barrett

Hi,

In message “Re: Funny IO.select behaviour”
on Thu, 27 May 2010 22:26:16 +0900, Dennis N.
[email protected] writes:

|No takers I guess. Code must be worse than I thought… (;

I think the problem was ill indented (and wrongly wrapped) code. It’s
quite tough to re-indent the whole lines of code. I was too busy.
Also, the instruction to reproduce the error is sought.

          matz.

On Thu, May 27, 2010 at 3:23 PM, Yukihiro M. [email protected]
wrote:

Hi,

In message “Re: Funny IO.select behaviour”
on Thu, 27 May 2010 22:26:16 +0900, Dennis N. [email protected] writes:

|No takers I guess. Code must be worse than I thought… (;

I think the problem was ill indented (and wrongly wrapped) code. It’s
quite tough to re-indent the whole lines of code. I was too busy.
Also, the instruction to reproduce the error is sought.

What can I do to help? I’m certianly not demanding… just asking. (;


I know a mouse
And he hasn’t got a house
I don’t know why
I call him Gerald
He’s getting rather old
But he’s a good mouse

  • Syd Barrett

On Tue, May 25, 2010 at 2:23 PM, Yukihiro M. [email protected]
wrote:

I feel sympathy, but above code snippet help us nothing. If you need
help from the list, you’d better disclose everything, to reproduce the
problem, no matter how bad your code is right now.

But Matz, my Ruby is real bad. It looks like my Pascal did. I never
did manage to get my head around this new fangled stuff. I’m 41, and
i learned to program when i was about 10, on a pdp 11. Anyway, I’m
getting off topic. Did I thank you for this wonderful language.
Anyway, here goes… these are the two main files…

fsed.rb (Poor Dossy)

Full Screen EDitor (FSED) for QUARKware QBBS.

Copyright (C) 2002, Dossy [email protected]

All rights reserved.

$Id: fsed.rb,v 1.1 2002/09/12 12:27:16 dossy Exp $

module Editors
module FSED
VERSION = “0.75”
ESC = 27.chr
RETURN = 10.chr

class Buffer
  def initialize(max_lines,in_file)
    @buffer = getfile(in_file)
    @max_lines = max_lines
  end

  def []=(x, y, value)
    if @buffer[y - 1] == nil
      @buffer[y - 1] = []
    end
    @buffer[y - 1][x - 1] = value
  end

  def [](x, y)
    if @buffer[y - 1].nil?
      nil
    else
      @buffer[y - 1][x - 1]
    end
  end

  def clear
    @buffer = []
  end

def length
@buffer.length
end

  def delete_at(x, y)
    unless @buffer[y - 1].nil?

@buffer[y - 1].slice!(x - 1) # used to use delete_at but that
didn’t always work.
end
end

  def insert_at_line(y,x,in_str)
   inthing = nil
   if !in_str.nil? then
    in_str.each_with_index {|c,i| @buffer[y-1].insert(x+ i,c)}
   end
  end

  def insert_line_at(y,ln)
   @buffer[y] = []  if @buffer[y] == nil
   @buffer.insert(y,ln)
 end

 def delete_line_at(y)
   @buffer.delete_at(y - 1)
 end

 def buffer_length

  return @buffer.length
 end


 def length_y(y)
   if !@buffer[y - 1].nil?
    return @buffer[y - 1].length
   else
    return 0
   end
 end

def del_range(y,x1,x2)
 total = x2 - x1
 str = @buffer[y-1].slice!(-(total),total)
 return str
end

  def insert_char(x, y, value)
   @buffer[y - 1] = []  if @buffer[y - 1] == nil
    if (x-1) > @buffer[y-1].length then
@buffer[y-1] << value

else
@buffer[y - 1].insert(x-1,value)
end
end

def find_first_space(y)
   return @buffer[y-1].index(" ")
end

def find_nearest_space(y,space)
   result = nil
   @buffer[y - 1] = [] if @buffer[y - 1].nil?
   highest = 0
  @buffer[y-1].each_with_index {|c,i|
           highest = i
           result = i   if (c == " ") and (i <= space)
           }
   result= highest if highest <= space
  return result
end

 def paragraph_up(start_y,width)

   for i in [email protected] #- 1

break if @buffer[i,0].nil?
pos = length_y(i-1)
space = width - pos #how much space on the line above?
unwrap_space = find_nearest_space(i,space)
break if unwrap_space.nil? or unwrap_space == 0
unwrap_str = del_range(i,0,unwrap_space+1)
insert_at_line(i - 1,pos,unwrap_str)
end
end

def detect_and_wrap(y,x,width)
  l_space = 0; wrap = nil
  @buffer[y - 1] = [] if @buffer[y - 1].nil?
  l  = @buffer[y-1].length - 1
  test = @buffer[y-1]

  if !@buffer[y-1][width].nil? then #is there now a character past 

max_width
test.slice!(-1) if test.last == " "
l_space = test.rindex(’ ')
wrap = @buffer[y-1][l_space…l]
del_range(y,l_space+1,l+1)
return [l_space,wrap]
end
end

  def line(line)
    if !@buffer[line - 1].nil? then  #protect against backspace on

an empty line – produces a nil
@buffer[line - 1].collect { |char|
if char.nil?
" "
else
char
end
}.to_s.chomp
end
end

 def buff_out
      @buffer.collect { |line|
      if line.nil?
        "\n"
      else
        [ line.collect { |char|
          if char.nil?
            " "
          else
            char
          end
        }, "\n" ].to_s
      end
    }
  end


 def dump
      @buffer.collect { |line|
      if line.nil?
        "\n"
      else
        [ line.collect { |char|
          if char.nil?
            " "
          else
            char
          end
        }, "\n" ].to_s
      end
    }.to_s.chomp
  end

def display

i = 0

@buffer.collect { |line| i = i + 1

#      if line.nil?
  #      "#{i}: \n"
    #  else
     #   "#{i}: " << [  line.collect { |char|
      #    if char.nil?
       #     " "
       #   else
      #      char
      #    end
     #   }, "\n" ].to_s
   #   end
  #  }.to_s.chomp

#end

 def to_s(top_start,vp_height)

 out = String.new
 top_stop = @buffer.length - 1
 top_stop = vp_height + top_start - 1 if @buffer.length - 1 >=

vp_height + top_start

   for i in top_start..top_stop
    one_line = @buffer[i].to_s
    out = out+ one_line + "\n"
    end
    out
  end

def room_on_line(y,str,width)

room = false

if !@buffer[y].nil?

if !str.nil? then
room = true if (@buffer[y].length - 1) + str.length < width
end
end
return room
end

def getfile(filename)

file_array = []
if !filename.nil? then
#this used to use chars.to_a but it didn’t always work right
if File.exists?(filename)
IO.foreach(filename) { |line|
line.gsub!(“\n”,“”)
line.gsub!(“\r”,“”)
build = []
for i in 0…line.length-1
build << line[i].chr
end
file_array << build}
end
end
puts
file_array
end

end

class EditorState
  attr_reader :current_cursor_position, :previous_cursor_position
  attr_reader :screen_width, :screen_height
  attr_reader :viewport_width, :viewport_height
  attr_reader :header_height
  attr_reader :buffer

  def initialize(width, height,in_file)
    @dirty = true
    @current_cursor_position = [1, 1]
    @previous_cursor_position = [1, 1]
    @screen_width = width
    @screen_height = height
    @buffer = Buffer.new(500,in_file)
    @buffer_top = 0

    @header_height = 2
    @viewport_width = @screen_width
    @viewport_height = @screen_height - @header_height
    @wrapped = false

@insert = true

    open_error_log
  end

  require "windows.rb"

  def open_error_log
    $lf = File.new("debug.txt", File::CREAT|File::TRUNC|File::RDWR, 
  1. end

    def current_x
    @current_cursor_position[0]
    end

    def current_y
    @current_cursor_position[1]
    end

    def place_cursor(x, y)
    @previous_cursor_position = @current_cursor_position
    @current_cursor_position = [x, y]
    @dirty = true
    end

    def move_cursor_up(x)
    result = NO_REDRAW
    new_y = current_y - x
    if new_y < 1 then
    new_y = 1
    @buffer_top -=x if @buffer_top > 0
    result = REDRAW
    end
    place_cursor(current_x, new_y)
    return result
    end

    def page_up
    redraw = move_cursor_up(@viewport_height)
    return redraw
    end

    def move_cursor_down(x)
    result = NO_REDRAW
    new_y = current_y + x
    @wrapped = false
    if new_y >=@viewport_height then
    new_y = (current_y)
    @buffer_top += x
    result = REDRAW
    end
    place_cursor(current_x, new_y)
    return result
    end

    def page_down
    down = @buffer.buffer_length - (current_y+ @buffer_top)
    if down > @viewport_height then
    redraw = move_cursor_down(@viewport_height)
    return redraw
    else
    return NO_REDRAW
    end
    end

    def move_cursor_left(x)
    new_x = current_x - x
    new_x = 1 if new_x < 1
    place_cursor(new_x, current_y)
    end

    def home_cursor
    place_cursor(1,current_y)
    end

    def move_cursor_right(x)
    new_x = current_x + x
    new_x = @viewport_width if new_x > @viewport_width
    place_cursor(new_x, current_y)
    end

def end_cursor
end_line = @buffer.length_y(current_y)+1
end_line = @viewport_width if end_line > @viewport_width
place_cursor(end_line,current_y)
end

def clear_screen
“#{ESC}[2J#{ESC}[H#{ESC}[00m”
end

def toggle_ins
@insert = !@insert
end

def parse_c(line)
COLORTABLE.each_pair {|color, result| line.gsub!(color,result) }
return line
end

def header
out_str = “INS”
out_str = “OVR” if !@insert
out = String.new
out << parse_c(“%WQuark%YEDIT #{VERSION}%W”.fit(79)) +“\n”
out << parse_c(“%YCTRL + e%YX%Wit %Y|%W %YG%W Help %Y|%W %YS%Wave
%Y|%W %YN%Wewline %Y|%W %YY%W Delete %Y|%W #{out_str} %Y|%W Line:
#{current_y + @buffer_top}”.fit(79)) << “\n”
out << bg(“black”) << fg(“WHITE”)
return out
end

  def redraw(force)
    @dirty = true if force
    if @dirty
      @dirty = false
      if force
        [clear_screen,
        header,
        buffer.to_s(@buffer_top,@viewport_height),
        update_cursor_position].to_s
      else
        ""
      end
    else
      ""
    end
  end

  def clear
    @buffer.clear
  end

this is complicated… too complicated…

  def input_char_at_cursor(c)
   if @insert then                                        #we are

in insert mode
@buffer.insert_char(current_x,(current_y) + @buffer_top,c)
l_space,wrap =
@buffer.detect_and_wrap(current_y,current_x,@screen_width - 1)
if !wrap.nil? then
if !(current_x < @buffer.length_y(current_y) - 1) then
#no wrap… insert a character
if (current_x + wrap.length) < @screen_width then
move_cursor_right(1)
return [c,NO_REDRAW]
else
#wrap at insert at end of line
@buffer.insert_line_at(current_y,wrap.to_s.strip!)
home_cursor
move_cursor_right(wrap.length - 1)
move_cursor_down(1)
end
$lf.print “I’m here…wrap line\n”
return [nil,REDRAW] #we don’t want a character
printed because we are in overflow
end

  $lf.print "@buffer.length + wrap.length:

#{@buffer.length_y(current_y) +(wrap.length + 2)}\n"
$lf.print “@screen_width: #{@screen_width}\n”
$lf.print “room on line: #{@buffer.room_on_line(current_y +
1,wrap,@screen_width)}\n”
$lf.print “@buffer.length: #{@buffer.length}\n”
if (@buffer.length_y(current_y) + (wrap.length + 2)) >=
@screen_width then #wrap for insert not at end of line
$lf.print “in insert not at end of line…\n”
if @buffer.room_on_line(current_y + 1,wrap,@screen_width) then

  @buffer.insert_at_line(current_y+1,0,wrap)  #subsequent words go

to next line

  $lf.print "on next existing line...\n"
 else

   @buffer.insert_line_at(current_y,wrap) #out of room so make a new 

line

   $lf.print "on a new line...\n"
 end
        move_cursor_right(1)
        $lf.print "done with insert before line\n"
        return [c,REDRAW]
      end
     end
    move_cursor_right(1)  #redraw because we are inserting...
    if (@buffer.length_y(current_y)+1) == current_x then
     return [c,NO_REDRAW]     #insert mode at eol so no redraw
    else
   return [c,REDRAW] #insert mode not at eol, so redraw
  end

else
if current_x < @screen_width then
@buffer[current_x,(current_y) + @buffer_top] = c #we are in
over-write mode…
move_cursor_right(1)
$lf.print “Overwrite Mode\n”
return [c,NO_REDRAW]
else
$lf.print “I’m here…sixth return\n”
return [nil,NO_REDRAW]
end
end
end

def newline

if @buffer.length_y(current_y) == 0 then
@buffer.insert_line_at(current_y,nil)
move_cursor_down(1)
else
str =
@buffer.del_range(current_y,current_x-1,@buffer.length_y(current_y))
@buffer.insert_line_at(current_y,str)
move_cursor_left(current_x)
move_cursor_down(1)
end
@dirty = true
end

def deleteline
@buffer.delete_line_at(current_y)
end

def backspace
if current_x > 1 then #normal delete,
not at BOL
move_cursor_left(1)
@buffer.delete_at(current_x, current_y)
else
if current_y > 1 then # delete at BOL
if @buffer.length_y(current_y-1) == 0 then #blank line above
@buffer.delete_line_at(current_y-1)
move_cursor_up(1)
else
@buffer.paragraph_up(current_y,@screen_width) #move up until you
hit a blank line…
move_cursor_up(1)
home_cursor
move_cursor_right(@buffer.length_y(current_y))
end
return REDRAW
end
end
return REDRAW
end

def update_cursor_position
“#{ESC}[#{current_y + @header_height};#{current_x}H”
end

def w_update_cursor(x,y)
“#{ESC}[#{y + @header_height};#{x}H”
end

def w_clear
return @c.reset
end

def fg(forground)

out = String.new

case forground
  when "red"
   out =  "e[31m"
  when "RED"
   out  = "e[;1;31m"
  when "green"
   out << "e[32m"
  when "GREEN"
   out = "e[;1;32m"
  when "blue"
   out  = "e[34m"
  when "BLUE"
   out = "e[;1;34m"
  when "cyan"
   out = "e[36m"
  when "CYAN"
   out = "e[;1;36m"
  when "magenta"
   out = "e[35m"
  when "MAGENTA"
   out = "e[;1;35m"
  when "yellow"
   out = "e[33m"
  when "YELLOW"
   out = "e[;1;33m"
  when "black"
   out = "e[30m"
  when "BLACK"
   out = "e[;1;30m"
   when "hide"
    out = "e[?25l"
   when "show"
    out = "e[?25h"
   when "reset"
    out = "e[0m"

  end

return out
end

def bg(background)

out = String.new

case background
  when "red"
   out =  "e[41m"
  when "green"
   out = "e[42m"
  when "blue"
   out  = "e[44m"
  when "cyan"
   out = "e[46m"
  when "magenta"
   out = "e[45m"
  when "yellow"
   out = "e[43m"
  when "black"
   out = "e[40m"
  when "white"
   out = "e[47m"
  end

return out
end

def center(string,width,color)
result = String.new
outdash = ((width / 2 ) - (string.length / 2))
outdash.times {result << " "}
result << color if !color.nil?
result << string
(width - (outdash + string.length)).times {result << " "}
return result
end

def
make_window(startx,starty,width,height,forground,background,border,title)

f_color = fg(forground)
b_color = bg(background)
bdr_color = bg(border)
window = String.new

window << w_update_cursor(startx,starty)
window << bdr_color
window << center(title,width,nil)
for i in 1…height do
window << w_update_cursor(startx,starty+i)
window << bdr_color << " " << b_color
(width - 2).times {window << " "}
window << bdr_color << " "
window << bg(“white”) << " "
end
window << w_update_cursor(startx,starty+height) << bdr_color
width.times {window << " "}
window << w_update_cursor(startx+1,starty+height+1) << bg(“white”)
width.times {window << " "}
window << w_update_cursor(startx,starty)

return window
end

def help_window

idt = 16
str = 5
width=58
out = make_window(str,2,60,12,“BLACK”,“cyan”,“blue”,“Help Window”)
out << w_update_cursor(idt,str) << fg(“yellow”) << bg(“cyan”)
out << “CTRL-A” << fg(“white”) << " Abort Message"
out << w_update_cursor(idt,str+1) << fg(“yellow”)
out << “CTRL-L” << fg(“white”) << " Refresh Screen"
out << w_update_cursor(idt,str+2) << fg(“yellow”)
out << “CTRL-N” << fg(“white”) << " New Line"
out << w_update_cursor(idt,str+3) << fg(“yellow”)
out << “CTRL-X” << fg(“white”) << " Save (Post) Message"
out << w_update_cursor(idt,str+4) << fg(“yellow”)
out << “CTRL-Y” << fg(“white”) << " Delete Line"
out << w_update_cursor(idt,str+6) << fg(“yellow”)
out << “INSERT” << fg(“white”) << " Toggle Insert/Overwrite"
out << w_update_cursor(idt,str+8)
out << “ESC to exit this window.” << fg(“white”)
end

def splash_window

idt = 15
str = 8
width = 38
out = make_window(idt-1,str-1,40,8,“WHITE”,“magenta”,“cyan”,“About”)
out << w_update_cursor(idt,str+1) <<fg(“yellow”) << bg(“magenta”)
out << center(“QUARKedit #{VERSION}”,width,fg(“white”))
out << w_update_cursor(idt,str+3)
out << center(“By Dossy and Mark F.”,width,fg(“white”))
out <<w_update_cursor(idt+36,str+7)
#out << fg(“hide”)
end

def yes_no_window(question)
idt = 11
str = 10
w_width = question.length + 14
width = w_width - 2
out =
make_window(idt-2,str-1,w_width,4,“WHITE”,“red”,“yellow”,“Confirm”)
out << w_update_cursor(idt+1,str+1)
out << fg(“WHITE”) << bg(“red”)
out << question << "(Y,n): "
end

def screen_clear # I don’t know why. Needs two redraws or the
background color is wrong…
out = redraw(true)
out << redraw(true)
return out
end

end #of class

class Editor

  #Window Constants
  MESSAGE = 1
  ABORT     = 2
  SAVE       = 3
  SPELL      = 4

  def initialize(width, height, in_io, out_io,in_file,bbs_mode)
    @state = EditorState.new(width, height,in_file)
    @in_io  = in_io
    @out_io    = out_io

@w_mode = false
@w_type = MESSAGE
@supress = false
@bbs_mode = bbs_mode
end

  def run
    @out_io.sync = true
    @in_io.sync = false

@out_io.print @state.screen_clear
@out_io.print @state.redraw(true)
@out_io.print @state.splash_window
sleep(1)
@out_io.print @state.redraw(true)
@out_io.print @state.redraw(true)
buf = nil

    while true

    if select([@in_io], nil, nil, 1)
     $lf.print "I made it"


    c = @in_io.sysread(1)

$lf.print “after sysread”
#c = @in_io.getc
# $lf.print"c: #{c}\n"
# $lf.print"c-chr: #{c[0]}\n"

if @supress then # if we are suppressing the mysterious

extra linefeed… we do that here.
# @supress = false

c = 0.chr if c.bytes.to_a[0] = 10

end

     if @w_mode then    #We are in window mode, not edit mode...
       # $lf.print "in wmode\n"
        #$lf.print "c: #{c.upcase}"

      case c
       when "\e"      #effectively, esc this is cancel for 

everything
@w_mode = false
@out_io.print @state.screen_clear
else

       case @w_type
          when ABORT,SAVE
            if c.upcase == "Y" or c == RETURN then
 print "Y"
             @state.clear if @w_type == ABORT
             @state.clear_screen
            sleep(2)
             break
            else
             @out_io.print @state.screen_clear
             @w_mode = false
           end
        end
      end


else
  case c
  when "\cX" # exit

@out_io.print @state.yes_no_window(“Post message… Are you sure?”)
@w_type = SAVE
@w_mode = true
when “\cG”,“\eOP”
@out_io.print @state.help_window
@w_type = MESSAGE
@w_mode = true
when “\cA”
@out_io.print @state.yes_no_window(“Abort message… Are you sure?”)
@w_type = ABORT
@w_mode = true
when “\cN” #insert line
@state.newline
@out_io.print @state.redraw(true)
when “\cY” #delete line
@state.deleteline
@out_io.print @state.redraw(true)
when “\cL” # refresh
@out_io.print @state.redraw(true)
when “\r”,“\n”
@state.newline
@supress = true if @bbs_mode #telnet seems to like to echo
linefeeds. lets supress this …
@out_io.print @state.redraw(true)
when “\010”, “\177”
redraw = @state.backspace
@out_io.print “\e[#{@state.current_y +
@state.header_height};1H\e[K”
@out_io.print @state.buffer.line(@state.current_y)
@out_io.print @state.update_cursor_position
@out_io.print @state.redraw(true) if redraw
when “\e” # escape
buf = c
else
if buf.nil?
chr = c.unpack(“c”)[0]
if (chr >= 32 && chr <= 127)
out_c,redraw = @state.input_char_at_cursor(c)
@out_io.putc(out_c) if !out_c.nil?
@out_io.print @state.redraw(true) if redraw
end
else
buf << c
# $lf.print “buf: #{buf}\n”
case buf
when “\e[H”,“\e[1”
@state.home_cursor
@out_io.print @state.update_cursor_position
when “\e[F”,“\e[4”
@state.end_cursor
@out_io.print @state.update_cursor_position
when “\e[6”
redraw = @state.page_down
@out_io.print @state.redraw(true) if redraw
when “\e[5”
redraw = @state.page_up
@out_io.print @state.redraw(true) if redraw
when “\e[2”
@state.toggle_ins
@out_io.print @state.redraw(true)
when “\e[A”
redraw = @state.move_cursor_up(1)
if redraw
@out_io.print @state.redraw(true)
else
@out_io.print @state.update_cursor_position
end
buf = nil
when “\e[B”
redraw = @state.move_cursor_down(1)
if redraw
@out_io.print @state.redraw(true)
else
@out_io.print @state.update_cursor_position
end
buf = nil
when “\e[D”
@state.move_cursor_left(1)
@out_io.print @state.update_cursor_position
buf = nil
when “\e[C”
@state.move_cursor_right(1)
@out_io.print @state.update_cursor_position
buf = nil
else
if buf.size >= 3
buf = nil
end
end
end
end
end
end
end
@state.buffer

end

end

end

end

file edit.rb:

require ‘fsed’
require “tools.rb”
#require “raspell”

#Consts

SPELL_CHECK = true #if you don’t want raspell, comment out the
require above.

COLORTABLE = {
‘%R’ => “\e[;1;31;44m”, ‘%G’ => “\e[;1;32;44m”,
‘%Y’ => “\e[;1;33;44m”, ‘%B’ => “\e[;1;34;44m”,
‘%M’ => “\e[;1;35;44m”, ‘%C’ => “\e[;1;36;44m”,
‘%W’ => “\e[;1;37;44m”, ‘%r’ => “\e[;31;44m”,
‘%g’ => “\e[;32;44m”, ‘%y’ => “\e[;33;44m”,
‘%b’ => “\e[;34;44m”, ‘%m’ => “\e[;35;44m”,
‘%c’ => “\e[;36;44m”, ‘%w’ => “\e[;31;44m”
}

REDRAW = true
NO_REDRAW = false

def tcgetattr(io)
_TCGETA = 0x5405
attr = [0, 0, 0, 0].pack(“SSSS”)
io.ioctl(_TCGETA, attr)
attr
end

def tcsetattr(io, attr)
_TCSETA = 0x5406
io.ioctl(_TCSETA, attr)
end

def writefile (filename,array)

lf = File.new(filename, File::WRONLY|File::TRUNC|File::CREAT, 0644)
array.each {|x|
print “.”
lf.puts x}
lf.close
puts
end

def pull_apart_args(args)

bbs_mode = false
filename = nil
if !args.nil then
filename = args.last
args.each {|arg| bbs_mode = true if arg == “-L”
#put more switches here
}
end
return [bbs_mode,filename]
end

begin
unless RUBY_PLATFORM =~ /mswin32/
# turn off stdin buffering and echo

# c_iflag bits
INLCR  = "0000100".to_i
IGNCR  = "0000200".to_i
ICRNL  = "0000400".to_i

# c_oflag bits
OPOST  = "0000001".to_i

# c_lflag bits
ISIG   = "0000001".to_i
ICANON = "0000002".to_i
ECHO   = "0000010".to_i

old_attr = tcgetattr($stdin)
input, output, control, local = old_attr.unpack("SSSS")
# input &= ~(INLCR | IGNCR | ICRNL)
# output &= ~OPOST
#local &= ~(ECHO | ICANON | ISIG)
local &= ~(ECHO)
new_attr = [input, output, control, local].pack("SSSS")
tcsetattr($stdin, new_attr)

end

bbs_mode,in_file = pull_apart_args(ARGV)
puts “bbsmode: #{bbs_mode}”
sleep(2)
editor = Editors::FSED::Editor.new(80, 23, STDIN.to_io,
$>.to_io,in_file,bbs_mode)

buffer = editor.run

if bbs_mode then

$lf.print “writing file…\n”
writefile(in_file,buffer.buff_out)
$lf.print “file written…\n”
#end
ensure
unless RUBY_PLATFORM =~ /mswin32/
tcsetattr($stdin, old_attr)
end
end


I know a mouse
And he hasn’t got a house
I don’t know why
I call him Gerald
He’s getting rather old
But he’s a good mouse

  • Syd Barrett

Hi,

In message “Re: Funny IO.select behaviour”
on Thu, 27 May 2010 23:24:33 +0900, Dennis N.
[email protected] writes:

|On Thu, May 27, 2010 at 3:23 PM, Yukihiro M. [email protected] wrote:
|> Hi,
|>
|> In message “Re: Funny IO.select behaviour”
|> on Thu, 27 May 2010 22:26:16 +0900, Dennis N. [email protected] writes:
|>
|> |No takers I guess. Code must be worse than I thought… (;
|>
|> I think the problem was ill indented (and wrongly wrapped) code. It’s
|> quite tough to re-indent the whole lines of code. I was too busy.
|> Also, the instruction to reproduce the error is sought.
|
|What can I do to help? I’m certianly not demanding… just asking. (;

Probably your MUA wraps lines and modifies indentation, so attach the
code to your mail. Plus, instruction to reproduce the error is
preferable (command line options, key strokes, etc).

          matz.

On 5/27/10, Dennis N. [email protected] wrote:

What can I do to help? I’m certianly not demanding… just asking. (;

If you can boil the problem down to 10 lines of code or less, I’m sure
that would help too. I know this isn’t always easy…

On Thu, May 27, 2010 at 3:54 PM, Caleb C. [email protected]
wrote:

On 5/27/10, Dennis N. [email protected] wrote:

If you can boil the problem down to 10 lines of code or less, I’m sure
that would help too. I know this isn’t always easy…

That is one of the issues. I can’t. Getting random QUITs doesn’t
help, and getting an error on the select doesn’t tell me much either.
I can’t see any reason for the issue. It used to work fine, until I
started cleaning up some of the horrible bits, and fixed (well mostly)
the word wrapping routines.

Very odd. I’m baffled.


I know a mouse
And he hasn’t got a house
I don’t know why
I call him Gerald
He’s getting rather old
But he’s a good mouse

  • Syd Barrett

On Thu, May 27, 2010 at 8:29 PM, Dennis N. [email protected]
wrote:

That is one of the issues. I can’t. Getting random QUITs doesn’t
help, and getting an error on the select doesn’t tell me much either.
I can’t see any reason for the issue. It used to work fine, until I
started cleaning up some of the horrible bits, and fixed (well mostly)
the word wrapping routines.

I’ve pushed the code to github, and am updating it to run on ruby
1.9.1. There’s a good chance that will clear up any weird issues.

martin