From nobody at rubyforge.org Thu Oct 18 14:32:50 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Thu, 18 Oct 2007 14:32:50 -0400 (EDT) Subject: [Muby-submits] [235] bin: renamed the binary Message-ID: <20071018183250.508B118585FF@rubyforge.org> Revision: 235 Author: zond Date: 2007-10-18 14:32:50 -0400 (Thu, 18 Oct 2007) Log Message: ----------- renamed the binary Added Paths: ----------- bin/muby Removed Paths: ------------- bin/muby.rb Copied: bin/muby (from rev 234, bin/muby.rb) =================================================================== --- bin/muby (rev 0) +++ bin/muby 2007-10-18 18:32:50 UTC (rev 235) @@ -0,0 +1,125 @@ +#!/usr/bin/env ruby +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# or browse to http://www.gnu.org/licenses/gpl.txt +# +# Copyright 2004-2006 Martin Kihlgren +# +# Secondary coding by Sy Ali who donates his +# contributions to the codebase, which are to be included in the same licence. +# + +#################################################################### +# muby, the ruby mud client # +# (really a half-assed telnet client - telnet protocol options are # +# recognized but ignored, but there are pretty nice scripting # +# capabilities :) # +#################################################################### + +# http://jrandomhacker.info/Muby +# http://rubyforge.org/projects/muby + +MUBY_VERSION = "0.6.5" + +$: << File.expand_path(File.dirname(__FILE__)) + +require "socket" +require "pathname" +begin + require "rubygems" + # Require a specific version or higher? + require_gem "ncurses" +rescue LoadError + # How do we ensure that we have the right version? + require "ncurses" +end + +require "lib/user_methods.rb" +require "lib/displayer.rb" +require "lib/configuration.rb" +require "lib/logger.rb" +require "lib/style.rb" +require "lib/outputwindow.rb" +require "lib/inputwindow.rb" +require "lib/connection.rb" +require "lib/help.rb" +require "lib/completer.rb" + +class Application + + include Muby::Configurable + include Muby::Displayer + + def initialize + + # + # Load all user files + # + conf.load_user_files! + + # Init all the ncurses magic. + Ncurses.initscr + Ncurses.raw + Ncurses.keypad(Ncurses.stdscr, true) + Ncurses.noecho + Ncurses.refresh + if Ncurses.has_colors? + Ncurses.start_color + end + + # initialize late (to enable changes from $RC_FILE) + Muby::OutputWindow.get_instance.go(conf.output_buffer, conf.input_height) + Muby::InputWindow.get_instance.go(Muby::OutputWindow.get_instance, conf.input_height) + + # + # Exit commands + # If we die by normal death (control-C for example): + # + at_exit do + begin + conf.shutdown_triggers.each do |proc| + Muby::InputWindow.get_instance.execute(proc) + end + Muby::InputWindow.get_instance.saveHistory + rescue Exception => e + exception(e) + error("Sleeping 10 seconds before closing") + sleep(10) + ensure + Ncurses.endwin + puts "Exiting muby..." + end + end + + # + # The main loop + # + begin + Muby::InputWindow.get_instance.process + rescue SystemExit => ex + violentDeath = false + raise ex + rescue Exception => error + exception(error) + error("Sleeping 10 seconds before closing") + sleep(10) + end + end +end + +if __FILE__ == $0 + # Start the whole shebang + Application.new +end Deleted: bin/muby.rb =================================================================== --- bin/muby.rb 2007-10-18 18:32:20 UTC (rev 234) +++ bin/muby.rb 2007-10-18 18:32:50 UTC (rev 235) @@ -1,125 +0,0 @@ -#!/usr/bin/env ruby -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# or browse to http://www.gnu.org/licenses/gpl.txt -# -# Copyright 2004-2006 Martin Kihlgren -# -# Secondary coding by Sy Ali who donates his -# contributions to the codebase, which are to be included in the same licence. -# - -#################################################################### -# muby, the ruby mud client # -# (really a half-assed telnet client - telnet protocol options are # -# recognized but ignored, but there are pretty nice scripting # -# capabilities :) # -#################################################################### - -# http://jrandomhacker.info/Muby -# http://rubyforge.org/projects/muby - -MUBY_VERSION = "0.6.5" - -$: << File.expand_path(File.dirname(__FILE__)) - -require "socket" -require "pathname" -begin - require "rubygems" - # Require a specific version or higher? - require_gem "ncurses" -rescue LoadError - # How do we ensure that we have the right version? - require "ncurses" -end - -require "lib/user_methods.rb" -require "lib/displayer.rb" -require "lib/configuration.rb" -require "lib/logger.rb" -require "lib/style.rb" -require "lib/outputwindow.rb" -require "lib/inputwindow.rb" -require "lib/connection.rb" -require "lib/help.rb" -require "lib/completer.rb" - -class Application - - include Muby::Configurable - include Muby::Displayer - - def initialize - - # - # Load all user files - # - conf.load_user_files! - - # Init all the ncurses magic. - Ncurses.initscr - Ncurses.raw - Ncurses.keypad(Ncurses.stdscr, true) - Ncurses.noecho - Ncurses.refresh - if Ncurses.has_colors? - Ncurses.start_color - end - - # initialize late (to enable changes from $RC_FILE) - Muby::OutputWindow.get_instance.go(conf.output_buffer, conf.input_height) - Muby::InputWindow.get_instance.go(Muby::OutputWindow.get_instance, conf.input_height) - - # - # Exit commands - # If we die by normal death (control-C for example): - # - at_exit do - begin - conf.shutdown_triggers.each do |proc| - Muby::InputWindow.get_instance.execute(proc) - end - Muby::InputWindow.get_instance.saveHistory - rescue Exception => e - exception(e) - error("Sleeping 10 seconds before closing") - sleep(10) - ensure - Ncurses.endwin - puts "Exiting muby..." - end - end - - # - # The main loop - # - begin - Muby::InputWindow.get_instance.process - rescue SystemExit => ex - violentDeath = false - raise ex - rescue Exception => error - exception(error) - error("Sleeping 10 seconds before closing") - sleep(10) - end - end -end - -if __FILE__ == $0 - # Start the whole shebang - Application.new -end From nobody at rubyforge.org Thu Oct 18 14:46:56 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Thu, 18 Oct 2007 14:46:56 -0400 (EDT) Subject: [Muby-submits] [236] lib/muby: ah, now you can build a gem, and install it, and... Message-ID: <20071018184656.4779318585E8@rubyforge.org> Revision: 236 Author: zond Date: 2007-10-18 14:46:55 -0400 (Thu, 18 Oct 2007) Log Message: ----------- ah, now you can build a gem, and install it, and... et voila, muby is installed in /usr/bin and WORKS Modified Paths: -------------- Rakefile bin/muby lib/muby/configuration.rb lib/muby/inputwindow.rb lib/muby/outputwindow.rb Added Paths: ----------- lib/muby/application.rb lib/muby.rb Modified: Rakefile =================================================================== --- Rakefile 2007-10-18 18:32:50 UTC (rev 235) +++ Rakefile 2007-10-18 18:46:55 UTC (rev 236) @@ -3,12 +3,12 @@ require 'rubygems' Gem::manage_gems require 'rake/gempackagetask' +require 'lib/muby/configuration' - spec = Gem::Specification.new do |s| s.platform = Gem::Platform::RUBY s.name = "muby" - s.version = "0.6.5" + s.version = Muby::VERSION s.author = "Martin Kihlgren, Sy Ali" s.email = "muby-talk at rubyforge dot org" s.summary = "A simple but powerful mud client." @@ -16,10 +16,11 @@ s.require_path = "lib" s.autorequire = "muby" s.has_rdoc = true - s.executables = "bin/muby" + s.bindir = "bin" + s.executables = "muby" s.rdoc_options << '--line-numbers' s.rdoc_options << '--inline-source' - s.add_dependency('ncurses', '> 0.9.1') + s.add_dependency('ncurses', '>= 0.9.1') end Modified: bin/muby =================================================================== --- bin/muby 2007-10-18 18:32:50 UTC (rev 235) +++ bin/muby 2007-10-18 18:46:55 UTC (rev 236) @@ -31,95 +31,7 @@ # http://jrandomhacker.info/Muby # http://rubyforge.org/projects/muby -MUBY_VERSION = "0.6.5" +require 'rubygems' +require 'muby' -$: << File.expand_path(File.dirname(__FILE__)) - -require "socket" -require "pathname" -begin - require "rubygems" - # Require a specific version or higher? - require_gem "ncurses" -rescue LoadError - # How do we ensure that we have the right version? - require "ncurses" -end - -require "lib/user_methods.rb" -require "lib/displayer.rb" -require "lib/configuration.rb" -require "lib/logger.rb" -require "lib/style.rb" -require "lib/outputwindow.rb" -require "lib/inputwindow.rb" -require "lib/connection.rb" -require "lib/help.rb" -require "lib/completer.rb" - -class Application - - include Muby::Configurable - include Muby::Displayer - - def initialize - - # - # Load all user files - # - conf.load_user_files! - - # Init all the ncurses magic. - Ncurses.initscr - Ncurses.raw - Ncurses.keypad(Ncurses.stdscr, true) - Ncurses.noecho - Ncurses.refresh - if Ncurses.has_colors? - Ncurses.start_color - end - - # initialize late (to enable changes from $RC_FILE) - Muby::OutputWindow.get_instance.go(conf.output_buffer, conf.input_height) - Muby::InputWindow.get_instance.go(Muby::OutputWindow.get_instance, conf.input_height) - - # - # Exit commands - # If we die by normal death (control-C for example): - # - at_exit do - begin - conf.shutdown_triggers.each do |proc| - Muby::InputWindow.get_instance.execute(proc) - end - Muby::InputWindow.get_instance.saveHistory - rescue Exception => e - exception(e) - error("Sleeping 10 seconds before closing") - sleep(10) - ensure - Ncurses.endwin - puts "Exiting muby..." - end - end - - # - # The main loop - # - begin - Muby::InputWindow.get_instance.process - rescue SystemExit => ex - violentDeath = false - raise ex - rescue Exception => error - exception(error) - error("Sleeping 10 seconds before closing") - sleep(10) - end - end -end - -if __FILE__ == $0 - # Start the whole shebang - Application.new -end +Muby::Application.new Added: lib/muby/application.rb =================================================================== --- lib/muby/application.rb (rev 0) +++ lib/muby/application.rb 2007-10-18 18:46:55 UTC (rev 236) @@ -0,0 +1,66 @@ + +module Muby + + class Application + + include Muby::Configurable + include Muby::Displayer + + def initialize + + # + # Load all user files + # + conf.load_user_files! + + # Init all the ncurses magic. + Ncurses.initscr + Ncurses.raw + Ncurses.keypad(Ncurses.stdscr, true) + Ncurses.noecho + Ncurses.refresh + if Ncurses.has_colors? + Ncurses.start_color + end + + # initialize late (to enable changes from $RC_FILE) + Muby::OutputWindow.get_instance.go(conf.output_buffer, conf.input_height) + Muby::InputWindow.get_instance.go(Muby::OutputWindow.get_instance, conf.input_height) + + # + # Exit commands + # If we die by normal death (control-C for example): + # + at_exit do + begin + conf.shutdown_triggers.each do |proc| + Muby::InputWindow.get_instance.execute(proc) + end + Muby::InputWindow.get_instance.saveHistory + rescue Exception => e + exception(e) + error("Sleeping 10 seconds before closing") + sleep(10) + ensure + Ncurses.endwin + puts "Exiting muby..." + end + end + + # + # The main loop + # + begin + Muby::InputWindow.get_instance.process + rescue SystemExit => ex + violentDeath = false + raise ex + rescue Exception => error + exception(error) + error("Sleeping 10 seconds before closing") + sleep(10) + end + end + end + +end Modified: lib/muby/configuration.rb =================================================================== --- lib/muby/configuration.rb 2007-10-18 18:32:50 UTC (rev 235) +++ lib/muby/configuration.rb 2007-10-18 18:46:55 UTC (rev 236) @@ -1,6 +1,10 @@ +require 'ncurses' + module Muby + VERSION = "0.6.5" + # # The class that encapsulates all configuration. # Modified: lib/muby/inputwindow.rb =================================================================== --- lib/muby/inputwindow.rb 2007-10-18 18:32:50 UTC (rev 235) +++ lib/muby/inputwindow.rb 2007-10-18 18:46:55 UTC (rev 236) @@ -1,3 +1,6 @@ + +require 'pathname' + # # The fancy window that gets our input. # Modified: lib/muby/outputwindow.rb =================================================================== --- lib/muby/outputwindow.rb 2007-10-18 18:32:50 UTC (rev 235) +++ lib/muby/outputwindow.rb 2007-10-18 18:46:55 UTC (rev 236) @@ -57,7 +57,7 @@ '--'--'--'-----'----'--. : The Ruby MUD Client : : ------------------- '--' - Version #{MUBY_VERSION} + Version #{Muby::VERSION} ") end Added: lib/muby.rb =================================================================== --- lib/muby.rb (rev 0) +++ lib/muby.rb 2007-10-18 18:46:55 UTC (rev 236) @@ -0,0 +1,13 @@ +$: << File.join(File.dirname(__FILE__), "lib") +require "muby/user_methods" +require "muby/displayer" +require "muby/configuration" +require "muby/logger" +require "muby/style" +require "muby/outputwindow" +require "muby/inputwindow" +require "muby/connection" +require "muby/help" +require "muby/completer" +require "muby/application" + From nobody at rubyforge.org Thu Oct 18 15:35:37 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Thu, 18 Oct 2007 15:35:37 -0400 (EDT) Subject: [Muby-submits] [237] lib/muby/configuration.rb: made the log level slightly more failsafe. Message-ID: <20071018193537.3823F18585FF@rubyforge.org> Revision: 237 Author: zond Date: 2007-10-18 15:35:36 -0400 (Thu, 18 Oct 2007) Log Message: ----------- made the log level slightly more failsafe. beautified the load_user_files method Modified Paths: -------------- lib/muby/configuration.rb Modified: lib/muby/configuration.rb =================================================================== --- lib/muby/configuration.rb 2007-10-18 18:46:55 UTC (rev 236) +++ lib/muby/configuration.rb 2007-10-18 19:35:36 UTC (rev 237) @@ -217,7 +217,7 @@ # def display?(level) levels = [:trace, :debug, :info, :warn, :error] - levels.index(level) >= levels.index(@show_level) + levels.index(level) >= (levels.index(@show_level) || 0) end # @@ -250,13 +250,11 @@ # def load_user_files! @loaded_rc_file = false - [".mubyrc", "mubyrc"].each do |file_name| - to_load = File.join(ENV["HOME"], file_name) - if File.exists?(to_load) - nice_load!(to_load) - @loaded_rc_file = to_load - break + if to_load = [".mubyrc", "mubyrc"].find do |file_name| + File.exists?(File.join(ENV["HOME"], file_name)) end + nice_load!(to_load) + @loaded_rc_file = to_load end unless @loaded_rc_file From nobody at rubyforge.org Thu Oct 18 15:39:33 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Thu, 18 Oct 2007 15:39:33 -0400 (EDT) Subject: [Muby-submits] [238] trunk: moved everything to trunk Message-ID: <20071018193933.19C2018585FF@rubyforge.org> Revision: 238 Author: zond Date: 2007-10-18 15:39:32 -0400 (Thu, 18 Oct 2007) Log Message: ----------- moved everything to trunk Added Paths: ----------- trunk/ trunk/LICENSE trunk/Rakefile trunk/bin/ trunk/contrib/ trunk/lib/ Removed Paths: ------------- LICENSE Rakefile bin/ contrib/ lib/ Deleted: LICENSE =================================================================== --- LICENSE 2007-10-18 19:35:36 UTC (rev 237) +++ LICENSE 2007-10-18 19:39:32 UTC (rev 238) @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. Deleted: Rakefile =================================================================== --- Rakefile 2007-10-18 19:35:36 UTC (rev 237) +++ Rakefile 2007-10-18 19:39:32 UTC (rev 238) @@ -1,35 +0,0 @@ - -require 'rake' -require 'rubygems' -Gem::manage_gems -require 'rake/gempackagetask' -require 'lib/muby/configuration' - -spec = Gem::Specification.new do |s| - s.platform = Gem::Platform::RUBY - s.name = "muby" - s.version = Muby::VERSION - s.author = "Martin Kihlgren, Sy Ali" - s.email = "muby-talk at rubyforge dot org" - s.summary = "A simple but powerful mud client." - s.files = FileList['lib/**/*.rb', 'contrib/**/*.rb', 'contrib/**/*.txt', 'bin/**/*.rb', 'LICENSE'].to_a - s.require_path = "lib" - s.autorequire = "muby" - s.has_rdoc = true - s.bindir = "bin" - s.executables = "muby" - s.rdoc_options << '--line-numbers' - s.rdoc_options << '--inline-source' - s.add_dependency('ncurses', '>= 0.9.1') -end - - -Rake::GemPackageTask.new(spec) do |pkg| - pkg.need_tar = true -end - -desc "Package a gem from the source" -task :gem => "pkg/#{spec.name}-#{spec.version}.gem" do - puts "generated latest version" -end - Copied: trunk/LICENSE (from rev 237, LICENSE) =================================================================== --- trunk/LICENSE (rev 0) +++ trunk/LICENSE 2007-10-18 19:39:32 UTC (rev 238) @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. Copied: trunk/Rakefile (from rev 237, Rakefile) =================================================================== --- trunk/Rakefile (rev 0) +++ trunk/Rakefile 2007-10-18 19:39:32 UTC (rev 238) @@ -0,0 +1,35 @@ + +require 'rake' +require 'rubygems' +Gem::manage_gems +require 'rake/gempackagetask' +require 'lib/muby/configuration' + +spec = Gem::Specification.new do |s| + s.platform = Gem::Platform::RUBY + s.name = "muby" + s.version = Muby::VERSION + s.author = "Martin Kihlgren, Sy Ali" + s.email = "muby-talk at rubyforge dot org" + s.summary = "A simple but powerful mud client." + s.files = FileList['lib/**/*.rb', 'contrib/**/*.rb', 'contrib/**/*.txt', 'bin/**/*.rb', 'LICENSE'].to_a + s.require_path = "lib" + s.autorequire = "muby" + s.has_rdoc = true + s.bindir = "bin" + s.executables = "muby" + s.rdoc_options << '--line-numbers' + s.rdoc_options << '--inline-source' + s.add_dependency('ncurses', '>= 0.9.1') +end + + +Rake::GemPackageTask.new(spec) do |pkg| + pkg.need_tar = true +end + +desc "Package a gem from the source" +task :gem => "pkg/#{spec.name}-#{spec.version}.gem" do + puts "generated latest version" +end + Copied: trunk/bin (from rev 237, bin) Copied: trunk/contrib (from rev 237, contrib) Copied: trunk/lib (from rev 237, lib) From nobody at rubyforge.org Thu Oct 18 15:42:31 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Thu, 18 Oct 2007 15:42:31 -0400 (EDT) Subject: [Muby-submits] [239] made release tag 0.6.5 Message-ID: <20071018194231.1344718585F9@rubyforge.org> Revision: 239 Author: zond Date: 2007-10-18 15:42:30 -0400 (Thu, 18 Oct 2007) Log Message: ----------- made release tag 0.6.5 Added Paths: ----------- tags/ tags/release_0_6_5/ Property Changed: ---------------- trunk/ Copied: tags/release_0_6_5 (from rev 238, trunk) Property changes on: tags/release_0_6_5 ___________________________________________________________________ Name: svn:ignore + pkg Property changes on: trunk ___________________________________________________________________ Name: svn:ignore + pkg From nobody at rubyforge.org Thu Oct 18 14:32:20 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Thu, 18 Oct 2007 14:32:20 -0400 (EDT) Subject: [Muby-submits] [234] lib/muby: shuffling around EVERYTHING to enable creating a muby gem.. . Message-ID: <20071018183220.B7F1E18585FF@rubyforge.org> Revision: 234 Author: zond Date: 2007-10-18 14:32:20 -0400 (Thu, 18 Oct 2007) Log Message: ----------- shuffling around EVERYTHING to enable creating a muby gem... have patience, nothing will work for a short while Added Paths: ----------- Rakefile bin/ bin/muby.rb lib/muby/ lib/muby/completer.rb lib/muby/configuration.rb lib/muby/connection.rb lib/muby/displayer.rb lib/muby/help.rb lib/muby/inputwindow.rb lib/muby/logger.rb lib/muby/outputwindow.rb lib/muby/style.rb lib/muby/user_methods.rb Removed Paths: ------------- lib/completer.rb lib/configuration.rb lib/connection.rb lib/displayer.rb lib/help.rb lib/inputwindow.rb lib/logger.rb lib/outputwindow.rb lib/style.rb lib/user_methods.rb muby.rb prepare_release_tarball.sh Property Changed: ---------------- / Property changes on: ___________________________________________________________________ Name: svn:ignore - _MTN + _MTN pkg Added: Rakefile =================================================================== --- Rakefile (rev 0) +++ Rakefile 2007-10-18 18:32:20 UTC (rev 234) @@ -0,0 +1,34 @@ + +require 'rake' +require 'rubygems' +Gem::manage_gems +require 'rake/gempackagetask' + + +spec = Gem::Specification.new do |s| + s.platform = Gem::Platform::RUBY + s.name = "muby" + s.version = "0.6.5" + s.author = "Martin Kihlgren, Sy Ali" + s.email = "muby-talk at rubyforge dot org" + s.summary = "A simple but powerful mud client." + s.files = FileList['lib/**/*.rb', 'contrib/**/*.rb', 'contrib/**/*.txt', 'bin/**/*.rb', 'LICENSE'].to_a + s.require_path = "lib" + s.autorequire = "muby" + s.has_rdoc = true + s.executables = "bin/muby" + s.rdoc_options << '--line-numbers' + s.rdoc_options << '--inline-source' + s.add_dependency('ncurses', '> 0.9.1') +end + + +Rake::GemPackageTask.new(spec) do |pkg| + pkg.need_tar = true +end + +desc "Package a gem from the source" +task :gem => "pkg/#{spec.name}-#{spec.version}.gem" do + puts "generated latest version" +end + Added: bin/muby.rb =================================================================== --- bin/muby.rb (rev 0) +++ bin/muby.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -0,0 +1,125 @@ +#!/usr/bin/env ruby +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# or browse to http://www.gnu.org/licenses/gpl.txt +# +# Copyright 2004-2006 Martin Kihlgren +# +# Secondary coding by Sy Ali who donates his +# contributions to the codebase, which are to be included in the same licence. +# + +#################################################################### +# muby, the ruby mud client # +# (really a half-assed telnet client - telnet protocol options are # +# recognized but ignored, but there are pretty nice scripting # +# capabilities :) # +#################################################################### + +# http://jrandomhacker.info/Muby +# http://rubyforge.org/projects/muby + +MUBY_VERSION = "0.6.5" + +$: << File.expand_path(File.dirname(__FILE__)) + +require "socket" +require "pathname" +begin + require "rubygems" + # Require a specific version or higher? + require_gem "ncurses" +rescue LoadError + # How do we ensure that we have the right version? + require "ncurses" +end + +require "lib/user_methods.rb" +require "lib/displayer.rb" +require "lib/configuration.rb" +require "lib/logger.rb" +require "lib/style.rb" +require "lib/outputwindow.rb" +require "lib/inputwindow.rb" +require "lib/connection.rb" +require "lib/help.rb" +require "lib/completer.rb" + +class Application + + include Muby::Configurable + include Muby::Displayer + + def initialize + + # + # Load all user files + # + conf.load_user_files! + + # Init all the ncurses magic. + Ncurses.initscr + Ncurses.raw + Ncurses.keypad(Ncurses.stdscr, true) + Ncurses.noecho + Ncurses.refresh + if Ncurses.has_colors? + Ncurses.start_color + end + + # initialize late (to enable changes from $RC_FILE) + Muby::OutputWindow.get_instance.go(conf.output_buffer, conf.input_height) + Muby::InputWindow.get_instance.go(Muby::OutputWindow.get_instance, conf.input_height) + + # + # Exit commands + # If we die by normal death (control-C for example): + # + at_exit do + begin + conf.shutdown_triggers.each do |proc| + Muby::InputWindow.get_instance.execute(proc) + end + Muby::InputWindow.get_instance.saveHistory + rescue Exception => e + exception(e) + error("Sleeping 10 seconds before closing") + sleep(10) + ensure + Ncurses.endwin + puts "Exiting muby..." + end + end + + # + # The main loop + # + begin + Muby::InputWindow.get_instance.process + rescue SystemExit => ex + violentDeath = false + raise ex + rescue Exception => error + exception(error) + error("Sleeping 10 seconds before closing") + sleep(10) + end + end +end + +if __FILE__ == $0 + # Start the whole shebang + Application.new +end Property changes on: bin/muby.rb ___________________________________________________________________ Name: svn:executable + * Deleted: lib/completer.rb =================================================================== --- lib/completer.rb 2007-05-05 01:32:00 UTC (rev 233) +++ lib/completer.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -1,62 +0,0 @@ -module Muby - - class Completer - - attr_reader :completions - - def initialize - @completions = {} - end - - @@instance = Muby::Completer.new - - def self.get_instance - @@instance - end - - def complete(s) - subhash = find_subhash(s, @completions) || {} - find_endings(s, subhash) - end - - def store(s) - s.split(/\W+/).each do |part| - store_in_hash(part, @completions) unless part.empty? - end - end - - def find_endings(s, hash) - return_value = [] - hash.each do |char, value| - if char == :end - return_value << s - else - return_value |= find_endings(s + char, value) - end - end - return_value - end - - def find_subhash(s, hash) - return {} if hash.nil? - if s.size == 0 - hash - else - rval = find_subhash(s[1..-1], hash[s[0..0]]) - rval.merge(find_subhash(s[1..-1], hash[s[0..0].swapcase])) - end - end - - def store_in_hash(s, hash) - if s.size == 1 - hash[s] ||= {} - hash[s][:end] = true - else - hash[s[0..0]] ||= {} - store_in_hash(s[1..-1], hash[s[0..0]]) - end - end - - end - -end Deleted: lib/configuration.rb =================================================================== --- lib/configuration.rb 2007-05-05 01:32:00 UTC (rev 233) +++ lib/configuration.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -1,363 +0,0 @@ - -module Muby - - # - # The class that encapsulates all configuration. - # - # To simplify its use, include Muby::Configurable in your class. - # Then you can access Configuration as 'conf' (nice shorthand :) - # - # All options in Configuration are get'able and set'able. - # - # Look in help.rb to get the meaning of them. - # - class Configuration - - def initialize - # - # verbosity options - # - - @extra_verbosity_settings = { - :echo_keycodes => true, - :echo => true, - :show_level => :debug, - :timestamp => true, - :connection_status => true - } - - @echo_keycodes = false - - @echo = true - - @show_level = :info - - @timestamp = false - - @connection_status = true - - # - # options to control what you see - # - - @disable_blink = false - - @timeformat = "%H:%M:%S" - - @broken_keycodes = { - 13 => true - } - - @max_history = 100 - - @default_attributes = Ncurses.const_get("A_NORMAL") - @default_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] - - @echo_attributes = Ncurses.const_get("A_BOLD") - @echo_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] - - @trace_attributes = Ncurses.const_get("A_NORMAL") - @trace_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] - - @debug_attributes = Ncurses.const_get("A_NORMAL") - @debug_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] - - @info_attributes = Ncurses.const_get("A_NORMAL") - @info_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] - - @warn_attributes = Ncurses.const_get("A_NORMAL") - @warn_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] - - @error_attributes = Ncurses.const_get("A_NORMAL") - @error_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] - - @flush = true - - @gags = [] - - @anti_gags = [] - - @remote_substitutions = {} - - @local_substitutions = {} - - # - # options to control what gets run when # - # - - @startup_triggers = [] - - @connect_triggers = [] - - @shutdown_triggers = [] - - @remote_triggers = {} - - @remote_character_triggers = {} - - @local_triggers = { - /^\/(.*)\n$/m => :execute_command!, - /^!(.*)\n$/m => :shell_command!, - /^#.*\n$/m => :ignore_command! - } - - @key_commands = { - #18 => :resize, # ctrl-l - Ncurses.const_get("KEY_PPAGE") => :scroll_up!, - Ncurses.const_get("KEY_NPAGE") => :scroll_down!, - Ncurses.const_get("KEY_ENTER") => :process_buffer!, - 10 => :process_buffer!, # enter - 3 => :two_step_quit!, # ctrl-c - 9 => :complete!, # tab - 18 => :toggle_history_search!, # ctrl-r - 127 => :backspace_buffer!, # backspace - Ncurses.const_get("KEY_BACKSPACE") => :backspace_buffer!, - 27 => { - 91 => { - 53 => { - 68 => :previous_word_buffer!, # ctrl-key_left - 67 => :next_word_buffer!, # ctrl-key_right - } - } - }, - Ncurses.const_get("KEY_DC") => :delete_buffer!, - Ncurses.const_get("KEY_UP") => :previous_history_buffer!, - Ncurses.const_get("KEY_DOWN") => :next_history_buffer!, - 262 => :home_buffer!, # home_key - 360 => :end_buffer!, # end_key - Ncurses.const_get("KEY_LEFT") => :previous_character_buffer!, - Ncurses.const_get("KEY_RIGHT") => :next_character_buffer!, - 22 => :toggle_verbosity!, # ctrl-v - 265 => :help # f1 - } - - # - # miscellaneous options # - # - - @feed_completer_with_history = true - - @feed_completer_with_input = true - - @extra_completions = [] - - @loaded_rc_file = false - - @user_edited_config_file = false - - @userdir = File.join(ENV["HOME"], "mubyrc.d") - - @history_file = File.join(@userdir, "history") - - @output_buffer = 1000 - - @input_height = 3 - - @input_logfile = nil - - @output_logfile = nil - - end - - @@instance = Configuration.new - - def self.get - @@instance - end - - # - # The magical method that lets us get and set the settings without - # having to write getters and setters for all of them - # - def method_missing(*args) - method_name = args[0].to_s - var_name = method_name[/^[^=]*/] - - setter = method_name =~ /=$/ - if setter - return super unless args.size == 2 - instance_variable_set("@#{var_name}", args[1]) - return args[1] - else - return super unless args.size == 1 - return instance_variable_get("@#{var_name}") - end - end - - # - # The halfway magical method that toggles all settings covered in - # @extra_verbosity_settings to what they are in that hash, - # and then stores them away inside the same hash for back-toggling again. - # - def toggle_verbosity! - - # copy old extra-settings to a copy - settings_copy = @extra_verbosity_settings.clone - - # set our extra-settings to be the currently applied settings - @extra_verbosity_settings.clone.each do |key, value| - @extra_verbosity_settings[key] = self.send(key) - end - - # apply the extra-settings - settings_copy.each do |key, value| - self.send("#{key}=", value) - end - - Muby::Displayer.info("Toggled verbosity. Press again to toggle back.") - end - - # - # Returns true if we are supposed to display messages - # of +level+. - # - def display?(level) - levels = [:trace, :debug, :info, :warn, :error] - levels.index(level) >= levels.index(@show_level) - end - - # - # Will save the current configuration to the loaded rc file, - # or to mubyrc if no such file was loaded. - # - def save_configuration_file! - to_save = @loaded_rc_file ? @loaded_rc_file : File.join(ENV["HOME"], "mubyrc") - begin - Kernel::open(to_save, "w") do |output| - output.write(self.to_ruby) - @loaded_rc_file = to_save - end - Muby::Displayer.info("Saved default configuration to #{to_save}.") - rescue Exception => e - Muby::Displayer.warn("Failed saving default configuration to #{to_save}: #{e.message}") - Muby::Displayer.debug(e.backtrace.join("\n")) - end - end - - # - # Tries to load all the users files, defined as - # any file named .mubyrc or mubyrc in the users ENV["HOME"] - # and all **/*.rb files in the users ENV["HOME"]/@userdir - # with the root of the userdir taking precidence over subdirectories. - # Directories starting with a . are ignored. - # - # If none of the mubyrc-files existed, it will try to create one - # for the user to edit to his/her liking. - # - def load_user_files! - @loaded_rc_file = false - [".mubyrc", "mubyrc"].each do |file_name| - to_load = File.join(ENV["HOME"], file_name) - if File.exists?(to_load) - nice_load!(to_load) - @loaded_rc_file = to_load - break - end - end - - unless @loaded_rc_file - save_configuration_file! - end - - if File.exists?(@userdir) - # Only load *.rb files within sub-directories of the current directory, and not the current directory's *.rb files!) - # Test: Dir[File.join(Dir.pwd, "*", "**", "*.rb")].each do |f| puts f end ; nil - Dir[File.join(@userdir, "*", "**", "*.rb")].each do |file_name| - nice_load!(file_name) - end - # Only load *.rb files of the current directory. - # This is very useful for users to create "overrides" for items in subdirectories. - # NOTE: This does follow symbolic links (files and directories) - # Test: Dir[File.join(Dir.pwd, "*.rb")].each do |f| puts f end ; nil - Dir[File.join(@userdir, "*.rb")].each do |file_name| - nice_load!(file_name) - end - else - Muby::Displayer.warn("#{@userdir} does not exist. If it did, *.rb in it would be loaded now.") - end - end - - # - # A non-raising method that tries to load +f+ and tells the output window about its success. - # - def nice_load!(f) - begin - Kernel::load(f) - Muby::Displayer.info("Loaded #{f}") - rescue Exception => e - Muby::Displayer.exception(e) - end - end - - # - # Will reload the entire app, ie the class files and the - # user files. - # - # TODO: Remove the spammyness. - # It is not appropriate to use 'puts' when reload_application! is being called by the user. - # To turn off "uninitialised constant" warnings, do: $VERBOSE = nil - # - # Simply set your show_level to :warn instead of :info, and you wont see the load messages. - # - # Any other messages come from your own files :O - # - def reload_application! - Dir[File.join(File.dirname(__FILE__), "**", "*.rb")].each do |file_name| - nice_load! file_name - end - load_user_files! - end - - # - # The not so magical at all method that prints our content - # to a String so that we easily can save our current settings - # in a file, or create a default config file. - # - def to_ruby - "# -# This is the default configuration of muby. -# To learn more about how to configure it, you -# can type '/help' in the client. -# -include Muby::Configurable -" + - instance_variables.sort.collect do |var_name| - value = eval(var_name) - case value - when Hash - space = "conf.#{var_name[1..-1]} = _".size - value = value.inspect.gsub(/, /, ",\n#{" " * space}") - when File - begin - value.read(0) - value = "open(\"#{value.path}\", \"r\")" - rescue - value = "open(\"#{value.path}\", \"a\")" - end - when NilClass - value = value.inspect - else - value = value.inspect - end - var_name = var_name[1..-1] - help_text = Muby::Help.configuration[var_name.to_sym] || "no help available for #{var_name}" - help_text = help_text.split("\n").join("\n# ") - " -# #{help_text} -conf.#{var_name} = #{value}" - end.join("\n") - end - - end - - # - # The module that provides the shorthand for - # using classes. - # - module Configurable - def conf - Configuration.get - end - end - -end Deleted: lib/connection.rb =================================================================== --- lib/connection.rb 2007-05-05 01:32:00 UTC (rev 233) +++ lib/connection.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -1,332 +0,0 @@ -# -# The class that encapsulates the actual Connection -# -class Muby::Connection - - include Muby::Logger - include Muby::Configurable - include Muby::Displayer - - # - # Set it up with windows, handle and host info. - # - def initialize(inputWindow, outputWindow, host, port) - @inputWindow = inputWindow - @outputWindow = outputWindow - status("Connecting to " + host.inspect + ":" + port.inspect) - @host = host - @port = port - @socket = TCPSocket.open(host, port) if host && port - conf.connect_triggers.each do |command| - @inputWindow.execute(command, @inputWindow, @outputWindow) - end - status("Connected to " + host.inspect + ":" + port.inspect) - @matchBuffer = "" - @showBuffer = [] - @used_triggers = {} - @listener = Thread.new do - begin - status("Listening thread started") - listen - status("Listening thread finished") - rescue Exception => e - exception(e) - ensure - close - end - end if @socket - end - - # - # Display a status message in the outputwindow if wanted (conf.connection_status) - # - def status(message) - if conf.connection_status - @outputWindow.print_on_newline(*[message + "\n"]) - end - end - - # - # Check if we want to gag the current matchBuffer and debug about it. - # - # Remove the gag regexp if it is broken. - # - def gag(matchBuffer) - returnValue = false - conf.gags.each do |gag| - begin - if matchBuffer.match(gag) - trace(matchBuffer + " matches " + gag.inspect + ": gag active") - returnValue = true - end - rescue RegexpError => error - conf.gags.delete(key) - exception(e) - end - end - returnValue - end - - # - # Check if we should definitely NOT gag the current matchBuffer, and debug about it. - # - # Remove the nongag regexp if it is broken. - # - def nongag(matchBuffer) - returnValue = false - conf.anti_gags.each do |nongag| - begin - if matchBuffer.match(nongag) - trace(matchBuffer + " matches " + nongag.inspect + ": nongag active") - returnValue = true - end - rescue RegexpError => error - conf.anti_gags.delete(key) - exception(e) - end - end - returnValue - end - - # - # Check if we should trigger a Proc on the current matchBuffer, and debug about it. - # - # Remove the trigger regexp if it is broken. - # - def trigger(matchBuffer, hash, skip_used = true) - hash.each do |key, value| - if skip_used && @used_triggers.include?(key) - trace("#{key.inspect} has already been matched on this line, skipping it") - else - trace("checking if " + matchBuffer + " matches " + key.inspect) - begin - if match = matchBuffer.match(key) - trace(matchBuffer + " matches " + key.inspect + ": .call'ing Proc") - # Run the procedure associated with that trigger: - @inputWindow.execute(value, @inputWindow, @outputWindow, match) - @used_triggers[key] = true if skip_used - end - # If we received an error with the regular expression: - rescue RegexpError => error - hash.delete(key) - exception(error) - end - end - end - end - - def feed(s) - s.unpack("C*").each do |c| - handle(c) - end - nil - end - - def getc - c = @socket.getc - log_input(c.chr) if c - c - end - - def handle(c) - # - # The telnet support (just so we dont explode or something) - # - # We are just plain ignoring it atm. - # - if c == 255 # telnet interpret as command (IAC) - c = getc # get the request (DO|DONT) - c = getc # get the latest part whatever that is - elsif c == 27 # escape char! this is probably some ANSI color or shite - c = getc - if c.chr == "[" # this is an ansi-something that is more than one char long - ansiString = "" - while !"cnRhl()HABCfsurhgKJipm".include?((c = getc).chr) - ansiString << c.chr - end - if c.chr == "m" && Ncurses.has_colors? # ah, text property! i understand this! - properties = ansiString.split(";") - attributes = 0 - bgcolor = false - fgcolor = false - reset = properties.index("0") - if reset - properties.delete("0") - end - properties.each do |property| - case property.to_i - when 1 - attributes = attributes | Ncurses.const_get("A_BOLD") - when 2 - attributes = attributes | Ncurses.const_get("A_DIM") - when 4 - attributes = attributes | Ncurses.const_get("A_UNDERLINE") - when 5 - attributes = attributes | Ncurses.const_get("A_BLINK") unless conf.disable_blink - when 7 - attributes = attributes | Ncurses.const_get("A_REVERSE") - when 8 - attributes = attributes | Ncurses.const_get("A_INVIS") - when 30 - fgcolor = Ncurses.const_get("COLOR_BLACK") - when 31 - fgcolor = Ncurses.const_get("COLOR_RED") - when 32 - fgcolor = Ncurses.const_get("COLOR_GREEN") - when 33 - fgcolor = Ncurses.const_get("COLOR_YELLOW") - when 34 - fgcolor = Ncurses.const_get("COLOR_BLUE") - when 35 - fgcolor = Ncurses.const_get("COLOR_MAGENTA") - when 36 - fgcolor = Ncurses.const_get("COLOR_CYAN") - when 37 - fgcolor = Ncurses.const_get("COLOR_WHITE") - when 40 - bgcolor = Ncurses.const_get("COLOR_BLACK") - when 41 - bgcolor = Ncurses.const_get("COLOR_RED") - when 42 - bgcolor = Ncurses.const_get("COLOR_GREEN") - when 43 - bgcolor = Ncurses.const_get("COLOR_YELLOW") - when 44 - bgcolor = Ncurses.const_get("COLOR_BLUE") - when 45 - bgcolor = Ncurses.const_get("COLOR_MAGENTA") - when 46 - bgcolor = Ncurses.const_get("COLOR_CYAN") - when 47 - bgcolor = Ncurses.const_get("COLOR_WHITE") - end - end - style = nil - if reset - style = Muby::Style.new(attributes, fgcolor, bgcolor, false) - else - style = Muby::Style.new(attributes, fgcolor, bgcolor, true) - end - @showBuffer.push(style) - end - end - elsif ! conf.broken_keycodes.include?(c) - # - # This is not telnet command OR ansi, lets treat it as nice MUD text! - # - # Debug about it, add it to match buffer, add it to show buffer and show if we want to show. - # Then check it for triggers. - # - @matchBuffer = @matchBuffer + c.chr - append_show_buffer(c.chr) - manage_buffers(c) - end - end - - def append_show_buffer(c) - if String === @showBuffer.last - @showBuffer.last << c - else - @showBuffer << c - end - end - - # - # Keep listening to the remote socket and react accordingly. - # - def listen - c = true - # We have to look at each byte for ncurses reasons as well as triggers etc. - while c - while select([@socket],nil,nil,1) && c = getc - handle(c) - end - if conf.flush - display_buffer - end - end - status("Connection closed by remote end") - @inputWindow.disconnect - end - - def close - if Thread.current != @listener && @listener && @listener.alive? - status("Killing listening thread") - @listener.kill - end - if @socket && !@socket.closed? - status("Disconnecting our end") - @socket.close if @socket - end - end - - def manage_buffers(c) - trigger(@matchBuffer, conf.remote_character_triggers, true) - if c == 10 - trigger(@matchBuffer, conf.remote_triggers, false) - display_buffer - @matchBuffer = "" - @used_triggers = {} - @showBuffer = [] - end - end - - def homemade_split(s, r) - rval = [] - rest = s - while match = rest.match(/(.*?)#{r.source}(.*)/) - rval << match[1] - rest = match[2] - end - rval << rest - rval - end - - def substitute(buffer, hash) - return_value = [] - buffer.each do |part| - if String === part - part_to_append = [part] - hash.each do |regexp, substitution| - case substitution - when String - part_to_append = [part.gsub(regexp, substitution)] - when Array - if part.match(regexp) - split_part = homemade_split(part, regexp) - part_to_append = split_part.zip([substitution] * (split_part.size - 1)).flatten.compact - end - end - end - return_value += part_to_append - else - return_value << part - end - end - return_value - end - - def display_buffer - unless @showBuffer.empty? - if !gag(@matchBuffer) || nongag(@matchBuffer) - @showBuffer = substitute(@showBuffer, conf.remote_substitutions) - Muby::Completer.get_instance.store(@matchBuffer) if conf.feed_completer_with_input - @outputWindow.print(*@showBuffer) - end - @showBuffer = [] - end - end - - # - # Just plain send the string we got. - # - def send(s) - log_output(s) - conf.local_substitutions.each do |key, value| - # It might be useful to allow colour codes for highlighting local substitutions.. but only when echo is on. - # No, cause this only gets sent to the server, it never shows up to the user. - s.gsub!(key, value) - end - @socket.print(s) if @socket - end -end # class Connection Deleted: lib/displayer.rb =================================================================== --- lib/displayer.rb 2007-05-05 01:32:00 UTC (rev 233) +++ lib/displayer.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -1,60 +0,0 @@ - -module Muby - - module Displayer - - def exception(e) - error("#{e.class}: #{e.message}") - debug(e.backtrace.join("\n")) - end - - def trace(s) - if Muby::OutputWindow.get_instance.ready? - Muby::OutputWindow.get_instance.show(:trace, s) - elsif Muby::Configuration.get.display?(:trace) - puts s - end - end - - def debug(s) - if Muby::OutputWindow.get_instance.ready? - Muby::OutputWindow.get_instance.show(:debug, s) - elsif Muby::Configuration.get.display?(:debug) - puts s - end - end - - def info(s) - if Muby::OutputWindow.get_instance.ready? - Muby::OutputWindow.get_instance.show(:info, s) - elsif Muby::Configuration.get.display?(:info) - puts s - end - end - - def warn(s) - if Muby::OutputWindow.get_instance.ready? - Muby::OutputWindow.get_instance.show(:warn, s) - elsif Muby::Configuration.get.display?(:warn) - puts s - end - end - - def error(s) - if Muby::OutputWindow.get_instance.ready? - Muby::OutputWindow.get_instance.show(:error, s) - elsif Muby::Configuration.get.display?(:error) - puts s - end - end - - module_function :trace - module_function :debug - module_function :info - module_function :warn - module_function :error - module_function :exception - - end - -end Deleted: lib/help.rb =================================================================== --- lib/help.rb 2007-05-05 01:32:00 UTC (rev 233) +++ lib/help.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -1,88 +0,0 @@ -module Muby - - module Help - def self.configuration - { - :feed_completer_with_history => "If true, the completion command will use history to calculate possible completions.", - :feed_completer_with_input => "If true, the completion command will use everything seen from the remote end to calculate possible completions.", - :extra_completions => "Fill this array with words that you allways want to be able to complete to.", - :extra_verbosity_settings => "The settings we want to toggle to when running the toggle_verbosity! method.", - :echo_keycodes => "Whether to echo the keycode for every key pressed or not.", - :echo => "Whether to print what is sent to the server to the outputwindow.", - :show_level => "What level of information to provide the user. -:trace may tell you each and every step the app takes. -:debug may tell the user most everything that happens. -:info will tell the user basically what we are doing. -:warn will only tell the user when we think he/she may gain from it. -:error will only tell the user when an error occurs.", - :timestamp => "Whether to timestamp all messages in the output window.", - :connection_status => "Whether to give status reports on the connections.", - :timeformat => "What type of timestamp to use.", - :loaded_rc_file => "This will be set to whichever mubyrc file was loaded upon startup.", - :disable_blink => "Set this to true if you NEVER want to see BLINKING text from the server.", - :broken_keycodes => "Which characters to filter out completely.", - :max_history => "The maximum length of the history buffer.", - :user_edited_config_file => "Change this to true when you dont want to see the help message anymore.", - :default_attributes => "The default ncurses attributes for text.", - :default_colors => "The default ncurses colors for text.", - :echo_attributes => "The default ncurses attributes for echoed (typed by you, showed in the output window) text.", - :echo_colors => "The default ncurses colors for echoed (typed by you, showed in the output window) text.", - :trace_attributes => "The default ncurses attributes for messages shown under trace loglevel.", - :trace_colors => "The default ncurses colors attributes for messages shown under trace loglevel.", - :debug_attributes => "The default ncurses attributes for messages shown under debug loglevel.", - :debug_colors => "The default ncurses colors attributes for messages shown under debug loglevel.", - :info_attributes => "The default ncurses attributes for messages shown under info loglevel.", - :info_colors => "The default ncurses colors attributes for messages shown under info loglevel.", - :warn_attributes => "The default ncurses attributes for messages shown under warn loglevel.", - :warn_colors => "The default ncurses colors attributes for messages shown under warn loglevel.", - :error_attributes => "The default ncurses attributes for messages shown under error loglevel.", - :error_colors => "The default ncurses colors attributes for messages shown under error loglevel.", - :flush => "Whether to display every char we get as soon as there is a pause in the transfer or a newline. -In contrast to only displaying the input characters when there is a newline.", - :gags => "The gags. All lines from the server are checked against these regular expressions. -If any one matches that line will not be shown. Note that if you have flush == true, the characters may already have been shown.", - :remote_substitutions => "The remote substitutions. -The same buffer that the remote_triggers work on will be searched for matches to the keys in this hash. -All values to matching keys will replace the keys in the buffer.", - :local_substitutions => "The local substitutions. -The text you send to the server will be searched for matches to the keys in this hash. -All values to matching keys will replace the keys in the text.", - :anti_gags => "The anti gags. -If flush == false the lines matching these regular expressions will be shown as soon as they are matched. -A line matching an anti gag and a gag will also be shown.", - :shutdown_triggers => "The shutdown triggers. Code in this array will be run in order at shutdown.", - :connect_triggers => "The connect triggers. Code in this array will be run in order when a connection is made.", - :startup_triggers => "The startup triggers. Code in this array will be run in order after the windows have been properly initialized.", - :remote_triggers => 'The remote triggers. -Each line received from the server will be checked against all regular expression keys in this hash, and all values to matching keys will be executed with three parameters: the input window, the output window and the match object. -Example: conf.remote_triggers[/^You feel dazed$/] = Proc.new do |inwin, outwin, match| inwin.set_status_message("dazed") end', - :remote_character_triggers => 'The remote character triggers. -All input from the server is added to a buffer that is cleared on newline and each time a new character is added to that buffer the buffer will be checked against all the regular expression keys in the remote_character_triggers. -All code values belonging to matching keys will be executed with three parameters: the input window, the output window and the match object. -Example: conf.remote_character_triggers[/^(\S+) attacks you$/] = Proc.new do |inwin, outwin, match| inwin.send("kill #{match[1]}") end', - :local_triggers => 'The local triggers. -Every line that is to be sent to the server is matched against the regular expression keys in this hash before they are sent. -All code values belonging to matching keys will be executed with three parameters: the input window, the output window and the match object. -Only if the return value of this execution is not false will the line be sent to the server. -Example: conf.local_triggers[/^bp (\S+)$/] = Proc.new do |inwin, outwin, match| inwin.send("put #{match[1]} in backpack") end', - :key_commands => 'The key commands. -Each key pressed will have its keycode checked against the integer keys of this hash. -If no key match and the keycode is below 256, the character corresponding to this code will be appended to the input line. -If a key matches the value in the hash will be checked. -If the value is another hash a new key will be waited for, and the same procedure will take place with the value hash instead. -If the value is not a hash it will be executed as code with three parameters: the input window, the output window and the matching key. -Example: conf.key_commands[65] = Proc.new do |inwin, outwin, char| inwin.echo("I just pressed A") end', - :userdir => 'The user directory. All *.rb files in this directory will be loaded on startup and on reload_application! -The root of the user directory takes precidence over (overrides) sub-directories. -Symbolic links (files and directories) are also used. -Directories beginning with a period are ignored.', - :history_file => 'The file where we will store the history of entered commands.', - :output_buffer => 'The number of rows that will be buffered in the output window for scrollback.', - :input_height => 'The number of rows in the input window.', - :input_logfile => 'The IO object that will receive everything we receive from the remote end.', - :output_logfile => 'The IO object that will receive everything we send to the remote end.' - } - end - end - -end Deleted: lib/inputwindow.rb =================================================================== --- lib/inputwindow.rb 2007-05-05 01:32:00 UTC (rev 233) +++ lib/inputwindow.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -1,192 +0,0 @@ -# -# The fancy window that gets our input. -# -# The class handles everything to do with -# the input window itself, the user callable -# methods are in the UserMethods module. -# -# All commands entered with conf.escape_character will be eval'd in -# this class scope. -# -class Muby::InputWindow - - include Muby::Logger - include Muby::Configurable - include Muby::Displayer - include Muby::UserMethods - include Muby::Styled - - @@instance = Muby::InputWindow.new unless defined?(@@instance) - - def self.get_instance - @@instance - end - - attr_reader :history - - # - # Start working! - # - def go(outputWindow, inputHeight = 3) - # Init all the default values - @outputWindow = outputWindow - @inputHeight = inputHeight - @buffer = "" - @cursorPosition = 0 - @history = [] - @historyPointer = nil - @inputWidth = Ncurses.COLS - 2 - @connection = nil - @statusLine = "" - @messageLine = "" - @recent_escape = [] - @handle_mode = :append_buffer! - - # Init the input box - @inputBorder = Ncurses.newwin(@inputHeight + 2, Ncurses.COLS, Ncurses.LINES - (@inputHeight + 2), 0) - @inputBorder.box(0,0) - @inputBorder.keypad(true) - @inputBorder.refresh - - # Init the window itself - @inputWindow = Ncurses.newwin(@inputHeight, at inputWidth,Ncurses.LINES - (@inputHeight + 1), 1) - @inputWindow.keypad(true) - @inputWindow.scrollok(true) - @inputWindow.nodelay(true) - @inputWindow.refresh - - help unless conf.user_edited_config_file - end - - # - # Update the input box, redrawing borders and text etc. - # - def update - @inputBorder.box(0,0) - @inputBorder.mvwprintw(0,1,"%s", @statusLine) - @inputBorder.mvwprintw(@inputHeight + 1, 1, "%s", @messageLine) - @inputBorder.refresh - - @inputWindow.werase - row = 0 - col = @cursorPosition - while col > @inputWidth - row = row + 1 - col = col - @inputWidth - end - @inputWindow.mvwprintw(row,col,"%s", @buffer[@cursorPosition, at buffer.size - @cursorPosition]) - @inputWindow.mvwprintw(0,0,"%s", @buffer[0, @cursorPosition]) - @inputWindow.refresh - end - - def execute(command, *args) - execute_with_verbosity(:debug, command, *args) - end - - def execute_with_verbosity(verbosity, command, *args) - begin - result = nil - if Proc === command - result = command.call(*args[0...(command.arity)]) - elsif String === command - result = eval(command) - elsif Symbol === command - method = self.method(command) - args = args[0...(method.arity)] - result = method.call(*args) - elsif Array === command - method = self.method(command.first) - args = (command[1..-1] + args)[0...(method.arity)] - result = method.call(*args) - end - unless result.nil? - case result - when String - @outputWindow.show(verbosity, result) - else - @outputWindow.show(verbosity, result.inspect) - end - end - result - rescue SystemExit => ex - quit - rescue Exception => e - exception(e) - end - end - - # - # Save our history into the history file. - # - def saveHistory - # This should be wrapped in something else, which checks for sanity (writability) - dir = Pathname.new(conf.history_file).parent - dir.mkpath unless dir.exist? - file = Pathname.new(conf.history_file) - file.open("w") do |output| - Marshal.dump(@history, output) - end - end - - # - # Load our history from the history file. - # - def loadHistory - begin - if FileTest.readable?(conf.history_file) - info("Reading history file") - Kernel::open(conf.history_file) do |input| - @history = Marshal.load(input.read) - end - @history.each do |line| - Muby::Completer.get_instance.store(line) - end if conf.feed_completer_with_history - end - rescue Exception => e - exception(e) - end - @history ||= [] - end - - def handle(c, hash) - # Echo the keycode we got if we have conf.echo_keycodes == true (good for setting up conf.key_commands) - if conf.echo_keycodes && c != Ncurses.const_get("ERR") - info(c.to_s) - end - if hash.include?(c) - value = hash[c] - if Hash === value - c = @inputWindow.wgetch - if value.include?(c) - handle(c, value) - else - handle(c, conf.key_commands) - end - else - execute(value, self, @outputWindow, c) - end - elsif 0 < c && c < 265 - method = self.method(@handle_mode) - method.call(c) - end - end - - # - # Just keep listening to the keyboard input. - # - def process - loadHistory - conf.startup_triggers.each do |trigger| - execute(trigger, self, @outputWindow) - end - # We need to check one key at a time due to triggers and conf.key_commands - while c = @inputWindow.wgetch - if c == Ncurses.const_get("ERR") - sleep(0.01) - else - handle(c, conf.key_commands) - end - end # while c = @inputWindow.wgetch - end # def process - -end # class InputWindow Deleted: lib/logger.rb =================================================================== --- lib/logger.rb 2007-05-05 01:32:00 UTC (rev 233) +++ lib/logger.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -1,28 +0,0 @@ -# -# A simple logger that logs to whatever logfiles you have defined -# in your preferences. -# -module Muby::Logger - - include Muby::Configurable - - # - # Logs everything that gets read from the remote connection. - # - def log_input(c) - if conf.input_logfile - conf.input_logfile.write(c) - conf.input_logfile.flush - end - end - - # - # Logs everything that gets sent to the remote connection. - # - def log_output(c) - if conf.output_logfile - conf.output_logfile.write(c) - conf.output_logfile.flush - end - end -end # module Logger Added: lib/muby/completer.rb =================================================================== --- lib/muby/completer.rb (rev 0) +++ lib/muby/completer.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -0,0 +1,62 @@ +module Muby + + class Completer + + attr_reader :completions + + def initialize + @completions = {} + end + + @@instance = Muby::Completer.new + + def self.get_instance + @@instance + end + + def complete(s) + subhash = find_subhash(s, @completions) || {} + find_endings(s, subhash) + end + + def store(s) + s.split(/\W+/).each do |part| + store_in_hash(part, @completions) unless part.empty? + end + end + + def find_endings(s, hash) + return_value = [] + hash.each do |char, value| + if char == :end + return_value << s + else + return_value |= find_endings(s + char, value) + end + end + return_value + end + + def find_subhash(s, hash) + return {} if hash.nil? + if s.size == 0 + hash + else + rval = find_subhash(s[1..-1], hash[s[0..0]]) + rval.merge(find_subhash(s[1..-1], hash[s[0..0].swapcase])) + end + end + + def store_in_hash(s, hash) + if s.size == 1 + hash[s] ||= {} + hash[s][:end] = true + else + hash[s[0..0]] ||= {} + store_in_hash(s[1..-1], hash[s[0..0]]) + end + end + + end + +end Added: lib/muby/configuration.rb =================================================================== --- lib/muby/configuration.rb (rev 0) +++ lib/muby/configuration.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -0,0 +1,363 @@ + +module Muby + + # + # The class that encapsulates all configuration. + # + # To simplify its use, include Muby::Configurable in your class. + # Then you can access Configuration as 'conf' (nice shorthand :) + # + # All options in Configuration are get'able and set'able. + # + # Look in help.rb to get the meaning of them. + # + class Configuration + + def initialize + # + # verbosity options + # + + @extra_verbosity_settings = { + :echo_keycodes => true, + :echo => true, + :show_level => :debug, + :timestamp => true, + :connection_status => true + } + + @echo_keycodes = false + + @echo = true + + @show_level = :info + + @timestamp = false + + @connection_status = true + + # + # options to control what you see + # + + @disable_blink = false + + @timeformat = "%H:%M:%S" + + @broken_keycodes = { + 13 => true + } + + @max_history = 100 + + @default_attributes = Ncurses.const_get("A_NORMAL") + @default_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] + + @echo_attributes = Ncurses.const_get("A_BOLD") + @echo_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] + + @trace_attributes = Ncurses.const_get("A_NORMAL") + @trace_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] + + @debug_attributes = Ncurses.const_get("A_NORMAL") + @debug_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] + + @info_attributes = Ncurses.const_get("A_NORMAL") + @info_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] + + @warn_attributes = Ncurses.const_get("A_NORMAL") + @warn_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] + + @error_attributes = Ncurses.const_get("A_NORMAL") + @error_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] + + @flush = true + + @gags = [] + + @anti_gags = [] + + @remote_substitutions = {} + + @local_substitutions = {} + + # + # options to control what gets run when # + # + + @startup_triggers = [] + + @connect_triggers = [] + + @shutdown_triggers = [] + + @remote_triggers = {} + + @remote_character_triggers = {} + + @local_triggers = { + /^\/(.*)\n$/m => :execute_command!, + /^!(.*)\n$/m => :shell_command!, + /^#.*\n$/m => :ignore_command! + } + + @key_commands = { + #18 => :resize, # ctrl-l + Ncurses.const_get("KEY_PPAGE") => :scroll_up!, + Ncurses.const_get("KEY_NPAGE") => :scroll_down!, + Ncurses.const_get("KEY_ENTER") => :process_buffer!, + 10 => :process_buffer!, # enter + 3 => :two_step_quit!, # ctrl-c + 9 => :complete!, # tab + 18 => :toggle_history_search!, # ctrl-r + 127 => :backspace_buffer!, # backspace + Ncurses.const_get("KEY_BACKSPACE") => :backspace_buffer!, + 27 => { + 91 => { + 53 => { + 68 => :previous_word_buffer!, # ctrl-key_left + 67 => :next_word_buffer!, # ctrl-key_right + } + } + }, + Ncurses.const_get("KEY_DC") => :delete_buffer!, + Ncurses.const_get("KEY_UP") => :previous_history_buffer!, + Ncurses.const_get("KEY_DOWN") => :next_history_buffer!, + 262 => :home_buffer!, # home_key + 360 => :end_buffer!, # end_key + Ncurses.const_get("KEY_LEFT") => :previous_character_buffer!, + Ncurses.const_get("KEY_RIGHT") => :next_character_buffer!, + 22 => :toggle_verbosity!, # ctrl-v + 265 => :help # f1 + } + + # + # miscellaneous options # + # + + @feed_completer_with_history = true + + @feed_completer_with_input = true + + @extra_completions = [] + + @loaded_rc_file = false + + @user_edited_config_file = false + + @userdir = File.join(ENV["HOME"], "mubyrc.d") + + @history_file = File.join(@userdir, "history") + + @output_buffer = 1000 + + @input_height = 3 + + @input_logfile = nil + + @output_logfile = nil + + end + + @@instance = Configuration.new + + def self.get + @@instance + end + + # + # The magical method that lets us get and set the settings without + # having to write getters and setters for all of them + # + def method_missing(*args) + method_name = args[0].to_s + var_name = method_name[/^[^=]*/] + + setter = method_name =~ /=$/ + if setter + return super unless args.size == 2 + instance_variable_set("@#{var_name}", args[1]) + return args[1] + else + return super unless args.size == 1 + return instance_variable_get("@#{var_name}") + end + end + + # + # The halfway magical method that toggles all settings covered in + # @extra_verbosity_settings to what they are in that hash, + # and then stores them away inside the same hash for back-toggling again. + # + def toggle_verbosity! + + # copy old extra-settings to a copy + settings_copy = @extra_verbosity_settings.clone + + # set our extra-settings to be the currently applied settings + @extra_verbosity_settings.clone.each do |key, value| + @extra_verbosity_settings[key] = self.send(key) + end + + # apply the extra-settings + settings_copy.each do |key, value| + self.send("#{key}=", value) + end + + Muby::Displayer.info("Toggled verbosity. Press again to toggle back.") + end + + # + # Returns true if we are supposed to display messages + # of +level+. + # + def display?(level) + levels = [:trace, :debug, :info, :warn, :error] + levels.index(level) >= levels.index(@show_level) + end + + # + # Will save the current configuration to the loaded rc file, + # or to mubyrc if no such file was loaded. + # + def save_configuration_file! + to_save = @loaded_rc_file ? @loaded_rc_file : File.join(ENV["HOME"], "mubyrc") + begin + Kernel::open(to_save, "w") do |output| + output.write(self.to_ruby) + @loaded_rc_file = to_save + end + Muby::Displayer.info("Saved default configuration to #{to_save}.") + rescue Exception => e + Muby::Displayer.warn("Failed saving default configuration to #{to_save}: #{e.message}") + Muby::Displayer.debug(e.backtrace.join("\n")) + end + end + + # + # Tries to load all the users files, defined as + # any file named .mubyrc or mubyrc in the users ENV["HOME"] + # and all **/*.rb files in the users ENV["HOME"]/@userdir + # with the root of the userdir taking precidence over subdirectories. + # Directories starting with a . are ignored. + # + # If none of the mubyrc-files existed, it will try to create one + # for the user to edit to his/her liking. + # + def load_user_files! + @loaded_rc_file = false + [".mubyrc", "mubyrc"].each do |file_name| + to_load = File.join(ENV["HOME"], file_name) + if File.exists?(to_load) + nice_load!(to_load) + @loaded_rc_file = to_load + break + end + end + + unless @loaded_rc_file + save_configuration_file! + end + + if File.exists?(@userdir) + # Only load *.rb files within sub-directories of the current directory, and not the current directory's *.rb files!) + # Test: Dir[File.join(Dir.pwd, "*", "**", "*.rb")].each do |f| puts f end ; nil + Dir[File.join(@userdir, "*", "**", "*.rb")].each do |file_name| + nice_load!(file_name) + end + # Only load *.rb files of the current directory. + # This is very useful for users to create "overrides" for items in subdirectories. + # NOTE: This does follow symbolic links (files and directories) + # Test: Dir[File.join(Dir.pwd, "*.rb")].each do |f| puts f end ; nil + Dir[File.join(@userdir, "*.rb")].each do |file_name| + nice_load!(file_name) + end + else + Muby::Displayer.warn("#{@userdir} does not exist. If it did, *.rb in it would be loaded now.") + end + end + + # + # A non-raising method that tries to load +f+ and tells the output window about its success. + # + def nice_load!(f) + begin + Kernel::load(f) + Muby::Displayer.info("Loaded #{f}") + rescue Exception => e + Muby::Displayer.exception(e) + end + end + + # + # Will reload the entire app, ie the class files and the + # user files. + # + # TODO: Remove the spammyness. + # It is not appropriate to use 'puts' when reload_application! is being called by the user. + # To turn off "uninitialised constant" warnings, do: $VERBOSE = nil + # + # Simply set your show_level to :warn instead of :info, and you wont see the load messages. + # + # Any other messages come from your own files :O + # + def reload_application! + Dir[File.join(File.dirname(__FILE__), "**", "*.rb")].each do |file_name| + nice_load! file_name + end + load_user_files! + end + + # + # The not so magical at all method that prints our content + # to a String so that we easily can save our current settings + # in a file, or create a default config file. + # + def to_ruby + "# +# This is the default configuration of muby. +# To learn more about how to configure it, you +# can type '/help' in the client. +# +include Muby::Configurable +" + + instance_variables.sort.collect do |var_name| + value = eval(var_name) + case value + when Hash + space = "conf.#{var_name[1..-1]} = _".size + value = value.inspect.gsub(/, /, ",\n#{" " * space}") + when File + begin + value.read(0) + value = "open(\"#{value.path}\", \"r\")" + rescue + value = "open(\"#{value.path}\", \"a\")" + end + when NilClass + value = value.inspect + else + value = value.inspect + end + var_name = var_name[1..-1] + help_text = Muby::Help.configuration[var_name.to_sym] || "no help available for #{var_name}" + help_text = help_text.split("\n").join("\n# ") + " +# #{help_text} +conf.#{var_name} = #{value}" + end.join("\n") + end + + end + + # + # The module that provides the shorthand for + # using classes. + # + module Configurable + def conf + Configuration.get + end + end + +end Added: lib/muby/connection.rb =================================================================== --- lib/muby/connection.rb (rev 0) +++ lib/muby/connection.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -0,0 +1,332 @@ +# +# The class that encapsulates the actual Connection +# +class Muby::Connection + + include Muby::Logger + include Muby::Configurable + include Muby::Displayer + + # + # Set it up with windows, handle and host info. + # + def initialize(inputWindow, outputWindow, host, port) + @inputWindow = inputWindow + @outputWindow = outputWindow + status("Connecting to " + host.inspect + ":" + port.inspect) + @host = host + @port = port + @socket = TCPSocket.open(host, port) if host && port + conf.connect_triggers.each do |command| + @inputWindow.execute(command, @inputWindow, @outputWindow) + end + status("Connected to " + host.inspect + ":" + port.inspect) + @matchBuffer = "" + @showBuffer = [] + @used_triggers = {} + @listener = Thread.new do + begin + status("Listening thread started") + listen + status("Listening thread finished") + rescue Exception => e + exception(e) + ensure + close + end + end if @socket + end + + # + # Display a status message in the outputwindow if wanted (conf.connection_status) + # + def status(message) + if conf.connection_status + @outputWindow.print_on_newline(*[message + "\n"]) + end + end + + # + # Check if we want to gag the current matchBuffer and debug about it. + # + # Remove the gag regexp if it is broken. + # + def gag(matchBuffer) + returnValue = false + conf.gags.each do |gag| + begin + if matchBuffer.match(gag) + trace(matchBuffer + " matches " + gag.inspect + ": gag active") + returnValue = true + end + rescue RegexpError => error + conf.gags.delete(key) + exception(e) + end + end + returnValue + end + + # + # Check if we should definitely NOT gag the current matchBuffer, and debug about it. + # + # Remove the nongag regexp if it is broken. + # + def nongag(matchBuffer) + returnValue = false + conf.anti_gags.each do |nongag| + begin + if matchBuffer.match(nongag) + trace(matchBuffer + " matches " + nongag.inspect + ": nongag active") + returnValue = true + end + rescue RegexpError => error + conf.anti_gags.delete(key) + exception(e) + end + end + returnValue + end + + # + # Check if we should trigger a Proc on the current matchBuffer, and debug about it. + # + # Remove the trigger regexp if it is broken. + # + def trigger(matchBuffer, hash, skip_used = true) + hash.each do |key, value| + if skip_used && @used_triggers.include?(key) + trace("#{key.inspect} has already been matched on this line, skipping it") + else + trace("checking if " + matchBuffer + " matches " + key.inspect) + begin + if match = matchBuffer.match(key) + trace(matchBuffer + " matches " + key.inspect + ": .call'ing Proc") + # Run the procedure associated with that trigger: + @inputWindow.execute(value, @inputWindow, @outputWindow, match) + @used_triggers[key] = true if skip_used + end + # If we received an error with the regular expression: + rescue RegexpError => error + hash.delete(key) + exception(error) + end + end + end + end + + def feed(s) + s.unpack("C*").each do |c| + handle(c) + end + nil + end + + def getc + c = @socket.getc + log_input(c.chr) if c + c + end + + def handle(c) + # + # The telnet support (just so we dont explode or something) + # + # We are just plain ignoring it atm. + # + if c == 255 # telnet interpret as command (IAC) + c = getc # get the request (DO|DONT) + c = getc # get the latest part whatever that is + elsif c == 27 # escape char! this is probably some ANSI color or shite + c = getc + if c.chr == "[" # this is an ansi-something that is more than one char long + ansiString = "" + while !"cnRhl()HABCfsurhgKJipm".include?((c = getc).chr) + ansiString << c.chr + end + if c.chr == "m" && Ncurses.has_colors? # ah, text property! i understand this! + properties = ansiString.split(";") + attributes = 0 + bgcolor = false + fgcolor = false + reset = properties.index("0") + if reset + properties.delete("0") + end + properties.each do |property| + case property.to_i + when 1 + attributes = attributes | Ncurses.const_get("A_BOLD") + when 2 + attributes = attributes | Ncurses.const_get("A_DIM") + when 4 + attributes = attributes | Ncurses.const_get("A_UNDERLINE") + when 5 + attributes = attributes | Ncurses.const_get("A_BLINK") unless conf.disable_blink + when 7 + attributes = attributes | Ncurses.const_get("A_REVERSE") + when 8 + attributes = attributes | Ncurses.const_get("A_INVIS") + when 30 + fgcolor = Ncurses.const_get("COLOR_BLACK") + when 31 + fgcolor = Ncurses.const_get("COLOR_RED") + when 32 + fgcolor = Ncurses.const_get("COLOR_GREEN") + when 33 + fgcolor = Ncurses.const_get("COLOR_YELLOW") + when 34 + fgcolor = Ncurses.const_get("COLOR_BLUE") + when 35 + fgcolor = Ncurses.const_get("COLOR_MAGENTA") + when 36 + fgcolor = Ncurses.const_get("COLOR_CYAN") + when 37 + fgcolor = Ncurses.const_get("COLOR_WHITE") + when 40 + bgcolor = Ncurses.const_get("COLOR_BLACK") + when 41 + bgcolor = Ncurses.const_get("COLOR_RED") + when 42 + bgcolor = Ncurses.const_get("COLOR_GREEN") + when 43 + bgcolor = Ncurses.const_get("COLOR_YELLOW") + when 44 + bgcolor = Ncurses.const_get("COLOR_BLUE") + when 45 + bgcolor = Ncurses.const_get("COLOR_MAGENTA") + when 46 + bgcolor = Ncurses.const_get("COLOR_CYAN") + when 47 + bgcolor = Ncurses.const_get("COLOR_WHITE") + end + end + style = nil + if reset + style = Muby::Style.new(attributes, fgcolor, bgcolor, false) + else + style = Muby::Style.new(attributes, fgcolor, bgcolor, true) + end + @showBuffer.push(style) + end + end + elsif ! conf.broken_keycodes.include?(c) + # + # This is not telnet command OR ansi, lets treat it as nice MUD text! + # + # Debug about it, add it to match buffer, add it to show buffer and show if we want to show. + # Then check it for triggers. + # + @matchBuffer = @matchBuffer + c.chr + append_show_buffer(c.chr) + manage_buffers(c) + end + end + + def append_show_buffer(c) + if String === @showBuffer.last + @showBuffer.last << c + else + @showBuffer << c + end + end + + # + # Keep listening to the remote socket and react accordingly. + # + def listen + c = true + # We have to look at each byte for ncurses reasons as well as triggers etc. + while c + while select([@socket],nil,nil,1) && c = getc + handle(c) + end + if conf.flush + display_buffer + end + end + status("Connection closed by remote end") + @inputWindow.disconnect + end + + def close + if Thread.current != @listener && @listener && @listener.alive? + status("Killing listening thread") + @listener.kill + end + if @socket && !@socket.closed? + status("Disconnecting our end") + @socket.close if @socket + end + end + + def manage_buffers(c) + trigger(@matchBuffer, conf.remote_character_triggers, true) + if c == 10 + trigger(@matchBuffer, conf.remote_triggers, false) + display_buffer + @matchBuffer = "" + @used_triggers = {} + @showBuffer = [] + end + end + + def homemade_split(s, r) + rval = [] + rest = s + while match = rest.match(/(.*?)#{r.source}(.*)/) + rval << match[1] + rest = match[2] + end + rval << rest + rval + end + + def substitute(buffer, hash) + return_value = [] + buffer.each do |part| + if String === part + part_to_append = [part] + hash.each do |regexp, substitution| + case substitution + when String + part_to_append = [part.gsub(regexp, substitution)] + when Array + if part.match(regexp) + split_part = homemade_split(part, regexp) + part_to_append = split_part.zip([substitution] * (split_part.size - 1)).flatten.compact + end + end + end + return_value += part_to_append + else + return_value << part + end + end + return_value + end + + def display_buffer + unless @showBuffer.empty? + if !gag(@matchBuffer) || nongag(@matchBuffer) + @showBuffer = substitute(@showBuffer, conf.remote_substitutions) + Muby::Completer.get_instance.store(@matchBuffer) if conf.feed_completer_with_input + @outputWindow.print(*@showBuffer) + end + @showBuffer = [] + end + end + + # + # Just plain send the string we got. + # + def send(s) + log_output(s) + conf.local_substitutions.each do |key, value| + # It might be useful to allow colour codes for highlighting local substitutions.. but only when echo is on. + # No, cause this only gets sent to the server, it never shows up to the user. + s.gsub!(key, value) + end + @socket.print(s) if @socket + end +end # class Connection Added: lib/muby/displayer.rb =================================================================== --- lib/muby/displayer.rb (rev 0) +++ lib/muby/displayer.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -0,0 +1,60 @@ + +module Muby + + module Displayer + + def exception(e) + error("#{e.class}: #{e.message}") + debug(e.backtrace.join("\n")) + end + + def trace(s) + if Muby::OutputWindow.get_instance.ready? + Muby::OutputWindow.get_instance.show(:trace, s) + elsif Muby::Configuration.get.display?(:trace) + puts s + end + end + + def debug(s) + if Muby::OutputWindow.get_instance.ready? + Muby::OutputWindow.get_instance.show(:debug, s) + elsif Muby::Configuration.get.display?(:debug) + puts s + end + end + + def info(s) + if Muby::OutputWindow.get_instance.ready? + Muby::OutputWindow.get_instance.show(:info, s) + elsif Muby::Configuration.get.display?(:info) + puts s + end + end + + def warn(s) + if Muby::OutputWindow.get_instance.ready? + Muby::OutputWindow.get_instance.show(:warn, s) + elsif Muby::Configuration.get.display?(:warn) + puts s + end + end + + def error(s) + if Muby::OutputWindow.get_instance.ready? + Muby::OutputWindow.get_instance.show(:error, s) + elsif Muby::Configuration.get.display?(:error) + puts s + end + end + + module_function :trace + module_function :debug + module_function :info + module_function :warn + module_function :error + module_function :exception + + end + +end Added: lib/muby/help.rb =================================================================== --- lib/muby/help.rb (rev 0) +++ lib/muby/help.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -0,0 +1,88 @@ +module Muby + + module Help + def self.configuration + { + :feed_completer_with_history => "If true, the completion command will use history to calculate possible completions.", + :feed_completer_with_input => "If true, the completion command will use everything seen from the remote end to calculate possible completions.", + :extra_completions => "Fill this array with words that you allways want to be able to complete to.", + :extra_verbosity_settings => "The settings we want to toggle to when running the toggle_verbosity! method.", + :echo_keycodes => "Whether to echo the keycode for every key pressed or not.", + :echo => "Whether to print what is sent to the server to the outputwindow.", + :show_level => "What level of information to provide the user. +:trace may tell you each and every step the app takes. +:debug may tell the user most everything that happens. +:info will tell the user basically what we are doing. +:warn will only tell the user when we think he/she may gain from it. +:error will only tell the user when an error occurs.", + :timestamp => "Whether to timestamp all messages in the output window.", + :connection_status => "Whether to give status reports on the connections.", + :timeformat => "What type of timestamp to use.", + :loaded_rc_file => "This will be set to whichever mubyrc file was loaded upon startup.", + :disable_blink => "Set this to true if you NEVER want to see BLINKING text from the server.", + :broken_keycodes => "Which characters to filter out completely.", + :max_history => "The maximum length of the history buffer.", + :user_edited_config_file => "Change this to true when you dont want to see the help message anymore.", + :default_attributes => "The default ncurses attributes for text.", + :default_colors => "The default ncurses colors for text.", + :echo_attributes => "The default ncurses attributes for echoed (typed by you, showed in the output window) text.", + :echo_colors => "The default ncurses colors for echoed (typed by you, showed in the output window) text.", + :trace_attributes => "The default ncurses attributes for messages shown under trace loglevel.", + :trace_colors => "The default ncurses colors attributes for messages shown under trace loglevel.", + :debug_attributes => "The default ncurses attributes for messages shown under debug loglevel.", + :debug_colors => "The default ncurses colors attributes for messages shown under debug loglevel.", + :info_attributes => "The default ncurses attributes for messages shown under info loglevel.", + :info_colors => "The default ncurses colors attributes for messages shown under info loglevel.", + :warn_attributes => "The default ncurses attributes for messages shown under warn loglevel.", + :warn_colors => "The default ncurses colors attributes for messages shown under warn loglevel.", + :error_attributes => "The default ncurses attributes for messages shown under error loglevel.", + :error_colors => "The default ncurses colors attributes for messages shown under error loglevel.", + :flush => "Whether to display every char we get as soon as there is a pause in the transfer or a newline. +In contrast to only displaying the input characters when there is a newline.", + :gags => "The gags. All lines from the server are checked against these regular expressions. +If any one matches that line will not be shown. Note that if you have flush == true, the characters may already have been shown.", + :remote_substitutions => "The remote substitutions. +The same buffer that the remote_triggers work on will be searched for matches to the keys in this hash. +All values to matching keys will replace the keys in the buffer.", + :local_substitutions => "The local substitutions. +The text you send to the server will be searched for matches to the keys in this hash. +All values to matching keys will replace the keys in the text.", + :anti_gags => "The anti gags. +If flush == false the lines matching these regular expressions will be shown as soon as they are matched. +A line matching an anti gag and a gag will also be shown.", + :shutdown_triggers => "The shutdown triggers. Code in this array will be run in order at shutdown.", + :connect_triggers => "The connect triggers. Code in this array will be run in order when a connection is made.", + :startup_triggers => "The startup triggers. Code in this array will be run in order after the windows have been properly initialized.", + :remote_triggers => 'The remote triggers. +Each line received from the server will be checked against all regular expression keys in this hash, and all values to matching keys will be executed with three parameters: the input window, the output window and the match object. +Example: conf.remote_triggers[/^You feel dazed$/] = Proc.new do |inwin, outwin, match| inwin.set_status_message("dazed") end', + :remote_character_triggers => 'The remote character triggers. +All input from the server is added to a buffer that is cleared on newline and each time a new character is added to that buffer the buffer will be checked against all the regular expression keys in the remote_character_triggers. +All code values belonging to matching keys will be executed with three parameters: the input window, the output window and the match object. +Example: conf.remote_character_triggers[/^(\S+) attacks you$/] = Proc.new do |inwin, outwin, match| inwin.send("kill #{match[1]}") end', + :local_triggers => 'The local triggers. +Every line that is to be sent to the server is matched against the regular expression keys in this hash before they are sent. +All code values belonging to matching keys will be executed with three parameters: the input window, the output window and the match object. +Only if the return value of this execution is not false will the line be sent to the server. +Example: conf.local_triggers[/^bp (\S+)$/] = Proc.new do |inwin, outwin, match| inwin.send("put #{match[1]} in backpack") end', + :key_commands => 'The key commands. +Each key pressed will have its keycode checked against the integer keys of this hash. +If no key match and the keycode is below 256, the character corresponding to this code will be appended to the input line. +If a key matches the value in the hash will be checked. +If the value is another hash a new key will be waited for, and the same procedure will take place with the value hash instead. +If the value is not a hash it will be executed as code with three parameters: the input window, the output window and the matching key. +Example: conf.key_commands[65] = Proc.new do |inwin, outwin, char| inwin.echo("I just pressed A") end', + :userdir => 'The user directory. All *.rb files in this directory will be loaded on startup and on reload_application! +The root of the user directory takes precidence over (overrides) sub-directories. +Symbolic links (files and directories) are also used. +Directories beginning with a period are ignored.', + :history_file => 'The file where we will store the history of entered commands.', + :output_buffer => 'The number of rows that will be buffered in the output window for scrollback.', + :input_height => 'The number of rows in the input window.', + :input_logfile => 'The IO object that will receive everything we receive from the remote end.', + :output_logfile => 'The IO object that will receive everything we send to the remote end.' + } + end + end + +end Added: lib/muby/inputwindow.rb =================================================================== --- lib/muby/inputwindow.rb (rev 0) +++ lib/muby/inputwindow.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -0,0 +1,192 @@ +# +# The fancy window that gets our input. +# +# The class handles everything to do with +# the input window itself, the user callable +# methods are in the UserMethods module. +# +# All commands entered with conf.escape_character will be eval'd in +# this class scope. +# +class Muby::InputWindow + + include Muby::Logger + include Muby::Configurable + include Muby::Displayer + include Muby::UserMethods + include Muby::Styled + + @@instance = Muby::InputWindow.new unless defined?(@@instance) + + def self.get_instance + @@instance + end + + attr_reader :history + + # + # Start working! + # + def go(outputWindow, inputHeight = 3) + # Init all the default values + @outputWindow = outputWindow + @inputHeight = inputHeight + @buffer = "" + @cursorPosition = 0 + @history = [] + @historyPointer = nil + @inputWidth = Ncurses.COLS - 2 + @connection = nil + @statusLine = "" + @messageLine = "" + @recent_escape = [] + @handle_mode = :append_buffer! + + # Init the input box + @inputBorder = Ncurses.newwin(@inputHeight + 2, Ncurses.COLS, Ncurses.LINES - (@inputHeight + 2), 0) + @inputBorder.box(0,0) + @inputBorder.keypad(true) + @inputBorder.refresh + + # Init the window itself + @inputWindow = Ncurses.newwin(@inputHeight, at inputWidth,Ncurses.LINES - (@inputHeight + 1), 1) + @inputWindow.keypad(true) + @inputWindow.scrollok(true) + @inputWindow.nodelay(true) + @inputWindow.refresh + + help unless conf.user_edited_config_file + end + + # + # Update the input box, redrawing borders and text etc. + # + def update + @inputBorder.box(0,0) + @inputBorder.mvwprintw(0,1,"%s", @statusLine) + @inputBorder.mvwprintw(@inputHeight + 1, 1, "%s", @messageLine) + @inputBorder.refresh + + @inputWindow.werase + row = 0 + col = @cursorPosition + while col > @inputWidth + row = row + 1 + col = col - @inputWidth + end + @inputWindow.mvwprintw(row,col,"%s", @buffer[@cursorPosition, at buffer.size - @cursorPosition]) + @inputWindow.mvwprintw(0,0,"%s", @buffer[0, @cursorPosition]) + @inputWindow.refresh + end + + def execute(command, *args) + execute_with_verbosity(:debug, command, *args) + end + + def execute_with_verbosity(verbosity, command, *args) + begin + result = nil + if Proc === command + result = command.call(*args[0...(command.arity)]) + elsif String === command + result = eval(command) + elsif Symbol === command + method = self.method(command) + args = args[0...(method.arity)] + result = method.call(*args) + elsif Array === command + method = self.method(command.first) + args = (command[1..-1] + args)[0...(method.arity)] + result = method.call(*args) + end + unless result.nil? + case result + when String + @outputWindow.show(verbosity, result) + else + @outputWindow.show(verbosity, result.inspect) + end + end + result + rescue SystemExit => ex + quit + rescue Exception => e + exception(e) + end + end + + # + # Save our history into the history file. + # + def saveHistory + # This should be wrapped in something else, which checks for sanity (writability) + dir = Pathname.new(conf.history_file).parent + dir.mkpath unless dir.exist? + file = Pathname.new(conf.history_file) + file.open("w") do |output| + Marshal.dump(@history, output) + end + end + + # + # Load our history from the history file. + # + def loadHistory + begin + if FileTest.readable?(conf.history_file) + info("Reading history file") + Kernel::open(conf.history_file) do |input| + @history = Marshal.load(input.read) + end + @history.each do |line| + Muby::Completer.get_instance.store(line) + end if conf.feed_completer_with_history + end + rescue Exception => e + exception(e) + end + @history ||= [] + end + + def handle(c, hash) + # Echo the keycode we got if we have conf.echo_keycodes == true (good for setting up conf.key_commands) + if conf.echo_keycodes && c != Ncurses.const_get("ERR") + info(c.to_s) + end + if hash.include?(c) + value = hash[c] + if Hash === value + c = @inputWindow.wgetch + if value.include?(c) + handle(c, value) + else + handle(c, conf.key_commands) + end + else + execute(value, self, @outputWindow, c) + end + elsif 0 < c && c < 265 + method = self.method(@handle_mode) + method.call(c) + end + end + + # + # Just keep listening to the keyboard input. + # + def process + loadHistory + conf.startup_triggers.each do |trigger| + execute(trigger, self, @outputWindow) + end + # We need to check one key at a time due to triggers and conf.key_commands + while c = @inputWindow.wgetch + if c == Ncurses.const_get("ERR") + sleep(0.01) + else + handle(c, conf.key_commands) + end + end # while c = @inputWindow.wgetch + end # def process + +end # class InputWindow Added: lib/muby/logger.rb =================================================================== --- lib/muby/logger.rb (rev 0) +++ lib/muby/logger.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -0,0 +1,28 @@ +# +# A simple logger that logs to whatever logfiles you have defined +# in your preferences. +# +module Muby::Logger + + include Muby::Configurable + + # + # Logs everything that gets read from the remote connection. + # + def log_input(c) + if conf.input_logfile + conf.input_logfile.write(c) + conf.input_logfile.flush + end + end + + # + # Logs everything that gets sent to the remote connection. + # + def log_output(c) + if conf.output_logfile + conf.output_logfile.write(c) + conf.output_logfile.flush + end + end +end # module Logger Added: lib/muby/outputwindow.rb =================================================================== --- lib/muby/outputwindow.rb (rev 0) +++ lib/muby/outputwindow.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -0,0 +1,167 @@ +# +# The class that controls what we see. +# +class Muby::OutputWindow + + include Muby::Logger + include Muby::Configurable + + attr_reader :scrollback, :pageSize, :size, :outputBuffer + + @@instance = Muby::OutputWindow.new unless defined?(@@instance) + + def self.get_instance + @@instance + end + + def initialize + @ready = false + end + + def ready? + @ready + end + + # + # Start working! + # + def go(size = 1000, inputHeight = 3) + @size = size + @inputHeight = inputHeight + @scrollback = 0 + @pageSize = Ncurses.LINES - inputHeight - 2 + @waitBuffer = [] + @lines = 0 + + @outputBuffer = Ncurses.newpad(@size, Ncurses.COLS) + @outputBuffer.wclear + @outputBuffer.scrollok(true) + @outputBuffer.idlok(true) + defaultAttributes = Muby::Style.new(conf.default_attributes, conf.default_colors[0], conf.default_colors[1]) + defaultAttributes.affect(@outputBuffer) + # Prepare the output window: + @outputBuffer.mvprintw(@size - 1, 0, "\n") + + show_version + refresh + + @ready = true + end + + def show_version + print(" +.--.--.--. .--. +: :--.--: : .--.--. +: : : : : : '-: : : +: : : : : : : : ' : +'--'--'--'-----'----'--. : + The Ruby MUD Client : : + ------------------- '--' + Version #{MUBY_VERSION} +") + end + + # + # Refresh the output buffer (if we have scrolled etc) + # + def refresh + @outputBuffer.prefresh(@size - (@pageSize * (@scrollback + 1)), 0, 0, 0, @pageSize - 1, Ncurses.COLS) + end + + # + # Scroll up, and give the user a message about it. + # + def scroll_up(inputWindow) + if @scrollback * @pageSize < conf.output_buffer && + @scrollback * @pageSize < @lines + @scrollback += 1 + # BUG: set_message_line is in userMethods. + # No, its not a bug. + inputWindow.set_message_line("SCROLLED - I/O PAUSED") + refresh + end + end + + # + # Scroll down again. + # + def scroll_down(inputWindow) + if @scrollback > 0 + @scrollback -= 1 + if @scrollback == 0 + # BUG: + # No + inputWindow.set_message_line("") + unless @waitBuffer.empty? + print(*@waitBuffer) + @waitBuffer = [] + end + end + end + refresh + end + + def timestamp(message) + if conf.timestamp && @recent_linebreak + Time.new.strftime(conf.timeformat) + "\t" + message + else + message + end + end + + def show(level, message) + if conf.display?(level) + to_print = [message, "\n"] + if level_attributes = conf.send("#{level}_attributes") + level_colors = conf.send("#{level}_colors") + style = Muby::Style.new(level_attributes, level_colors[0], level_colors[1]) + oldStyle = Muby::Style.extract(@outputBuffer) + to_print = [style] + to_print + [oldStyle] + end + + print_on_newline(*to_print) + end + end + + def print_on_newline(*info) + if @recent_linebreak + print(*info) + else + print(*(["\n"] + info)) + end + end + + # + # Print an info Array to the outputBuffer. + # + # Will print text as is, and add any Styles encountered to the outputBuffer. + # + def print(*info) + if @scrollback == 0 + info.each do |e| + if String === e + rest = e + while (match = rest.match(/^([^\r\n]*)([\r\n]*)(.*)$/m)) + to_print = match[1] + linebreak = match[2] + rest = match[3] + + break if to_print.empty? and linebreak.empty? + + @outputBuffer.printw("%s", timestamp(to_print) + linebreak) + + @recent_linebreak = !linebreak.empty? + @lines += 1 unless linebreak.empty? + end + elsif Muby::Style === e + e.affect(@outputBuffer) + end + end + else + @waitBuffer += info + end + refresh + nil + end + +end # class OutputWindow Added: lib/muby/style.rb =================================================================== --- lib/muby/style.rb (rev 0) +++ lib/muby/style.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -0,0 +1,142 @@ +module Muby + + # + # The encapsulation of all the ncurses horror. + # + class Style + + include Muby::Logger + include Muby::Configurable + + attr_reader :attributes, :color1, :color2 + + class ColorPair + @@instances = [] + @@initialized = false + def self.init_pairs + unless @@initialized + 1.upto(Ncurses.COLOR_PAIRS - 1) do |n| + @@instances << ColorPair.new(n) + end + @@initialized = true + end + end + def self.get_pair(fg, bg) + init_pairs + + found = @@instances.find do |color| + color.bg == bg && color.fg == fg + end + + found = @@instances.find do |color| + color.bg.nil? && color.fg.nil? + end unless found + + found = @@instances.sort do |c1, c2| + c1.used_at <=> c2.used_at + end.first unless found + + found.use(fg, bg) + + found + end + + attr_accessor :bg, :fg, :number, :used_at + + def initialize(number) + @number = number + @used_at = Time.new + end + + def to_i + Ncurses.COLOR_PAIR(@number) + end + + def use(fg, bg) + @used_at = Time.new + if (bg != @bg || fg != @fg) + @bg = bg + @fg = fg + Ncurses.init_pair(@number, @fg, @bg) + end + end + end + + def initialize(attributes, color1, color2, toAdd = false) + @attributes = attributes + @color1 = color1 + @color2 = color2 + @toAdd = toAdd + end + + # + # Get a Style instance from a window (so we can save it and restore it) + # + def self.extract(window) + tmp = [] + oldAttributes = [] + oldAttribute = 0 + oldColorPair = [] + oldColor1 = [] + oldColor2 = [] + + window.wattr_get(oldAttributes,oldColorPair,tmp) + oldAttribute = oldAttributes[0] ^ Ncurses.COLOR_PAIR(oldColorPair[0]) + Ncurses.pair_content(oldColorPair[0], oldColor1, oldColor2) + + Muby::Style.new(oldAttribute, oldColor1[0], oldColor2[0]) + end + + # + # Affect the window, either overwriting its style or adding to it. + # + def affect(window) + if @toAdd + window.wattron(to_int(window)) + else + window.wattrset(to_int(window)) + end + end + + def get_color_value(fg, bg) + Muby::Style::ColorPair.get_pair(fg, bg).to_i + end + + # + # Get an int representation of this style, to send to ncurses. + # + def to_int(window) + oldAttributes = self.class.extract(window) + color1 = @color1 == :copy ? oldAttributes.color1 : @color1 || conf.default_colors[0] + color2 = @color2 == :copy ? oldAttributes.color2 : @color2 || conf.default_colors[1] + @attributes | get_color_value(color1, color2) + end + + end # class Style + + module Styled + unless defined?(RED) + RED = Muby::Style.new(0, Ncurses.const_get("COLOR_RED"), :copy, true) + BLACK = Muby::Style.new(0, Ncurses.const_get("COLOR_BLACK"), :copy, true) + GREEN = Muby::Style.new(0, Ncurses.const_get("COLOR_GREEN"), :copy, true) + YELLOW = Muby::Style.new(0, Ncurses.const_get("COLOR_YELLOW"), :copy, true) + MAGENTA = Muby::Style.new(0, Ncurses.const_get("COLOR_MAGENTA"), :copy, true) + BLUE = Muby::Style.new(0, Ncurses.const_get("COLOR_BLUE"), :copy, true) + CYAN = Muby::Style.new(0, Ncurses.const_get("COLOR_CYAN"), :copy, true) + WHITE = Muby::Style.new(0, Ncurses.const_get("COLOR_WHITE"), :copy, true) + + BOLD = Muby::Style.new(Ncurses.const_get("A_BOLD"), :copy, :copy, true) + DIM = Muby::Style.new(Ncurses.const_get("A_DIM"), :copy, :copy, true) + UNDERLINE = Muby::Style.new(Ncurses.const_get("A_UNDERLINE"), :copy, :copy, true) + BLINK = Muby::Style.new(Ncurses.const_get("A_BLINK"), :copy, :copy, true) + REVERSE = Muby::Style.new(Ncurses.const_get("A_REVERSE"), :copy, :copy, true) + INVIS = Muby::Style.new(Ncurses.const_get("A_INVIS"), :copy, :copy, true) + STANDOUT = Muby::Style.new(Ncurses.const_get("A_STANDOUT"), :copy, :copy, true) + PROTECT = Muby::Style.new(Ncurses.const_get("A_PROTECT"), :copy, :copy, true) + ALTCHARSET = Muby::Style.new(Ncurses.const_get("A_ALTCHARSET"), :copy, :copy, true) + CHARTEXT = Muby::Style.new(Ncurses.const_get("A_CHARTEXT"), :copy, :copy, true) + + NORMAL = Muby::Style.new(Ncurses.const_get("A_NORMAL"), :copy, :copy, false) + end + end +end Added: lib/muby/user_methods.rb =================================================================== --- lib/muby/user_methods.rb (rev 0) +++ lib/muby/user_methods.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -0,0 +1,462 @@ + +module Muby + + # + # This is the UserMethod module. + # + # It is supposed to contain all the muby kernel methods that are + # supposed to be used by the user or the key_commands. + # + module UserMethods + + def help + help = < conf.max_history + @history.shift + end + @buffer << c.chr + conf.local_triggers.each do |regexp, command| + begin + if match = @buffer.match(regexp) + @buffer = "" unless execute(command, self, @outputWindow, match) + end + rescue RegexpError => error + conf.local_triggers.delete(key) + exception(error) + end + end + sendn(@buffer) unless @buffer.empty? + @buffer = "" + @cursorPosition = 0 + update + nil + end + + def backspace_buffer! + if @handle_mode == :history_search! + if @cursorPosition > 1 + @search_buffer = @search_buffer[0...-1] + @cursorPosition -= 1 + update_history_search! + end + else + if @cursorPosition > 0 + @buffer = @buffer[0, @cursorPosition - 1] + @buffer[@cursorPosition, @buffer.size - @cursorPosition] + @cursorPosition -= 1 + update + end + end + nil + end + + def word_backspace_buffer! + unless @handle_mode == :history_search! + if @cursorPosition > 0 + while @cursorPosition != 0 && @buffer[@cursorPosition - 1].chr.match("\\W") + @buffer = @buffer[0, @cursorPosition - 1] + @buffer[@cursorPosition, @buffer.size - @cursorPosition] + @cursorPosition = @cursorPosition - 1 + end + while @cursorPosition != 0 && @buffer[@cursorPosition - 1].chr.match("\\w") + @buffer = @buffer[0, @cursorPosition - 1] + @buffer[@cursorPosition, @buffer.size - @cursorPosition] + @cursorPosition = @cursorPosition - 1 + end + update + end + end + nil + end + + def delete_buffer! + unless @handle_mode == :history_search! + if @cursorPosition < @buffer.size + @buffer = @buffer[0, @cursorPosition] + @buffer[@cursorPosition + 1, @buffer.size - @cursorPosition - 1] + update + end + end + nil + end + + def reload_application! + conf.reload_application! + end + + def complete! + unless @handle_mode == :history_search! + last_word = @buffer.match(/(\w*)$/)[1] + completions = Muby::Completer.get_instance.complete(last_word) + if completions.size == 1 + @buffer.gsub!(last_word, completions[0]) + @cursorPosition = @buffer.size + update + else + info(completions.inspect) + end + end + nil + end + + def update_history_buffer! + if @historyPointer && @history.size > 0 + @buffer = @history[@historyPointer].clone + else + @buffer = "" + end + @cursorPosition = @buffer.size + update + nil + end + + def previous_history_buffer! + if @handle_mode == :append_buffer! + if @history.size > 0 + if @historyPointer && @historyPointer > 0 + @historyPointer -= 1 + elsif @historyPointer.nil? + @historyPointer = @history.size - 1 + end + update_history_buffer! + end + else + @historyPointer += 1 + update_history_search! + end + nil + end + + def next_history_buffer! + if @handle_mode == :append_buffer! + if @history.size > 0 && @historyPointer + if @historyPointer < @history.size - 1 + @historyPointer += 1 + else + @historyPointer = nil + end + update_history_buffer! + end + else + @historyPointer -= 1 + update_history_search! + end + nil + end + + def next_word_buffer! + unless @handle_mode == :history_search! + if @buffer.size > 0 + start = @cursorPosition + @cursorPosition = (@cursorPosition + 1) % (@buffer.size) + while @cursorPosition != 0 && @cursorPosition != @buffer.size && @cursorPosition != start && @buffer[@cursorPosition].chr.match("\\w") + @cursorPosition = (@cursorPosition + 1) % (@buffer.size + 1) + end + update + end + end + nil + end + + def home_buffer! + unless @handle_mode == :history_search! + @cursorPosition = 0 + update + end + nil + end + + def previous_word_buffer! + unless @handle_mode == :history_search! + if @buffer.size > 0 + start = @cursorPosition + @cursorPosition = (@cursorPosition - 1) % (@buffer.size) + while @cursorPosition != 0 && @cursorPosition != @buffer.size && @cursorPosition != start && @buffer[@cursorPosition].chr.match("\\w") + @cursorPosition = (@cursorPosition - 1) % (@buffer.size + 1) + end + update + end + end + nil + end + + def previous_character_buffer! + unless @handle_mode == :history_search! + if @buffer.size > 0 + @cursorPosition = (@cursorPosition - 1) % (@buffer.size + 1) + update + end + end + nil + end + + def next_character_buffer! + unless @handle_mode == :history_search! + if @buffer.size > 0 + @cursorPosition = (@cursorPosition + 1) % (@buffer.size + 1) + update + end + end + nil + end + + def end_buffer! + unless @handle_mode == :history_search! + @cursorPosition = @buffer.size + update + end + nil + end + + def two_step_quit! + if @user_quit then + quit + else + @user_quit = true + info "Press again within 5 seconds to quit." + Thread.new do + sleep(5) + @user_quit = false + end + end + nil + end + + def toggle_history_search! + if @handle_mode == :append_buffer! + enable_history_search! + else + disable_history_search! + end + nil + end + + def enable_history_search! + if @handle_mode == :append_buffer! + @historyPointer = 0 + @handle_mode = :history_search! + @search_buffer = @buffer + update_history_search! + end + nil + end + + def disable_history_search! + unless @handle_mode == :append_buffer! + @historyPointer = nil + @handle_mode = :append_buffer! + @buffer = @found_history || "" + @cursorPosition = @buffer.size + @search_buffer = "" + update + end + nil + end + + def update_history_search! + @search_buffer ||= "" + @found_history_array = @history.reverse.select do |line| + line.match(Regexp.new(@search_buffer)) + end + @found_history_array << "" if @found_history_array.empty? + @found_history = @found_history_array[@historyPointer % @found_history_array.size] + @buffer = "(#{@search_buffer}): `#{@found_history}`" + @cursorPosition = @search_buffer.size + 1 + update + end + + def history_search!(c) + @search_buffer << c.chr + update_history_search! + end + + def append_buffer!(c) + @buffer = @buffer[0, @cursorPosition] + c.chr + @buffer[@cursorPosition, @buffer.size - @cursorPosition] + @cursorPosition = @cursorPosition + 1 + update + nil + end + + def scroll_up!(input_window) + @outputWindow.scroll_up(input_window) + nil + end + + def scroll_down!(input_window) + @outputWindow.scroll_down(input_window) + nil + end + + def toggle_verbosity! + conf.toggle_verbosity! + nil + end + + def print(*message) + oldStyle = Muby::Style.extract(@outputWindow.outputBuffer) + @outputWindow.print(*(message + [oldStyle])) + end + + # + # Echoes a message, if we want to (conf.echo) + # + def echo(*message) + if conf.echo + style = Muby::Style.new(conf.echo_attributes, conf.echo_colors[0], conf.echo_colors[1]) + oldStyle = Muby::Style.extract(@outputWindow.outputBuffer) + @outputWindow.print_on_newline(*([style] + message + [oldStyle])) + end + end + end + +end Deleted: lib/outputwindow.rb =================================================================== --- lib/outputwindow.rb 2007-05-05 01:32:00 UTC (rev 233) +++ lib/outputwindow.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -1,167 +0,0 @@ -# -# The class that controls what we see. -# -class Muby::OutputWindow - - include Muby::Logger - include Muby::Configurable - - attr_reader :scrollback, :pageSize, :size, :outputBuffer - - @@instance = Muby::OutputWindow.new unless defined?(@@instance) - - def self.get_instance - @@instance - end - - def initialize - @ready = false - end - - def ready? - @ready - end - - # - # Start working! - # - def go(size = 1000, inputHeight = 3) - @size = size - @inputHeight = inputHeight - @scrollback = 0 - @pageSize = Ncurses.LINES - inputHeight - 2 - @waitBuffer = [] - @lines = 0 - - @outputBuffer = Ncurses.newpad(@size, Ncurses.COLS) - @outputBuffer.wclear - @outputBuffer.scrollok(true) - @outputBuffer.idlok(true) - defaultAttributes = Muby::Style.new(conf.default_attributes, conf.default_colors[0], conf.default_colors[1]) - defaultAttributes.affect(@outputBuffer) - # Prepare the output window: - @outputBuffer.mvprintw(@size - 1, 0, "\n") - - show_version - refresh - - @ready = true - end - - def show_version - print(" -.--.--.--. .--. -: :--.--: : .--.--. -: : : : : : '-: : : -: : : : : : : : ' : -'--'--'--'-----'----'--. : - The Ruby MUD Client : : - ------------------- '--' - Version #{MUBY_VERSION} -") - end - - # - # Refresh the output buffer (if we have scrolled etc) - # - def refresh - @outputBuffer.prefresh(@size - (@pageSize * (@scrollback + 1)), 0, 0, 0, @pageSize - 1, Ncurses.COLS) - end - - # - # Scroll up, and give the user a message about it. - # - def scroll_up(inputWindow) - if @scrollback * @pageSize < conf.output_buffer && - @scrollback * @pageSize < @lines - @scrollback += 1 - # BUG: set_message_line is in userMethods. - # No, its not a bug. - inputWindow.set_message_line("SCROLLED - I/O PAUSED") - refresh - end - end - - # - # Scroll down again. - # - def scroll_down(inputWindow) - if @scrollback > 0 - @scrollback -= 1 - if @scrollback == 0 - # BUG: - # No - inputWindow.set_message_line("") - unless @waitBuffer.empty? - print(*@waitBuffer) - @waitBuffer = [] - end - end - end - refresh - end - - def timestamp(message) - if conf.timestamp && @recent_linebreak - Time.new.strftime(conf.timeformat) + "\t" + message - else - message - end - end - - def show(level, message) - if conf.display?(level) - to_print = [message, "\n"] - if level_attributes = conf.send("#{level}_attributes") - level_colors = conf.send("#{level}_colors") - style = Muby::Style.new(level_attributes, level_colors[0], level_colors[1]) - oldStyle = Muby::Style.extract(@outputBuffer) - to_print = [style] + to_print + [oldStyle] - end - - print_on_newline(*to_print) - end - end - - def print_on_newline(*info) - if @recent_linebreak - print(*info) - else - print(*(["\n"] + info)) - end - end - - # - # Print an info Array to the outputBuffer. - # - # Will print text as is, and add any Styles encountered to the outputBuffer. - # - def print(*info) - if @scrollback == 0 - info.each do |e| - if String === e - rest = e - while (match = rest.match(/^([^\r\n]*)([\r\n]*)(.*)$/m)) - to_print = match[1] - linebreak = match[2] - rest = match[3] - - break if to_print.empty? and linebreak.empty? - - @outputBuffer.printw("%s", timestamp(to_print) + linebreak) - - @recent_linebreak = !linebreak.empty? - @lines += 1 unless linebreak.empty? - end - elsif Muby::Style === e - e.affect(@outputBuffer) - end - end - else - @waitBuffer += info - end - refresh - nil - end - -end # class OutputWindow Deleted: lib/style.rb =================================================================== --- lib/style.rb 2007-05-05 01:32:00 UTC (rev 233) +++ lib/style.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -1,142 +0,0 @@ -module Muby - - # - # The encapsulation of all the ncurses horror. - # - class Style - - include Muby::Logger - include Muby::Configurable - - attr_reader :attributes, :color1, :color2 - - class ColorPair - @@instances = [] - @@initialized = false - def self.init_pairs - unless @@initialized - 1.upto(Ncurses.COLOR_PAIRS - 1) do |n| - @@instances << ColorPair.new(n) - end - @@initialized = true - end - end - def self.get_pair(fg, bg) - init_pairs - - found = @@instances.find do |color| - color.bg == bg && color.fg == fg - end - - found = @@instances.find do |color| - color.bg.nil? && color.fg.nil? - end unless found - - found = @@instances.sort do |c1, c2| - c1.used_at <=> c2.used_at - end.first unless found - - found.use(fg, bg) - - found - end - - attr_accessor :bg, :fg, :number, :used_at - - def initialize(number) - @number = number - @used_at = Time.new - end - - def to_i - Ncurses.COLOR_PAIR(@number) - end - - def use(fg, bg) - @used_at = Time.new - if (bg != @bg || fg != @fg) - @bg = bg - @fg = fg - Ncurses.init_pair(@number, @fg, @bg) - end - end - end - - def initialize(attributes, color1, color2, toAdd = false) - @attributes = attributes - @color1 = color1 - @color2 = color2 - @toAdd = toAdd - end - - # - # Get a Style instance from a window (so we can save it and restore it) - # - def self.extract(window) - tmp = [] - oldAttributes = [] - oldAttribute = 0 - oldColorPair = [] - oldColor1 = [] - oldColor2 = [] - - window.wattr_get(oldAttributes,oldColorPair,tmp) - oldAttribute = oldAttributes[0] ^ Ncurses.COLOR_PAIR(oldColorPair[0]) - Ncurses.pair_content(oldColorPair[0], oldColor1, oldColor2) - - Muby::Style.new(oldAttribute, oldColor1[0], oldColor2[0]) - end - - # - # Affect the window, either overwriting its style or adding to it. - # - def affect(window) - if @toAdd - window.wattron(to_int(window)) - else - window.wattrset(to_int(window)) - end - end - - def get_color_value(fg, bg) - Muby::Style::ColorPair.get_pair(fg, bg).to_i - end - - # - # Get an int representation of this style, to send to ncurses. - # - def to_int(window) - oldAttributes = self.class.extract(window) - color1 = @color1 == :copy ? oldAttributes.color1 : @color1 || conf.default_colors[0] - color2 = @color2 == :copy ? oldAttributes.color2 : @color2 || conf.default_colors[1] - @attributes | get_color_value(color1, color2) - end - - end # class Style - - module Styled - unless defined?(RED) - RED = Muby::Style.new(0, Ncurses.const_get("COLOR_RED"), :copy, true) - BLACK = Muby::Style.new(0, Ncurses.const_get("COLOR_BLACK"), :copy, true) - GREEN = Muby::Style.new(0, Ncurses.const_get("COLOR_GREEN"), :copy, true) - YELLOW = Muby::Style.new(0, Ncurses.const_get("COLOR_YELLOW"), :copy, true) - MAGENTA = Muby::Style.new(0, Ncurses.const_get("COLOR_MAGENTA"), :copy, true) - BLUE = Muby::Style.new(0, Ncurses.const_get("COLOR_BLUE"), :copy, true) - CYAN = Muby::Style.new(0, Ncurses.const_get("COLOR_CYAN"), :copy, true) - WHITE = Muby::Style.new(0, Ncurses.const_get("COLOR_WHITE"), :copy, true) - - BOLD = Muby::Style.new(Ncurses.const_get("A_BOLD"), :copy, :copy, true) - DIM = Muby::Style.new(Ncurses.const_get("A_DIM"), :copy, :copy, true) - UNDERLINE = Muby::Style.new(Ncurses.const_get("A_UNDERLINE"), :copy, :copy, true) - BLINK = Muby::Style.new(Ncurses.const_get("A_BLINK"), :copy, :copy, true) - REVERSE = Muby::Style.new(Ncurses.const_get("A_REVERSE"), :copy, :copy, true) - INVIS = Muby::Style.new(Ncurses.const_get("A_INVIS"), :copy, :copy, true) - STANDOUT = Muby::Style.new(Ncurses.const_get("A_STANDOUT"), :copy, :copy, true) - PROTECT = Muby::Style.new(Ncurses.const_get("A_PROTECT"), :copy, :copy, true) - ALTCHARSET = Muby::Style.new(Ncurses.const_get("A_ALTCHARSET"), :copy, :copy, true) - CHARTEXT = Muby::Style.new(Ncurses.const_get("A_CHARTEXT"), :copy, :copy, true) - - NORMAL = Muby::Style.new(Ncurses.const_get("A_NORMAL"), :copy, :copy, false) - end - end -end Deleted: lib/user_methods.rb =================================================================== --- lib/user_methods.rb 2007-05-05 01:32:00 UTC (rev 233) +++ lib/user_methods.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -1,462 +0,0 @@ - -module Muby - - # - # This is the UserMethod module. - # - # It is supposed to contain all the muby kernel methods that are - # supposed to be used by the user or the key_commands. - # - module UserMethods - - def help - help = < conf.max_history - @history.shift - end - @buffer << c.chr - conf.local_triggers.each do |regexp, command| - begin - if match = @buffer.match(regexp) - @buffer = "" unless execute(command, self, @outputWindow, match) - end - rescue RegexpError => error - conf.local_triggers.delete(key) - exception(error) - end - end - sendn(@buffer) unless @buffer.empty? - @buffer = "" - @cursorPosition = 0 - update - nil - end - - def backspace_buffer! - if @handle_mode == :history_search! - if @cursorPosition > 1 - @search_buffer = @search_buffer[0...-1] - @cursorPosition -= 1 - update_history_search! - end - else - if @cursorPosition > 0 - @buffer = @buffer[0, @cursorPosition - 1] + @buffer[@cursorPosition, @buffer.size - @cursorPosition] - @cursorPosition -= 1 - update - end - end - nil - end - - def word_backspace_buffer! - unless @handle_mode == :history_search! - if @cursorPosition > 0 - while @cursorPosition != 0 && @buffer[@cursorPosition - 1].chr.match("\\W") - @buffer = @buffer[0, @cursorPosition - 1] + @buffer[@cursorPosition, @buffer.size - @cursorPosition] - @cursorPosition = @cursorPosition - 1 - end - while @cursorPosition != 0 && @buffer[@cursorPosition - 1].chr.match("\\w") - @buffer = @buffer[0, @cursorPosition - 1] + @buffer[@cursorPosition, @buffer.size - @cursorPosition] - @cursorPosition = @cursorPosition - 1 - end - update - end - end - nil - end - - def delete_buffer! - unless @handle_mode == :history_search! - if @cursorPosition < @buffer.size - @buffer = @buffer[0, @cursorPosition] + @buffer[@cursorPosition + 1, @buffer.size - @cursorPosition - 1] - update - end - end - nil - end - - def reload_application! - conf.reload_application! - end - - def complete! - unless @handle_mode == :history_search! - last_word = @buffer.match(/(\w*)$/)[1] - completions = Muby::Completer.get_instance.complete(last_word) - if completions.size == 1 - @buffer.gsub!(last_word, completions[0]) - @cursorPosition = @buffer.size - update - else - info(completions.inspect) - end - end - nil - end - - def update_history_buffer! - if @historyPointer && @history.size > 0 - @buffer = @history[@historyPointer].clone - else - @buffer = "" - end - @cursorPosition = @buffer.size - update - nil - end - - def previous_history_buffer! - if @handle_mode == :append_buffer! - if @history.size > 0 - if @historyPointer && @historyPointer > 0 - @historyPointer -= 1 - elsif @historyPointer.nil? - @historyPointer = @history.size - 1 - end - update_history_buffer! - end - else - @historyPointer += 1 - update_history_search! - end - nil - end - - def next_history_buffer! - if @handle_mode == :append_buffer! - if @history.size > 0 && @historyPointer - if @historyPointer < @history.size - 1 - @historyPointer += 1 - else - @historyPointer = nil - end - update_history_buffer! - end - else - @historyPointer -= 1 - update_history_search! - end - nil - end - - def next_word_buffer! - unless @handle_mode == :history_search! - if @buffer.size > 0 - start = @cursorPosition - @cursorPosition = (@cursorPosition + 1) % (@buffer.size) - while @cursorPosition != 0 && @cursorPosition != @buffer.size && @cursorPosition != start && @buffer[@cursorPosition].chr.match("\\w") - @cursorPosition = (@cursorPosition + 1) % (@buffer.size + 1) - end - update - end - end - nil - end - - def home_buffer! - unless @handle_mode == :history_search! - @cursorPosition = 0 - update - end - nil - end - - def previous_word_buffer! - unless @handle_mode == :history_search! - if @buffer.size > 0 - start = @cursorPosition - @cursorPosition = (@cursorPosition - 1) % (@buffer.size) - while @cursorPosition != 0 && @cursorPosition != @buffer.size && @cursorPosition != start && @buffer[@cursorPosition].chr.match("\\w") - @cursorPosition = (@cursorPosition - 1) % (@buffer.size + 1) - end - update - end - end - nil - end - - def previous_character_buffer! - unless @handle_mode == :history_search! - if @buffer.size > 0 - @cursorPosition = (@cursorPosition - 1) % (@buffer.size + 1) - update - end - end - nil - end - - def next_character_buffer! - unless @handle_mode == :history_search! - if @buffer.size > 0 - @cursorPosition = (@cursorPosition + 1) % (@buffer.size + 1) - update - end - end - nil - end - - def end_buffer! - unless @handle_mode == :history_search! - @cursorPosition = @buffer.size - update - end - nil - end - - def two_step_quit! - if @user_quit then - quit - else - @user_quit = true - info "Press again within 5 seconds to quit." - Thread.new do - sleep(5) - @user_quit = false - end - end - nil - end - - def toggle_history_search! - if @handle_mode == :append_buffer! - enable_history_search! - else - disable_history_search! - end - nil - end - - def enable_history_search! - if @handle_mode == :append_buffer! - @historyPointer = 0 - @handle_mode = :history_search! - @search_buffer = @buffer - update_history_search! - end - nil - end - - def disable_history_search! - unless @handle_mode == :append_buffer! - @historyPointer = nil - @handle_mode = :append_buffer! - @buffer = @found_history || "" - @cursorPosition = @buffer.size - @search_buffer = "" - update - end - nil - end - - def update_history_search! - @search_buffer ||= "" - @found_history_array = @history.reverse.select do |line| - line.match(Regexp.new(@search_buffer)) - end - @found_history_array << "" if @found_history_array.empty? - @found_history = @found_history_array[@historyPointer % @found_history_array.size] - @buffer = "(#{@search_buffer}): `#{@found_history}`" - @cursorPosition = @search_buffer.size + 1 - update - end - - def history_search!(c) - @search_buffer << c.chr - update_history_search! - end - - def append_buffer!(c) - @buffer = @buffer[0, @cursorPosition] + c.chr + @buffer[@cursorPosition, @buffer.size - @cursorPosition] - @cursorPosition = @cursorPosition + 1 - update - nil - end - - def scroll_up!(input_window) - @outputWindow.scroll_up(input_window) - nil - end - - def scroll_down!(input_window) - @outputWindow.scroll_down(input_window) - nil - end - - def toggle_verbosity! - conf.toggle_verbosity! - nil - end - - def print(*message) - oldStyle = Muby::Style.extract(@outputWindow.outputBuffer) - @outputWindow.print(*(message + [oldStyle])) - end - - # - # Echoes a message, if we want to (conf.echo) - # - def echo(*message) - if conf.echo - style = Muby::Style.new(conf.echo_attributes, conf.echo_colors[0], conf.echo_colors[1]) - oldStyle = Muby::Style.extract(@outputWindow.outputBuffer) - @outputWindow.print_on_newline(*([style] + message + [oldStyle])) - end - end - end - -end Deleted: muby.rb =================================================================== --- muby.rb 2007-05-05 01:32:00 UTC (rev 233) +++ muby.rb 2007-10-18 18:32:20 UTC (rev 234) @@ -1,125 +0,0 @@ -#!/usr/bin/env ruby -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# or browse to http://www.gnu.org/licenses/gpl.txt -# -# Copyright 2004-2006 Martin Kihlgren -# -# Secondary coding by Sy Ali who donates his -# contributions to the codebase, which are to be included in the same licence. -# - -#################################################################### -# muby, the ruby mud client # -# (really a half-assed telnet client - telnet protocol options are # -# recognized but ignored, but there are pretty nice scripting # -# capabilities :) # -#################################################################### - -# http://jrandomhacker.info/Muby -# http://rubyforge.org/projects/muby - -MUBY_VERSION = "0.6.4" - -$: << File.expand_path(File.dirname(__FILE__)) - -require "socket" -require "pathname" -begin - require "rubygems" - # Require a specific version or higher? - require_gem "ncurses" -rescue LoadError - # How do we ensure that we have the right version? - require "ncurses" -end - -require "lib/user_methods.rb" -require "lib/displayer.rb" -require "lib/configuration.rb" -require "lib/logger.rb" -require "lib/style.rb" -require "lib/outputwindow.rb" -require "lib/inputwindow.rb" -require "lib/connection.rb" -require "lib/help.rb" -require "lib/completer.rb" - -class Application - - include Muby::Configurable - include Muby::Displayer - - def initialize - - # - # Load all user files - # - conf.load_user_files! - - # Init all the ncurses magic. - Ncurses.initscr - Ncurses.raw - Ncurses.keypad(Ncurses.stdscr, true) - Ncurses.noecho - Ncurses.refresh - if Ncurses.has_colors? - Ncurses.start_color - end - - # initialize late (to enable changes from $RC_FILE) - Muby::OutputWindow.get_instance.go(conf.output_buffer, conf.input_height) - Muby::InputWindow.get_instance.go(Muby::OutputWindow.get_instance, conf.input_height) - - # - # Exit commands - # If we die by normal death (control-C for example): - # - at_exit do - begin - conf.shutdown_triggers.each do |proc| - Muby::InputWindow.get_instance.execute(proc) - end - Muby::InputWindow.get_instance.saveHistory - rescue Exception => e - exception(e) - error("Sleeping 10 seconds before closing") - sleep(10) - ensure - Ncurses.endwin - puts "Exiting muby..." - end - end - - # - # The main loop - # - begin - Muby::InputWindow.get_instance.process - rescue SystemExit => ex - violentDeath = false - raise ex - rescue Exception => error - exception(error) - error("Sleeping 10 seconds before closing") - sleep(10) - end - end -end - -if __FILE__ == $0 - # Start the whole shebang - Application.new -end Deleted: prepare_release_tarball.sh =================================================================== --- prepare_release_tarball.sh 2007-05-05 01:32:00 UTC (rev 233) +++ prepare_release_tarball.sh 2007-10-18 18:32:20 UTC (rev 234) @@ -1,23 +0,0 @@ -# TODO: learn the version number, and automatically name the archive. -distribution_file=$(basename $(pwd))-.tar.gz - -# Nuke the temporary files: -find -L ./ -name '*~' -exec rm {} \; -find -L ./ -name '.*~' -exec rm {} \; -rm -f $distribution_file -# Delete zero-length files: -# NOTE: This will delete symbolic links! -find -L ./ -name '*' -empty -exec rm {} \; - -# All files, even dotfiles, but not .svn or anything in a .svn directory. -# Ignore .fuse_hidden files created from fuse filesystems. This is a sign -# of a temporary file which has been locked by fuse and shouldn't be used. -# Unfortunately, I cannot have this script's exact name in any sub-directory either. -tar \ ---exclude "`basename $0`" \ ---exclude ".svn" \ ---exclude ".fuse_hidden*" \ --czvf $distribution_file * `ls -A|grep "^\."` - - -# BUG: This doesn't put the files in a directory.. so when extracting it extracts to the current directory! From nobody at rubyforge.org Fri Oct 19 10:57:56 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Fri, 19 Oct 2007 10:57:56 -0400 (EDT) Subject: [Muby-submits] [240] trunk/lib: prettified lots of things and classes. Message-ID: <20071019145756.197AE1858658@rubyforge.org> Revision: 240 Author: zond Date: 2007-10-19 10:57:54 -0400 (Fri, 19 Oct 2007) Log Message: ----------- prettified lots of things and classes. made it possible to more or less freely define the geometry of input and output windows. next step is to simplify creation of user defined windows. Modified Paths: -------------- trunk/lib/muby/application.rb trunk/lib/muby/configuration.rb trunk/lib/muby/inputwindow.rb trunk/lib/muby/outputwindow.rb trunk/lib/muby/user_methods.rb trunk/lib/muby.rb Added Paths: ----------- trunk/lib/muby/helper_methods.rb Modified: trunk/lib/muby/application.rb =================================================================== --- trunk/lib/muby/application.rb 2007-10-18 19:42:30 UTC (rev 239) +++ trunk/lib/muby/application.rb 2007-10-19 14:57:54 UTC (rev 240) @@ -24,8 +24,8 @@ end # initialize late (to enable changes from $RC_FILE) - Muby::OutputWindow.get_instance.go(conf.output_buffer, conf.input_height) - Muby::InputWindow.get_instance.go(Muby::OutputWindow.get_instance, conf.input_height) + Muby::OutputWindow.get_instance.go + Muby::InputWindow.get_instance.go # # Exit commands Modified: trunk/lib/muby/configuration.rb =================================================================== --- trunk/lib/muby/configuration.rb 2007-10-18 19:42:30 UTC (rev 239) +++ trunk/lib/muby/configuration.rb 2007-10-19 14:57:54 UTC (rev 240) @@ -3,7 +3,7 @@ module Muby - VERSION = "0.6.5" + VERSION = "0.6.6" # # The class that encapsulates all configuration. @@ -17,6 +17,12 @@ # class Configuration + @@instance = nil + + def self.get + @@instance ||= Configuration.new + end + def initialize # # verbosity options @@ -29,6 +35,20 @@ :timestamp => true, :connection_status => true } + + @output_window_geometry = { + :top => 0, + :left => 0, + :width => "Ncurses.COLS", + :height => "Ncurses.LINES - Muby::InputWindow.get_instance.height" + } + + @input_window_geometry = { + :top => "Ncurses.LINES - conf.input_height - 2", + :left => 0, + :width => "Ncurses.COLS", + :height => "conf.input_height + 2" + } @echo_keycodes = false @@ -163,12 +183,6 @@ end - @@instance = Configuration.new - - def self.get - @@instance - end - # # The magical method that lets us get and set the settings without # having to write getters and setters for all of them Added: trunk/lib/muby/helper_methods.rb =================================================================== --- trunk/lib/muby/helper_methods.rb (rev 0) +++ trunk/lib/muby/helper_methods.rb 2007-10-19 14:57:54 UTC (rev 240) @@ -0,0 +1,46 @@ + +module Muby + + module HelperMethods + + def execute(command, *args) + execute_with_verbosity(:debug, command, *args) + end + + def execute_with_verbosity(verbosity, command, *args) + begin + result = nil + if Proc === command + result = command.call(*args[0...(command.arity)]) + elsif String === command + result = eval(command) + elsif Symbol === command + method = self.method(command) + args = args[0...(method.arity)] + result = method.call(*args) + elsif Array === command + method = self.method(command.first) + args = (command[1..-1] + args)[0...(method.arity)] + result = method.call(*args) + else + result = command + end + unless result.nil? + case result + when String + Muby::OutputWindow.get_instance.show(verbosity, result) + else + Muby::OutputWindow.get_instance.show(verbosity, result.inspect) + end + end + result + rescue SystemExit => ex + quit + rescue Exception => e + exception(e) + end + end + + end + +end Modified: trunk/lib/muby/inputwindow.rb =================================================================== --- trunk/lib/muby/inputwindow.rb 2007-10-18 19:42:30 UTC (rev 239) +++ trunk/lib/muby/inputwindow.rb 2007-10-19 14:57:54 UTC (rev 240) @@ -18,11 +18,12 @@ include Muby::Displayer include Muby::UserMethods include Muby::Styled + include Muby::HelperMethods - @@instance = Muby::InputWindow.new unless defined?(@@instance) + @@instance = nil def self.get_instance - @@instance + @@instance ||= Muby::InputWindow.new end attr_reader :history @@ -30,15 +31,12 @@ # # Start working! # - def go(outputWindow, inputHeight = 3) + def go # Init all the default values - @outputWindow = outputWindow - @inputHeight = inputHeight @buffer = "" @cursorPosition = 0 @history = [] @historyPointer = nil - @inputWidth = Ncurses.COLS - 2 @connection = nil @statusLine = "" @messageLine = "" @@ -46,13 +44,13 @@ @handle_mode = :append_buffer! # Init the input box - @inputBorder = Ncurses.newwin(@inputHeight + 2, Ncurses.COLS, Ncurses.LINES - (@inputHeight + 2), 0) + @inputBorder = Ncurses.newwin(height, width, top, left) @inputBorder.box(0,0) @inputBorder.keypad(true) @inputBorder.refresh # Init the window itself - @inputWindow = Ncurses.newwin(@inputHeight, at inputWidth,Ncurses.LINES - (@inputHeight + 1), 1) + @inputWindow = Ncurses.newwin(height - 2, width - 2, top + 1, left + 1) @inputWindow.keypad(true) @inputWindow.scrollok(true) @inputWindow.nodelay(true) @@ -60,64 +58,44 @@ help unless conf.user_edited_config_file end + + def left + execute_with_verbosity(:trace, conf.input_window_geometry[:left]) + end + def top + execute_with_verbosity(:trace, conf.input_window_geometry[:top]) + end + + def width + execute_with_verbosity(:trace, conf.input_window_geometry[:width]) + end + + def height + execute_with_verbosity(:trace, conf.input_window_geometry[:height]) + end + # # Update the input box, redrawing borders and text etc. # def update @inputBorder.box(0,0) @inputBorder.mvwprintw(0,1,"%s", @statusLine) - @inputBorder.mvwprintw(@inputHeight + 1, 1, "%s", @messageLine) + @inputBorder.mvwprintw(height - 1, 1, "%s", @messageLine) @inputBorder.refresh @inputWindow.werase row = 0 col = @cursorPosition - while col > @inputWidth + while col > width - 2 row = row + 1 - col = col - @inputWidth + col = col - width - 2 end @inputWindow.mvwprintw(row,col,"%s", @buffer[@cursorPosition, at buffer.size - @cursorPosition]) @inputWindow.mvwprintw(0,0,"%s", @buffer[0, @cursorPosition]) @inputWindow.refresh end - def execute(command, *args) - execute_with_verbosity(:debug, command, *args) - end - - def execute_with_verbosity(verbosity, command, *args) - begin - result = nil - if Proc === command - result = command.call(*args[0...(command.arity)]) - elsif String === command - result = eval(command) - elsif Symbol === command - method = self.method(command) - args = args[0...(method.arity)] - result = method.call(*args) - elsif Array === command - method = self.method(command.first) - args = (command[1..-1] + args)[0...(method.arity)] - result = method.call(*args) - end - unless result.nil? - case result - when String - @outputWindow.show(verbosity, result) - else - @outputWindow.show(verbosity, result.inspect) - end - end - result - rescue SystemExit => ex - quit - rescue Exception => e - exception(e) - end - end - # # Save our history into the history file. # @@ -166,7 +144,7 @@ handle(c, conf.key_commands) end else - execute(value, self, @outputWindow, c) + execute(value, self, Muby::OutputWindow.get_instance, c) end elsif 0 < c && c < 265 method = self.method(@handle_mode) @@ -180,7 +158,7 @@ def process loadHistory conf.startup_triggers.each do |trigger| - execute(trigger, self, @outputWindow) + execute(trigger, self, Muby::OutputWindow.get_instance) end # We need to check one key at a time due to triggers and conf.key_commands while c = @inputWindow.wgetch Modified: trunk/lib/muby/outputwindow.rb =================================================================== --- trunk/lib/muby/outputwindow.rb 2007-10-18 19:42:30 UTC (rev 239) +++ trunk/lib/muby/outputwindow.rb 2007-10-19 14:57:54 UTC (rev 240) @@ -5,13 +5,15 @@ include Muby::Logger include Muby::Configurable + include Muby::HelperMethods + include Muby::Displayer - attr_reader :scrollback, :pageSize, :size, :outputBuffer + attr_reader :scrollback, :size, :outputBuffer - @@instance = Muby::OutputWindow.new unless defined?(@@instance) + @@instance = nil def self.get_instance - @@instance + @@instance ||= Muby::OutputWindow.new end def initialize @@ -25,22 +27,19 @@ # # Start working! # - def go(size = 1000, inputHeight = 3) - @size = size - @inputHeight = inputHeight + def go @scrollback = 0 - @pageSize = Ncurses.LINES - inputHeight - 2 @waitBuffer = [] @lines = 0 - @outputBuffer = Ncurses.newpad(@size, Ncurses.COLS) + @outputBuffer = Ncurses.newpad(conf.output_buffer, width) @outputBuffer.wclear @outputBuffer.scrollok(true) @outputBuffer.idlok(true) defaultAttributes = Muby::Style.new(conf.default_attributes, conf.default_colors[0], conf.default_colors[1]) defaultAttributes.affect(@outputBuffer) # Prepare the output window: - @outputBuffer.mvprintw(@size - 1, 0, "\n") + @outputBuffer.mvprintw(conf.output_buffer - 1, 0, "\n") show_version refresh @@ -48,6 +47,29 @@ @ready = true end + def reload! + @left = nil + @top = nil + @width = nil + @height = nil + end + + def left + @left ||= execute_with_verbosity(:trace, conf.output_window_geometry[:left]) + end + + def top + @top ||= execute_with_verbosity(:trace, conf.output_window_geometry[:top]) + end + + def width + @width ||= execute_with_verbosity(:trace, conf.output_window_geometry[:width]) + end + + def height + @height ||= execute_with_verbosity(:trace, conf.output_window_geometry[:height]) + end + def show_version print(" .--.--.--. .--. @@ -65,15 +87,15 @@ # Refresh the output buffer (if we have scrolled etc) # def refresh - @outputBuffer.prefresh(@size - (@pageSize * (@scrollback + 1)), 0, 0, 0, @pageSize - 1, Ncurses.COLS) + @outputBuffer.prefresh(conf.output_buffer - (height * (@scrollback + 1)), 0, top, left, height - 1, width) end # # Scroll up, and give the user a message about it. # def scroll_up(inputWindow) - if @scrollback * @pageSize < conf.output_buffer && - @scrollback * @pageSize < @lines + if @scrollback * height < conf.output_buffer && + @scrollback * height < @lines @scrollback += 1 # BUG: set_message_line is in userMethods. # No, its not a bug. Modified: trunk/lib/muby/user_methods.rb =================================================================== --- trunk/lib/muby/user_methods.rb 2007-10-18 19:42:30 UTC (rev 239) +++ trunk/lib/muby/user_methods.rb 2007-10-19 14:57:54 UTC (rev 240) @@ -113,7 +113,7 @@ # Make a fake connection for debug purposes # def fake_connect - @connection = Muby::Connection.new(self, @outputWindow, nil, nil) + @connection = Muby::Connection.new(self, Muby::OutputWindow.get_instance, nil, nil) nil end @@ -172,7 +172,7 @@ conf.local_triggers.each do |regexp, command| begin if match = @buffer.match(regexp) - @buffer = "" unless execute(command, self, @outputWindow, match) + @buffer = "" unless execute(command, self, Muby::OutputWindow.get_instance, match) end rescue RegexpError => error conf.local_triggers.delete(key) @@ -232,6 +232,7 @@ def reload_application! conf.reload_application! + Muby::OutputWindow.get_instance.reload! end def complete! @@ -428,12 +429,12 @@ end def scroll_up!(input_window) - @outputWindow.scroll_up(input_window) + Muby::OutputWindow.get_instance.scroll_up(input_window) nil end def scroll_down!(input_window) - @outputWindow.scroll_down(input_window) + Muby::OutputWindow.get_instance.scroll_down(input_window) nil end @@ -443,8 +444,8 @@ end def print(*message) - oldStyle = Muby::Style.extract(@outputWindow.outputBuffer) - @outputWindow.print(*(message + [oldStyle])) + oldStyle = Muby::Style.extract(Muby::OutputWindow.get_instance.outputBuffer) + Muby::OutputWindow.get_instance.print(*(message + [oldStyle])) end # @@ -453,8 +454,8 @@ def echo(*message) if conf.echo style = Muby::Style.new(conf.echo_attributes, conf.echo_colors[0], conf.echo_colors[1]) - oldStyle = Muby::Style.extract(@outputWindow.outputBuffer) - @outputWindow.print_on_newline(*([style] + message + [oldStyle])) + oldStyle = Muby::Style.extract(Muby::OutputWindow.get_instance.outputBuffer) + Muby::OutputWindow.get_instance.print_on_newline(*([style] + message + [oldStyle])) end end end Modified: trunk/lib/muby.rb =================================================================== --- trunk/lib/muby.rb 2007-10-18 19:42:30 UTC (rev 239) +++ trunk/lib/muby.rb 2007-10-19 14:57:54 UTC (rev 240) @@ -1,4 +1,6 @@ $: << File.join(File.dirname(__FILE__), "lib") +require 'pp' +require "muby/helper_methods" require "muby/user_methods" require "muby/displayer" require "muby/configuration" From nobody at rubyforge.org Fri Oct 19 10:58:27 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Fri, 19 Oct 2007 10:58:27 -0400 (EDT) Subject: [Muby-submits] [241] tags: made release tag 0.6.6 Message-ID: <20071019145827.AA4A11858658@rubyforge.org> Revision: 241 Author: zond Date: 2007-10-19 10:58:27 -0400 (Fri, 19 Oct 2007) Log Message: ----------- made release tag 0.6.6 Added Paths: ----------- tags/release_0_6_6/ tags/release_0_6_6/lib/muby/application.rb tags/release_0_6_6/lib/muby/configuration.rb tags/release_0_6_6/lib/muby/helper_methods.rb tags/release_0_6_6/lib/muby/inputwindow.rb tags/release_0_6_6/lib/muby/outputwindow.rb tags/release_0_6_6/lib/muby/user_methods.rb tags/release_0_6_6/lib/muby.rb Removed Paths: ------------- tags/release_0_6_6/lib/muby/application.rb tags/release_0_6_6/lib/muby/configuration.rb tags/release_0_6_6/lib/muby/inputwindow.rb tags/release_0_6_6/lib/muby/outputwindow.rb tags/release_0_6_6/lib/muby/user_methods.rb tags/release_0_6_6/lib/muby.rb Copied: tags/release_0_6_6 (from rev 239, trunk) Deleted: tags/release_0_6_6/lib/muby/application.rb =================================================================== --- trunk/lib/muby/application.rb 2007-10-18 19:42:30 UTC (rev 239) +++ tags/release_0_6_6/lib/muby/application.rb 2007-10-19 14:58:27 UTC (rev 241) @@ -1,66 +0,0 @@ - -module Muby - - class Application - - include Muby::Configurable - include Muby::Displayer - - def initialize - - # - # Load all user files - # - conf.load_user_files! - - # Init all the ncurses magic. - Ncurses.initscr - Ncurses.raw - Ncurses.keypad(Ncurses.stdscr, true) - Ncurses.noecho - Ncurses.refresh - if Ncurses.has_colors? - Ncurses.start_color - end - - # initialize late (to enable changes from $RC_FILE) - Muby::OutputWindow.get_instance.go(conf.output_buffer, conf.input_height) - Muby::InputWindow.get_instance.go(Muby::OutputWindow.get_instance, conf.input_height) - - # - # Exit commands - # If we die by normal death (control-C for example): - # - at_exit do - begin - conf.shutdown_triggers.each do |proc| - Muby::InputWindow.get_instance.execute(proc) - end - Muby::InputWindow.get_instance.saveHistory - rescue Exception => e - exception(e) - error("Sleeping 10 seconds before closing") - sleep(10) - ensure - Ncurses.endwin - puts "Exiting muby..." - end - end - - # - # The main loop - # - begin - Muby::InputWindow.get_instance.process - rescue SystemExit => ex - violentDeath = false - raise ex - rescue Exception => error - exception(error) - error("Sleeping 10 seconds before closing") - sleep(10) - end - end - end - -end Copied: tags/release_0_6_6/lib/muby/application.rb (from rev 240, trunk/lib/muby/application.rb) =================================================================== --- tags/release_0_6_6/lib/muby/application.rb (rev 0) +++ tags/release_0_6_6/lib/muby/application.rb 2007-10-19 14:58:27 UTC (rev 241) @@ -0,0 +1,66 @@ + +module Muby + + class Application + + include Muby::Configurable + include Muby::Displayer + + def initialize + + # + # Load all user files + # + conf.load_user_files! + + # Init all the ncurses magic. + Ncurses.initscr + Ncurses.raw + Ncurses.keypad(Ncurses.stdscr, true) + Ncurses.noecho + Ncurses.refresh + if Ncurses.has_colors? + Ncurses.start_color + end + + # initialize late (to enable changes from $RC_FILE) + Muby::OutputWindow.get_instance.go + Muby::InputWindow.get_instance.go + + # + # Exit commands + # If we die by normal death (control-C for example): + # + at_exit do + begin + conf.shutdown_triggers.each do |proc| + Muby::InputWindow.get_instance.execute(proc) + end + Muby::InputWindow.get_instance.saveHistory + rescue Exception => e + exception(e) + error("Sleeping 10 seconds before closing") + sleep(10) + ensure + Ncurses.endwin + puts "Exiting muby..." + end + end + + # + # The main loop + # + begin + Muby::InputWindow.get_instance.process + rescue SystemExit => ex + violentDeath = false + raise ex + rescue Exception => error + exception(error) + error("Sleeping 10 seconds before closing") + sleep(10) + end + end + end + +end Deleted: tags/release_0_6_6/lib/muby/configuration.rb =================================================================== --- trunk/lib/muby/configuration.rb 2007-10-18 19:42:30 UTC (rev 239) +++ tags/release_0_6_6/lib/muby/configuration.rb 2007-10-19 14:58:27 UTC (rev 241) @@ -1,365 +0,0 @@ - -require 'ncurses' - -module Muby - - VERSION = "0.6.5" - - # - # The class that encapsulates all configuration. - # - # To simplify its use, include Muby::Configurable in your class. - # Then you can access Configuration as 'conf' (nice shorthand :) - # - # All options in Configuration are get'able and set'able. - # - # Look in help.rb to get the meaning of them. - # - class Configuration - - def initialize - # - # verbosity options - # - - @extra_verbosity_settings = { - :echo_keycodes => true, - :echo => true, - :show_level => :debug, - :timestamp => true, - :connection_status => true - } - - @echo_keycodes = false - - @echo = true - - @show_level = :info - - @timestamp = false - - @connection_status = true - - # - # options to control what you see - # - - @disable_blink = false - - @timeformat = "%H:%M:%S" - - @broken_keycodes = { - 13 => true - } - - @max_history = 100 - - @default_attributes = Ncurses.const_get("A_NORMAL") - @default_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] - - @echo_attributes = Ncurses.const_get("A_BOLD") - @echo_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] - - @trace_attributes = Ncurses.const_get("A_NORMAL") - @trace_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] - - @debug_attributes = Ncurses.const_get("A_NORMAL") - @debug_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] - - @info_attributes = Ncurses.const_get("A_NORMAL") - @info_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] - - @warn_attributes = Ncurses.const_get("A_NORMAL") - @warn_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] - - @error_attributes = Ncurses.const_get("A_NORMAL") - @error_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] - - @flush = true - - @gags = [] - - @anti_gags = [] - - @remote_substitutions = {} - - @local_substitutions = {} - - # - # options to control what gets run when # - # - - @startup_triggers = [] - - @connect_triggers = [] - - @shutdown_triggers = [] - - @remote_triggers = {} - - @remote_character_triggers = {} - - @local_triggers = { - /^\/(.*)\n$/m => :execute_command!, - /^!(.*)\n$/m => :shell_command!, - /^#.*\n$/m => :ignore_command! - } - - @key_commands = { - #18 => :resize, # ctrl-l - Ncurses.const_get("KEY_PPAGE") => :scroll_up!, - Ncurses.const_get("KEY_NPAGE") => :scroll_down!, - Ncurses.const_get("KEY_ENTER") => :process_buffer!, - 10 => :process_buffer!, # enter - 3 => :two_step_quit!, # ctrl-c - 9 => :complete!, # tab - 18 => :toggle_history_search!, # ctrl-r - 127 => :backspace_buffer!, # backspace - Ncurses.const_get("KEY_BACKSPACE") => :backspace_buffer!, - 27 => { - 91 => { - 53 => { - 68 => :previous_word_buffer!, # ctrl-key_left - 67 => :next_word_buffer!, # ctrl-key_right - } - } - }, - Ncurses.const_get("KEY_DC") => :delete_buffer!, - Ncurses.const_get("KEY_UP") => :previous_history_buffer!, - Ncurses.const_get("KEY_DOWN") => :next_history_buffer!, - 262 => :home_buffer!, # home_key - 360 => :end_buffer!, # end_key - Ncurses.const_get("KEY_LEFT") => :previous_character_buffer!, - Ncurses.const_get("KEY_RIGHT") => :next_character_buffer!, - 22 => :toggle_verbosity!, # ctrl-v - 265 => :help # f1 - } - - # - # miscellaneous options # - # - - @feed_completer_with_history = true - - @feed_completer_with_input = true - - @extra_completions = [] - - @loaded_rc_file = false - - @user_edited_config_file = false - - @userdir = File.join(ENV["HOME"], "mubyrc.d") - - @history_file = File.join(@userdir, "history") - - @output_buffer = 1000 - - @input_height = 3 - - @input_logfile = nil - - @output_logfile = nil - - end - - @@instance = Configuration.new - - def self.get - @@instance - end - - # - # The magical method that lets us get and set the settings without - # having to write getters and setters for all of them - # - def method_missing(*args) - method_name = args[0].to_s - var_name = method_name[/^[^=]*/] - - setter = method_name =~ /=$/ - if setter - return super unless args.size == 2 - instance_variable_set("@#{var_name}", args[1]) - return args[1] - else - return super unless args.size == 1 - return instance_variable_get("@#{var_name}") - end - end - - # - # The halfway magical method that toggles all settings covered in - # @extra_verbosity_settings to what they are in that hash, - # and then stores them away inside the same hash for back-toggling again. - # - def toggle_verbosity! - - # copy old extra-settings to a copy - settings_copy = @extra_verbosity_settings.clone - - # set our extra-settings to be the currently applied settings - @extra_verbosity_settings.clone.each do |key, value| - @extra_verbosity_settings[key] = self.send(key) - end - - # apply the extra-settings - settings_copy.each do |key, value| - self.send("#{key}=", value) - end - - Muby::Displayer.info("Toggled verbosity. Press again to toggle back.") - end - - # - # Returns true if we are supposed to display messages - # of +level+. - # - def display?(level) - levels = [:trace, :debug, :info, :warn, :error] - levels.index(level) >= (levels.index(@show_level) || 0) - end - - # - # Will save the current configuration to the loaded rc file, - # or to mubyrc if no such file was loaded. - # - def save_configuration_file! - to_save = @loaded_rc_file ? @loaded_rc_file : File.join(ENV["HOME"], "mubyrc") - begin - Kernel::open(to_save, "w") do |output| - output.write(self.to_ruby) - @loaded_rc_file = to_save - end - Muby::Displayer.info("Saved default configuration to #{to_save}.") - rescue Exception => e - Muby::Displayer.warn("Failed saving default configuration to #{to_save}: #{e.message}") - Muby::Displayer.debug(e.backtrace.join("\n")) - end - end - - # - # Tries to load all the users files, defined as - # any file named .mubyrc or mubyrc in the users ENV["HOME"] - # and all **/*.rb files in the users ENV["HOME"]/@userdir - # with the root of the userdir taking precidence over subdirectories. - # Directories starting with a . are ignored. - # - # If none of the mubyrc-files existed, it will try to create one - # for the user to edit to his/her liking. - # - def load_user_files! - @loaded_rc_file = false - if to_load = [".mubyrc", "mubyrc"].find do |file_name| - File.exists?(File.join(ENV["HOME"], file_name)) - end - nice_load!(to_load) - @loaded_rc_file = to_load - end - - unless @loaded_rc_file - save_configuration_file! - end - - if File.exists?(@userdir) - # Only load *.rb files within sub-directories of the current directory, and not the current directory's *.rb files!) - # Test: Dir[File.join(Dir.pwd, "*", "**", "*.rb")].each do |f| puts f end ; nil - Dir[File.join(@userdir, "*", "**", "*.rb")].each do |file_name| - nice_load!(file_name) - end - # Only load *.rb files of the current directory. - # This is very useful for users to create "overrides" for items in subdirectories. - # NOTE: This does follow symbolic links (files and directories) - # Test: Dir[File.join(Dir.pwd, "*.rb")].each do |f| puts f end ; nil - Dir[File.join(@userdir, "*.rb")].each do |file_name| - nice_load!(file_name) - end - else - Muby::Displayer.warn("#{@userdir} does not exist. If it did, *.rb in it would be loaded now.") - end - end - - # - # A non-raising method that tries to load +f+ and tells the output window about its success. - # - def nice_load!(f) - begin - Kernel::load(f) - Muby::Displayer.info("Loaded #{f}") - rescue Exception => e - Muby::Displayer.exception(e) - end - end - - # - # Will reload the entire app, ie the class files and the - # user files. - # - # TODO: Remove the spammyness. - # It is not appropriate to use 'puts' when reload_application! is being called by the user. - # To turn off "uninitialised constant" warnings, do: $VERBOSE = nil - # - # Simply set your show_level to :warn instead of :info, and you wont see the load messages. - # - # Any other messages come from your own files :O - # - def reload_application! - Dir[File.join(File.dirname(__FILE__), "**", "*.rb")].each do |file_name| - nice_load! file_name - end - load_user_files! - end - - # - # The not so magical at all method that prints our content - # to a String so that we easily can save our current settings - # in a file, or create a default config file. - # - def to_ruby - "# -# This is the default configuration of muby. -# To learn more about how to configure it, you -# can type '/help' in the client. -# -include Muby::Configurable -" + - instance_variables.sort.collect do |var_name| - value = eval(var_name) - case value - when Hash - space = "conf.#{var_name[1..-1]} = _".size - value = value.inspect.gsub(/, /, ",\n#{" " * space}") - when File - begin - value.read(0) - value = "open(\"#{value.path}\", \"r\")" - rescue - value = "open(\"#{value.path}\", \"a\")" - end - when NilClass - value = value.inspect - else - value = value.inspect - end - var_name = var_name[1..-1] - help_text = Muby::Help.configuration[var_name.to_sym] || "no help available for #{var_name}" - help_text = help_text.split("\n").join("\n# ") - " -# #{help_text} -conf.#{var_name} = #{value}" - end.join("\n") - end - - end - - # - # The module that provides the shorthand for - # using classes. - # - module Configurable - def conf - Configuration.get - end - end - -end Copied: tags/release_0_6_6/lib/muby/configuration.rb (from rev 240, trunk/lib/muby/configuration.rb) =================================================================== --- tags/release_0_6_6/lib/muby/configuration.rb (rev 0) +++ tags/release_0_6_6/lib/muby/configuration.rb 2007-10-19 14:58:27 UTC (rev 241) @@ -0,0 +1,379 @@ + +require 'ncurses' + +module Muby + + VERSION = "0.6.6" + + # + # The class that encapsulates all configuration. + # + # To simplify its use, include Muby::Configurable in your class. + # Then you can access Configuration as 'conf' (nice shorthand :) + # + # All options in Configuration are get'able and set'able. + # + # Look in help.rb to get the meaning of them. + # + class Configuration + + @@instance = nil + + def self.get + @@instance ||= Configuration.new + end + + def initialize + # + # verbosity options + # + + @extra_verbosity_settings = { + :echo_keycodes => true, + :echo => true, + :show_level => :debug, + :timestamp => true, + :connection_status => true + } + + @output_window_geometry = { + :top => 0, + :left => 0, + :width => "Ncurses.COLS", + :height => "Ncurses.LINES - Muby::InputWindow.get_instance.height" + } + + @input_window_geometry = { + :top => "Ncurses.LINES - conf.input_height - 2", + :left => 0, + :width => "Ncurses.COLS", + :height => "conf.input_height + 2" + } + + @echo_keycodes = false + + @echo = true + + @show_level = :info + + @timestamp = false + + @connection_status = true + + # + # options to control what you see + # + + @disable_blink = false + + @timeformat = "%H:%M:%S" + + @broken_keycodes = { + 13 => true + } + + @max_history = 100 + + @default_attributes = Ncurses.const_get("A_NORMAL") + @default_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] + + @echo_attributes = Ncurses.const_get("A_BOLD") + @echo_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] + + @trace_attributes = Ncurses.const_get("A_NORMAL") + @trace_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] + + @debug_attributes = Ncurses.const_get("A_NORMAL") + @debug_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] + + @info_attributes = Ncurses.const_get("A_NORMAL") + @info_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] + + @warn_attributes = Ncurses.const_get("A_NORMAL") + @warn_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] + + @error_attributes = Ncurses.const_get("A_NORMAL") + @error_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] + + @flush = true + + @gags = [] + + @anti_gags = [] + + @remote_substitutions = {} + + @local_substitutions = {} + + # + # options to control what gets run when # + # + + @startup_triggers = [] + + @connect_triggers = [] + + @shutdown_triggers = [] + + @remote_triggers = {} + + @remote_character_triggers = {} + + @local_triggers = { + /^\/(.*)\n$/m => :execute_command!, + /^!(.*)\n$/m => :shell_command!, + /^#.*\n$/m => :ignore_command! + } + + @key_commands = { + #18 => :resize, # ctrl-l + Ncurses.const_get("KEY_PPAGE") => :scroll_up!, + Ncurses.const_get("KEY_NPAGE") => :scroll_down!, + Ncurses.const_get("KEY_ENTER") => :process_buffer!, + 10 => :process_buffer!, # enter + 3 => :two_step_quit!, # ctrl-c + 9 => :complete!, # tab + 18 => :toggle_history_search!, # ctrl-r + 127 => :backspace_buffer!, # backspace + Ncurses.const_get("KEY_BACKSPACE") => :backspace_buffer!, + 27 => { + 91 => { + 53 => { + 68 => :previous_word_buffer!, # ctrl-key_left + 67 => :next_word_buffer!, # ctrl-key_right + } + } + }, + Ncurses.const_get("KEY_DC") => :delete_buffer!, + Ncurses.const_get("KEY_UP") => :previous_history_buffer!, + Ncurses.const_get("KEY_DOWN") => :next_history_buffer!, + 262 => :home_buffer!, # home_key + 360 => :end_buffer!, # end_key + Ncurses.const_get("KEY_LEFT") => :previous_character_buffer!, + Ncurses.const_get("KEY_RIGHT") => :next_character_buffer!, + 22 => :toggle_verbosity!, # ctrl-v + 265 => :help # f1 + } + + # + # miscellaneous options # + # + + @feed_completer_with_history = true + + @feed_completer_with_input = true + + @extra_completions = [] + + @loaded_rc_file = false + + @user_edited_config_file = false + + @userdir = File.join(ENV["HOME"], "mubyrc.d") + + @history_file = File.join(@userdir, "history") + + @output_buffer = 1000 + + @input_height = 3 + + @input_logfile = nil + + @output_logfile = nil + + end + + # + # The magical method that lets us get and set the settings without + # having to write getters and setters for all of them + # + def method_missing(*args) + method_name = args[0].to_s + var_name = method_name[/^[^=]*/] + + setter = method_name =~ /=$/ + if setter + return super unless args.size == 2 + instance_variable_set("@#{var_name}", args[1]) + return args[1] + else + return super unless args.size == 1 + return instance_variable_get("@#{var_name}") + end + end + + # + # The halfway magical method that toggles all settings covered in + # @extra_verbosity_settings to what they are in that hash, + # and then stores them away inside the same hash for back-toggling again. + # + def toggle_verbosity! + + # copy old extra-settings to a copy + settings_copy = @extra_verbosity_settings.clone + + # set our extra-settings to be the currently applied settings + @extra_verbosity_settings.clone.each do |key, value| + @extra_verbosity_settings[key] = self.send(key) + end + + # apply the extra-settings + settings_copy.each do |key, value| + self.send("#{key}=", value) + end + + Muby::Displayer.info("Toggled verbosity. Press again to toggle back.") + end + + # + # Returns true if we are supposed to display messages + # of +level+. + # + def display?(level) + levels = [:trace, :debug, :info, :warn, :error] + levels.index(level) >= (levels.index(@show_level) || 0) + end + + # + # Will save the current configuration to the loaded rc file, + # or to mubyrc if no such file was loaded. + # + def save_configuration_file! + to_save = @loaded_rc_file ? @loaded_rc_file : File.join(ENV["HOME"], "mubyrc") + begin + Kernel::open(to_save, "w") do |output| + output.write(self.to_ruby) + @loaded_rc_file = to_save + end + Muby::Displayer.info("Saved default configuration to #{to_save}.") + rescue Exception => e + Muby::Displayer.warn("Failed saving default configuration to #{to_save}: #{e.message}") + Muby::Displayer.debug(e.backtrace.join("\n")) + end + end + + # + # Tries to load all the users files, defined as + # any file named .mubyrc or mubyrc in the users ENV["HOME"] + # and all **/*.rb files in the users ENV["HOME"]/@userdir + # with the root of the userdir taking precidence over subdirectories. + # Directories starting with a . are ignored. + # + # If none of the mubyrc-files existed, it will try to create one + # for the user to edit to his/her liking. + # + def load_user_files! + @loaded_rc_file = false + if to_load = [".mubyrc", "mubyrc"].find do |file_name| + File.exists?(File.join(ENV["HOME"], file_name)) + end + nice_load!(to_load) + @loaded_rc_file = to_load + end + + unless @loaded_rc_file + save_configuration_file! + end + + if File.exists?(@userdir) + # Only load *.rb files within sub-directories of the current directory, and not the current directory's *.rb files!) + # Test: Dir[File.join(Dir.pwd, "*", "**", "*.rb")].each do |f| puts f end ; nil + Dir[File.join(@userdir, "*", "**", "*.rb")].each do |file_name| + nice_load!(file_name) + end + # Only load *.rb files of the current directory. + # This is very useful for users to create "overrides" for items in subdirectories. + # NOTE: This does follow symbolic links (files and directories) + # Test: Dir[File.join(Dir.pwd, "*.rb")].each do |f| puts f end ; nil + Dir[File.join(@userdir, "*.rb")].each do |file_name| + nice_load!(file_name) + end + else + Muby::Displayer.warn("#{@userdir} does not exist. If it did, *.rb in it would be loaded now.") + end + end + + # + # A non-raising method that tries to load +f+ and tells the output window about its success. + # + def nice_load!(f) + begin + Kernel::load(f) + Muby::Displayer.info("Loaded #{f}") + rescue Exception => e + Muby::Displayer.exception(e) + end + end + + # + # Will reload the entire app, ie the class files and the + # user files. + # + # TODO: Remove the spammyness. + # It is not appropriate to use 'puts' when reload_application! is being called by the user. + # To turn off "uninitialised constant" warnings, do: $VERBOSE = nil + # + # Simply set your show_level to :warn instead of :info, and you wont see the load messages. + # + # Any other messages come from your own files :O + # + def reload_application! + Dir[File.join(File.dirname(__FILE__), "**", "*.rb")].each do |file_name| + nice_load! file_name + end + load_user_files! + end + + # + # The not so magical at all method that prints our content + # to a String so that we easily can save our current settings + # in a file, or create a default config file. + # + def to_ruby + "# +# This is the default configuration of muby. +# To learn more about how to configure it, you +# can type '/help' in the client. +# +include Muby::Configurable +" + + instance_variables.sort.collect do |var_name| + value = eval(var_name) + case value + when Hash + space = "conf.#{var_name[1..-1]} = _".size + value = value.inspect.gsub(/, /, ",\n#{" " * space}") + when File + begin + value.read(0) + value = "open(\"#{value.path}\", \"r\")" + rescue + value = "open(\"#{value.path}\", \"a\")" + end + when NilClass + value = value.inspect + else + value = value.inspect + end + var_name = var_name[1..-1] + help_text = Muby::Help.configuration[var_name.to_sym] || "no help available for #{var_name}" + help_text = help_text.split("\n").join("\n# ") + " +# #{help_text} +conf.#{var_name} = #{value}" + end.join("\n") + end + + end + + # + # The module that provides the shorthand for + # using classes. + # + module Configurable + def conf + Configuration.get + end + end + +end Copied: tags/release_0_6_6/lib/muby/helper_methods.rb (from rev 240, trunk/lib/muby/helper_methods.rb) =================================================================== --- tags/release_0_6_6/lib/muby/helper_methods.rb (rev 0) +++ tags/release_0_6_6/lib/muby/helper_methods.rb 2007-10-19 14:58:27 UTC (rev 241) @@ -0,0 +1,46 @@ + +module Muby + + module HelperMethods + + def execute(command, *args) + execute_with_verbosity(:debug, command, *args) + end + + def execute_with_verbosity(verbosity, command, *args) + begin + result = nil + if Proc === command + result = command.call(*args[0...(command.arity)]) + elsif String === command + result = eval(command) + elsif Symbol === command + method = self.method(command) + args = args[0...(method.arity)] + result = method.call(*args) + elsif Array === command + method = self.method(command.first) + args = (command[1..-1] + args)[0...(method.arity)] + result = method.call(*args) + else + result = command + end + unless result.nil? + case result + when String + Muby::OutputWindow.get_instance.show(verbosity, result) + else + Muby::OutputWindow.get_instance.show(verbosity, result.inspect) + end + end + result + rescue SystemExit => ex + quit + rescue Exception => e + exception(e) + end + end + + end + +end Deleted: tags/release_0_6_6/lib/muby/inputwindow.rb =================================================================== --- trunk/lib/muby/inputwindow.rb 2007-10-18 19:42:30 UTC (rev 239) +++ tags/release_0_6_6/lib/muby/inputwindow.rb 2007-10-19 14:58:27 UTC (rev 241) @@ -1,195 +0,0 @@ - -require 'pathname' - -# -# The fancy window that gets our input. -# -# The class handles everything to do with -# the input window itself, the user callable -# methods are in the UserMethods module. -# -# All commands entered with conf.escape_character will be eval'd in -# this class scope. -# -class Muby::InputWindow - - include Muby::Logger - include Muby::Configurable - include Muby::Displayer - include Muby::UserMethods - include Muby::Styled - - @@instance = Muby::InputWindow.new unless defined?(@@instance) - - def self.get_instance - @@instance - end - - attr_reader :history - - # - # Start working! - # - def go(outputWindow, inputHeight = 3) - # Init all the default values - @outputWindow = outputWindow - @inputHeight = inputHeight - @buffer = "" - @cursorPosition = 0 - @history = [] - @historyPointer = nil - @inputWidth = Ncurses.COLS - 2 - @connection = nil - @statusLine = "" - @messageLine = "" - @recent_escape = [] - @handle_mode = :append_buffer! - - # Init the input box - @inputBorder = Ncurses.newwin(@inputHeight + 2, Ncurses.COLS, Ncurses.LINES - (@inputHeight + 2), 0) - @inputBorder.box(0,0) - @inputBorder.keypad(true) - @inputBorder.refresh - - # Init the window itself - @inputWindow = Ncurses.newwin(@inputHeight, at inputWidth,Ncurses.LINES - (@inputHeight + 1), 1) - @inputWindow.keypad(true) - @inputWindow.scrollok(true) - @inputWindow.nodelay(true) - @inputWindow.refresh - - help unless conf.user_edited_config_file - end - - # - # Update the input box, redrawing borders and text etc. - # - def update - @inputBorder.box(0,0) - @inputBorder.mvwprintw(0,1,"%s", @statusLine) - @inputBorder.mvwprintw(@inputHeight + 1, 1, "%s", @messageLine) - @inputBorder.refresh - - @inputWindow.werase - row = 0 - col = @cursorPosition - while col > @inputWidth - row = row + 1 - col = col - @inputWidth - end - @inputWindow.mvwprintw(row,col,"%s", @buffer[@cursorPosition, at buffer.size - @cursorPosition]) - @inputWindow.mvwprintw(0,0,"%s", @buffer[0, @cursorPosition]) - @inputWindow.refresh - end - - def execute(command, *args) - execute_with_verbosity(:debug, command, *args) - end - - def execute_with_verbosity(verbosity, command, *args) - begin - result = nil - if Proc === command - result = command.call(*args[0...(command.arity)]) - elsif String === command - result = eval(command) - elsif Symbol === command - method = self.method(command) - args = args[0...(method.arity)] - result = method.call(*args) - elsif Array === command - method = self.method(command.first) - args = (command[1..-1] + args)[0...(method.arity)] - result = method.call(*args) - end - unless result.nil? - case result - when String - @outputWindow.show(verbosity, result) - else - @outputWindow.show(verbosity, result.inspect) - end - end - result - rescue SystemExit => ex - quit - rescue Exception => e - exception(e) - end - end - - # - # Save our history into the history file. - # - def saveHistory - # This should be wrapped in something else, which checks for sanity (writability) - dir = Pathname.new(conf.history_file).parent - dir.mkpath unless dir.exist? - file = Pathname.new(conf.history_file) - file.open("w") do |output| - Marshal.dump(@history, output) - end - end - - # - # Load our history from the history file. - # - def loadHistory - begin - if FileTest.readable?(conf.history_file) - info("Reading history file") - Kernel::open(conf.history_file) do |input| - @history = Marshal.load(input.read) - end - @history.each do |line| - Muby::Completer.get_instance.store(line) - end if conf.feed_completer_with_history - end - rescue Exception => e - exception(e) - end - @history ||= [] - end - - def handle(c, hash) - # Echo the keycode we got if we have conf.echo_keycodes == true (good for setting up conf.key_commands) - if conf.echo_keycodes && c != Ncurses.const_get("ERR") - info(c.to_s) - end - if hash.include?(c) - value = hash[c] - if Hash === value - c = @inputWindow.wgetch - if value.include?(c) - handle(c, value) - else - handle(c, conf.key_commands) - end - else - execute(value, self, @outputWindow, c) - end - elsif 0 < c && c < 265 - method = self.method(@handle_mode) - method.call(c) - end - end - - # - # Just keep listening to the keyboard input. - # - def process - loadHistory - conf.startup_triggers.each do |trigger| - execute(trigger, self, @outputWindow) - end - # We need to check one key at a time due to triggers and conf.key_commands - while c = @inputWindow.wgetch - if c == Ncurses.const_get("ERR") - sleep(0.01) - else - handle(c, conf.key_commands) - end - end # while c = @inputWindow.wgetch - end # def process - -end # class InputWindow Copied: tags/release_0_6_6/lib/muby/inputwindow.rb (from rev 240, trunk/lib/muby/inputwindow.rb) =================================================================== --- tags/release_0_6_6/lib/muby/inputwindow.rb (rev 0) +++ tags/release_0_6_6/lib/muby/inputwindow.rb 2007-10-19 14:58:27 UTC (rev 241) @@ -0,0 +1,173 @@ + +require 'pathname' + +# +# The fancy window that gets our input. +# +# The class handles everything to do with +# the input window itself, the user callable +# methods are in the UserMethods module. +# +# All commands entered with conf.escape_character will be eval'd in +# this class scope. +# +class Muby::InputWindow + + include Muby::Logger + include Muby::Configurable + include Muby::Displayer + include Muby::UserMethods + include Muby::Styled + include Muby::HelperMethods + + @@instance = nil + + def self.get_instance + @@instance ||= Muby::InputWindow.new + end + + attr_reader :history + + # + # Start working! + # + def go + # Init all the default values + @buffer = "" + @cursorPosition = 0 + @history = [] + @historyPointer = nil + @connection = nil + @statusLine = "" + @messageLine = "" + @recent_escape = [] + @handle_mode = :append_buffer! + + # Init the input box + @inputBorder = Ncurses.newwin(height, width, top, left) + @inputBorder.box(0,0) + @inputBorder.keypad(true) + @inputBorder.refresh + + # Init the window itself + @inputWindow = Ncurses.newwin(height - 2, width - 2, top + 1, left + 1) + @inputWindow.keypad(true) + @inputWindow.scrollok(true) + @inputWindow.nodelay(true) + @inputWindow.refresh + + help unless conf.user_edited_config_file + end + + def left + execute_with_verbosity(:trace, conf.input_window_geometry[:left]) + end + + def top + execute_with_verbosity(:trace, conf.input_window_geometry[:top]) + end + + def width + execute_with_verbosity(:trace, conf.input_window_geometry[:width]) + end + + def height + execute_with_verbosity(:trace, conf.input_window_geometry[:height]) + end + + # + # Update the input box, redrawing borders and text etc. + # + def update + @inputBorder.box(0,0) + @inputBorder.mvwprintw(0,1,"%s", @statusLine) + @inputBorder.mvwprintw(height - 1, 1, "%s", @messageLine) + @inputBorder.refresh + + @inputWindow.werase + row = 0 + col = @cursorPosition + while col > width - 2 + row = row + 1 + col = col - width - 2 + end + @inputWindow.mvwprintw(row,col,"%s", @buffer[@cursorPosition, at buffer.size - @cursorPosition]) + @inputWindow.mvwprintw(0,0,"%s", @buffer[0, @cursorPosition]) + @inputWindow.refresh + end + + # + # Save our history into the history file. + # + def saveHistory + # This should be wrapped in something else, which checks for sanity (writability) + dir = Pathname.new(conf.history_file).parent + dir.mkpath unless dir.exist? + file = Pathname.new(conf.history_file) + file.open("w") do |output| + Marshal.dump(@history, output) + end + end + + # + # Load our history from the history file. + # + def loadHistory + begin + if FileTest.readable?(conf.history_file) + info("Reading history file") + Kernel::open(conf.history_file) do |input| + @history = Marshal.load(input.read) + end + @history.each do |line| + Muby::Completer.get_instance.store(line) + end if conf.feed_completer_with_history + end + rescue Exception => e + exception(e) + end + @history ||= [] + end + + def handle(c, hash) + # Echo the keycode we got if we have conf.echo_keycodes == true (good for setting up conf.key_commands) + if conf.echo_keycodes && c != Ncurses.const_get("ERR") + info(c.to_s) + end + if hash.include?(c) + value = hash[c] + if Hash === value + c = @inputWindow.wgetch + if value.include?(c) + handle(c, value) + else + handle(c, conf.key_commands) + end + else + execute(value, self, Muby::OutputWindow.get_instance, c) + end + elsif 0 < c && c < 265 + method = self.method(@handle_mode) + method.call(c) + end + end + + # + # Just keep listening to the keyboard input. + # + def process + loadHistory + conf.startup_triggers.each do |trigger| + execute(trigger, self, Muby::OutputWindow.get_instance) + end + # We need to check one key at a time due to triggers and conf.key_commands + while c = @inputWindow.wgetch + if c == Ncurses.const_get("ERR") + sleep(0.01) + else + handle(c, conf.key_commands) + end + end # while c = @inputWindow.wgetch + end # def process + +end # class InputWindow Deleted: tags/release_0_6_6/lib/muby/outputwindow.rb =================================================================== --- trunk/lib/muby/outputwindow.rb 2007-10-18 19:42:30 UTC (rev 239) +++ tags/release_0_6_6/lib/muby/outputwindow.rb 2007-10-19 14:58:27 UTC (rev 241) @@ -1,167 +0,0 @@ -# -# The class that controls what we see. -# -class Muby::OutputWindow - - include Muby::Logger - include Muby::Configurable - - attr_reader :scrollback, :pageSize, :size, :outputBuffer - - @@instance = Muby::OutputWindow.new unless defined?(@@instance) - - def self.get_instance - @@instance - end - - def initialize - @ready = false - end - - def ready? - @ready - end - - # - # Start working! - # - def go(size = 1000, inputHeight = 3) - @size = size - @inputHeight = inputHeight - @scrollback = 0 - @pageSize = Ncurses.LINES - inputHeight - 2 - @waitBuffer = [] - @lines = 0 - - @outputBuffer = Ncurses.newpad(@size, Ncurses.COLS) - @outputBuffer.wclear - @outputBuffer.scrollok(true) - @outputBuffer.idlok(true) - defaultAttributes = Muby::Style.new(conf.default_attributes, conf.default_colors[0], conf.default_colors[1]) - defaultAttributes.affect(@outputBuffer) - # Prepare the output window: - @outputBuffer.mvprintw(@size - 1, 0, "\n") - - show_version - refresh - - @ready = true - end - - def show_version - print(" -.--.--.--. .--. -: :--.--: : .--.--. -: : : : : : '-: : : -: : : : : : : : ' : -'--'--'--'-----'----'--. : - The Ruby MUD Client : : - ------------------- '--' - Version #{Muby::VERSION} -") - end - - # - # Refresh the output buffer (if we have scrolled etc) - # - def refresh - @outputBuffer.prefresh(@size - (@pageSize * (@scrollback + 1)), 0, 0, 0, @pageSize - 1, Ncurses.COLS) - end - - # - # Scroll up, and give the user a message about it. - # - def scroll_up(inputWindow) - if @scrollback * @pageSize < conf.output_buffer && - @scrollback * @pageSize < @lines - @scrollback += 1 - # BUG: set_message_line is in userMethods. - # No, its not a bug. - inputWindow.set_message_line("SCROLLED - I/O PAUSED") - refresh - end - end - - # - # Scroll down again. - # - def scroll_down(inputWindow) - if @scrollback > 0 - @scrollback -= 1 - if @scrollback == 0 - # BUG: - # No - inputWindow.set_message_line("") - unless @waitBuffer.empty? - print(*@waitBuffer) - @waitBuffer = [] - end - end - end - refresh - end - - def timestamp(message) - if conf.timestamp && @recent_linebreak - Time.new.strftime(conf.timeformat) + "\t" + message - else - message - end - end - - def show(level, message) - if conf.display?(level) - to_print = [message, "\n"] - if level_attributes = conf.send("#{level}_attributes") - level_colors = conf.send("#{level}_colors") - style = Muby::Style.new(level_attributes, level_colors[0], level_colors[1]) - oldStyle = Muby::Style.extract(@outputBuffer) - to_print = [style] + to_print + [oldStyle] - end - - print_on_newline(*to_print) - end - end - - def print_on_newline(*info) - if @recent_linebreak - print(*info) - else - print(*(["\n"] + info)) - end - end - - # - # Print an info Array to the outputBuffer. - # - # Will print text as is, and add any Styles encountered to the outputBuffer. - # - def print(*info) - if @scrollback == 0 - info.each do |e| - if String === e - rest = e - while (match = rest.match(/^([^\r\n]*)([\r\n]*)(.*)$/m)) - to_print = match[1] - linebreak = match[2] - rest = match[3] - - break if to_print.empty? and linebreak.empty? - - @outputBuffer.printw("%s", timestamp(to_print) + linebreak) - - @recent_linebreak = !linebreak.empty? - @lines += 1 unless linebreak.empty? - end - elsif Muby::Style === e - e.affect(@outputBuffer) - end - end - else - @waitBuffer += info - end - refresh - nil - end - -end # class OutputWindow Copied: tags/release_0_6_6/lib/muby/outputwindow.rb (from rev 240, trunk/lib/muby/outputwindow.rb) =================================================================== --- tags/release_0_6_6/lib/muby/outputwindow.rb (rev 0) +++ tags/release_0_6_6/lib/muby/outputwindow.rb 2007-10-19 14:58:27 UTC (rev 241) @@ -0,0 +1,189 @@ +# +# The class that controls what we see. +# +class Muby::OutputWindow + + include Muby::Logger + include Muby::Configurable + include Muby::HelperMethods + include Muby::Displayer + + attr_reader :scrollback, :size, :outputBuffer + + @@instance = nil + + def self.get_instance + @@instance ||= Muby::OutputWindow.new + end + + def initialize + @ready = false + end + + def ready? + @ready + end + + # + # Start working! + # + def go + @scrollback = 0 + @waitBuffer = [] + @lines = 0 + + @outputBuffer = Ncurses.newpad(conf.output_buffer, width) + @outputBuffer.wclear + @outputBuffer.scrollok(true) + @outputBuffer.idlok(true) + defaultAttributes = Muby::Style.new(conf.default_attributes, conf.default_colors[0], conf.default_colors[1]) + defaultAttributes.affect(@outputBuffer) + # Prepare the output window: + @outputBuffer.mvprintw(conf.output_buffer - 1, 0, "\n") + + show_version + refresh + + @ready = true + end + + def reload! + @left = nil + @top = nil + @width = nil + @height = nil + end + + def left + @left ||= execute_with_verbosity(:trace, conf.output_window_geometry[:left]) + end + + def top + @top ||= execute_with_verbosity(:trace, conf.output_window_geometry[:top]) + end + + def width + @width ||= execute_with_verbosity(:trace, conf.output_window_geometry[:width]) + end + + def height + @height ||= execute_with_verbosity(:trace, conf.output_window_geometry[:height]) + end + + def show_version + print(" +.--.--.--. .--. +: :--.--: : .--.--. +: : : : : : '-: : : +: : : : : : : : ' : +'--'--'--'-----'----'--. : + The Ruby MUD Client : : + ------------------- '--' + Version #{Muby::VERSION} +") + end + + # + # Refresh the output buffer (if we have scrolled etc) + # + def refresh + @outputBuffer.prefresh(conf.output_buffer - (height * (@scrollback + 1)), 0, top, left, height - 1, width) + end + + # + # Scroll up, and give the user a message about it. + # + def scroll_up(inputWindow) + if @scrollback * height < conf.output_buffer && + @scrollback * height < @lines + @scrollback += 1 + # BUG: set_message_line is in userMethods. + # No, its not a bug. + inputWindow.set_message_line("SCROLLED - I/O PAUSED") + refresh + end + end + + # + # Scroll down again. + # + def scroll_down(inputWindow) + if @scrollback > 0 + @scrollback -= 1 + if @scrollback == 0 + # BUG: + # No + inputWindow.set_message_line("") + unless @waitBuffer.empty? + print(*@waitBuffer) + @waitBuffer = [] + end + end + end + refresh + end + + def timestamp(message) + if conf.timestamp && @recent_linebreak + Time.new.strftime(conf.timeformat) + "\t" + message + else + message + end + end + + def show(level, message) + if conf.display?(level) + to_print = [message, "\n"] + if level_attributes = conf.send("#{level}_attributes") + level_colors = conf.send("#{level}_colors") + style = Muby::Style.new(level_attributes, level_colors[0], level_colors[1]) + oldStyle = Muby::Style.extract(@outputBuffer) + to_print = [style] + to_print + [oldStyle] + end + + print_on_newline(*to_print) + end + end + + def print_on_newline(*info) + if @recent_linebreak + print(*info) + else + print(*(["\n"] + info)) + end + end + + # + # Print an info Array to the outputBuffer. + # + # Will print text as is, and add any Styles encountered to the outputBuffer. + # + def print(*info) + if @scrollback == 0 + info.each do |e| + if String === e + rest = e + while (match = rest.match(/^([^\r\n]*)([\r\n]*)(.*)$/m)) + to_print = match[1] + linebreak = match[2] + rest = match[3] + + break if to_print.empty? and linebreak.empty? + + @outputBuffer.printw("%s", timestamp(to_print) + linebreak) + + @recent_linebreak = !linebreak.empty? + @lines += 1 unless linebreak.empty? + end + elsif Muby::Style === e + e.affect(@outputBuffer) + end + end + else + @waitBuffer += info + end + refresh + nil + end + +end # class OutputWindow Deleted: tags/release_0_6_6/lib/muby/user_methods.rb =================================================================== --- trunk/lib/muby/user_methods.rb 2007-10-18 19:42:30 UTC (rev 239) +++ tags/release_0_6_6/lib/muby/user_methods.rb 2007-10-19 14:58:27 UTC (rev 241) @@ -1,462 +0,0 @@ - -module Muby - - # - # This is the UserMethod module. - # - # It is supposed to contain all the muby kernel methods that are - # supposed to be used by the user or the key_commands. - # - module UserMethods - - def help - help = < conf.max_history - @history.shift - end - @buffer << c.chr - conf.local_triggers.each do |regexp, command| - begin - if match = @buffer.match(regexp) - @buffer = "" unless execute(command, self, @outputWindow, match) - end - rescue RegexpError => error - conf.local_triggers.delete(key) - exception(error) - end - end - sendn(@buffer) unless @buffer.empty? - @buffer = "" - @cursorPosition = 0 - update - nil - end - - def backspace_buffer! - if @handle_mode == :history_search! - if @cursorPosition > 1 - @search_buffer = @search_buffer[0...-1] - @cursorPosition -= 1 - update_history_search! - end - else - if @cursorPosition > 0 - @buffer = @buffer[0, @cursorPosition - 1] + @buffer[@cursorPosition, @buffer.size - @cursorPosition] - @cursorPosition -= 1 - update - end - end - nil - end - - def word_backspace_buffer! - unless @handle_mode == :history_search! - if @cursorPosition > 0 - while @cursorPosition != 0 && @buffer[@cursorPosition - 1].chr.match("\\W") - @buffer = @buffer[0, @cursorPosition - 1] + @buffer[@cursorPosition, @buffer.size - @cursorPosition] - @cursorPosition = @cursorPosition - 1 - end - while @cursorPosition != 0 && @buffer[@cursorPosition - 1].chr.match("\\w") - @buffer = @buffer[0, @cursorPosition - 1] + @buffer[@cursorPosition, @buffer.size - @cursorPosition] - @cursorPosition = @cursorPosition - 1 - end - update - end - end - nil - end - - def delete_buffer! - unless @handle_mode == :history_search! - if @cursorPosition < @buffer.size - @buffer = @buffer[0, @cursorPosition] + @buffer[@cursorPosition + 1, @buffer.size - @cursorPosition - 1] - update - end - end - nil - end - - def reload_application! - conf.reload_application! - end - - def complete! - unless @handle_mode == :history_search! - last_word = @buffer.match(/(\w*)$/)[1] - completions = Muby::Completer.get_instance.complete(last_word) - if completions.size == 1 - @buffer.gsub!(last_word, completions[0]) - @cursorPosition = @buffer.size - update - else - info(completions.inspect) - end - end - nil - end - - def update_history_buffer! - if @historyPointer && @history.size > 0 - @buffer = @history[@historyPointer].clone - else - @buffer = "" - end - @cursorPosition = @buffer.size - update - nil - end - - def previous_history_buffer! - if @handle_mode == :append_buffer! - if @history.size > 0 - if @historyPointer && @historyPointer > 0 - @historyPointer -= 1 - elsif @historyPointer.nil? - @historyPointer = @history.size - 1 - end - update_history_buffer! - end - else - @historyPointer += 1 - update_history_search! - end - nil - end - - def next_history_buffer! - if @handle_mode == :append_buffer! - if @history.size > 0 && @historyPointer - if @historyPointer < @history.size - 1 - @historyPointer += 1 - else - @historyPointer = nil - end - update_history_buffer! - end - else - @historyPointer -= 1 - update_history_search! - end - nil - end - - def next_word_buffer! - unless @handle_mode == :history_search! - if @buffer.size > 0 - start = @cursorPosition - @cursorPosition = (@cursorPosition + 1) % (@buffer.size) - while @cursorPosition != 0 && @cursorPosition != @buffer.size && @cursorPosition != start && @buffer[@cursorPosition].chr.match("\\w") - @cursorPosition = (@cursorPosition + 1) % (@buffer.size + 1) - end - update - end - end - nil - end - - def home_buffer! - unless @handle_mode == :history_search! - @cursorPosition = 0 - update - end - nil - end - - def previous_word_buffer! - unless @handle_mode == :history_search! - if @buffer.size > 0 - start = @cursorPosition - @cursorPosition = (@cursorPosition - 1) % (@buffer.size) - while @cursorPosition != 0 && @cursorPosition != @buffer.size && @cursorPosition != start && @buffer[@cursorPosition].chr.match("\\w") - @cursorPosition = (@cursorPosition - 1) % (@buffer.size + 1) - end - update - end - end - nil - end - - def previous_character_buffer! - unless @handle_mode == :history_search! - if @buffer.size > 0 - @cursorPosition = (@cursorPosition - 1) % (@buffer.size + 1) - update - end - end - nil - end - - def next_character_buffer! - unless @handle_mode == :history_search! - if @buffer.size > 0 - @cursorPosition = (@cursorPosition + 1) % (@buffer.size + 1) - update - end - end - nil - end - - def end_buffer! - unless @handle_mode == :history_search! - @cursorPosition = @buffer.size - update - end - nil - end - - def two_step_quit! - if @user_quit then - quit - else - @user_quit = true - info "Press again within 5 seconds to quit." - Thread.new do - sleep(5) - @user_quit = false - end - end - nil - end - - def toggle_history_search! - if @handle_mode == :append_buffer! - enable_history_search! - else - disable_history_search! - end - nil - end - - def enable_history_search! - if @handle_mode == :append_buffer! - @historyPointer = 0 - @handle_mode = :history_search! - @search_buffer = @buffer - update_history_search! - end - nil - end - - def disable_history_search! - unless @handle_mode == :append_buffer! - @historyPointer = nil - @handle_mode = :append_buffer! - @buffer = @found_history || "" - @cursorPosition = @buffer.size - @search_buffer = "" - update - end - nil - end - - def update_history_search! - @search_buffer ||= "" - @found_history_array = @history.reverse.select do |line| - line.match(Regexp.new(@search_buffer)) - end - @found_history_array << "" if @found_history_array.empty? - @found_history = @found_history_array[@historyPointer % @found_history_array.size] - @buffer = "(#{@search_buffer}): `#{@found_history}`" - @cursorPosition = @search_buffer.size + 1 - update - end - - def history_search!(c) - @search_buffer << c.chr - update_history_search! - end - - def append_buffer!(c) - @buffer = @buffer[0, @cursorPosition] + c.chr + @buffer[@cursorPosition, @buffer.size - @cursorPosition] - @cursorPosition = @cursorPosition + 1 - update - nil - end - - def scroll_up!(input_window) - @outputWindow.scroll_up(input_window) - nil - end - - def scroll_down!(input_window) - @outputWindow.scroll_down(input_window) - nil - end - - def toggle_verbosity! - conf.toggle_verbosity! - nil - end - - def print(*message) - oldStyle = Muby::Style.extract(@outputWindow.outputBuffer) - @outputWindow.print(*(message + [oldStyle])) - end - - # - # Echoes a message, if we want to (conf.echo) - # - def echo(*message) - if conf.echo - style = Muby::Style.new(conf.echo_attributes, conf.echo_colors[0], conf.echo_colors[1]) - oldStyle = Muby::Style.extract(@outputWindow.outputBuffer) - @outputWindow.print_on_newline(*([style] + message + [oldStyle])) - end - end - end - -end Copied: tags/release_0_6_6/lib/muby/user_methods.rb (from rev 240, trunk/lib/muby/user_methods.rb) =================================================================== --- tags/release_0_6_6/lib/muby/user_methods.rb (rev 0) +++ tags/release_0_6_6/lib/muby/user_methods.rb 2007-10-19 14:58:27 UTC (rev 241) @@ -0,0 +1,463 @@ + +module Muby + + # + # This is the UserMethod module. + # + # It is supposed to contain all the muby kernel methods that are + # supposed to be used by the user or the key_commands. + # + module UserMethods + + def help + help = < conf.max_history + @history.shift + end + @buffer << c.chr + conf.local_triggers.each do |regexp, command| + begin + if match = @buffer.match(regexp) + @buffer = "" unless execute(command, self, Muby::OutputWindow.get_instance, match) + end + rescue RegexpError => error + conf.local_triggers.delete(key) + exception(error) + end + end + sendn(@buffer) unless @buffer.empty? + @buffer = "" + @cursorPosition = 0 + update + nil + end + + def backspace_buffer! + if @handle_mode == :history_search! + if @cursorPosition > 1 + @search_buffer = @search_buffer[0...-1] + @cursorPosition -= 1 + update_history_search! + end + else + if @cursorPosition > 0 + @buffer = @buffer[0, @cursorPosition - 1] + @buffer[@cursorPosition, @buffer.size - @cursorPosition] + @cursorPosition -= 1 + update + end + end + nil + end + + def word_backspace_buffer! + unless @handle_mode == :history_search! + if @cursorPosition > 0 + while @cursorPosition != 0 && @buffer[@cursorPosition - 1].chr.match("\\W") + @buffer = @buffer[0, @cursorPosition - 1] + @buffer[@cursorPosition, @buffer.size - @cursorPosition] + @cursorPosition = @cursorPosition - 1 + end + while @cursorPosition != 0 && @buffer[@cursorPosition - 1].chr.match("\\w") + @buffer = @buffer[0, @cursorPosition - 1] + @buffer[@cursorPosition, @buffer.size - @cursorPosition] + @cursorPosition = @cursorPosition - 1 + end + update + end + end + nil + end + + def delete_buffer! + unless @handle_mode == :history_search! + if @cursorPosition < @buffer.size + @buffer = @buffer[0, @cursorPosition] + @buffer[@cursorPosition + 1, @buffer.size - @cursorPosition - 1] + update + end + end + nil + end + + def reload_application! + conf.reload_application! + Muby::OutputWindow.get_instance.reload! + end + + def complete! + unless @handle_mode == :history_search! + last_word = @buffer.match(/(\w*)$/)[1] + completions = Muby::Completer.get_instance.complete(last_word) + if completions.size == 1 + @buffer.gsub!(last_word, completions[0]) + @cursorPosition = @buffer.size + update + else + info(completions.inspect) + end + end + nil + end + + def update_history_buffer! + if @historyPointer && @history.size > 0 + @buffer = @history[@historyPointer].clone + else + @buffer = "" + end + @cursorPosition = @buffer.size + update + nil + end + + def previous_history_buffer! + if @handle_mode == :append_buffer! + if @history.size > 0 + if @historyPointer && @historyPointer > 0 + @historyPointer -= 1 + elsif @historyPointer.nil? + @historyPointer = @history.size - 1 + end + update_history_buffer! + end + else + @historyPointer += 1 + update_history_search! + end + nil + end + + def next_history_buffer! + if @handle_mode == :append_buffer! + if @history.size > 0 && @historyPointer + if @historyPointer < @history.size - 1 + @historyPointer += 1 + else + @historyPointer = nil + end + update_history_buffer! + end + else + @historyPointer -= 1 + update_history_search! + end + nil + end + + def next_word_buffer! + unless @handle_mode == :history_search! + if @buffer.size > 0 + start = @cursorPosition + @cursorPosition = (@cursorPosition + 1) % (@buffer.size) + while @cursorPosition != 0 && @cursorPosition != @buffer.size && @cursorPosition != start && @buffer[@cursorPosition].chr.match("\\w") + @cursorPosition = (@cursorPosition + 1) % (@buffer.size + 1) + end + update + end + end + nil + end + + def home_buffer! + unless @handle_mode == :history_search! + @cursorPosition = 0 + update + end + nil + end + + def previous_word_buffer! + unless @handle_mode == :history_search! + if @buffer.size > 0 + start = @cursorPosition + @cursorPosition = (@cursorPosition - 1) % (@buffer.size) + while @cursorPosition != 0 && @cursorPosition != @buffer.size && @cursorPosition != start && @buffer[@cursorPosition].chr.match("\\w") + @cursorPosition = (@cursorPosition - 1) % (@buffer.size + 1) + end + update + end + end + nil + end + + def previous_character_buffer! + unless @handle_mode == :history_search! + if @buffer.size > 0 + @cursorPosition = (@cursorPosition - 1) % (@buffer.size + 1) + update + end + end + nil + end + + def next_character_buffer! + unless @handle_mode == :history_search! + if @buffer.size > 0 + @cursorPosition = (@cursorPosition + 1) % (@buffer.size + 1) + update + end + end + nil + end + + def end_buffer! + unless @handle_mode == :history_search! + @cursorPosition = @buffer.size + update + end + nil + end + + def two_step_quit! + if @user_quit then + quit + else + @user_quit = true + info "Press again within 5 seconds to quit." + Thread.new do + sleep(5) + @user_quit = false + end + end + nil + end + + def toggle_history_search! + if @handle_mode == :append_buffer! + enable_history_search! + else + disable_history_search! + end + nil + end + + def enable_history_search! + if @handle_mode == :append_buffer! + @historyPointer = 0 + @handle_mode = :history_search! + @search_buffer = @buffer + update_history_search! + end + nil + end + + def disable_history_search! + unless @handle_mode == :append_buffer! + @historyPointer = nil + @handle_mode = :append_buffer! + @buffer = @found_history || "" + @cursorPosition = @buffer.size + @search_buffer = "" + update + end + nil + end + + def update_history_search! + @search_buffer ||= "" + @found_history_array = @history.reverse.select do |line| + line.match(Regexp.new(@search_buffer)) + end + @found_history_array << "" if @found_history_array.empty? + @found_history = @found_history_array[@historyPointer % @found_history_array.size] + @buffer = "(#{@search_buffer}): `#{@found_history}`" + @cursorPosition = @search_buffer.size + 1 + update + end + + def history_search!(c) + @search_buffer << c.chr + update_history_search! + end + + def append_buffer!(c) + @buffer = @buffer[0, @cursorPosition] + c.chr + @buffer[@cursorPosition, @buffer.size - @cursorPosition] + @cursorPosition = @cursorPosition + 1 + update + nil + end + + def scroll_up!(input_window) + Muby::OutputWindow.get_instance.scroll_up(input_window) + nil + end + + def scroll_down!(input_window) + Muby::OutputWindow.get_instance.scroll_down(input_window) + nil + end + + def toggle_verbosity! + conf.toggle_verbosity! + nil + end + + def print(*message) + oldStyle = Muby::Style.extract(Muby::OutputWindow.get_instance.outputBuffer) + Muby::OutputWindow.get_instance.print(*(message + [oldStyle])) + end + + # + # Echoes a message, if we want to (conf.echo) + # + def echo(*message) + if conf.echo + style = Muby::Style.new(conf.echo_attributes, conf.echo_colors[0], conf.echo_colors[1]) + oldStyle = Muby::Style.extract(Muby::OutputWindow.get_instance.outputBuffer) + Muby::OutputWindow.get_instance.print_on_newline(*([style] + message + [oldStyle])) + end + end + end + +end Deleted: tags/release_0_6_6/lib/muby.rb =================================================================== --- trunk/lib/muby.rb 2007-10-18 19:42:30 UTC (rev 239) +++ tags/release_0_6_6/lib/muby.rb 2007-10-19 14:58:27 UTC (rev 241) @@ -1,13 +0,0 @@ -$: << File.join(File.dirname(__FILE__), "lib") -require "muby/user_methods" -require "muby/displayer" -require "muby/configuration" -require "muby/logger" -require "muby/style" -require "muby/outputwindow" -require "muby/inputwindow" -require "muby/connection" -require "muby/help" -require "muby/completer" -require "muby/application" - Copied: tags/release_0_6_6/lib/muby.rb (from rev 240, trunk/lib/muby.rb) =================================================================== --- tags/release_0_6_6/lib/muby.rb (rev 0) +++ tags/release_0_6_6/lib/muby.rb 2007-10-19 14:58:27 UTC (rev 241) @@ -0,0 +1,15 @@ +$: << File.join(File.dirname(__FILE__), "lib") +require 'pp' +require "muby/helper_methods" +require "muby/user_methods" +require "muby/displayer" +require "muby/configuration" +require "muby/logger" +require "muby/style" +require "muby/outputwindow" +require "muby/inputwindow" +require "muby/connection" +require "muby/help" +require "muby/completer" +require "muby/application" + From nobody at rubyforge.org Fri Oct 19 13:58:53 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Fri, 19 Oct 2007 13:58:53 -0400 (EDT) Subject: [Muby-submits] [242] trunk/lib: added a simple Muby:: UserWindow that a user can throw up anywhere on the screen ( make sure to move away input and output windows first, or you will probably get weird update behaviour) and write to using Muby:: UserWindow#print and clear using Muby::UserWindow#clear. Message-ID: <20071019175853.432C81858622@rubyforge.org> Revision: 242 Author: zond Date: 2007-10-19 13:58:52 -0400 (Fri, 19 Oct 2007) Log Message: ----------- added a simple Muby::UserWindow that a user can throw up anywhere on the screen (make sure to move away input and output windows first, or you will probably get weird update behaviour) and write to using Muby::UserWindow#print and clear using Muby::UserWindow#clear. accepts Muby::Style's for colors and other text styling. Modified Paths: -------------- trunk/lib/muby.rb Added Paths: ----------- trunk/lib/muby/user_window.rb Added: trunk/lib/muby/user_window.rb =================================================================== --- trunk/lib/muby/user_window.rb (rev 0) +++ trunk/lib/muby/user_window.rb 2007-10-19 17:58:52 UTC (rev 242) @@ -0,0 +1,41 @@ + +module Muby + + class UserWindow + + def initialize(options = {}) + @top = options.delete(:top) + @left = options.delete(:left) + @width = options.delete(:width) + @height = options.delete(:height) + @border = Ncurses.newwin(@height, @width, @top, @left) + @border.box(0,0) + @border.keypad(true) + @border.refresh + @window = Ncurses.newwin(@height - 2, @width - 2, @top + 1, @left + 1) + @window.keypad(true) + @window.scrollok(true) + @window.nodelay(true) + @window.refresh + end + + def print(line, col, *info) + @window.move(line, col) + info.each do |e| + if String === e + @window.printw("%s", e) + elsif Muby::Style === e + e.affect(@window) + end + end + @window.refresh + end + + def clear + @window.erase + @window.refresh + end + + end + +end Modified: trunk/lib/muby.rb =================================================================== --- trunk/lib/muby.rb 2007-10-19 14:58:27 UTC (rev 241) +++ trunk/lib/muby.rb 2007-10-19 17:58:52 UTC (rev 242) @@ -1,6 +1,7 @@ $: << File.join(File.dirname(__FILE__), "lib") require 'pp' require "muby/helper_methods" +require "muby/user_window" require "muby/user_methods" require "muby/displayer" require "muby/configuration" From nobody at rubyforge.org Fri Oct 19 13:59:32 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Fri, 19 Oct 2007 13:59:32 -0400 (EDT) Subject: [Muby-submits] [243] tags/release_0_7_0/: made release 0.7.0. Message-ID: <20071019175932.700F71858632@rubyforge.org> Revision: 243 Author: zond Date: 2007-10-19 13:59:32 -0400 (Fri, 19 Oct 2007) Log Message: ----------- made release 0.7.0. woot! Added Paths: ----------- tags/release_0_7_0/ Copied: tags/release_0_7_0 (from rev 242, trunk) From nobody at rubyforge.org Fri Oct 19 14:00:05 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Fri, 19 Oct 2007 14:00:05 -0400 (EDT) Subject: [Muby-submits] [244] trunk/lib/muby/configuration.rb: actually upped the version number Message-ID: <20071019180005.932541858632@rubyforge.org> Revision: 244 Author: zond Date: 2007-10-19 14:00:05 -0400 (Fri, 19 Oct 2007) Log Message: ----------- actually upped the version number Modified Paths: -------------- trunk/lib/muby/configuration.rb Modified: trunk/lib/muby/configuration.rb =================================================================== --- trunk/lib/muby/configuration.rb 2007-10-19 17:59:32 UTC (rev 243) +++ trunk/lib/muby/configuration.rb 2007-10-19 18:00:05 UTC (rev 244) @@ -3,7 +3,7 @@ module Muby - VERSION = "0.6.6" + VERSION = "0.7.0" # # The class that encapsulates all configuration. From nobody at rubyforge.org Fri Oct 19 14:00:40 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Fri, 19 Oct 2007 14:00:40 -0400 (EDT) Subject: [Muby-submits] [245] tags/release_0_7_0: updated the tag... Message-ID: <20071019180041.02DE8185862D@rubyforge.org> Revision: 245 Author: zond Date: 2007-10-19 14:00:40 -0400 (Fri, 19 Oct 2007) Log Message: ----------- updated the tag... Added Paths: ----------- tags/release_0_7_0/trunk/ tags/release_0_7_0/trunk/lib/muby/configuration.rb Removed Paths: ------------- tags/release_0_7_0/trunk/lib/muby/configuration.rb Copied: tags/release_0_7_0/trunk (from rev 243, trunk) Deleted: tags/release_0_7_0/trunk/lib/muby/configuration.rb =================================================================== --- trunk/lib/muby/configuration.rb 2007-10-19 17:59:32 UTC (rev 243) +++ tags/release_0_7_0/trunk/lib/muby/configuration.rb 2007-10-19 18:00:40 UTC (rev 245) @@ -1,379 +0,0 @@ - -require 'ncurses' - -module Muby - - VERSION = "0.6.6" - - # - # The class that encapsulates all configuration. - # - # To simplify its use, include Muby::Configurable in your class. - # Then you can access Configuration as 'conf' (nice shorthand :) - # - # All options in Configuration are get'able and set'able. - # - # Look in help.rb to get the meaning of them. - # - class Configuration - - @@instance = nil - - def self.get - @@instance ||= Configuration.new - end - - def initialize - # - # verbosity options - # - - @extra_verbosity_settings = { - :echo_keycodes => true, - :echo => true, - :show_level => :debug, - :timestamp => true, - :connection_status => true - } - - @output_window_geometry = { - :top => 0, - :left => 0, - :width => "Ncurses.COLS", - :height => "Ncurses.LINES - Muby::InputWindow.get_instance.height" - } - - @input_window_geometry = { - :top => "Ncurses.LINES - conf.input_height - 2", - :left => 0, - :width => "Ncurses.COLS", - :height => "conf.input_height + 2" - } - - @echo_keycodes = false - - @echo = true - - @show_level = :info - - @timestamp = false - - @connection_status = true - - # - # options to control what you see - # - - @disable_blink = false - - @timeformat = "%H:%M:%S" - - @broken_keycodes = { - 13 => true - } - - @max_history = 100 - - @default_attributes = Ncurses.const_get("A_NORMAL") - @default_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] - - @echo_attributes = Ncurses.const_get("A_BOLD") - @echo_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] - - @trace_attributes = Ncurses.const_get("A_NORMAL") - @trace_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] - - @debug_attributes = Ncurses.const_get("A_NORMAL") - @debug_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] - - @info_attributes = Ncurses.const_get("A_NORMAL") - @info_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] - - @warn_attributes = Ncurses.const_get("A_NORMAL") - @warn_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] - - @error_attributes = Ncurses.const_get("A_NORMAL") - @error_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] - - @flush = true - - @gags = [] - - @anti_gags = [] - - @remote_substitutions = {} - - @local_substitutions = {} - - # - # options to control what gets run when # - # - - @startup_triggers = [] - - @connect_triggers = [] - - @shutdown_triggers = [] - - @remote_triggers = {} - - @remote_character_triggers = {} - - @local_triggers = { - /^\/(.*)\n$/m => :execute_command!, - /^!(.*)\n$/m => :shell_command!, - /^#.*\n$/m => :ignore_command! - } - - @key_commands = { - #18 => :resize, # ctrl-l - Ncurses.const_get("KEY_PPAGE") => :scroll_up!, - Ncurses.const_get("KEY_NPAGE") => :scroll_down!, - Ncurses.const_get("KEY_ENTER") => :process_buffer!, - 10 => :process_buffer!, # enter - 3 => :two_step_quit!, # ctrl-c - 9 => :complete!, # tab - 18 => :toggle_history_search!, # ctrl-r - 127 => :backspace_buffer!, # backspace - Ncurses.const_get("KEY_BACKSPACE") => :backspace_buffer!, - 27 => { - 91 => { - 53 => { - 68 => :previous_word_buffer!, # ctrl-key_left - 67 => :next_word_buffer!, # ctrl-key_right - } - } - }, - Ncurses.const_get("KEY_DC") => :delete_buffer!, - Ncurses.const_get("KEY_UP") => :previous_history_buffer!, - Ncurses.const_get("KEY_DOWN") => :next_history_buffer!, - 262 => :home_buffer!, # home_key - 360 => :end_buffer!, # end_key - Ncurses.const_get("KEY_LEFT") => :previous_character_buffer!, - Ncurses.const_get("KEY_RIGHT") => :next_character_buffer!, - 22 => :toggle_verbosity!, # ctrl-v - 265 => :help # f1 - } - - # - # miscellaneous options # - # - - @feed_completer_with_history = true - - @feed_completer_with_input = true - - @extra_completions = [] - - @loaded_rc_file = false - - @user_edited_config_file = false - - @userdir = File.join(ENV["HOME"], "mubyrc.d") - - @history_file = File.join(@userdir, "history") - - @output_buffer = 1000 - - @input_height = 3 - - @input_logfile = nil - - @output_logfile = nil - - end - - # - # The magical method that lets us get and set the settings without - # having to write getters and setters for all of them - # - def method_missing(*args) - method_name = args[0].to_s - var_name = method_name[/^[^=]*/] - - setter = method_name =~ /=$/ - if setter - return super unless args.size == 2 - instance_variable_set("@#{var_name}", args[1]) - return args[1] - else - return super unless args.size == 1 - return instance_variable_get("@#{var_name}") - end - end - - # - # The halfway magical method that toggles all settings covered in - # @extra_verbosity_settings to what they are in that hash, - # and then stores them away inside the same hash for back-toggling again. - # - def toggle_verbosity! - - # copy old extra-settings to a copy - settings_copy = @extra_verbosity_settings.clone - - # set our extra-settings to be the currently applied settings - @extra_verbosity_settings.clone.each do |key, value| - @extra_verbosity_settings[key] = self.send(key) - end - - # apply the extra-settings - settings_copy.each do |key, value| - self.send("#{key}=", value) - end - - Muby::Displayer.info("Toggled verbosity. Press again to toggle back.") - end - - # - # Returns true if we are supposed to display messages - # of +level+. - # - def display?(level) - levels = [:trace, :debug, :info, :warn, :error] - levels.index(level) >= (levels.index(@show_level) || 0) - end - - # - # Will save the current configuration to the loaded rc file, - # or to mubyrc if no such file was loaded. - # - def save_configuration_file! - to_save = @loaded_rc_file ? @loaded_rc_file : File.join(ENV["HOME"], "mubyrc") - begin - Kernel::open(to_save, "w") do |output| - output.write(self.to_ruby) - @loaded_rc_file = to_save - end - Muby::Displayer.info("Saved default configuration to #{to_save}.") - rescue Exception => e - Muby::Displayer.warn("Failed saving default configuration to #{to_save}: #{e.message}") - Muby::Displayer.debug(e.backtrace.join("\n")) - end - end - - # - # Tries to load all the users files, defined as - # any file named .mubyrc or mubyrc in the users ENV["HOME"] - # and all **/*.rb files in the users ENV["HOME"]/@userdir - # with the root of the userdir taking precidence over subdirectories. - # Directories starting with a . are ignored. - # - # If none of the mubyrc-files existed, it will try to create one - # for the user to edit to his/her liking. - # - def load_user_files! - @loaded_rc_file = false - if to_load = [".mubyrc", "mubyrc"].find do |file_name| - File.exists?(File.join(ENV["HOME"], file_name)) - end - nice_load!(to_load) - @loaded_rc_file = to_load - end - - unless @loaded_rc_file - save_configuration_file! - end - - if File.exists?(@userdir) - # Only load *.rb files within sub-directories of the current directory, and not the current directory's *.rb files!) - # Test: Dir[File.join(Dir.pwd, "*", "**", "*.rb")].each do |f| puts f end ; nil - Dir[File.join(@userdir, "*", "**", "*.rb")].each do |file_name| - nice_load!(file_name) - end - # Only load *.rb files of the current directory. - # This is very useful for users to create "overrides" for items in subdirectories. - # NOTE: This does follow symbolic links (files and directories) - # Test: Dir[File.join(Dir.pwd, "*.rb")].each do |f| puts f end ; nil - Dir[File.join(@userdir, "*.rb")].each do |file_name| - nice_load!(file_name) - end - else - Muby::Displayer.warn("#{@userdir} does not exist. If it did, *.rb in it would be loaded now.") - end - end - - # - # A non-raising method that tries to load +f+ and tells the output window about its success. - # - def nice_load!(f) - begin - Kernel::load(f) - Muby::Displayer.info("Loaded #{f}") - rescue Exception => e - Muby::Displayer.exception(e) - end - end - - # - # Will reload the entire app, ie the class files and the - # user files. - # - # TODO: Remove the spammyness. - # It is not appropriate to use 'puts' when reload_application! is being called by the user. - # To turn off "uninitialised constant" warnings, do: $VERBOSE = nil - # - # Simply set your show_level to :warn instead of :info, and you wont see the load messages. - # - # Any other messages come from your own files :O - # - def reload_application! - Dir[File.join(File.dirname(__FILE__), "**", "*.rb")].each do |file_name| - nice_load! file_name - end - load_user_files! - end - - # - # The not so magical at all method that prints our content - # to a String so that we easily can save our current settings - # in a file, or create a default config file. - # - def to_ruby - "# -# This is the default configuration of muby. -# To learn more about how to configure it, you -# can type '/help' in the client. -# -include Muby::Configurable -" + - instance_variables.sort.collect do |var_name| - value = eval(var_name) - case value - when Hash - space = "conf.#{var_name[1..-1]} = _".size - value = value.inspect.gsub(/, /, ",\n#{" " * space}") - when File - begin - value.read(0) - value = "open(\"#{value.path}\", \"r\")" - rescue - value = "open(\"#{value.path}\", \"a\")" - end - when NilClass - value = value.inspect - else - value = value.inspect - end - var_name = var_name[1..-1] - help_text = Muby::Help.configuration[var_name.to_sym] || "no help available for #{var_name}" - help_text = help_text.split("\n").join("\n# ") - " -# #{help_text} -conf.#{var_name} = #{value}" - end.join("\n") - end - - end - - # - # The module that provides the shorthand for - # using classes. - # - module Configurable - def conf - Configuration.get - end - end - -end Copied: tags/release_0_7_0/trunk/lib/muby/configuration.rb (from rev 244, trunk/lib/muby/configuration.rb) =================================================================== --- tags/release_0_7_0/trunk/lib/muby/configuration.rb (rev 0) +++ tags/release_0_7_0/trunk/lib/muby/configuration.rb 2007-10-19 18:00:40 UTC (rev 245) @@ -0,0 +1,379 @@ + +require 'ncurses' + +module Muby + + VERSION = "0.7.0" + + # + # The class that encapsulates all configuration. + # + # To simplify its use, include Muby::Configurable in your class. + # Then you can access Configuration as 'conf' (nice shorthand :) + # + # All options in Configuration are get'able and set'able. + # + # Look in help.rb to get the meaning of them. + # + class Configuration + + @@instance = nil + + def self.get + @@instance ||= Configuration.new + end + + def initialize + # + # verbosity options + # + + @extra_verbosity_settings = { + :echo_keycodes => true, + :echo => true, + :show_level => :debug, + :timestamp => true, + :connection_status => true + } + + @output_window_geometry = { + :top => 0, + :left => 0, + :width => "Ncurses.COLS", + :height => "Ncurses.LINES - Muby::InputWindow.get_instance.height" + } + + @input_window_geometry = { + :top => "Ncurses.LINES - conf.input_height - 2", + :left => 0, + :width => "Ncurses.COLS", + :height => "conf.input_height + 2" + } + + @echo_keycodes = false + + @echo = true + + @show_level = :info + + @timestamp = false + + @connection_status = true + + # + # options to control what you see + # + + @disable_blink = false + + @timeformat = "%H:%M:%S" + + @broken_keycodes = { + 13 => true + } + + @max_history = 100 + + @default_attributes = Ncurses.const_get("A_NORMAL") + @default_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] + + @echo_attributes = Ncurses.const_get("A_BOLD") + @echo_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] + + @trace_attributes = Ncurses.const_get("A_NORMAL") + @trace_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] + + @debug_attributes = Ncurses.const_get("A_NORMAL") + @debug_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] + + @info_attributes = Ncurses.const_get("A_NORMAL") + @info_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] + + @warn_attributes = Ncurses.const_get("A_NORMAL") + @warn_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] + + @error_attributes = Ncurses.const_get("A_NORMAL") + @error_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] + + @flush = true + + @gags = [] + + @anti_gags = [] + + @remote_substitutions = {} + + @local_substitutions = {} + + # + # options to control what gets run when # + # + + @startup_triggers = [] + + @connect_triggers = [] + + @shutdown_triggers = [] + + @remote_triggers = {} + + @remote_character_triggers = {} + + @local_triggers = { + /^\/(.*)\n$/m => :execute_command!, + /^!(.*)\n$/m => :shell_command!, + /^#.*\n$/m => :ignore_command! + } + + @key_commands = { + #18 => :resize, # ctrl-l + Ncurses.const_get("KEY_PPAGE") => :scroll_up!, + Ncurses.const_get("KEY_NPAGE") => :scroll_down!, + Ncurses.const_get("KEY_ENTER") => :process_buffer!, + 10 => :process_buffer!, # enter + 3 => :two_step_quit!, # ctrl-c + 9 => :complete!, # tab + 18 => :toggle_history_search!, # ctrl-r + 127 => :backspace_buffer!, # backspace + Ncurses.const_get("KEY_BACKSPACE") => :backspace_buffer!, + 27 => { + 91 => { + 53 => { + 68 => :previous_word_buffer!, # ctrl-key_left + 67 => :next_word_buffer!, # ctrl-key_right + } + } + }, + Ncurses.const_get("KEY_DC") => :delete_buffer!, + Ncurses.const_get("KEY_UP") => :previous_history_buffer!, + Ncurses.const_get("KEY_DOWN") => :next_history_buffer!, + 262 => :home_buffer!, # home_key + 360 => :end_buffer!, # end_key + Ncurses.const_get("KEY_LEFT") => :previous_character_buffer!, + Ncurses.const_get("KEY_RIGHT") => :next_character_buffer!, + 22 => :toggle_verbosity!, # ctrl-v + 265 => :help # f1 + } + + # + # miscellaneous options # + # + + @feed_completer_with_history = true + + @feed_completer_with_input = true + + @extra_completions = [] + + @loaded_rc_file = false + + @user_edited_config_file = false + + @userdir = File.join(ENV["HOME"], "mubyrc.d") + + @history_file = File.join(@userdir, "history") + + @output_buffer = 1000 + + @input_height = 3 + + @input_logfile = nil + + @output_logfile = nil + + end + + # + # The magical method that lets us get and set the settings without + # having to write getters and setters for all of them + # + def method_missing(*args) + method_name = args[0].to_s + var_name = method_name[/^[^=]*/] + + setter = method_name =~ /=$/ + if setter + return super unless args.size == 2 + instance_variable_set("@#{var_name}", args[1]) + return args[1] + else + return super unless args.size == 1 + return instance_variable_get("@#{var_name}") + end + end + + # + # The halfway magical method that toggles all settings covered in + # @extra_verbosity_settings to what they are in that hash, + # and then stores them away inside the same hash for back-toggling again. + # + def toggle_verbosity! + + # copy old extra-settings to a copy + settings_copy = @extra_verbosity_settings.clone + + # set our extra-settings to be the currently applied settings + @extra_verbosity_settings.clone.each do |key, value| + @extra_verbosity_settings[key] = self.send(key) + end + + # apply the extra-settings + settings_copy.each do |key, value| + self.send("#{key}=", value) + end + + Muby::Displayer.info("Toggled verbosity. Press again to toggle back.") + end + + # + # Returns true if we are supposed to display messages + # of +level+. + # + def display?(level) + levels = [:trace, :debug, :info, :warn, :error] + levels.index(level) >= (levels.index(@show_level) || 0) + end + + # + # Will save the current configuration to the loaded rc file, + # or to mubyrc if no such file was loaded. + # + def save_configuration_file! + to_save = @loaded_rc_file ? @loaded_rc_file : File.join(ENV["HOME"], "mubyrc") + begin + Kernel::open(to_save, "w") do |output| + output.write(self.to_ruby) + @loaded_rc_file = to_save + end + Muby::Displayer.info("Saved default configuration to #{to_save}.") + rescue Exception => e + Muby::Displayer.warn("Failed saving default configuration to #{to_save}: #{e.message}") + Muby::Displayer.debug(e.backtrace.join("\n")) + end + end + + # + # Tries to load all the users files, defined as + # any file named .mubyrc or mubyrc in the users ENV["HOME"] + # and all **/*.rb files in the users ENV["HOME"]/@userdir + # with the root of the userdir taking precidence over subdirectories. + # Directories starting with a . are ignored. + # + # If none of the mubyrc-files existed, it will try to create one + # for the user to edit to his/her liking. + # + def load_user_files! + @loaded_rc_file = false + if to_load = [".mubyrc", "mubyrc"].find do |file_name| + File.exists?(File.join(ENV["HOME"], file_name)) + end + nice_load!(to_load) + @loaded_rc_file = to_load + end + + unless @loaded_rc_file + save_configuration_file! + end + + if File.exists?(@userdir) + # Only load *.rb files within sub-directories of the current directory, and not the current directory's *.rb files!) + # Test: Dir[File.join(Dir.pwd, "*", "**", "*.rb")].each do |f| puts f end ; nil + Dir[File.join(@userdir, "*", "**", "*.rb")].each do |file_name| + nice_load!(file_name) + end + # Only load *.rb files of the current directory. + # This is very useful for users to create "overrides" for items in subdirectories. + # NOTE: This does follow symbolic links (files and directories) + # Test: Dir[File.join(Dir.pwd, "*.rb")].each do |f| puts f end ; nil + Dir[File.join(@userdir, "*.rb")].each do |file_name| + nice_load!(file_name) + end + else + Muby::Displayer.warn("#{@userdir} does not exist. If it did, *.rb in it would be loaded now.") + end + end + + # + # A non-raising method that tries to load +f+ and tells the output window about its success. + # + def nice_load!(f) + begin + Kernel::load(f) + Muby::Displayer.info("Loaded #{f}") + rescue Exception => e + Muby::Displayer.exception(e) + end + end + + # + # Will reload the entire app, ie the class files and the + # user files. + # + # TODO: Remove the spammyness. + # It is not appropriate to use 'puts' when reload_application! is being called by the user. + # To turn off "uninitialised constant" warnings, do: $VERBOSE = nil + # + # Simply set your show_level to :warn instead of :info, and you wont see the load messages. + # + # Any other messages come from your own files :O + # + def reload_application! + Dir[File.join(File.dirname(__FILE__), "**", "*.rb")].each do |file_name| + nice_load! file_name + end + load_user_files! + end + + # + # The not so magical at all method that prints our content + # to a String so that we easily can save our current settings + # in a file, or create a default config file. + # + def to_ruby + "# +# This is the default configuration of muby. +# To learn more about how to configure it, you +# can type '/help' in the client. +# +include Muby::Configurable +" + + instance_variables.sort.collect do |var_name| + value = eval(var_name) + case value + when Hash + space = "conf.#{var_name[1..-1]} = _".size + value = value.inspect.gsub(/, /, ",\n#{" " * space}") + when File + begin + value.read(0) + value = "open(\"#{value.path}\", \"r\")" + rescue + value = "open(\"#{value.path}\", \"a\")" + end + when NilClass + value = value.inspect + else + value = value.inspect + end + var_name = var_name[1..-1] + help_text = Muby::Help.configuration[var_name.to_sym] || "no help available for #{var_name}" + help_text = help_text.split("\n").join("\n# ") + " +# #{help_text} +conf.#{var_name} = #{value}" + end.join("\n") + end + + end + + # + # The module that provides the shorthand for + # using classes. + # + module Configurable + def conf + Configuration.get + end + end + +end From nobody at rubyforge.org Fri Oct 19 14:01:22 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Fri, 19 Oct 2007 14:01:22 -0400 (EDT) Subject: [Muby-submits] [246] tags/release_0_7_0/trunk/: cleaning up my mistakes :/ Message-ID: <20071019180122.C33CA1858632@rubyforge.org> Revision: 246 Author: zond Date: 2007-10-19 14:01:22 -0400 (Fri, 19 Oct 2007) Log Message: ----------- cleaning up my mistakes :/ Removed Paths: ------------- tags/release_0_7_0/trunk/ From nobody at rubyforge.org Fri Oct 19 14:02:17 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Fri, 19 Oct 2007 14:02:17 -0400 (EDT) Subject: [Muby-submits] [247] tags/release_0_7_0/: clean up Message-ID: <20071019180217.1FF96185862D@rubyforge.org> Revision: 247 Author: zond Date: 2007-10-19 14:02:16 -0400 (Fri, 19 Oct 2007) Log Message: ----------- clean up Removed Paths: ------------- tags/release_0_7_0/ From nobody at rubyforge.org Fri Oct 19 14:03:11 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Fri, 19 Oct 2007 14:03:11 -0400 (EDT) Subject: [Muby-submits] [248] tags/release_0_7_0/: now made a real tag of a real version 0.7.0 Message-ID: <20071019180311.0C872185862D@rubyforge.org> Revision: 248 Author: zond Date: 2007-10-19 14:03:10 -0400 (Fri, 19 Oct 2007) Log Message: ----------- now made a real tag of a real version 0.7.0 Added Paths: ----------- tags/release_0_7_0/ Copied: tags/release_0_7_0 (from rev 247, trunk) From nobody at rubyforge.org Fri Oct 19 14:21:25 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Fri, 19 Oct 2007 14:21:25 -0400 (EDT) Subject: [Muby-submits] [249] trunk/lib/muby: made the reload_application! method work again. Message-ID: <20071019182125.F275B185861B@rubyforge.org> Revision: 249 Author: zond Date: 2007-10-19 14:21:25 -0400 (Fri, 19 Oct 2007) Log Message: ----------- made the reload_application! method work again. added help for the input/output window geometries. Modified Paths: -------------- trunk/lib/muby/configuration.rb trunk/lib/muby/help.rb trunk/lib/muby/inputwindow.rb trunk/lib/muby/outputwindow.rb trunk/lib/muby/user_methods.rb Modified: trunk/lib/muby/configuration.rb =================================================================== --- trunk/lib/muby/configuration.rb 2007-10-19 18:03:10 UTC (rev 248) +++ trunk/lib/muby/configuration.rb 2007-10-19 18:21:25 UTC (rev 249) @@ -3,8 +3,9 @@ module Muby - VERSION = "0.7.0" + VERSION = "0.7.0" unless defined?(Muby::VERSION) + # # The class that encapsulates all configuration. # @@ -17,7 +18,7 @@ # class Configuration - @@instance = nil + @@instance ||= nil def self.get @@instance ||= Configuration.new Modified: trunk/lib/muby/help.rb =================================================================== --- trunk/lib/muby/help.rb 2007-10-19 18:03:10 UTC (rev 248) +++ trunk/lib/muby/help.rb 2007-10-19 18:21:25 UTC (rev 249) @@ -7,6 +7,8 @@ :feed_completer_with_input => "If true, the completion command will use everything seen from the remote end to calculate possible completions.", :extra_completions => "Fill this array with words that you allways want to be able to complete to.", :extra_verbosity_settings => "The settings we want to toggle to when running the toggle_verbosity! method.", + :input_window_geometry => "The top and left corners of the InputWindow, and its width and height. The values will be set to what you enter here, or if they are Strings will be evaluated when the windows are set up.", + :output_window_geometry => "The top and left corners of the OutputWindow, and its width and height. The values will be set to what you enter here, or if they are Strings will be evaluated when the windows are set up.", :echo_keycodes => "Whether to echo the keycode for every key pressed or not.", :echo => "Whether to print what is sent to the server to the outputwindow.", :show_level => "What level of information to provide the user. Modified: trunk/lib/muby/inputwindow.rb =================================================================== --- trunk/lib/muby/inputwindow.rb 2007-10-19 18:03:10 UTC (rev 248) +++ trunk/lib/muby/inputwindow.rb 2007-10-19 18:21:25 UTC (rev 249) @@ -20,8 +20,8 @@ include Muby::Styled include Muby::HelperMethods - @@instance = nil - + @@instance ||= nil + def self.get_instance @@instance ||= Muby::InputWindow.new end @@ -59,20 +59,27 @@ help unless conf.user_edited_config_file end + def reload! + @left = nil + @top = nil + @width = nil + @height = nil + end + def left - execute_with_verbosity(:trace, conf.input_window_geometry[:left]) + @left ||= execute_with_verbosity(:trace, conf.input_window_geometry[:left]) end def top - execute_with_verbosity(:trace, conf.input_window_geometry[:top]) + @top ||= execute_with_verbosity(:trace, conf.input_window_geometry[:top]) end def width - execute_with_verbosity(:trace, conf.input_window_geometry[:width]) + @width ||= execute_with_verbosity(:trace, conf.input_window_geometry[:width]) end def height - execute_with_verbosity(:trace, conf.input_window_geometry[:height]) + @height ||= execute_with_verbosity(:trace, conf.input_window_geometry[:height]) end # Modified: trunk/lib/muby/outputwindow.rb =================================================================== --- trunk/lib/muby/outputwindow.rb 2007-10-19 18:03:10 UTC (rev 248) +++ trunk/lib/muby/outputwindow.rb 2007-10-19 18:21:25 UTC (rev 249) @@ -10,7 +10,7 @@ attr_reader :scrollback, :size, :outputBuffer - @@instance = nil + @@instance ||= nil def self.get_instance @@instance ||= Muby::OutputWindow.new Modified: trunk/lib/muby/user_methods.rb =================================================================== --- trunk/lib/muby/user_methods.rb 2007-10-19 18:03:10 UTC (rev 248) +++ trunk/lib/muby/user_methods.rb 2007-10-19 18:21:25 UTC (rev 249) @@ -233,6 +233,7 @@ def reload_application! conf.reload_application! Muby::OutputWindow.get_instance.reload! + Muby::InputWindow.get_instance.reload! end def complete! From nobody at rubyforge.org Fri Oct 19 14:21:48 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Fri, 19 Oct 2007 14:21:48 -0400 (EDT) Subject: [Muby-submits] [250] trunk/lib/muby/configuration.rb: bumped the version number Message-ID: <20071019182148.CB200185863A@rubyforge.org> Revision: 250 Author: zond Date: 2007-10-19 14:21:48 -0400 (Fri, 19 Oct 2007) Log Message: ----------- bumped the version number Modified Paths: -------------- trunk/lib/muby/configuration.rb Modified: trunk/lib/muby/configuration.rb =================================================================== --- trunk/lib/muby/configuration.rb 2007-10-19 18:21:25 UTC (rev 249) +++ trunk/lib/muby/configuration.rb 2007-10-19 18:21:48 UTC (rev 250) @@ -4,7 +4,7 @@ module Muby - VERSION = "0.7.0" unless defined?(Muby::VERSION) + VERSION = "0.7.1" unless defined?(Muby::VERSION) # # The class that encapsulates all configuration. From nobody at rubyforge.org Fri Oct 19 14:22:19 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Fri, 19 Oct 2007 14:22:19 -0400 (EDT) Subject: [Muby-submits] [251] tags/release_0_7_1/: made the release 0.7.1 tag Message-ID: <20071019182219.B70A5185861B@rubyforge.org> Revision: 251 Author: zond Date: 2007-10-19 14:22:19 -0400 (Fri, 19 Oct 2007) Log Message: ----------- made the release 0.7.1 tag Added Paths: ----------- tags/release_0_7_1/ Copied: tags/release_0_7_1 (from rev 250, trunk) From nobody at rubyforge.org Sat Oct 20 11:58:15 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Sat, 20 Oct 2007 11:58:15 -0400 (EDT) Subject: [Muby-submits] [252] trunk/lib/muby: fixed lots of bugs with reload_application. Message-ID: <20071020155815.709F91858663@rubyforge.org> Revision: 252 Author: zond Date: 2007-10-20 11:58:15 -0400 (Sat, 20 Oct 2007) Log Message: ----------- fixed lots of bugs with reload_application. added a method resize_application to handle window resizes. please not that this does not currently work properly if you change the width of the terminal window (make it wider,and the output buffer will retain the same width, make it less wide, and the output buffer will simply stop working until you make it wider again) due to ncurses problems i dont yet understand. it does work when you make the window higher though :) made a new patch level to celebrate. Modified Paths: -------------- trunk/lib/muby/configuration.rb trunk/lib/muby/helper_methods.rb trunk/lib/muby/inputwindow.rb trunk/lib/muby/outputwindow.rb trunk/lib/muby/user_methods.rb Modified: trunk/lib/muby/configuration.rb =================================================================== --- trunk/lib/muby/configuration.rb 2007-10-19 18:22:19 UTC (rev 251) +++ trunk/lib/muby/configuration.rb 2007-10-20 15:58:15 UTC (rev 252) @@ -4,7 +4,7 @@ module Muby - VERSION = "0.7.1" unless defined?(Muby::VERSION) + VERSION = "0.7.2" unless defined?(Muby::VERSION) # # The class that encapsulates all configuration. Modified: trunk/lib/muby/helper_methods.rb =================================================================== --- trunk/lib/muby/helper_methods.rb 2007-10-19 18:22:19 UTC (rev 251) +++ trunk/lib/muby/helper_methods.rb 2007-10-20 15:58:15 UTC (rev 252) @@ -7,24 +7,29 @@ execute_with_verbosity(:debug, command, *args) end + def do_execute(command, *args) + result = nil + if Proc === command + result = command.call(*args[0...(command.arity)]) + elsif String === command + result = eval(command) + elsif Symbol === command + method = self.method(command) + args = args[0...(method.arity)] + result = method.call(*args) + elsif Array === command + method = self.method(command.first) + args = (command[1..-1] + args)[0...(method.arity)] + result = method.call(*args) + else + result = command + end + result + end + def execute_with_verbosity(verbosity, command, *args) begin - result = nil - if Proc === command - result = command.call(*args[0...(command.arity)]) - elsif String === command - result = eval(command) - elsif Symbol === command - method = self.method(command) - args = args[0...(method.arity)] - result = method.call(*args) - elsif Array === command - method = self.method(command.first) - args = (command[1..-1] + args)[0...(method.arity)] - result = method.call(*args) - else - result = command - end + result = do_execute(command, *args) unless result.nil? case result when String Modified: trunk/lib/muby/inputwindow.rb =================================================================== --- trunk/lib/muby/inputwindow.rb 2007-10-19 18:22:19 UTC (rev 251) +++ trunk/lib/muby/inputwindow.rb 2007-10-20 15:58:15 UTC (rev 252) @@ -32,6 +32,17 @@ # Start working! # def go + # Ensure our size is calculable + begin + height + width + top + left + rescue Exception => e + Ncurses.endwin + raise "Unable to calculate input window geometry: #{e}\n\nCheck your config file (#{conf.loaded_rc_file}) for errors in 'conf.input_window_geometry!\n\n" + end + # Init all the default values @buffer = "" @cursorPosition = 0 @@ -43,6 +54,12 @@ @recent_escape = [] @handle_mode = :append_buffer! + resize! + + help unless conf.user_edited_config_file + end + + def resize! # Init the input box @inputBorder = Ncurses.newwin(height, width, top, left) @inputBorder.box(0,0) @@ -55,31 +72,26 @@ @inputWindow.scrollok(true) @inputWindow.nodelay(true) @inputWindow.refresh - - help unless conf.user_edited_config_file end def reload! - @left = nil - @top = nil - @width = nil - @height = nil + do_startup_triggers end def left - @left ||= execute_with_verbosity(:trace, conf.input_window_geometry[:left]) + do_execute(conf.input_window_geometry[:left]) end def top - @top ||= execute_with_verbosity(:trace, conf.input_window_geometry[:top]) + do_execute(conf.input_window_geometry[:top]) end def width - @width ||= execute_with_verbosity(:trace, conf.input_window_geometry[:width]) + do_execute(conf.input_window_geometry[:width]) end def height - @height ||= execute_with_verbosity(:trace, conf.input_window_geometry[:height]) + do_execute(conf.input_window_geometry[:height]) end # @@ -159,20 +171,25 @@ end end + def do_startup_triggers + conf.startup_triggers.each do |trigger| + execute(trigger, self, Muby::OutputWindow.get_instance) + end + end + # # Just keep listening to the keyboard input. # def process loadHistory - conf.startup_triggers.each do |trigger| - execute(trigger, self, Muby::OutputWindow.get_instance) - end + do_startup_triggers # We need to check one key at a time due to triggers and conf.key_commands while c = @inputWindow.wgetch if c == Ncurses.const_get("ERR") sleep(0.01) else handle(c, conf.key_commands) + update end end # while c = @inputWindow.wgetch end # def process Modified: trunk/lib/muby/outputwindow.rb =================================================================== --- trunk/lib/muby/outputwindow.rb 2007-10-19 18:22:19 UTC (rev 251) +++ trunk/lib/muby/outputwindow.rb 2007-10-20 15:58:15 UTC (rev 252) @@ -28,6 +28,17 @@ # Start working! # def go + # Ensure our size is calculable + begin + height + width + top + left + rescue Exception => e + Ncurses.endwin + raise "Unable to calculate output window geometry: #{e}\n\nCheck your config file (#{conf.loaded_rc_file}) for errors in 'conf.output_window_geometry!\n\n" + end + @scrollback = 0 @waitBuffer = [] @lines = 0 @@ -47,27 +58,24 @@ @ready = true end - def reload! - @left = nil - @top = nil - @width = nil - @height = nil + def resize! + refresh end def left - @left ||= execute_with_verbosity(:trace, conf.output_window_geometry[:left]) + do_execute(conf.output_window_geometry[:left]) end def top - @top ||= execute_with_verbosity(:trace, conf.output_window_geometry[:top]) + do_execute(conf.output_window_geometry[:top]) end def width - @width ||= execute_with_verbosity(:trace, conf.output_window_geometry[:width]) + do_execute(conf.output_window_geometry[:width]) end def height - @height ||= execute_with_verbosity(:trace, conf.output_window_geometry[:height]) + do_execute(conf.output_window_geometry[:height]) end def show_version Modified: trunk/lib/muby/user_methods.rb =================================================================== --- trunk/lib/muby/user_methods.rb 2007-10-19 18:22:19 UTC (rev 251) +++ trunk/lib/muby/user_methods.rb 2007-10-20 15:58:15 UTC (rev 252) @@ -41,7 +41,7 @@ (Then, you could type /help or press F1 to get the help text again) The configuration file the system has tried to create for you -is at #{conf.loaded_rc_file}. +is at #{File.expand_path(conf.loaded_rc_file)}. ENDTEXT info help end @@ -229,10 +229,15 @@ end nil end + + def resize_application! + Muby::OutputWindow.get_instance.resize! + Muby::InputWindow.get_instance.resize! + end def reload_application! + resize_application! conf.reload_application! - Muby::OutputWindow.get_instance.reload! Muby::InputWindow.get_instance.reload! end From nobody at rubyforge.org Sat Oct 20 11:58:47 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Sat, 20 Oct 2007 11:58:47 -0400 (EDT) Subject: [Muby-submits] [253] tags/release_0_7_2/: made release 0.7.2 Message-ID: <20071020155847.A95951858665@rubyforge.org> Revision: 253 Author: zond Date: 2007-10-20 11:58:47 -0400 (Sat, 20 Oct 2007) Log Message: ----------- made release 0.7.2 Added Paths: ----------- tags/release_0_7_2/ Copied: tags/release_0_7_2 (from rev 252, trunk) From nobody at rubyforge.org Sat Oct 20 12:06:51 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Sat, 20 Oct 2007 12:06:51 -0400 (EDT) Subject: [Muby-submits] [254] trunk/lib/muby: made the connection work again :O oops Message-ID: <20071020160651.398491858664@rubyforge.org> Revision: 254 Author: zond Date: 2007-10-20 12:06:50 -0400 (Sat, 20 Oct 2007) Log Message: ----------- made the connection work again :O oops Modified Paths: -------------- trunk/lib/muby/configuration.rb trunk/lib/muby/connection.rb Modified: trunk/lib/muby/configuration.rb =================================================================== --- trunk/lib/muby/configuration.rb 2007-10-20 15:58:47 UTC (rev 253) +++ trunk/lib/muby/configuration.rb 2007-10-20 16:06:50 UTC (rev 254) @@ -4,7 +4,7 @@ module Muby - VERSION = "0.7.2" unless defined?(Muby::VERSION) + VERSION = "0.7.3" unless defined?(Muby::VERSION) # # The class that encapsulates all configuration. Modified: trunk/lib/muby/connection.rb =================================================================== --- trunk/lib/muby/connection.rb 2007-10-20 15:58:47 UTC (rev 253) +++ trunk/lib/muby/connection.rb 2007-10-20 16:06:50 UTC (rev 254) @@ -1,3 +1,6 @@ + +require 'socket' + # # The class that encapsulates the actual Connection # From nobody at rubyforge.org Sat Oct 20 12:07:21 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Sat, 20 Oct 2007 12:07:21 -0400 (EDT) Subject: [Muby-submits] [255] tags/release_0_7_3/: made release 0.7.3 Message-ID: <20071020160721.6119D1858667@rubyforge.org> Revision: 255 Author: zond Date: 2007-10-20 12:07:21 -0400 (Sat, 20 Oct 2007) Log Message: ----------- made release 0.7.3 Added Paths: ----------- tags/release_0_7_3/ Copied: tags/release_0_7_3 (from rev 254, trunk) From nobody at rubyforge.org Sat Oct 20 12:31:39 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Sat, 20 Oct 2007 12:31:39 -0400 (EDT) Subject: [Muby-submits] [256] trunk/lib/muby/inputwindow.rb: added better feedback about history file Message-ID: <20071020163139.9F3851858662@rubyforge.org> Revision: 256 Author: zond Date: 2007-10-20 12:31:39 -0400 (Sat, 20 Oct 2007) Log Message: ----------- added better feedback about history file Modified Paths: -------------- trunk/lib/muby/inputwindow.rb Modified: trunk/lib/muby/inputwindow.rb =================================================================== --- trunk/lib/muby/inputwindow.rb 2007-10-20 16:07:21 UTC (rev 255) +++ trunk/lib/muby/inputwindow.rb 2007-10-20 16:31:39 UTC (rev 256) @@ -134,7 +134,7 @@ def loadHistory begin if FileTest.readable?(conf.history_file) - info("Reading history file") + info("Reading #{conf.history_file}") Kernel::open(conf.history_file) do |input| @history = Marshal.load(input.read) end From nobody at rubyforge.org Mon Oct 22 16:19:39 2007 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Mon, 22 Oct 2007 16:19:39 -0400 (EDT) Subject: [Muby-submits] [257] trunk/lib/muby/configuration.rb: modified default configuration to match modern debian default installation . Message-ID: <20071022201939.6D33A1858614@rubyforge.org> Revision: 257 Author: zond Date: 2007-10-22 16:19:39 -0400 (Mon, 22 Oct 2007) Log Message: ----------- modified default configuration to match modern debian default installation. one nice feature would be autodetecting platform and selecting key config accordingly... Modified Paths: -------------- trunk/lib/muby/configuration.rb Modified: trunk/lib/muby/configuration.rb =================================================================== --- trunk/lib/muby/configuration.rb 2007-10-20 16:31:39 UTC (rev 256) +++ trunk/lib/muby/configuration.rb 2007-10-22 20:19:39 UTC (rev 257) @@ -127,7 +127,7 @@ } @key_commands = { - #18 => :resize, # ctrl-l + 12 => :resize_application!, # ctrl-l Ncurses.const_get("KEY_PPAGE") => :scroll_up!, Ncurses.const_get("KEY_NPAGE") => :scroll_down!, Ncurses.const_get("KEY_ENTER") => :process_buffer!, @@ -138,10 +138,15 @@ 127 => :backspace_buffer!, # backspace Ncurses.const_get("KEY_BACKSPACE") => :backspace_buffer!, 27 => { + 263 => :word_backspace_buffer!, # alt-backspace 91 => { - 53 => { - 68 => :previous_word_buffer!, # ctrl-key_left - 67 => :next_word_buffer!, # ctrl-key_right + 49 => { + 59 => { + 53 => { + 68 => :previous_word_buffer!, # ctrl-key_left + 67 => :next_word_buffer!, # ctrl-key_right + } + } } } },