ned 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 23d27cc1a81863250fe7b264e9199fb794c8d3e62fe879dab529f3201019e2f2
4
+ data.tar.gz: 6a1124febf6502f5a54693617da98eb869a0c181ae90aa678ec670937b26879d
5
+ SHA512:
6
+ metadata.gz: 99fd8ede92eea52aed8a2308f6e05487219769c06a92104e7fe43fdbb96ea33aa833b598bbe5305a6741758657a7c0b16cfe01c7d96a38727c4166a83ec3fc78
7
+ data.tar.gz: 5f800186643b9638f32cdee823b64694fd0b4a60041af701e178d9c68967c63849726b0c29758899a483906c8a148103dda11495489d5219b9ae2949dff8e59d
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ ned-*.gem
2
+ .idea
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
6
+
7
+ group :test do
8
+ gem 'rspec'
9
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,32 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ned (0.0.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.5.0)
10
+ rspec (3.11.0)
11
+ rspec-core (~> 3.11.0)
12
+ rspec-expectations (~> 3.11.0)
13
+ rspec-mocks (~> 3.11.0)
14
+ rspec-core (3.11.0)
15
+ rspec-support (~> 3.11.0)
16
+ rspec-expectations (3.11.0)
17
+ diff-lcs (>= 1.2.0, < 2.0)
18
+ rspec-support (~> 3.11.0)
19
+ rspec-mocks (3.11.1)
20
+ diff-lcs (>= 1.2.0, < 2.0)
21
+ rspec-support (~> 3.11.0)
22
+ rspec-support (3.11.0)
23
+
24
+ PLATFORMS
25
+ x86_64-darwin-20
26
+
27
+ DEPENDENCIES
28
+ ned!
29
+ rspec
30
+
31
+ BUNDLED WITH
32
+ 2.3.3
data/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # Ned
2
+
3
+ ```
4
+ A stream editor.
5
+
6
+ Usage: ned [file] [options ...]
7
+
8
+ Options:
9
+ --help Print this message.
10
+ --version Print version.
11
+ -a, --append string Append the specified string to each line.
12
+ -b, --backward Invert all input lines.
13
+ -g, --grep pattern Search using the specified pattern.
14
+ -h, --head [num] Print the first n lines. Defaults to 10.
15
+ -i, --index start[..end] Print only the specified lines. Use -1 etc to index from end.
16
+ -j, --join [string] Join input lines, optionally with the specified string.
17
+ -o, --only pattern Search using the specified pattern. Only print matching part of line.
18
+ -p, --prepend string Prepend the specified string to each line.
19
+ -q, --quote [string] Quote each line, optionally with the specified string.
20
+ -r, --replace pattern replacement Regex replace.
21
+ -s, --sort ["num"|"alpha"] Sort. Defaults to alphabetical.
22
+ -t, --tail [num] Print the last n lines. Defaults to 10.
23
+ -u, --uniq Unique.
24
+ ```
data/bin/ned ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift "#{__dir__}/../lib"
4
+
5
+ require 'ned'
6
+
7
+ exit Ned.run
@@ -0,0 +1,18 @@
1
+ module Ned
2
+ class Command
3
+ attr_reader :config, :params
4
+
5
+ def initialize(config, params)
6
+ @config = config
7
+ @params = params
8
+ end
9
+
10
+ def all?
11
+ config.all?(params)
12
+ end
13
+
14
+ def execute(context)
15
+ config.execute(context, *params)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ Ned::Config.add(
4
+ name: 'append',
5
+ description: 'Append the specified string to each line.',
6
+ short: '-a',
7
+ long: '--append',
8
+ params: 'string',
9
+ validator: Ned::Validators.num(1),
10
+ execute: lambda do |context, string|
11
+ context.lines = context.lines.flat_map do |line|
12
+ "#{line}#{string}".split("\n")
13
+ end
14
+ end
15
+ )
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ Ned::Config.add(
4
+ name: 'backward',
5
+ description: 'Invert all input lines.',
6
+ short: '-b',
7
+ long: '--backward',
8
+ params: nil,
9
+ validator: Ned::Validators.none(),
10
+ execute: lambda do |context|
11
+ context.lines.reverse!
12
+ end,
13
+ all: true
14
+ )
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ Ned::Config.add(
4
+ name: 'grep',
5
+ description: 'Search using the specified pattern.',
6
+ short: '-g',
7
+ long: '--grep',
8
+ params: 'pattern',
9
+ validator: Ned::Validators.num(1),
10
+ execute: lambda do |context, pattern|
11
+ regexp = Regexp.new(pattern)
12
+ context.lines = context.lines.flat_map do |line|
13
+ line.match(pattern) ? [line] : []
14
+ end
15
+ end
16
+ )
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ Ned::Config.add(
4
+ name: 'head',
5
+ description: 'Print the first n lines. Defaults to 10.',
6
+ short: '-h',
7
+ long: '--head',
8
+ params: '[num]',
9
+ validator: Ned::Validators.num(0, 1) do |num|
10
+ if num
11
+ Integer(num) rescue nil
12
+ else
13
+ []
14
+ end
15
+ end,
16
+ execute: lambda do |context, num=10|
17
+ context.lines = context.lines.flat_map do |line|
18
+ context.start_index < num ? [line] : []
19
+ end
20
+ end
21
+ )
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ Ned::Config.add(
4
+ name: 'index',
5
+ description: 'Print only the specified lines. Use -1 etc to index from end.',
6
+ short: '-i',
7
+ long: '--index',
8
+ params: 'start[..end]',
9
+ validator: Ned::Validators.num(1) do |param|
10
+ if param.index('..')
11
+ parts = param.split('..')
12
+ next unless parts.size == 2
13
+
14
+ [Integer(parts[0]), Integer(parts[1])] rescue nil
15
+ else
16
+ Integer(param) rescue nil
17
+ end
18
+ end,
19
+ execute: lambda do |context, start, ending = nil|
20
+ context.lines = (ending.nil? ? context.lines[start..start] : context.lines[start..ending]) || []
21
+ end,
22
+ all: lambda do |start, ending = nil|
23
+ true
24
+ # todo
25
+ #start < 0 || (!ending.nil? && ending < 0)
26
+ end
27
+ )
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ Ned::Config.add(
4
+ name: 'join',
5
+ description: 'Join input lines, optionally with the specified string.',
6
+ short: '-j',
7
+ long: '--join',
8
+ params: '[string]',
9
+ validator: Ned::Validators.num(0, 1),
10
+ execute: lambda do |context, string=''|
11
+ context.lines = context.lines.join(string).split("\n")
12
+ end,
13
+ all: true
14
+ )
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ Ned::Config.add(
4
+ name: 'only',
5
+ description: 'Search using the specified pattern. Only print matching part of line.',
6
+ short: '-o',
7
+ long: '--only',
8
+ params: 'pattern',
9
+ validator: Ned::Validators.num(1),
10
+ execute: lambda do |context, pattern|
11
+ regexp = Regexp.new(pattern)
12
+ context.lines = context.lines.flat_map do |line|
13
+ match = line.match(pattern)
14
+ match ? [match[0]] : []
15
+ end
16
+ end
17
+ )
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ Ned::Config.add(
4
+ name: 'prepend',
5
+ description: 'Prepend the specified string to each line.',
6
+ short: '-p',
7
+ long: '--prepend',
8
+ params: 'string',
9
+ validator: Ned::Validators.num(1),
10
+ execute: lambda do |context, string|
11
+ context.lines = context.lines.flat_map do |line|
12
+ "#{string}#{line}".split("\n")
13
+ end
14
+ end
15
+ )
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ Ned::Config.add(
4
+ name: 'quote',
5
+ description: 'Quote each line, optionally with the specified string.',
6
+ short: '-q',
7
+ long: '--quote',
8
+ params: '[string]',
9
+ validator: Ned::Validators.num(0, 1),
10
+ execute: lambda do |context, char='"'|
11
+ context.lines = context.lines.flat_map do |line|
12
+ "#{char}#{line}#{char}".split("\n")
13
+ end
14
+ end
15
+ )
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ Ned::Config.add(
4
+ name: 'replace',
5
+ description: 'Regex replace.',
6
+ short: '-r',
7
+ long: '--replace',
8
+ params: 'pattern replacement',
9
+ validator: Ned::Validators.num(2),
10
+ execute: lambda do |context, pattern, string|
11
+ context.lines = context.lines.flat_map do |line|
12
+ line.gsub(Regexp.new(pattern), string).split("\n")
13
+ end
14
+ end
15
+ )
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ned
4
+ module Sort
5
+ DIGIT_MATCH = /^ *((?:0|-?[1-9][0-9]*)(?:[.][0-9]+)?)(.*)/
6
+ end
7
+ end
8
+
9
+ Ned::Config.add(
10
+ name: 'sort',
11
+ description: 'Sort. Defaults to alphabetical.',
12
+ short: '-s',
13
+ long: '--sort',
14
+ params: '["num"|"alpha"]',
15
+ validator: Ned::Validators.num(0, 1) do |type|
16
+ if type
17
+ ['num', 'alpha'].include?(type) ? [type] : nil
18
+ else
19
+ []
20
+ end
21
+ end,
22
+ execute: lambda do |context, type='alpha'|
23
+ if type == 'alpha'
24
+ context.lines.sort!
25
+ else
26
+ sortable = context.lines.map do |line|
27
+ match = line.match(Ned::Sort::DIGIT_MATCH)
28
+ if match
29
+ [0, Float(match[1]), match[2], line]
30
+ else
31
+ [1, nil, nil, line]
32
+ end
33
+ end
34
+ context.lines = sortable.sort.map { |v| v[3] }
35
+ end
36
+ end,
37
+ all: true
38
+ )
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ Ned::Config.add(
4
+ name: 'tail',
5
+ description: 'Print the last n lines. Defaults to 10.',
6
+ short: '-t',
7
+ long: '--tail',
8
+ params: '[num]',
9
+ validator: Ned::Validators.num(0, 1) do |num|
10
+ if num
11
+ Integer(num) rescue nil
12
+ else
13
+ []
14
+ end
15
+ end,
16
+ execute: lambda do |context, num=10|
17
+ if num < context.lines.length
18
+ context.lines = context.lines[-num..-1]
19
+ end
20
+ end,
21
+ all: true
22
+ )
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ Ned::Config.add(
4
+ name: 'uniq',
5
+ description: 'Unique.',
6
+ short: '-u',
7
+ long: '--uniq',
8
+ params: nil,
9
+ validator: Ned::Validators.none,
10
+ execute: lambda do |context|
11
+ context.lines = context.lines.each_with_index.flat_map do |line, index|
12
+ if index == 0 || context.lines[index - 1] != line
13
+ [line]
14
+ else
15
+ []
16
+ end
17
+ end
18
+ end,
19
+ all: true
20
+ )
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ Ned::Config.add(
4
+ name: 'visual',
5
+ short: '-v',
6
+ long: '--visual',
7
+ params: 'start[..end]',
8
+ description: 'Select a range to apply commands to. Use -1 etc to index from end.',
9
+ validator: Ned::Validators.num(1) do |param|
10
+ if param.index('..')
11
+ parts = param.split('..')
12
+ next unless parts.size == 2
13
+
14
+ [Integer(parts[0]), Integer(parts[1])] rescue nil
15
+ else
16
+ Integer(param) rescue nil
17
+ end
18
+ end,
19
+ execute: lambda do |context, start, ending = nil|
20
+ end,
21
+ hidden: true
22
+ )
data/lib/ned/config.rb ADDED
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ned
4
+ class Config
5
+ class << self
6
+ attr_reader :all
7
+ end
8
+
9
+ @all = []
10
+
11
+ def self.add(name:, description:, short:, long:, params:, validator:, execute:, all: nil, hidden: false)
12
+ @all.each do |config|
13
+ if config.short.start_with?(short) || short.start_with?(config.short)
14
+ raise "Cannot add command #{name}. Flag conflicts with #{config.name}."
15
+ end
16
+
17
+ if config.long.start_with?(long) || long.start_with?(config.long)
18
+ raise "Cannot add command #{name}. Flag conflicts with #{config.name}."
19
+ end
20
+ end
21
+
22
+ @all << Config.new(
23
+ name: name,
24
+ description: description,
25
+ short: short,
26
+ long: long,
27
+ params: params,
28
+ validator: validator,
29
+ execute: execute,
30
+ all: all,
31
+ hidden: hidden
32
+ )
33
+ end
34
+
35
+ attr_reader :name, :description, :short, :long, :params
36
+
37
+ def initialize(name:, description:, short:, long:, params:, validator:, execute:, all: nil, hidden: false)
38
+ @name = name
39
+ @description = description
40
+ @short = short
41
+ @long = long
42
+ @params = params
43
+ @validator = validator
44
+ @execute = execute
45
+ @hidden = hidden
46
+
47
+ all = all || false
48
+ if [true, false].include? all
49
+ @all = lambda { |*params| all }
50
+ elsif all.is_a? Proc
51
+ @all = all
52
+ else
53
+ raise "Invalid all type for #{name}: #{all.class}"
54
+ end
55
+ end
56
+
57
+ def validate(*args)
58
+ @validator.call(*args)
59
+ end
60
+
61
+ def all?(params)
62
+ @all.call(*params)
63
+ end
64
+
65
+ def hidden?
66
+ @hidden
67
+ end
68
+
69
+ def execute(*args)
70
+ @execute.call(*args)
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,10 @@
1
+ module Ned
2
+ class Context
3
+ attr_accessor :lines, :start_index
4
+
5
+ def initialize(lines, start_index)
6
+ @lines = lines
7
+ @start_index = start_index
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ned
4
+ class Strings
5
+ SEQUENCES = {
6
+ 'n' => "\n",
7
+ 't' => "\t",
8
+ '\\' => '\\'
9
+ }
10
+
11
+ def self.unescape!(string)
12
+ i = 0
13
+ while i < string.size - 1
14
+ if string[i] == '\\'
15
+ raise 'eof' if i == (string.size - 1)
16
+ c = string[i + 1]
17
+ r = SEQUENCES[c]
18
+ if r
19
+ string[i] = r
20
+ string[i + 1] = ''
21
+ end
22
+ end
23
+ i = i + 1
24
+ end
25
+
26
+ string
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ned
4
+ class Validators
5
+ def self.none
6
+ lambda { |*params| params.length == 0 ? [] : nil }
7
+ end
8
+
9
+ def self.num(min, max = nil, &block)
10
+ lambda do |*params|
11
+ max = min unless max
12
+
13
+ return nil if params.length < min || params.length > max
14
+
15
+ block.nil? ? params : yield(*params)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ned
4
+ VERSION = "0.0.1"
5
+ end
data/lib/ned.rb ADDED
@@ -0,0 +1,193 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ned/command'
4
+ require 'ned/config'
5
+ require 'ned/context'
6
+ require 'ned/strings'
7
+ require 'ned/validators'
8
+ require 'ned/version'
9
+
10
+ Dir["#{__dir__}/ned/commands/**/*.rb"].sort.each { |f| require f }
11
+
12
+ module Ned
13
+ def self.help(error_output)
14
+ error_output.puts <<~EOF
15
+ A stream editor.
16
+
17
+ Usage: ned [file] [options ...]
18
+
19
+ Options:
20
+ EOF
21
+
22
+ lines = [
23
+ [' --help', 'Print this message.'],
24
+ [' --version', 'Print version.']
25
+ ]
26
+ max = lines[0][0].length
27
+ Ned::Config.all.each do |config|
28
+ next if config.hidden?
29
+
30
+ line = "#{config.short}, #{config.long} #{config.params}"
31
+ lines << [line, config.description]
32
+ max = [max, line.length].max
33
+ end
34
+
35
+ lines.each do |line|
36
+ error_output.puts " #{line[0].ljust(max)} #{line[1]}"
37
+ end
38
+ end
39
+
40
+ def self.failure(error_output, message)
41
+ error_output.puts "fatal: #{message}\n\n"
42
+ help(error_output)
43
+ end
44
+
45
+ def self.run(input: $stdin, output: $stdout, error_output: $stderr, args: ARGV)
46
+ args = args.map do |arg|
47
+ Ned::Strings.unescape!(arg.dup)
48
+ end
49
+
50
+ if args.include?('--help')
51
+ help(error_output)
52
+ return 0
53
+ end
54
+
55
+ if args.include?('--version')
56
+ output.puts("Ned version #{Ned::VERSION}")
57
+ return 0
58
+ end
59
+
60
+ inputs = []
61
+ while args.first && !args.first.match(/^-./)
62
+ arg = args.shift
63
+
64
+ if arg == '-'
65
+ inputs << input
66
+ else
67
+ unless File.exist?(arg)
68
+ failure(error_output, "no such file: #{arg}")
69
+ return 1
70
+ end
71
+ inputs << arg
72
+ end
73
+ end
74
+
75
+ if input.tty? && (inputs.empty? || (inputs.size == 1 && inputs[0] == input))
76
+ failure(error_output, 'no input')
77
+ return 1
78
+ end
79
+
80
+ inputs = inputs.unshift(input) if !input.tty? && !inputs.index(input)
81
+
82
+ if inputs.count(input) > 1
83
+ failure(error_output, "can't read from standard in twice, silly")
84
+ return 1
85
+ end
86
+
87
+ if inputs.size > 1
88
+ failure(error_output, "more than one input not yet supported")
89
+ return 1
90
+ end
91
+
92
+ commands = []
93
+
94
+ while arg = args.shift
95
+ config = Ned::Config.all.find do |config|
96
+ arg.start_with?(config.short) || arg == config.long || arg.start_with?("#{config.long}=")
97
+ end
98
+
99
+ unless config
100
+ failure(error_output, "invalid option: #{arg}")
101
+ return 1
102
+ end
103
+
104
+ params = []
105
+
106
+ if arg.start_with?("#{config.long}=")
107
+ params << arg["#{config.long}=".size..-1]
108
+ elsif arg.start_with?(config.short) && arg != config.short
109
+ params << arg[config.short.size..-1]
110
+ else
111
+ while !args.empty? && !args.first.start_with?('-')
112
+ arg = args.shift
113
+ if arg.start_with? '\\-'
114
+ arg = arg[1..-1]
115
+ end
116
+ params << arg
117
+ end
118
+ end
119
+
120
+ valid = config.validate(*params)
121
+ if valid.nil?
122
+ if config.params.nil?
123
+ failure(error_output, "invalid param for #{config.name}. found: #{params}, expected none")
124
+ return 1
125
+ else
126
+ failure(error_output, "invalid param for #{config.name}. found: #{params}, expected: #{config.params}")
127
+ return 1
128
+ end
129
+ end
130
+
131
+ commands << Ned::Command.new(config, valid)
132
+ end
133
+
134
+ if commands.any?(&:all?)
135
+ lines = inputs.flat_map do |i|
136
+ if i.is_a? String
137
+ IO.readlines(i, sep="\n")
138
+ else
139
+ i.readlines(sep="\n")
140
+ end
141
+ end
142
+ process_all(commands, lines, output)
143
+ else
144
+ process_each(commands, inputs, output)
145
+ end
146
+
147
+ 0
148
+ end
149
+
150
+ def self.process_all(commands, lines, output)
151
+ final_newline = lines[-1]&.[](-1) == "\n" ? "\n" : ''
152
+
153
+ lines = lines.map { |line| line.chomp("\n") }
154
+ context = Context.new(lines, 0)
155
+ commands.each do |command|
156
+ command.execute(context)
157
+ end
158
+ last = context.lines.length - 1
159
+ context.lines.each_with_index do |line, index|
160
+ output.print "#{line}#{index == last ? final_newline : "\n"}"
161
+ end
162
+ end
163
+
164
+ def self.process_each(commands, inputs, output)
165
+ input = inputs[0]
166
+
167
+ if input.is_a? String
168
+ input = File.open(input)
169
+ end
170
+
171
+ current = input.gets(sep="\n")
172
+ next_line = input.gets(sep="\n")
173
+ index = 0
174
+
175
+ while current
176
+ final_newline = current[-1]&.[](-1) == "\n" ? "\n" : ''
177
+ context = Context.new([current.chomp("\n")], index)
178
+ commands.each do |command|
179
+ command.execute(context)
180
+ end
181
+ index = context.start_index + context.lines.size
182
+ last = context.lines.length - 1
183
+ context.lines.each_with_index do |line, index|
184
+ output.print "#{line}#{index == last && next_line.nil? ? final_newline : "\n"}"
185
+ end
186
+
187
+ current = next_line
188
+ next_line = input.gets(sep="\n")
189
+ end
190
+
191
+ input.close
192
+ end
193
+ end
data/ned.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/ned/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "ned"
7
+ spec.version = Ned::VERSION
8
+ spec.authors = ["Nick Dower"]
9
+ spec.email = ["nicholasdower@gmail.com"]
10
+
11
+ spec.summary = "A command line editor."
12
+ spec.description = "A command line editor"
13
+ spec.homepage = "https://github.com/nicholasdower/ned"
14
+ spec.license = "MIT"
15
+
16
+ spec.metadata["homepage_uri"] = spec.homepage
17
+ spec.metadata["source_code_uri"] = "https://github.com/nicholasdower/ned"
18
+ spec.metadata["changelog_uri"] = "https://github.com/nicholasdower/ned/releases"
19
+
20
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
21
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
22
+ end
23
+ spec.bindir = 'bin'
24
+ spec.executables << 'ned'
25
+ spec.require_paths = ["lib"]
26
+ end
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ puts <<~EOF
4
+ # Ned
5
+
6
+ ```
7
+ #{`bundle exec ned --help 2>&1`}```
8
+ EOF
data/scripts/release ADDED
@@ -0,0 +1,31 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ if [ $# -ne 1 ]; then
6
+ echo "usage: $0 <version>" >&2
7
+ exit 1
8
+ fi
9
+
10
+ if [ -n "$(git status --porcelain)" ]; then
11
+ echo "error: stage or commit your changes." >&2
12
+ exit 1;
13
+ fi
14
+
15
+ NEW_VERSION=$1
16
+ CURRENT_VERSION=$(grep VERSION lib/ned/version.rb | cut -d'"' -f 2)
17
+
18
+ ./scripts/test
19
+
20
+ echo "Updating from v$CURRENT_VERSION to v$NEW_VERSION. Press enter to continue."
21
+ read
22
+
23
+ sed -E -i '' "s/VERSION = \"[^\"]+\"/VERSION = \"$NEW_VERSION\"/g" lib/ned/version.rb
24
+
25
+ ./scripts/generate_readme > README.md
26
+
27
+ gem build
28
+ gem push ned-$NEW_VERSION.gem
29
+ bundle install
30
+ git commit -a -m "v$NEW_VERSION Release"
31
+ open "https://github.com/nicholasdower/ned/releases/new?title=v$NEW_VERSION%20Release&tag=v$NEW_VERSION&target=$(git rev-parse HEAD)"
data/scripts/test ADDED
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+
3
+ bundle exec rspec
data/todo ADDED
@@ -0,0 +1,15 @@
1
+ add support for a ~/.ned/ dir
2
+ implement highlight
3
+ add color
4
+ add support for more escape sequences, see https://github.com/ruby/ruby/blob/master/doc/syntax/literals.rdoc#label-Strings
5
+ add support for operating on one or more files
6
+ add support for editing files in place
7
+ handle --
8
+ add ljust
9
+ maybe add ability to highlight columns, not just full lines
10
+ write readme
11
+ add support for to_set
12
+ add support for overriding existing commands
13
+ add support for ommitting short or long flags
14
+ add support for uniq with count?
15
+ consider giving commands a way to operate on entire line with newline. currently can't replicate tr.
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ned
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Nick Dower
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-05-29 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A command line editor
14
+ email:
15
+ - nicholasdower@gmail.com
16
+ executables:
17
+ - ned
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - ".gitignore"
22
+ - Gemfile
23
+ - Gemfile.lock
24
+ - README.md
25
+ - bin/ned
26
+ - lib/ned.rb
27
+ - lib/ned/command.rb
28
+ - lib/ned/commands/append.rb
29
+ - lib/ned/commands/backward.rb
30
+ - lib/ned/commands/grep.rb
31
+ - lib/ned/commands/head.rb
32
+ - lib/ned/commands/index.rb
33
+ - lib/ned/commands/join.rb
34
+ - lib/ned/commands/only.rb
35
+ - lib/ned/commands/prepend.rb
36
+ - lib/ned/commands/quote.rb
37
+ - lib/ned/commands/replace.rb
38
+ - lib/ned/commands/sort.rb
39
+ - lib/ned/commands/tail.rb
40
+ - lib/ned/commands/uniq.rb
41
+ - lib/ned/commands/visual.rb
42
+ - lib/ned/config.rb
43
+ - lib/ned/context.rb
44
+ - lib/ned/strings.rb
45
+ - lib/ned/validators.rb
46
+ - lib/ned/version.rb
47
+ - ned.gemspec
48
+ - scripts/generate_readme
49
+ - scripts/release
50
+ - scripts/test
51
+ - todo
52
+ homepage: https://github.com/nicholasdower/ned
53
+ licenses:
54
+ - MIT
55
+ metadata:
56
+ homepage_uri: https://github.com/nicholasdower/ned
57
+ source_code_uri: https://github.com/nicholasdower/ned
58
+ changelog_uri: https://github.com/nicholasdower/ned/releases
59
+ post_install_message:
60
+ rdoc_options: []
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ requirements: []
74
+ rubygems_version: 3.3.3
75
+ signing_key:
76
+ specification_version: 4
77
+ summary: A command line editor.
78
+ test_files: []