File: lines_file.rb

package info (click to toggle)
ruby-tins 1.32.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,248 kB
  • sloc: ruby: 6,659; makefile: 3
file content (123 lines) | stat: -rw-r--r-- 2,526 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
module Tins
  class LinesFile
    module LineExtension
      attr_reader :line_number

      def filename
        lines_file.filename.dup
      end
    end

    def self.for_filename(filename, line_number = nil)
      obj = new(File.readlines(filename), line_number)
      obj.filename = filename
      obj
    end

    def self.for_file(file, line_number = nil)
      obj = new(file.readlines, line_number)
      obj.filename = file.path
      obj
    end

    def self.for_lines(lines, line_number = nil)
      new(lines, line_number)
    end

    def initialize(lines, line_number = nil)
      @lines = lines
      @lines.each_with_index do |line, i|
        line.extend LineExtension
        line.instance_variable_set :@line_number, i + 1
        line.instance_variable_set :@lines_file, self
      end
      instance_variable_set :@line_number, line_number || (@lines.empty? ? 0 : 1)
    end

    attr_accessor :filename

    attr_reader :line_number

    def rewind
      self.line_number = 1
      self
    end

    def next!
      old = line_number
      self.line_number += 1
      line_number > old ? self : nil
    end

    def previous!
      old = line_number
      self.line_number -= 1
      line_number < old ? self : nil
    end

    def line_number=(number)
      number = number.to_i
      if number > 0 && number <= last_line_number
        @line_number = number
      end
    end

    def last_line_number
      @lines.size
    end

    def empty?
      @lines.empty?
    end

    def each(&block)
      empty? and return self
      old_line_number = line_number
      1.upto(last_line_number) do |number|
        self.line_number = number
        block.call(line)
      end
      self
    ensure
      self.line_number = old_line_number
    end
    include Enumerable

    def line
      index = line_number - 1
      @lines[index] if index >= 0
    end

    def file_linenumber
      "#{filename}:#{line_number}"
    end

    def match_backward(regexp, previous_after_match = false)
      begin
        if line =~ regexp
          previous_after_match and previous!
          return $~.captures
        end
      end while previous!
    end

    def match_forward(regexp, next_after_match = false)
      begin
        if line =~ regexp
          next_after_match and next!
          return $~.captures
        end
      end while next!
    end

    def to_s
      "#{line_number} #{line.chomp}"
    end

    def inspect
      "#<#{self.class}: #{to_s.inspect}>"
    end
  end
end

require 'tins/alias'