Major movement of code into separate files.
This commit is contained in:
parent
343f83510b
commit
5f9fbfd751
|
@ -2,5 +2,5 @@
|
|||
|
||||
require 'diakonos'
|
||||
|
||||
diakonos = Diakonos.new( ARGV )
|
||||
diakonos = Diakonos::Diakonos.new( ARGV )
|
||||
diakonos.start
|
||||
|
|
2752
lib/diakonos.rb
2752
lib/diakonos.rb
File diff suppressed because it is too large
Load diff
10
lib/diakonos/array.rb
Normal file
10
lib/diakonos/array.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
class Array
|
||||
def to_keychain_s
|
||||
chain_str = ""
|
||||
each do |key|
|
||||
chain_str << key.keyString + " "
|
||||
end
|
||||
return chain_str
|
||||
end
|
||||
end
|
||||
|
6
lib/diakonos/bignum.rb
Normal file
6
lib/diakonos/bignum.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
require 'diakonos/keycode'
|
||||
|
||||
class Bignum
|
||||
include KeyCode
|
||||
end
|
||||
|
48
lib/diakonos/bookmark.rb
Normal file
48
lib/diakonos/bookmark.rb
Normal file
|
@ -0,0 +1,48 @@
|
|||
class Bookmark
|
||||
attr_reader :buffer, :row, :col, :name
|
||||
|
||||
def initialize( buffer, row, col, name = nil )
|
||||
@buffer = buffer
|
||||
@row = row
|
||||
@col = col
|
||||
@name = name
|
||||
end
|
||||
|
||||
def == (other)
|
||||
return false if other == nil
|
||||
return ( @buffer == other.buffer and @row == other.row and @col == other.col )
|
||||
end
|
||||
|
||||
def <=> (other)
|
||||
return nil if other == nil
|
||||
comparison = ( $diakonos.bufferToNumber( @buffer ) <=> $diakonos.bufferToNumber( other.buffer ) )
|
||||
return comparison if comparison != 0
|
||||
comparison = ( @row <=> other.row )
|
||||
return comparison if comparison != 0
|
||||
comparison = ( @col <=> other.col )
|
||||
return comparison
|
||||
end
|
||||
|
||||
def < (other)
|
||||
return ( ( self <=> other ) < 0 )
|
||||
end
|
||||
def > (other)
|
||||
return ( ( self <=> other ) > 0 )
|
||||
end
|
||||
|
||||
def incRow( increment )
|
||||
row += increment
|
||||
end
|
||||
def incCol( increment )
|
||||
col += increment
|
||||
end
|
||||
def shift( row_inc, col_inc )
|
||||
row += row_inc
|
||||
col += col_inc
|
||||
end
|
||||
|
||||
def to_s
|
||||
return "[#{@name}|#{@buffer.name}:#{@row+1},#{@col+1}]"
|
||||
end
|
||||
end
|
||||
|
18
lib/diakonos/buffer-hash.rb
Normal file
18
lib/diakonos/buffer-hash.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
class BufferHash < Hash
|
||||
def [] ( key )
|
||||
case key
|
||||
when String
|
||||
key = File.expand_path( key )
|
||||
end
|
||||
return super
|
||||
end
|
||||
|
||||
def []= ( key, value )
|
||||
case key
|
||||
when String
|
||||
key = File.expand_path( key )
|
||||
end
|
||||
super
|
||||
end
|
||||
end
|
||||
|
1696
lib/diakonos/buffer.rb
Normal file
1696
lib/diakonos/buffer.rb
Normal file
File diff suppressed because it is too large
Load diff
44
lib/diakonos/clipboard.rb
Normal file
44
lib/diakonos/clipboard.rb
Normal file
|
@ -0,0 +1,44 @@
|
|||
class Clipboard
|
||||
def initialize( max_clips )
|
||||
@clips = Array.new
|
||||
@max_clips = max_clips
|
||||
end
|
||||
|
||||
def [] ( arg )
|
||||
return @clips[ arg ]
|
||||
end
|
||||
|
||||
def clip
|
||||
return @clips[ 0 ]
|
||||
end
|
||||
|
||||
# text is an array of Strings
|
||||
# Returns true iff a clip was added,
|
||||
# and only non-nil text can be added.
|
||||
def addClip( text )
|
||||
return false if text == nil
|
||||
@clips.unshift text
|
||||
@clips.pop if @clips.length > @max_clips
|
||||
return true
|
||||
end
|
||||
|
||||
def each
|
||||
@clips.each do |clip|
|
||||
yield clip
|
||||
end
|
||||
end
|
||||
|
||||
# text is an array of Strings (lines)
|
||||
# Appends the lines to the current clip.
|
||||
# If no current clip, then a new clip is created.
|
||||
# Returns true iff the text was successfully appended.
|
||||
def appendToClip( text )
|
||||
return false if text.nil?
|
||||
return addClip( text ) if @clips.length == 0
|
||||
last_clip = @clips[ 0 ]
|
||||
last_clip.pop if last_clip[ -1 ] == ""
|
||||
@clips[ 0 ] = last_clip + text
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
25
lib/diakonos/ctag.rb
Normal file
25
lib/diakonos/ctag.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
class CTag
|
||||
attr_reader :file, :command, :kind, :rest
|
||||
|
||||
def initialize( file, command, kind, rest )
|
||||
@file = file
|
||||
@command = command
|
||||
@kind = kind
|
||||
@rest = rest
|
||||
end
|
||||
|
||||
def to_s
|
||||
return "#{@file}:#{@command} (#{@kind}) #{@rest}"
|
||||
end
|
||||
|
||||
def == ( other )
|
||||
return (
|
||||
other != nil and
|
||||
@file == other.file and
|
||||
@command == other.command and
|
||||
@kind == other.kind and
|
||||
@rest == other.rest
|
||||
)
|
||||
end
|
||||
end
|
||||
|
15
lib/diakonos/enumerable.rb
Normal file
15
lib/diakonos/enumerable.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
module Enumerable
|
||||
# Returns [array-index, string-index, string-index] triples for each match.
|
||||
def grep_indices( regexp )
|
||||
array = Array.new
|
||||
each_with_index do |element,index|
|
||||
element.scan( regexp ) do |match_text|
|
||||
match = Regexp.last_match
|
||||
strindex = match.begin( 0 )
|
||||
array.push [ index, strindex, strindex + match_text.length ]
|
||||
end
|
||||
end
|
||||
return array
|
||||
end
|
||||
end
|
||||
|
29
lib/diakonos/finding.rb
Normal file
29
lib/diakonos/finding.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
class Finding
|
||||
attr_reader :start_row, :start_col, :end_row, :end_col
|
||||
attr_writer :end_row, :end_col
|
||||
|
||||
def initialize( start_row, start_col, end_row, end_col )
|
||||
@start_row = start_row
|
||||
@start_col = start_col
|
||||
@end_row = end_row
|
||||
@end_col = end_col
|
||||
end
|
||||
|
||||
def match( regexps, lines )
|
||||
retval = true
|
||||
|
||||
i = @start_row + 1
|
||||
regexps[ 1..-1 ].each do |re|
|
||||
if lines[ i ] !~ re
|
||||
retval = false
|
||||
break
|
||||
end
|
||||
@end_row = i
|
||||
@end_col = Regexp.last_match[ 0 ].length
|
||||
i += 1
|
||||
end
|
||||
|
||||
return retval
|
||||
end
|
||||
end
|
||||
|
11
lib/diakonos/fixnum.rb
Normal file
11
lib/diakonos/fixnum.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
class Fixnum
|
||||
include KeyCode
|
||||
|
||||
def fit( min, max )
|
||||
return self if max < min
|
||||
return min if self < min
|
||||
return max if self > max
|
||||
return self
|
||||
end
|
||||
end
|
||||
|
101
lib/diakonos/hash.rb
Normal file
101
lib/diakonos/hash.rb
Normal file
|
@ -0,0 +1,101 @@
|
|||
class Hash
|
||||
# path is an array of hash keys
|
||||
# This method deletes a path of hash keys, with each step in the path
|
||||
# being a recursively deeper key in a hash tree.
|
||||
# Returns the possibly modified hash.
|
||||
def deleteKeyPath( path )
|
||||
if path.length > 1
|
||||
subtree = self[ path[ 0 ] ]
|
||||
if subtree.respond_to?( :deleteKeyPath )
|
||||
subtree.deleteKeyPath( path[ 1..-1 ] )
|
||||
if subtree.empty?
|
||||
delete( path[ 0 ] )
|
||||
end
|
||||
end
|
||||
elsif path.length == 1
|
||||
delete( path[ 0 ] )
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
def setKeyPath( path, leaf )
|
||||
if path.length > 1
|
||||
node = self[ path[ 0 ] ]
|
||||
if not node.respond_to?( :setKeyPath )
|
||||
node = self[ path[ 0 ] ] = Hash.new
|
||||
end
|
||||
node.setKeyPath( path[ 1..-1 ], leaf )
|
||||
elsif path.length == 1
|
||||
self[ path[ 0 ] ] = leaf
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
def getNode( path )
|
||||
node = self[ path[ 0 ] ]
|
||||
if path.length > 1
|
||||
if node != nil and node.respond_to?( :getNode )
|
||||
return node.getNode( path[ 1..-1 ] )
|
||||
end
|
||||
elsif path.length == 1
|
||||
return node
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
def getLeaf( path )
|
||||
node = getNode( path )
|
||||
if node.respond_to?( :getNode )
|
||||
# Only want a leaf node
|
||||
return nil
|
||||
else
|
||||
return node
|
||||
end
|
||||
end
|
||||
|
||||
def leaves( _leaves = Set.new )
|
||||
each_value do |value|
|
||||
if value.respond_to?( :leaves )
|
||||
_leaves.merge value.leaves( _leaves )
|
||||
else
|
||||
_leaves << value
|
||||
end
|
||||
end
|
||||
|
||||
return _leaves
|
||||
end
|
||||
|
||||
def paths_and_leaves( path_so_far = [], _paths_and_leaves = Set.new )
|
||||
each do |key, value|
|
||||
if value.respond_to?( :paths_and_leaves )
|
||||
_paths_and_leaves.merge(
|
||||
value.paths_and_leaves(
|
||||
path_so_far + [ key ],
|
||||
_paths_and_leaves
|
||||
)
|
||||
)
|
||||
else
|
||||
_paths_and_leaves << {
|
||||
:path => path_so_far + [ key ],
|
||||
:leaf => value
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
return _paths_and_leaves
|
||||
end
|
||||
|
||||
def each_path_and_leaf( path_so_far = [] )
|
||||
each do |key, value|
|
||||
if value.respond_to?( :each_path_and_leaf )
|
||||
value.each_path_and_leaf( path_so_far + [ key ] ) { |path, leaf| yield( path, leaf ) }
|
||||
else
|
||||
yield( path_so_far + [ key ], value )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
107
lib/diakonos/keycode.rb
Normal file
107
lib/diakonos/keycode.rb
Normal file
|
@ -0,0 +1,107 @@
|
|||
module KeyCode
|
||||
KEYSTRINGS = [
|
||||
"ctrl+space", # 0
|
||||
"ctrl+a", # 1
|
||||
"ctrl+b", # 2
|
||||
"ctrl+c", # 3
|
||||
"ctrl+d", # 4
|
||||
"ctrl+e", # 5
|
||||
"ctrl+f", # 6
|
||||
"ctrl+g", # 7
|
||||
nil, # 8
|
||||
"tab", # 9
|
||||
"ctrl+j", # 10
|
||||
"ctrl+k", # 11
|
||||
"ctrl+l", # 12
|
||||
"enter", # 13
|
||||
"ctrl+n", # 14
|
||||
"ctrl+o", # 15
|
||||
"ctrl+p", # 16
|
||||
"ctrl+q", # 17
|
||||
"ctrl+r", # 18
|
||||
"ctrl+s", # 19
|
||||
"ctrl+t", # 20
|
||||
"ctrl+u", # 21
|
||||
"ctrl+v", # 22
|
||||
"ctrl+w", # 23
|
||||
"ctrl+x", # 24
|
||||
"ctrl+y", # 25
|
||||
"ctrl+z", # 26
|
||||
"esc", # 27
|
||||
nil, # 28
|
||||
nil, # 29
|
||||
nil, # 30
|
||||
nil, # 31
|
||||
"space", # 32
|
||||
33.chr, 34.chr, 35.chr, 36.chr, 37.chr, 38.chr, 39.chr,
|
||||
40.chr, 41.chr, 42.chr, 43.chr, 44.chr, 45.chr, 46.chr, 47.chr, 48.chr, 49.chr,
|
||||
50.chr, 51.chr, 52.chr, 53.chr, 54.chr, 55.chr, 56.chr, 57.chr, 58.chr, 59.chr,
|
||||
60.chr, 61.chr, 62.chr, 63.chr, 64.chr, 65.chr, 66.chr, 67.chr, 68.chr, 69.chr,
|
||||
70.chr, 71.chr, 72.chr, 73.chr, 74.chr, 75.chr, 76.chr, 77.chr, 78.chr, 79.chr,
|
||||
80.chr, 81.chr, 82.chr, 83.chr, 84.chr, 85.chr, 86.chr, 87.chr, 88.chr, 89.chr,
|
||||
90.chr, 91.chr, 92.chr, 93.chr, 94.chr, 95.chr, 96.chr, 97.chr, 98.chr, 99.chr,
|
||||
100.chr, 101.chr, 102.chr, 103.chr, 104.chr, 105.chr, 106.chr, 107.chr, 108.chr, 109.chr,
|
||||
110.chr, 111.chr, 112.chr, 113.chr, 114.chr, 115.chr, 116.chr, 117.chr, 118.chr, 119.chr,
|
||||
120.chr, 121.chr, 122.chr, 123.chr, 124.chr, 125.chr, 126.chr,
|
||||
"backspace" # 127
|
||||
]
|
||||
|
||||
def keyString
|
||||
if self.class == Fixnum
|
||||
retval = KEYSTRINGS[ self ]
|
||||
end
|
||||
if retval == nil
|
||||
case self
|
||||
when Curses::KEY_DOWN
|
||||
retval = "down"
|
||||
when Curses::KEY_UP
|
||||
retval = "up"
|
||||
when Curses::KEY_LEFT
|
||||
retval = "left"
|
||||
when Curses::KEY_RIGHT
|
||||
retval = "right"
|
||||
when Curses::KEY_HOME
|
||||
retval = "home"
|
||||
when Curses::KEY_END
|
||||
retval = "end"
|
||||
when Curses::KEY_IC
|
||||
retval = "insert"
|
||||
when Curses::KEY_DC
|
||||
retval = "delete"
|
||||
when Curses::KEY_PPAGE
|
||||
retval = "page-up"
|
||||
when Curses::KEY_NPAGE
|
||||
retval = "page-down"
|
||||
when Curses::KEY_A1
|
||||
retval = "numpad7"
|
||||
when Curses::KEY_A3
|
||||
retval = "numpad9"
|
||||
when Curses::KEY_B2
|
||||
retval = "numpad5"
|
||||
when Curses::KEY_C1
|
||||
retval = "numpad1"
|
||||
when Curses::KEY_C3
|
||||
retval = "numpad3"
|
||||
when Curses::KEY_FIND
|
||||
retval = "find"
|
||||
when Curses::KEY_SELECT
|
||||
retval = "select"
|
||||
when Curses::KEY_SUSPEND
|
||||
retval = "suspend"
|
||||
when Curses::KEY_F0..(Curses::KEY_F0 + 24)
|
||||
retval = "f" + (self - Curses::KEY_F0).to_s
|
||||
when Diakonos::CTRL_H
|
||||
retval = "ctrl+h"
|
||||
when Curses::KEY_RESIZE
|
||||
retval = "resize"
|
||||
when Diakonos::RESIZE2
|
||||
retval = "resize2"
|
||||
end
|
||||
end
|
||||
if retval == nil and self.class == Fixnum
|
||||
retval = "keycode#{self}"
|
||||
end
|
||||
return retval
|
||||
end
|
||||
end
|
||||
|
190
lib/diakonos/readline.rb
Normal file
190
lib/diakonos/readline.rb
Normal file
|
@ -0,0 +1,190 @@
|
|||
module Diakonos
|
||||
|
||||
class Readline
|
||||
|
||||
# completion_array is the array of strings that tab completion can use
|
||||
def initialize( diakonos, window, initial_text = "", completion_array = nil, history = [] )
|
||||
@window = window
|
||||
@diakonos = diakonos
|
||||
@initial_text = initial_text
|
||||
@completion_array = completion_array
|
||||
@list_filename = @diakonos.list_filename
|
||||
|
||||
@history = history
|
||||
@history << initial_text
|
||||
@history_index = @history.length - 1
|
||||
end
|
||||
|
||||
# Returns nil on cancel.
|
||||
def readline
|
||||
@input = @initial_text
|
||||
@icurx = @window.curx
|
||||
@icury = @window.cury
|
||||
@window.addstr @initial_text
|
||||
@input_cursor = @initial_text.length
|
||||
@opened_list_file = false
|
||||
|
||||
loop do
|
||||
c = @window.getch
|
||||
|
||||
case c
|
||||
when Diakonos::PRINTABLE_CHARACTERS
|
||||
if @input_cursor == @input.length
|
||||
@input << c
|
||||
@window.addch c
|
||||
else
|
||||
@input = @input[ 0...@input_cursor ] + c.chr + @input[ @input_cursor..-1 ]
|
||||
@window.setpos( @window.cury, @window.curx + 1 )
|
||||
redrawInput
|
||||
end
|
||||
@input_cursor += 1
|
||||
when Curses::KEY_DC
|
||||
if @input_cursor < @input.length
|
||||
@window.delch
|
||||
@input = @input[ 0...@input_cursor ] + @input[ (@input_cursor + 1)..-1 ]
|
||||
end
|
||||
when Diakonos::BACKSPACE, Diakonos::CTRL_H
|
||||
# Curses::KEY_LEFT
|
||||
if @input_cursor > 0
|
||||
@input_cursor += -1
|
||||
@window.setpos( @window.cury, @window.curx - 1 )
|
||||
|
||||
# Curses::KEY_DC
|
||||
if @input_cursor < @input.length
|
||||
@window.delch
|
||||
@input = @input[ 0...@input_cursor ] + @input[ (@input_cursor + 1)..-1 ]
|
||||
end
|
||||
end
|
||||
when Diakonos::ENTER
|
||||
break
|
||||
when Diakonos::ESCAPE, Diakonos::CTRL_C, Diakonos::CTRL_D, Diakonos::CTRL_Q
|
||||
@input = nil
|
||||
break
|
||||
when Curses::KEY_LEFT
|
||||
if @input_cursor > 0
|
||||
@input_cursor += -1
|
||||
@window.setpos( @window.cury, @window.curx - 1 )
|
||||
end
|
||||
when Curses::KEY_RIGHT
|
||||
if @input_cursor < @input.length
|
||||
@input_cursor += 1
|
||||
@window.setpos( @window.cury, @window.curx + 1 )
|
||||
end
|
||||
when Curses::KEY_HOME
|
||||
@input_cursor = 0
|
||||
@window.setpos( @icury, @icurx )
|
||||
when Curses::KEY_END
|
||||
@input_cursor = @input.length
|
||||
@window.setpos( @window.cury, @icurx + @input.length )
|
||||
when Diakonos::TAB
|
||||
completeInput
|
||||
when Curses::KEY_NPAGE
|
||||
@diakonos.pageDown
|
||||
when Curses::KEY_PPAGE
|
||||
@diakonos.pageUp
|
||||
when Curses::KEY_UP
|
||||
if @history_index > 0
|
||||
@history[ @history_index ] = @input
|
||||
@history_index -= 1
|
||||
@input = @history[ @history_index ]
|
||||
cursorWriteInput
|
||||
end
|
||||
when Curses::KEY_DOWN
|
||||
if @history_index < @history.length - 1
|
||||
@history[ @history_index ] = @input
|
||||
@history_index += 1
|
||||
@input = @history[ @history_index ]
|
||||
cursorWriteInput
|
||||
end
|
||||
when Diakonos::CTRL_K
|
||||
@input = ""
|
||||
cursorWriteInput
|
||||
else
|
||||
@diakonos.log "Other input: #{c}"
|
||||
end
|
||||
end
|
||||
|
||||
@diakonos.closeListBuffer
|
||||
|
||||
@history[ -1 ] = @input
|
||||
|
||||
return @input
|
||||
end
|
||||
|
||||
def redrawInput
|
||||
curx = @window.curx
|
||||
cury = @window.cury
|
||||
@window.setpos( @icury, @icurx )
|
||||
@window.addstr "%-#{ Curses::cols - curx }s%s" % [ @input, " " * ( Curses::cols - @input.length ) ]
|
||||
@window.setpos( cury, curx )
|
||||
@window.refresh
|
||||
end
|
||||
|
||||
# Redisplays the input text starting at the start of the user input area,
|
||||
# positioning the cursor at the end of the text.
|
||||
def cursorWriteInput
|
||||
if @input != nil
|
||||
@input_cursor = @input.length
|
||||
@window.setpos( @window.cury, @icurx + @input.length )
|
||||
redrawInput
|
||||
end
|
||||
end
|
||||
|
||||
def completeInput
|
||||
if @completion_array != nil and @input.length > 0
|
||||
len = @input.length
|
||||
matches = @completion_array.find_all { |el| el[ 0...len ] == @input and len < el.length }
|
||||
else
|
||||
matches = Dir.glob( ( @input.subHome() + "*" ).gsub( /\*\*/, "*" ) )
|
||||
end
|
||||
|
||||
if matches.length == 1
|
||||
@input = matches[ 0 ]
|
||||
cursorWriteInput
|
||||
File.open( @list_filename, "w" ) do |f|
|
||||
f.puts "(unique)"
|
||||
end
|
||||
if @completion_array == nil and FileTest.directory?( @input )
|
||||
@input << "/"
|
||||
cursorWriteInput
|
||||
completeInput
|
||||
end
|
||||
elsif matches.length > 1
|
||||
common = matches[ 0 ]
|
||||
File.open( @list_filename, "w" ) do |f|
|
||||
i = nil
|
||||
matches.each do |match|
|
||||
f.puts match
|
||||
|
||||
if match[ 0 ] != common[ 0 ]
|
||||
common = nil
|
||||
break
|
||||
end
|
||||
|
||||
up_to = [ common.length - 1, match.length - 1 ].min
|
||||
i = 1
|
||||
while ( i <= up_to ) and ( match[ 0..i ] == common[ 0..i ] )
|
||||
i += 1
|
||||
end
|
||||
common = common[ 0...i ]
|
||||
end
|
||||
end
|
||||
if common == nil
|
||||
File.open( @list_filename, "w" ) do |f|
|
||||
f.puts "(no matches)"
|
||||
end
|
||||
else
|
||||
@input = common
|
||||
cursorWriteInput
|
||||
end
|
||||
else
|
||||
File.open( @list_filename, "w" ) do |f|
|
||||
f.puts "(no matches)"
|
||||
end
|
||||
end
|
||||
@diakonos.openListBuffer
|
||||
@window.setpos( @window.cury, @window.curx )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
6
lib/diakonos/regexp.rb
Normal file
6
lib/diakonos/regexp.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
class Regexp
|
||||
def uses_bos
|
||||
return ( source[ 0 ] == ?^ )
|
||||
end
|
||||
end
|
||||
|
48
lib/diakonos/sized-array.rb
Normal file
48
lib/diakonos/sized-array.rb
Normal file
|
@ -0,0 +1,48 @@
|
|||
class SizedArray < Array
|
||||
attr_reader :capacity
|
||||
|
||||
def initialize( capacity = 10, *args )
|
||||
@capacity = capacity
|
||||
super( *args )
|
||||
end
|
||||
|
||||
def resize
|
||||
if size > @capacity
|
||||
slice!( (0...-@capacity) )
|
||||
end
|
||||
end
|
||||
private :resize
|
||||
|
||||
def concat( other_array )
|
||||
super( other_array )
|
||||
resize
|
||||
return self
|
||||
end
|
||||
|
||||
def fill( *args )
|
||||
retval = super( *args )
|
||||
resize
|
||||
return self
|
||||
end
|
||||
|
||||
def <<( item )
|
||||
retval = super( item )
|
||||
if size > @capacity
|
||||
retval = shift
|
||||
end
|
||||
return retval
|
||||
end
|
||||
|
||||
def push( item )
|
||||
self << item
|
||||
end
|
||||
|
||||
def unshift( item )
|
||||
retval = super( item )
|
||||
if size > @capacity
|
||||
retval = pop
|
||||
end
|
||||
return retval
|
||||
end
|
||||
end
|
||||
|
318
lib/diakonos/string.rb
Normal file
318
lib/diakonos/string.rb
Normal file
|
@ -0,0 +1,318 @@
|
|||
class String
|
||||
def subHome
|
||||
return gsub( /~/, ENV[ "HOME" ] )
|
||||
end
|
||||
|
||||
def keyCode
|
||||
retval = nil
|
||||
case downcase
|
||||
when "down"
|
||||
retval = Curses::KEY_DOWN
|
||||
when "up"
|
||||
retval = Curses::KEY_UP
|
||||
when "left"
|
||||
retval = Curses::KEY_LEFT
|
||||
when "right"
|
||||
retval = Curses::KEY_RIGHT
|
||||
when "home"
|
||||
retval = Curses::KEY_HOME
|
||||
when "end"
|
||||
retval = Curses::KEY_END
|
||||
when "insert", "ins"
|
||||
retval = Curses::KEY_IC
|
||||
when "delete", "del"
|
||||
retval = Curses::KEY_DC
|
||||
when "backspace"
|
||||
retval = Diakonos::BACKSPACE
|
||||
when "tab"
|
||||
retval = 9
|
||||
when "pageup", "page-up"
|
||||
retval = Curses::KEY_PPAGE
|
||||
when "pagedown", "page-down"
|
||||
retval = Curses::KEY_NPAGE
|
||||
when "enter", "return"
|
||||
retval = Diakonos::ENTER
|
||||
when "numpad7", "keypad7", "kp-7"
|
||||
retval = Curses::KEY_A1
|
||||
when "numpad9", "keypad9", "kp-9"
|
||||
retval = Curses::KEY_A3
|
||||
when "numpad5", "keypad5", "kp-5"
|
||||
retval = Curses::KEY_B2
|
||||
when "numpad1", "keypad1", "kp-1"
|
||||
retval = Curses::KEY_C1
|
||||
when "numpad3", "keypad3", "kp-3"
|
||||
retval = Curses::KEY_C3
|
||||
when "escape", "esc"
|
||||
retval = Diakonos::ESCAPE
|
||||
when "space"
|
||||
retval = 32
|
||||
when "ctrl+space"
|
||||
retval = 0
|
||||
when "find"
|
||||
retval = Curses::KEY_FIND
|
||||
when "select"
|
||||
retval = Curses::KEY_SELECT
|
||||
when "suspend"
|
||||
retval = Curses::KEY_SUSPEND
|
||||
when /^f(\d\d?)$/
|
||||
retval = Curses::KEY_F0 + $1.to_i
|
||||
when /^ctrl\+[a-gi-z]$/
|
||||
retval = downcase[ -1 ] - 96
|
||||
when /^ctrl\+h$/
|
||||
retval = Diakonos::CTRL_H
|
||||
when /^alt\+(.)$/
|
||||
retval = [ Diakonos::ESCAPE, $1[ 0 ] ]
|
||||
when /^ctrl\+alt\+(.)$/, /^alt\+ctrl\+(.)$/
|
||||
retval = [ Diakonos::ESCAPE, downcase[ -1 ] - 96 ]
|
||||
when /^keycode(\d+)$/
|
||||
retval = $1.to_i
|
||||
when /^.$/
|
||||
retval = self[ 0 ]
|
||||
end
|
||||
if retval.class != Array
|
||||
retval = [ retval ]
|
||||
end
|
||||
return retval
|
||||
end
|
||||
|
||||
def toFormatting
|
||||
formatting = Curses::A_NORMAL
|
||||
split( /\s+/ ).each do |format|
|
||||
case format.downcase
|
||||
when "normal"
|
||||
formatting = Curses::A_NORMAL
|
||||
when "black", "0"
|
||||
formatting = formatting | Curses::color_pair( Curses::COLOR_BLACK )
|
||||
when "red", "1"
|
||||
formatting = formatting | Curses::color_pair( Curses::COLOR_RED )
|
||||
when "green", "2"
|
||||
formatting = formatting | Curses::color_pair( Curses::COLOR_GREEN )
|
||||
when "yellow", "brown", "3"
|
||||
formatting = formatting | Curses::color_pair( Curses::COLOR_YELLOW )
|
||||
when "blue", "4"
|
||||
formatting = formatting | Curses::color_pair( Curses::COLOR_BLUE )
|
||||
when "magenta", "purple", "5"
|
||||
formatting = formatting | Curses::color_pair( Curses::COLOR_MAGENTA )
|
||||
when "cyan", "6"
|
||||
formatting = formatting | Curses::color_pair( Curses::COLOR_CYAN )
|
||||
when "white", "7"
|
||||
formatting = formatting | Curses::color_pair( Curses::COLOR_WHITE )
|
||||
when "standout", "s", "so"
|
||||
formatting = formatting | Curses::A_STANDOUT
|
||||
when "underline", "u", "un", "ul"
|
||||
formatting = formatting | Curses::A_UNDERLINE
|
||||
when "reverse", "r", "rev", "inverse", "i", "inv"
|
||||
formatting = formatting | Curses::A_REVERSE
|
||||
when "blink", "bl", "blinking"
|
||||
formatting = formatting | Curses::A_BLINK
|
||||
when "dim", "d"
|
||||
formatting = formatting | Curses::A_DIM
|
||||
when "bold", "b", "bo"
|
||||
formatting = formatting | Curses::A_BOLD
|
||||
else
|
||||
if ( colour_number = format.to_i ) > Curses::COLOR_WHITE
|
||||
formatting = formatting | Curses::color_pair( colour_number )
|
||||
end
|
||||
end
|
||||
end
|
||||
return formatting
|
||||
end
|
||||
|
||||
def toColourConstant
|
||||
retval = Curses::COLOR_WHITE
|
||||
case downcase
|
||||
when "black", "0"
|
||||
retval = Curses::COLOR_BLACK
|
||||
when "red", "1"
|
||||
retval = Curses::COLOR_RED
|
||||
when "green", "2"
|
||||
retval = Curses::COLOR_GREEN
|
||||
when "yellow", "brown", "3"
|
||||
retval = Curses::COLOR_YELLOW
|
||||
when "blue", "4"
|
||||
retval = Curses::COLOR_BLUE
|
||||
when "magenta", "purple", "5"
|
||||
retval = Curses::COLOR_MAGENTA
|
||||
when "cyan", "6"
|
||||
retval = Curses::COLOR_CYAN
|
||||
when "white", "7"
|
||||
retval = Curses::COLOR_WHITE
|
||||
end
|
||||
end
|
||||
|
||||
def toDirection( default = :down )
|
||||
direction = nil
|
||||
case self
|
||||
when "up"
|
||||
direction = :up
|
||||
when /other/
|
||||
direction = :opposite
|
||||
when "down"
|
||||
direction = :down
|
||||
when "forward"
|
||||
direction = :forward
|
||||
when "backward"
|
||||
direction = :backward
|
||||
else
|
||||
direction = default
|
||||
end
|
||||
return direction
|
||||
end
|
||||
|
||||
def to_a
|
||||
return [ self ]
|
||||
end
|
||||
|
||||
def to_b
|
||||
retval = false
|
||||
case downcase
|
||||
when "true", "t", "1", "yes", "y", "on", "+"
|
||||
retval = true
|
||||
end
|
||||
return retval
|
||||
end
|
||||
|
||||
def indentation_level( indent_size, indent_roundup, tab_size = Diakonos::DEFAULT_TAB_SIZE, indent_ignore_charset = nil )
|
||||
if indent_ignore_charset == nil
|
||||
level = 0
|
||||
if self =~ /^([\s]+)/
|
||||
#whitespace = $1.gsub( /\t/, ' ' * tab_size )
|
||||
whitespace = $1.expandTabs( tab_size )
|
||||
level = whitespace.length / indent_size
|
||||
if indent_roundup and ( whitespace.length % indent_size > 0 )
|
||||
level += 1
|
||||
end
|
||||
end
|
||||
else
|
||||
if self =~ /^[\s#{indent_ignore_charset}]*$/ or self == ""
|
||||
level = -1
|
||||
elsif self =~ /^([\s#{indent_ignore_charset}]+)/
|
||||
#whitespace = $1.gsub( /\t/, ' ' * tab_size )
|
||||
whitespace = $1.expandTabs( tab_size )
|
||||
level = whitespace.length / indent_size
|
||||
if indent_roundup and ( whitespace.length % indent_size > 0 )
|
||||
level += 1
|
||||
end
|
||||
else
|
||||
level = 0
|
||||
end
|
||||
end
|
||||
|
||||
return level
|
||||
end
|
||||
|
||||
def expandTabs( tab_size = Diakonos::DEFAULT_TAB_SIZE )
|
||||
s = dup
|
||||
while s.sub!( /\t/ ) { |match_text|
|
||||
match = Regexp.last_match
|
||||
index = match.begin( 0 )
|
||||
# Return value for block:
|
||||
" " * ( tab_size - ( index % tab_size ) )
|
||||
}
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
def newlineSplit
|
||||
retval = split( /\\n/ )
|
||||
if self =~ /\\n$/
|
||||
retval << ""
|
||||
end
|
||||
if retval.length > 1
|
||||
retval[ 0 ] << "$"
|
||||
retval[ 1..-2 ].collect do |el|
|
||||
"^" << el << "$"
|
||||
end
|
||||
retval[ -1 ] = "^" << retval[ -1 ]
|
||||
end
|
||||
return retval
|
||||
end
|
||||
|
||||
# Works like normal String#index except returns the index
|
||||
# of the first matching regexp group if one or more groups are specified
|
||||
# in the regexp. Both the index and the matched text are returned.
|
||||
def group_index( regexp, offset = 0 )
|
||||
if regexp.class != Regexp
|
||||
return index( regexp, offset )
|
||||
end
|
||||
|
||||
i = nil
|
||||
match_text = nil
|
||||
working_offset = 0
|
||||
loop do
|
||||
index( regexp, working_offset )
|
||||
match = Regexp.last_match
|
||||
if match
|
||||
i = match.begin( 0 )
|
||||
match_text = match[ 0 ]
|
||||
if match.length > 1
|
||||
# Find first matching group
|
||||
1.upto( match.length - 1 ) do |match_item_index|
|
||||
if match[ match_item_index ] != nil
|
||||
i = match.begin( match_item_index )
|
||||
match_text = match[ match_item_index ]
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
break if i >= offset
|
||||
else
|
||||
i = nil
|
||||
break
|
||||
end
|
||||
working_offset += 1
|
||||
end
|
||||
|
||||
return i, match_text
|
||||
end
|
||||
|
||||
# Works like normal String#rindex except returns the index
|
||||
# of the first matching regexp group if one or more groups are specified
|
||||
# in the regexp. Both the index and the matched text are returned.
|
||||
def group_rindex( regexp, offset = length )
|
||||
if regexp.class != Regexp
|
||||
return rindex( regexp, offset )
|
||||
end
|
||||
|
||||
i = nil
|
||||
match_text = nil
|
||||
working_offset = length
|
||||
loop do
|
||||
rindex( regexp, working_offset )
|
||||
match = Regexp.last_match
|
||||
if match
|
||||
i = match.end( 0 ) - 1
|
||||
match_text = match[ 0 ]
|
||||
if match.length > 1
|
||||
# Find first matching group
|
||||
1.upto( match.length - 1 ) do |match_item_index|
|
||||
if match[ match_item_index ] != nil
|
||||
i = match.end( match_item_index ) - 1
|
||||
match_text = match[ match_item_index ]
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if match_text == ""
|
||||
# Assume that an empty string means that it matched $
|
||||
i += 1
|
||||
end
|
||||
|
||||
break if i <= offset
|
||||
else
|
||||
i = nil
|
||||
break
|
||||
end
|
||||
working_offset -= 1
|
||||
end
|
||||
|
||||
return i, match_text
|
||||
end
|
||||
|
||||
def movement?
|
||||
return ( ( self =~ /^((cursor|page|scroll)(Up|Down|Left|Right)|find)/ ) != nil )
|
||||
end
|
||||
end
|
||||
|
16
lib/diakonos/text-mark.rb
Normal file
16
lib/diakonos/text-mark.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
class TextMark
|
||||
attr_reader :formatting, :start_row, :start_col, :end_row, :end_col
|
||||
|
||||
def initialize( start_row, start_col, end_row, end_col, formatting )
|
||||
@start_row = start_row
|
||||
@start_col = start_col
|
||||
@end_row = end_row
|
||||
@end_col = end_col
|
||||
@formatting = formatting
|
||||
end
|
||||
|
||||
def to_s
|
||||
return "(#{start_row},#{start_col})-(#{end_row},#{end_col}) #{formatting}"
|
||||
end
|
||||
end
|
||||
|
32
lib/diakonos/window.rb
Normal file
32
lib/diakonos/window.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
class Curses::Window
|
||||
def puts( string = "" )
|
||||
addstr( string + "\n" )
|
||||
end
|
||||
|
||||
# setpos, but with some boundary checks
|
||||
def setpos_( y, x )
|
||||
$diakonos.debugLog "setpos: y < 0 (#{y})" if y < 0
|
||||
$diakonos.debugLog "setpos: x < 0 (#{x})" if x < 0
|
||||
$diakonos.debugLog "setpos: y > lines (#{y})" if y > Curses::lines
|
||||
$diakonos.debugLog "setpos: x > cols (#{x})" if x > Curses::cols
|
||||
setpos( y, x )
|
||||
end
|
||||
|
||||
def addstr_( string )
|
||||
x = curx
|
||||
y = cury
|
||||
x2 = curx + string.length
|
||||
|
||||
if y < 0 or x < 0 or y > Curses::lines or x > Curses::cols or x2 < 0 or x2 > Curses::cols
|
||||
begin
|
||||
raise Exception
|
||||
rescue Exception => e
|
||||
$diakonos.debugLog e.backtrace[ 1 ]
|
||||
$diakonos.debugLog e.backtrace[ 2 ]
|
||||
end
|
||||
end
|
||||
|
||||
addstr( string )
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in a new issue