ned 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +95 -20
- data/bin/ned +1 -1
- data/lib/ned/command.rb +131 -8
- data/lib/ned/command_registry.rb +27 -0
- data/lib/ned/commands/append.rb +27 -13
- data/lib/ned/commands/backward.rb +21 -14
- data/lib/ned/commands/head.rb +33 -18
- data/lib/ned/commands/index.rb +34 -25
- data/lib/ned/commands/join.rb +41 -14
- data/lib/ned/commands/prepend.rb +27 -13
- data/lib/ned/commands/print.rb +13 -0
- data/lib/ned/commands/quote.rb +29 -13
- data/lib/ned/commands/read.rb +40 -0
- data/lib/ned/commands/sort.rb +45 -31
- data/lib/ned/commands/tail.rb +29 -20
- data/lib/ned/commands/uniq.rb +53 -18
- data/lib/ned/string.rb +14 -0
- data/lib/ned/strings.rb +1 -1
- data/lib/ned/version.rb +1 -3
- data/lib/ned.rb +181 -138
- data/lib/{ned → ned_old}/commands/grep.rb +0 -0
- data/lib/{ned → ned_old}/commands/only.rb +0 -0
- data/lib/{ned → ned_old}/commands/replace.rb +0 -0
- data/lib/{ned → ned_old}/commands/visual.rb +0 -0
- data/lib/ned_old.rb +193 -0
- data/ned.gemspec +2 -2
- data/scripts/generate_readme +6 -0
- data/spec_old/file_spec.rb +29 -0
- metadata +14 -12
- data/lib/ned/config.rb +0 -73
- data/lib/ned/context.rb +0 -10
- data/lib/ned/validators.rb +0 -19
- data/todo +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 160b7291a491361041677df083e0b86804f07b8cd8915c6bf0d488bf080caaa3
|
4
|
+
data.tar.gz: 69e4cfa1448cf5e8b0f106d4e4782c498423aca84d3953b43618f6708f3fecf8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec4eb7adade48c639e707e71ed1ef1cddf47415390af025990ec69530b4733bbd2989280ea6fdae1783efe37391f7a667c4eb7fcbf9775440a905a8a44e88455
|
7
|
+
data.tar.gz: e898818ec2422271f845da80aca56389a637833e60e0247a96ed53569df00d66b93952332801b3a00778a110510b077d8fb183caf63fa3d2dee32a5e3f0d1761
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,24 +1,99 @@
|
|
1
1
|
# Ned
|
2
2
|
|
3
3
|
```
|
4
|
-
|
5
|
-
|
6
|
-
Usage: ned [
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
4
|
+
Ned, a stream editor.
|
5
|
+
|
6
|
+
Usage: ned [[ned_arg ...] --] [[command] [: command ...]]
|
7
|
+
|
8
|
+
OPTIONS
|
9
|
+
-i, --inplace Edit each file in place by processing each file independently.
|
10
|
+
-h, --help [COMMAND] Print this help.
|
11
|
+
-v, --version Print Ned version.
|
12
|
+
|
13
|
+
COMMANDS
|
14
|
+
|
15
|
+
append (a)
|
16
|
+
|
17
|
+
Append the specified string to each input line.
|
18
|
+
|
19
|
+
Usage: ned append STRING
|
20
|
+
|
21
|
+
backward (b)
|
22
|
+
|
23
|
+
Reverse input lines.
|
24
|
+
|
25
|
+
Usage: ned backward
|
26
|
+
|
27
|
+
head (h)
|
28
|
+
|
29
|
+
Print only the first input lines.
|
30
|
+
|
31
|
+
Usage: ned head [--num NUM]
|
32
|
+
|
33
|
+
Options:
|
34
|
+
-n, --num NUM Number of input lines to print. Defaults to 10.
|
35
|
+
|
36
|
+
index (i)
|
37
|
+
|
38
|
+
Print only the specified line(s). Use -1 etc to index from end.
|
39
|
+
|
40
|
+
Usage: ned index START [END]
|
41
|
+
|
42
|
+
join (j)
|
43
|
+
|
44
|
+
Join input lines, optionally with the specified delimiter.
|
45
|
+
|
46
|
+
Usage: ned join [--delimiter STRING]
|
47
|
+
|
48
|
+
Options:
|
49
|
+
-d, --delimiter STRING Join using the specified delimiter.
|
50
|
+
|
51
|
+
prepend (p)
|
52
|
+
|
53
|
+
Prepend the specified string to each input line.
|
54
|
+
|
55
|
+
Usage: ned prepend STRING
|
56
|
+
|
57
|
+
quote (q)
|
58
|
+
|
59
|
+
Wrap each input line in quotes.
|
60
|
+
|
61
|
+
Usage: ned quote [--quote STRING]
|
62
|
+
|
63
|
+
Options:
|
64
|
+
-q, --quote STRING Quote using the specified string.
|
65
|
+
|
66
|
+
sort (s)
|
67
|
+
|
68
|
+
Sort input lines.
|
69
|
+
|
70
|
+
Usage: ned sort [--numeric]
|
71
|
+
|
72
|
+
Options:
|
73
|
+
-n, --numeric Sort numerically.
|
74
|
+
-r, --reverse Reverse the sort order.
|
75
|
+
|
76
|
+
tail (t)
|
77
|
+
|
78
|
+
Print only the last input lines.
|
79
|
+
|
80
|
+
Usage: ned tail [--num NUM]
|
81
|
+
|
82
|
+
Options:
|
83
|
+
-n, --num NUM Number of input lines to print. Defaults to 10.
|
84
|
+
|
85
|
+
uniq (u)
|
86
|
+
|
87
|
+
Filter out repeated input lines.
|
88
|
+
|
89
|
+
Usage: ned uniq [--count]
|
90
|
+
|
91
|
+
Options:
|
92
|
+
-c, --count Precede each output line with the number of times the line occurred in the input, followed by a space.
|
93
|
+
```
|
94
|
+
|
95
|
+
## Installation
|
96
|
+
|
97
|
+
```
|
98
|
+
gem install ned
|
24
99
|
```
|
data/bin/ned
CHANGED
data/lib/ned/command.rb
CHANGED
@@ -1,18 +1,141 @@
|
|
1
1
|
module Ned
|
2
2
|
class Command
|
3
|
-
|
3
|
+
class ParseError < StandardError; end
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
class << self
|
6
|
+
def config(name, args)
|
7
|
+
@config ||= { }
|
8
|
+
|
9
|
+
if args.empty?
|
10
|
+
@config[name]
|
11
|
+
elsif args.size == 1
|
12
|
+
@config[name] = args[0]
|
13
|
+
nil
|
14
|
+
else
|
15
|
+
raise "invalid args: #{args}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def long_name(*args)
|
20
|
+
config(:long_name, args)
|
21
|
+
end
|
22
|
+
|
23
|
+
def short_name(*args)
|
24
|
+
config(:short_name, args)
|
25
|
+
end
|
26
|
+
|
27
|
+
def description(*args)
|
28
|
+
config(:description, args)
|
29
|
+
end
|
30
|
+
|
31
|
+
def option_parser(&block)
|
32
|
+
if block_given?
|
33
|
+
@option_parser = block
|
34
|
+
else
|
35
|
+
@option_parser
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def help
|
40
|
+
OptionParser.new do |opts|
|
41
|
+
option_parser.call(opts)
|
42
|
+
end.help
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def initialize(input)
|
47
|
+
@input = input
|
48
|
+
end
|
49
|
+
|
50
|
+
def options
|
51
|
+
@options ||= {}
|
52
|
+
end
|
53
|
+
|
54
|
+
def parse(args)
|
55
|
+
OptionParser.new do |opts|
|
56
|
+
opts.on('-h', '--help', 'Print this help.') do |help|
|
57
|
+
help
|
58
|
+
end
|
59
|
+
|
60
|
+
opts.on('-v', '--version', 'Print Ned version.') do |version|
|
61
|
+
version
|
62
|
+
end
|
63
|
+
|
64
|
+
instance_exec(opts, &self.class.option_parser)
|
65
|
+
end.parse!(args, into: options)
|
66
|
+
end
|
67
|
+
|
68
|
+
def execute
|
69
|
+
result = @input.execute
|
70
|
+
return nil if result.nil?
|
71
|
+
|
72
|
+
if result.is_a? Array
|
73
|
+
if require_flat_map?
|
74
|
+
result.flat_map do |line|
|
75
|
+
execute_internal(line)
|
76
|
+
end
|
77
|
+
else
|
78
|
+
result.map do |line|
|
79
|
+
execute_internal(line)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
else
|
83
|
+
execute_internal(result)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def execute_all
|
88
|
+
if require_flat_map?
|
89
|
+
lines = @input.execute_all.flat_map do |line|
|
90
|
+
execute_internal(line)
|
91
|
+
end
|
92
|
+
lines
|
93
|
+
else
|
94
|
+
lines = @input.execute_all
|
95
|
+
lines.each do |line|
|
96
|
+
execute_internal(line)
|
97
|
+
end
|
98
|
+
lines
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def require_flat_map(require_flat_map = true)
|
103
|
+
@require_flat_map = require_flat_map
|
104
|
+
end
|
105
|
+
|
106
|
+
def require_flat_map?
|
107
|
+
@require_flat_map || false
|
108
|
+
end
|
109
|
+
|
110
|
+
def execute_internal(line)
|
111
|
+
line
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
class AllCommand < Command
|
116
|
+
def execute
|
117
|
+
load_lines.empty? ? nil : load_lines.shift
|
118
|
+
end
|
119
|
+
|
120
|
+
def execute_all
|
121
|
+
load_lines
|
122
|
+
@lines.shift(@lines.size)
|
123
|
+
end
|
124
|
+
|
125
|
+
def ensure_trailing_newline
|
126
|
+
@lines[-1].ensure_trailing_newline if @lines[-1]
|
8
127
|
end
|
9
128
|
|
10
|
-
def
|
11
|
-
|
129
|
+
def load_lines
|
130
|
+
unless @lines
|
131
|
+
@lines = @input.execute_all
|
132
|
+
@lines = execute_internal(@lines)
|
133
|
+
end
|
134
|
+
@lines
|
12
135
|
end
|
13
136
|
|
14
|
-
def
|
15
|
-
|
137
|
+
def execute_internal(lines)
|
138
|
+
lines
|
16
139
|
end
|
17
140
|
end
|
18
141
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Ned
|
2
|
+
class CommandRegistry
|
3
|
+
@all = []
|
4
|
+
@names = { }
|
5
|
+
|
6
|
+
def self.add(command)
|
7
|
+
if @names.key?(command.long_name)
|
8
|
+
raise "duplicate command name \"#{command.long_name}\""
|
9
|
+
end
|
10
|
+
|
11
|
+
if @names.key?(command.short_name)
|
12
|
+
raise "duplicate command name \"#{command.short_name}\""
|
13
|
+
end
|
14
|
+
@names[command.long_name] = command
|
15
|
+
@names[command.short_name] = command
|
16
|
+
@all << command
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.find(name)
|
20
|
+
@names[name]
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.all
|
24
|
+
@all
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/ned/commands/append.rb
CHANGED
@@ -1,15 +1,29 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
1
|
+
module Ned
|
2
|
+
class Append < Command
|
3
|
+
long_name 'append'
|
4
|
+
short_name 'a'
|
5
|
+
|
6
|
+
option_parser do |opts|
|
7
|
+
opts.banner = <<~EOF
|
8
|
+
Append the specified string to each input line.
|
9
|
+
|
10
|
+
Usage: ned append STRING
|
11
|
+
EOF
|
12
|
+
end
|
13
|
+
|
14
|
+
def parse(args)
|
15
|
+
super
|
16
|
+
|
17
|
+
raise OptionParser::ParseError.new("missing string argument") if args.size == 0
|
18
|
+
@append = args.shift
|
19
|
+
require_flat_map if @append.index("\n")
|
20
|
+
end
|
21
|
+
|
22
|
+
def execute_internal(line)
|
23
|
+
line.insert_before_newline(@append)
|
24
|
+
require_flat_map? ? line.split(/(?<=\n)/) : line
|
13
25
|
end
|
26
|
+
|
27
|
+
Ned::CommandRegistry.add(Append)
|
14
28
|
end
|
15
|
-
|
29
|
+
end
|
@@ -1,14 +1,21 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
)
|
1
|
+
module Ned
|
2
|
+
class Backward < Ned::AllCommand
|
3
|
+
long_name 'backward'
|
4
|
+
short_name 'b'
|
5
|
+
|
6
|
+
option_parser do |opts|
|
7
|
+
opts.banner = <<~EOF
|
8
|
+
Reverse input lines.
|
9
|
+
|
10
|
+
Usage: ned backward
|
11
|
+
EOF
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute_internal(lines)
|
15
|
+
ensure_trailing_newline
|
16
|
+
lines.reverse!
|
17
|
+
end
|
18
|
+
|
19
|
+
Ned::CommandRegistry.add(Backward)
|
20
|
+
end
|
21
|
+
end
|
data/lib/ned/commands/head.rb
CHANGED
@@ -1,21 +1,36 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
1
|
+
module Ned
|
2
|
+
class Head < Command
|
3
|
+
long_name 'head'
|
4
|
+
short_name 'h'
|
5
|
+
|
6
|
+
option_parser do |opts|
|
7
|
+
opts.banner = <<~EOF
|
8
|
+
Print only the first input lines.
|
9
|
+
|
10
|
+
Usage: ned head [--num NUM]
|
11
|
+
|
12
|
+
Options:
|
13
|
+
EOF
|
14
|
+
|
15
|
+
opts.on('-n', '--num NUM', Integer, 'Number of input lines to print. Defaults to 10.') do |num|
|
16
|
+
raise OptionParser::ParseError.new('duplicate flag') if options[:num]
|
17
|
+
|
18
|
+
raise OptionParser::ParseError.new("invalid num: #{num}") if num < 0
|
19
|
+
|
20
|
+
num
|
21
|
+
end
|
14
22
|
end
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
23
|
+
|
24
|
+
def execute_internal(line)
|
25
|
+
@index ||= 0
|
26
|
+
@index += 1
|
27
|
+
if @index <= options.fetch(:num, 10)
|
28
|
+
line
|
29
|
+
else
|
30
|
+
nil
|
31
|
+
end
|
19
32
|
end
|
33
|
+
|
34
|
+
Ned::CommandRegistry.add(Head)
|
20
35
|
end
|
21
|
-
|
36
|
+
end
|
data/lib/ned/commands/index.rb
CHANGED
@@ -1,27 +1,36 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
next unless parts.size == 2
|
13
|
-
|
14
|
-
[Integer(parts[0]), Integer(parts[1])] rescue nil
|
15
|
-
else
|
16
|
-
Integer(param) rescue nil
|
1
|
+
module Ned
|
2
|
+
class Index < AllCommand
|
3
|
+
long_name 'index'
|
4
|
+
short_name 'i'
|
5
|
+
|
6
|
+
option_parser do |opts|
|
7
|
+
opts.banner = <<~EOF
|
8
|
+
Print only the specified line(s). Use -1 etc to index from end.
|
9
|
+
|
10
|
+
Usage: ned index START [END]
|
11
|
+
EOF
|
17
12
|
end
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
13
|
+
|
14
|
+
def parse(args)
|
15
|
+
if index = args.index { |arg| Integer(arg) rescue false }
|
16
|
+
@start = Integer(args.delete_at(index))
|
17
|
+
|
18
|
+
if index = args.index { |arg| Integer(arg) rescue false }
|
19
|
+
@end = Integer(args.delete_at(index))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
@end ||= @start
|
24
|
+
|
25
|
+
super
|
26
|
+
|
27
|
+
raise OptionParser::ParseError.new("missing index argument") unless @start
|
28
|
+
end
|
29
|
+
|
30
|
+
def execute_internal(lines)
|
31
|
+
lines[@start..@end] || []
|
32
|
+
end
|
33
|
+
|
34
|
+
Ned::CommandRegistry.add(Index)
|
26
35
|
end
|
27
|
-
|
36
|
+
end
|
data/lib/ned/commands/join.rb
CHANGED
@@ -1,14 +1,41 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
1
|
+
module Ned
|
2
|
+
class Join < Ned::AllCommand
|
3
|
+
long_name 'join'
|
4
|
+
short_name 'j'
|
5
|
+
|
6
|
+
option_parser do |opts|
|
7
|
+
opts.banner = <<~EOF
|
8
|
+
Join input lines, optionally with the specified delimiter.
|
9
|
+
|
10
|
+
Usage: ned join [--delimiter STRING]
|
11
|
+
|
12
|
+
Options:
|
13
|
+
EOF
|
14
|
+
|
15
|
+
opts.on("-d", '--delimiter STRING', 'Join using the specified delimiter.') do |delimiter|
|
16
|
+
raise OptionParser::ParseError.new('duplicate flag') if options[:delimiter]
|
17
|
+
|
18
|
+
@has_newline = delimiter.index("\n") != nil
|
19
|
+
delimiter
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def execute_internal(lines)
|
24
|
+
if lines[-1] && lines[-1][-1] == "\n"
|
25
|
+
trailing_newline = "\n"
|
26
|
+
lines.each { |line| line.slice!(-1) }
|
27
|
+
else
|
28
|
+
trailing_newline = ''
|
29
|
+
lines[0..-2].each { |line| line.slice!(-1) }
|
30
|
+
end
|
31
|
+
|
32
|
+
if @has_newline
|
33
|
+
lines.join(options.fetch(:delimiter, '')).insert(-1, trailing_newline).split(/(?<=\n)/)
|
34
|
+
else
|
35
|
+
[lines.join(options.fetch(:delimiter, '')).insert(-1, trailing_newline)]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
Ned::CommandRegistry.add(Join)
|
40
|
+
end
|
41
|
+
end
|
data/lib/ned/commands/prepend.rb
CHANGED
@@ -1,15 +1,29 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
1
|
+
module Ned
|
2
|
+
class Prepend < Command
|
3
|
+
long_name 'prepend'
|
4
|
+
short_name 'p'
|
5
|
+
|
6
|
+
option_parser do |opts|
|
7
|
+
opts.banner = <<~EOF
|
8
|
+
Prepend the specified string to each input line.
|
9
|
+
|
10
|
+
Usage: ned prepend STRING
|
11
|
+
EOF
|
12
|
+
end
|
13
|
+
|
14
|
+
def parse(args)
|
15
|
+
super
|
16
|
+
|
17
|
+
raise OptionParser::ParseError.new("missing string argument") if args.size == 0
|
18
|
+
@prepend = args.shift
|
19
|
+
require_flat_map if @prepend.index("\n")
|
20
|
+
end
|
21
|
+
|
22
|
+
def execute_internal(line)
|
23
|
+
line.insert(0, @prepend)
|
24
|
+
require_flat_map? ? line.split(/(?<=\n)/) : line
|
13
25
|
end
|
26
|
+
|
27
|
+
Ned::CommandRegistry.add(Prepend)
|
14
28
|
end
|
15
|
-
|
29
|
+
end
|
data/lib/ned/commands/quote.rb
CHANGED
@@ -1,15 +1,31 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
1
|
+
module Ned
|
2
|
+
class Quote < Ned::Command
|
3
|
+
long_name 'quote'
|
4
|
+
short_name 'q'
|
5
|
+
|
6
|
+
option_parser do |opts|
|
7
|
+
opts.banner = <<~EOF
|
8
|
+
Wrap each input line in quotes.
|
9
|
+
|
10
|
+
Usage: ned quote [--quote STRING]
|
11
|
+
|
12
|
+
Options:
|
13
|
+
EOF
|
14
|
+
|
15
|
+
opts.on('-q', '--quote STRING', 'Quote using the specified string.') do |quote|
|
16
|
+
raise OptionParser::ParseError.new('duplicate flag') if options[:quote]
|
17
|
+
|
18
|
+
require_flat_map if quote.index("\n")
|
19
|
+
quote
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def execute_internal(line)
|
24
|
+
line.insert(0, options.fetch(:quote, '"'))
|
25
|
+
line.insert_before_newline(options.fetch(:quote, '"'))
|
26
|
+
require_flat_map? ? line.split(/(?<=\n)/) : line
|
13
27
|
end
|
28
|
+
|
29
|
+
Ned::CommandRegistry.add(Quote)
|
14
30
|
end
|
15
|
-
|
31
|
+
end
|