module RupatMod

{RupatMod} contains the core functionality of {Rupat}.

Attributes

copybuf[R]

Copy buffer.

lines[R]

Array of lines including current content.

newFile[RW]

Created file reference.

orgFile[RW]

Original file reference.

Public Instance Methods

[]( range ) click to toggle source

Return lines content.

# File lib/rupat.rb, line 297
def []( range )
    @lines[ range ]
end
abort( file = @newFile ) click to toggle source

Don't save changes, just close the file.

# File lib/rupat.rb, line 518
def abort( file = @newFile )
    file.close if file.class == File
end
append( str = "" ) click to toggle source

Append line to current position.

@param str [String] Content for the appended line. @return [Object] Self.

# File lib/rupat.rb, line 412
def append( str = "" )
    forward
    @lines.insert( @curline, str )
    self
end
appendMany( content ) click to toggle source

Append lines to current position.

@param content [Object] Content (See: {#manyLineContent}). @return [Object] Self.

# File lib/rupat.rb, line 423
def appendMany( content )
    lines = manyLineContent( content )
    lines.each do |s|
        append( s )
    end
    self
end
back( count = 1 )
Alias for: backward
backward( count = 1 ) click to toggle source

Backwards line (or more).

@param count [Integer] Number of lines to step backwards. @return [Object] Self.

# File lib/rupat.rb, line 180
def backward( count = 1 )
    @curline -= count
    normalizeCurline
    self
end
Also aliased as: up, back, dec
bfind( re )
Alias for: findBackward
bfind?( re )
Alias for: findBackward?
close( file = @newFile ) click to toggle source

Save edits and close file.

@param file [String] File to save edits to. @return [String,NilClass] Backup file name if backup made,

otherwise nil.
# File lib/rupat.rb, line 528
def close( file = @newFile )

    # Backup original file:
    if @backup
        time = Time.now.strftime( "%y%m%d_%H%M_%S" )

        p = @orgFile.split( '/' )
        backupFile = "#{p[0..-2].join('/')}/rupat_#{time}_#{p[-1]}"

        File.rename( @orgFile, backupFile )
        @orgFile = backupFile
    end

    save( file )

    file.close if file.class == File

    if @backup
        backupFile
    else
        nil
    end
end
copy( l1 = nil, l2 = nil ) click to toggle source

Store content of lines bounded by start/end markers (inclusive) to copy-buffer.

@param l1 [Integer] Line marker 1 (See: {#linePairRef}). @param l2 [Integer] Line marker 2 (See: {#linePairRef}). @return [Array<String>] Line(s) content.

# File lib/rupat.rb, line 329
def copy( l1 = nil, l2 = nil )
    l1, l2 = linePairRef( l1, l2 )
    @copybuf = @lines[ lineRef( l1 )..lineRef( l2 ) ]
    self
end
create( orgFile, newFile = nil ) click to toggle source

Create new file based on given name (or IO stream).

@param orgFile [String,File] Source file. @param newFile [String] Destination file.

# File lib/rupat.rb, line 38
def create( orgFile, newFile = nil )

    @orgFile = orgFile
    @newFile = newFile

    @lines = readclean( @orgFile )

    @curline = 0
end
cut( l1 = nil, l2 = nil ) click to toggle source

Delete specified lines (inclusive). Save content to copy-buffer.

@param l1 [Integer] Line marker 1 (See: {#linePairRef}). @param l2 [Integer] Line marker 2 (See: {#linePairRef}). @return [Object] Self.

# File lib/rupat.rb, line 458
def cut( l1 = nil, l2 = nil )
    l1, l2 = linePairRef( l1, l2 )
    @copybuf = []
    cnt = l2-l1+1
    cnt.times do
        @copybuf.push @lines.delete_at( l1 )
    end
    self
end
dec( count = 1 )
Alias for: backward
delete() click to toggle source

Delete current line.

@return [Object] Self.

# File lib/rupat.rb, line 435
def delete
    @lines.delete_at( @curline )
    self
end
deleteMany( cnt = length ) click to toggle source

Delete current line N times.

@param cnt [Integer] Number of lines to delete. @return [Object] Self.

# File lib/rupat.rb, line 445
def deleteMany( cnt = length )
    cnt.times do
        @lines.delete_at( @curline )
    end
    self
end
down( count = 1 )
Alias for: forward
edit( file, backup = true ) click to toggle source

Create new file based on old. Original file is backupped.

@param file [String,File] Source file. @param backup [Boolean] Create backup from the source (original)

file.
# File lib/rupat.rb, line 54
def edit( file, backup = true )
    @backup = backup
    create( file, file )
end
excursion( &blk ) click to toggle source

Perform operations in block, but revert back to original position after block completion.

@yield blk Proc to execute on file content. @return [Object] Value of the block.

# File lib/rupat.rb, line 90
def excursion( &blk )
    startline = @curline
    ret = instance_eval( &blk )
    @curline = startline
    ret
end
ffind( re )
Alias for: findForward
ffind?( re )
Alias for: findForward?
find( re )
Alias for: findForward
find?( re )
Alias for: findForward?
findBackward( re ) click to toggle source

Find regexp backwards. Exception is generated, if pattern is not found.

@param re [Regexp] Search pattern regexp. @return Self if found.

# File lib/rupat.rb, line 263
def findBackward( re )
    findCommon( re, false )
end
Also aliased as: bfind
findBackward?( re ) click to toggle source

Find regexp backward.

@param re [Regexp] Search pattern regexp. @return Self if pattern found, nil otherwise.

# File lib/rupat.rb, line 272
def findBackward?( re )
    findCommon( re, false, false )
end
Also aliased as: bfind?
findBlock( re1, re2 ) click to toggle source

Return pair of line numbers that match the start/end regexps.

@param re1 [Regexp] Range start marking Regexp. @param re2 [Regexp] Range end marking Regexp. @return [Integer,Integer] Range start/end tuplet.

# File lib/rupat.rb, line 287
def findBlock( re1, re2 )
    findCommon( re1, true )
    l1 = line
    findCommon( re2, true )
    l2 = line
    [ l1, l2 ]
end
findForward( re ) click to toggle source

Find regexp forwards. Exception is generated, if pattern is not found.

@param re [Regexp] Search pattern regexp. @return Self if found.

# File lib/rupat.rb, line 237
def findForward( re )
    findCommon( re, true )
end
Also aliased as: find, ffind
findForward?( re ) click to toggle source

Find regexp forward.

@param re [Regexp] Search pattern regexp. @return Self if pattern found, nil otherwise.

# File lib/rupat.rb, line 246
def findForward?( re )
    findCommon( re, true, false )
end
Also aliased as: find?, ffind?
forward( count = 1 ) click to toggle source

Forward line (or more).

@param count [Integer] Number of lines to step forwards. @return [Object] Self.

# File lib/rupat.rb, line 169
def forward( count = 1 )
    @curline += count
    normalizeCurline
    self
end
Also aliased as: step, down, inc
get( line = nil ) click to toggle source

Return line content.

@param line [Integer,NilClass] Indexed or current line. @return [String] Line content.

# File lib/rupat.rb, line 306
def get( line = nil )
    @lines[ lineRef( line ) ]
end
getMany( l1 = nil, l2 = nil ) click to toggle source

Return content of lines bounded by start/end markers (inclusive).

@param l1 [Integer] Line marker 1 (See: {#linePairRef}). @param l2 [Integer] Line marker 2 (See: {#linePairRef}). @return [Array<String>] Line(s) content.

# File lib/rupat.rb, line 317
def getMany( l1 = nil, l2 = nil )
    l1, l2 = linePairRef( l1, l2 )
    @lines[ lineRef( l1 )..lineRef( l2 ) ]
end
goto( line = 0 ) click to toggle source

Goto line.

@param line [Integer] Line to access. @return [Object] Self.

# File lib/rupat.rb, line 102
def goto( line = 0 )
    @curline = line
    normalizeCurline
    self
end
Also aliased as: jump
goto1( line = 1 ) click to toggle source

Goto (text editor) line.

@param line [Integer] Line to access (updated to <line>-1). @return [Object] Self.

# File lib/rupat.rb, line 113
def goto1( line = 1 )
    @curline = line-1
    normalizeCurline
    self
end
gotoEnd() click to toggle source

Goto line after last line. User can append content starting with this line.

@return [Object] Self.

# File lib/rupat.rb, line 153
def gotoEnd
    @curline = @lines.length
    self
end
Also aliased as: jumpEnd
gotoFirst() click to toggle source

Goto first line.

@return [Object] Self.

# File lib/rupat.rb, line 135
def gotoFirst
    goto
end
Also aliased as: jumpFirst
gotoForce( line = 0 ) click to toggle source

Goto line without checking for line number validity.

NOTE: User has to be aware of out-of-bound indexing issues.

@param line [Integer] Line to access. @return [Object] Self.

# File lib/rupat.rb, line 126
def gotoForce( line = 0 )
    @curline = line
    self
end
gotoLast() click to toggle source

Goto last line.

@return [Object] Self.

# File lib/rupat.rb, line 143
def gotoLast
    @curline = @lines.length-1
    self
end
Also aliased as: jumpLast
inc( count = 1 )
Alias for: forward
insert( str = "" ) click to toggle source

Insert a line at current position.

@param str [String] Content for the inserted line. @return [Object] Self.

# File lib/rupat.rb, line 386
def insert( str = "" )
    @lines.insert( @curline, str )
    self
end
insertFile( file ) click to toggle source

Insert file content to current position.

@param file [String] Name of file to insert. @return [Object] Self.

# File lib/rupat.rb, line 473
def insertFile( file )
    excursion do
        lines = readclean( file )
        insertMany( lines )
    end
    self
end
insertMany( content ) click to toggle source

Insert multiple lines at current position.

@param content [Object] Content (See: {#manyLineContent}). @return [Object] Self.

# File lib/rupat.rb, line 396
def insertMany( content )
    lines = manyLineContent( content )
    excursion do
        insert( lines[0] )
        lines[1..-1].each do |s|
            append( s )
        end
    end
    self
end
jump( line = 0 )
Alias for: goto
jumpEnd()
Alias for: gotoEnd
jumpFirst()
Alias for: gotoFirst
jumpLast()
Alias for: gotoLast
last() click to toggle source

Return last line number.

# File lib/rupat.rb, line 227
def last
    length-1
end
length() click to toggle source

Return lines length.

# File lib/rupat.rb, line 512
def length
    @lines.length
end
line() click to toggle source

Return current line number. First line is 0.

# File lib/rupat.rb, line 214
def line
    @curline
end
line1() click to toggle source

Return current line number + one, i.e. matches what for example an text editor would show. First line is 1.

# File lib/rupat.rb, line 221
def line1
    @curline + 1
end
next() click to toggle source

Return next line number from current. Current line is not changed.

# File lib/rupat.rb, line 201
def next
    @curline+1
end
open( file ) click to toggle source

Open a file in source mode (read only).

@param file [String,File] Source file.

# File lib/rupat.rb, line 63
def open( file )
    create( file, nil )
end
paste( err = true ) click to toggle source

Insert content from {#copybuf} (i.e. from {#copy}) to current position.

@param err [Boolean] Generated exception for empty copybuf if

true.
# File lib/rupat.rb, line 341
def paste( err = true )
    if err
        unless @copybuf
            raise RupatPasteError, "Copy buffer was empty!"
        end
    end
    insertMany( @copybuf ) if @copybuf
    self
end
prev() click to toggle source

Return prev line number from current. Current line is not changed.

# File lib/rupat.rb, line 208
def prev
    @curline-1
end
print( fh = STDOUT ) click to toggle source

Print file content.

@param fh [IO] IO stream for printout.

replace( ) { |get| ... } click to toggle source

Replace the current line content (i.e. get&set).

@example

r.replace do |c|
   c.gsub( /foo/, 'bar'
end

@yield [get] Actions to perform for the content. Current content

is given as argument for the block.

@return [Object] Self.

# File lib/rupat.rb, line 373
def replace( &action )
    set( yield( get ) )
    self
end
Also aliased as: subs
replaceAll( re, str ) click to toggle source

Replace all occurance of re with str.

@param re [Regexp] Regexp to match replace lines to. @param str [String] New content. @return [Object] Self.

# File lib/rupat.rb, line 487
def replaceAll( re, str )
    @lines.each_index do |idx|
        @lines[idx].gsub!( re, str )
    end
    self
end
replaceWithin( re, str, l1 = nil, l2 = nil ) click to toggle source

Replace all occurance of re with str within given range.

@param re [Regexp] Regexp to match replace lines to. @param str [String] New content. @param l1 [Integer] Line marker 1 (See: {#linePairRef}). @param l2 [Integer] Line marker 2 (See: {#linePairRef}). @return [Object] Self.

# File lib/rupat.rb, line 502
def replaceWithin( re, str, l1 = nil, l2 = nil )
    l1, l2 = linePairRef( l1, l2 )
    @lines[l1..l2].each_index do |idx|
        @lines[idx].gsub!( re, str )
    end
    self
end
save( file = @newFile ) click to toggle source

Save edits. File handle is not closed. Use {#close} for complete file closing.

@param file [String,File] File to save edits to. If type is

File, stream is not closed.
# File lib/rupat.rb, line 558
def save( file = @newFile )

    raise RupatTypeError, "Can't use \"nil\" for file save!" unless file

    close = true

    case file
    when String
        if @orgFile.class == String
            # Open with original file permissions.
            fh = File.open( file, "w", File.stat( @orgFile ).mode )
        else
            # Open with default file permissions.
            fh = File.open( file, "w" )
        end
    when File
        fh = file
        close = false
    else
        raise RupatTypeError, "Can't use \"#{file.class}\" type for file save!"
    end

    @lines.each do |l|
        fh.syswrite( l + "\n" )
    end

    fh.close if close
end
set( str, line = nil ) click to toggle source

Set line content.

@param str [String] New content for line. @param line [Integer] Index to modified line. @return [Object] Self.

# File lib/rupat.rb, line 357
def set( str, line = nil )
    @lines[ lineRef( line ) ] = str
    self
end
step( count = 1 )

Goto next line.

Alias for: forward
subs( &action )
Alias for: replace
up( count = 1 )

Goto previous line.

Alias for: backward
update( &blk ) click to toggle source

Update the content using proc block.

@yield blk Proc to execute on file content.

# File lib/rupat.rb, line 80
def update( &blk )
    instance_eval &blk
end
use( lines ) click to toggle source

Use set of lines for editing.

@param lines [Array<String>] Lines to use.

# File lib/rupat.rb, line 71
def use( lines )
    @lines = lines
    @curline = 0
end

Private Instance Methods

linePairRef( line1, line2 ) click to toggle source

Fix a pair of line markers according to rules:

  • If both are nil, then pair is <current,current>.

  • If line2 is nil and line1 is positive, then pair is <current,current+line1>, i.e. line1 is offset from current line.

  • If line2 is nil and line1 is negative, then pair is <current-line1,current>, i.e. line1 is offset from current line for first marker.

  • If line1 and line2 are valid, then pair is <line1,line2>.

@param line1 [Integer] First line reference. @param line2 [Integer] Second line reference. @return [Array<Integer>] Pair of valid line references.

# File lib/rupat.rb, line 665
def linePairRef( line1, line2 )
    if !line1 && !line2
        [ @curline, @curline ]
    elsif line1 && !line2
        if line1 >= 0
            [ @curline, @curline+line1 ]
        else
            [ @curline+line1, @curline ]
        end
    else
        [ line1, line2 ]
    end
end
lineRef( line ) click to toggle source

Transform line reference.

@param line [Integer] Line reference. @return [Integer] Current line if line is nil, otherwise line.

# File lib/rupat.rb, line 643
def lineRef( line )
    if !line
        @curline
    else
        line
    end
end
manyLineContent( content ) click to toggle source

Fix “many” content, i.e. if String, split it with “n”. If Array, pass it as it is (except chomp).

# File lib/rupat.rb, line 682
def manyLineContent( content )
    case content
    when String; content.split("\n")
    when Array; content.collect{|i| i.chomp}
    else raise RupatTypeError, "Unknown \"many\" line content!"
    end
end
normalizeCurline( err = true ) click to toggle source

Normalize curline. Raise exception if needed.

# File lib/rupat.rb, line 692
def normalizeCurline( err = true )
    if @curline < 0
        @curline = 0
        raise RupatInvalidLineError, "Current line underflow..." if err
    elsif @curline > @lines.length
        @curline = @lines.length
        raise RupatInvalidLineError, "Current line overflow..." if err
    end
end
readclean( file ) click to toggle source

Read file/IO and remove newline from each line. Return clean line list.

# File lib/rupat.rb, line 606
def readclean( file )
    if file.class == String
        return File.readlines( file ).map{|line| line.chomp}
    elsif file.class == File
        return file.readlines.map{|line| line.chomp}
    else
        raise RupatError, "Invalid file object reference!"
    end
end