cmdline-sub 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/README +11 -3
  3. data/Rakefile +1 -0
  4. data/bin/sub +65 -75
  5. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2fd227736fa0bc8d59c84b1909f3c7abfd63ec86325a855ae5e4e2302693f35b
4
- data.tar.gz: 84c336782e6d58eddba82d06874809d22074c968fd94a82c61a88043d922bb52
3
+ metadata.gz: f8333cc1f6aa8e4eb3b47299c6038d0c04d26b9b0b8e4b2292e54906fc9e766d
4
+ data.tar.gz: 2b6fa1a2ef48f3ff9fec5aa017c7e4ef94e977085f424e64a4c9378822dc0a4b
5
5
  SHA512:
6
- metadata.gz: e1955cee9482f5b650924d6302185519553bc82dc9959b28449e57c5bb2f5527e2553eb18be60fe5a7f8cb9d752d5baf68709bab3448b66dfda3d196b2ad51e5
7
- data.tar.gz: 9435447e39679f02f4e2365faa2c01cd2b7e9fb3ca88388e5d894b913c6edf5885fde6a32504e85cd4da29d75a8c0395ae265dbdd3d5917265ca4fc3dd4116e8
6
+ metadata.gz: 3b162147e9a995230fdb3744963af0fa237ec96fe9f6088b561ce82de7a7a6d338096715dda296f2ad5c6060d2d3e826017aa346c283cb79662723884acd64c6
7
+ data.tar.gz: 2bb7d2a20e123d67ddb0ee09e8c2de7b7e0e46d6a39d31b3364df381b9f9481d15020df0096a0edc0b140b5a3d8ebae97926717f8cb2609fa5f7ea9861f40a41
data/README CHANGED
@@ -1,8 +1,8 @@
1
1
  Sub
2
2
  ===
3
3
 
4
- sub v0.1.0
5
- Usage: sub COMMANDLINE -- (PATTERN/SUBSTITUTION[/SUB_OPTIONS])+ (/GLOBAL_OPTIONS)?
4
+ sub v0.1.2
5
+ Usage: sub COMMANDLINE -- (PATTERN/SUBSTITUTION[/SUB_FLAGS])+ (/GLOBAL_FLAGS)?
6
6
 
7
7
  sub substitutes the matching pattern in every word in the command line with the
8
8
  substitution. Only the first matched pattern in the word is substituted unless
@@ -56,13 +56,19 @@ Substitution flags:
56
56
  -e: Expand * in commandline after replacements are made
57
57
  ex: sub ls mydir -- mydir/*/e #=> ls bin README
58
58
  Global flags:
59
- -p: Print the command instead of executing it
59
+ -p: Print the command instead of executing it (adds newline)
60
+ -P: Print the command instead of executing it (doesn't add newline)
60
61
  -c: Copy the command to clipboard instead of executing it
61
62
  -I: Set interactive mode: shows the command and asks if you want to execute it
62
63
  -v: Set verbose mode
63
64
  -D: Set debug mode
65
+ Other flags:
66
+ -h,--help: Show help (-h shows short help, --help shows full)
67
+ -v,--version: Show version followed by a newline
64
68
 
65
69
  Install:
70
+ gem install cmdline-sub
71
+ or:
66
72
  cd $HOME
67
73
  git clone git@github.com:luke-gru/sub.git
68
74
  cd sub
@@ -71,6 +77,8 @@ Install:
71
77
  # INSTALL_PREFIX="/bin" sudo rake install
72
78
 
73
79
  Uninstall:
80
+ gem uninstall cmdline-sub
81
+ or:
74
82
  cd $HOME/sub
75
83
  sudo rake uninstall # removes /usr/local/bin/sub
76
84
  # or
data/Rakefile CHANGED
@@ -57,6 +57,7 @@ end
57
57
 
58
58
  desc "Uninstall (removes /usr/local/bin/sub or $(INSTALL_PREFIX)/sub). Use sudo if necessary."
59
59
  task :uninstall do
60
+ require "fileutils"
60
61
  install_dir = ENV["INSTALL_PREFIX"] || "/usr/local/bin"
61
62
  unless File.directory?(install_dir)
62
63
  $stderr.puts "Directory #{install_dir} does not exist. Uninstall failed."
data/bin/sub CHANGED
@@ -2,10 +2,14 @@
2
2
  # vim: set ft=ruby
3
3
  # frozen_string_literal: true
4
4
 
5
- VERSION = "0.1.1"
5
+ if ENV["TESTING_SUB_CMD"] == "1" && ENV["DEBUGGING_SUB_CMD"] == "1"
6
+ require "debug"
7
+ end
8
+
9
+ VERSION = "0.1.2"
6
10
 
7
11
  USAGE = <<EOF
8
- Usage: sub COMMANDLINE -- (PATTERN/SUBSTITUTION[/SUB_OPTIONS])+ (/GLOBAL_OPTIONS)?
12
+ Usage: sub COMMANDLINE -- (PATTERN/SUBSTITUTION[/SUB_FLAGS])+ (/GLOBAL_FLAGS)?
9
13
 
10
14
  sub substitutes the matching pattern in every word in the command line with the
11
15
  substitution. Only the first matched pattern in the word is substituted unless
@@ -46,6 +50,8 @@ EOF
46
50
 
47
51
  INSTALLATION = <<EOF
48
52
  Install:
53
+ \t gem install cmdline-sub
54
+ or:
49
55
  \tcd $HOME
50
56
  \tgit clone git@github.com:luke-gru/sub.git
51
57
  \tcd sub
@@ -56,6 +62,8 @@ EOF
56
62
 
57
63
  UNINSTALLATION = <<EOF
58
64
  Uninstall:
65
+ \t gem uninstall cmdline-sub
66
+ or:
59
67
  \tcd $HOME/sub
60
68
  \tsudo rake uninstall # removes /usr/local/bin/sub
61
69
  \t# or
@@ -64,7 +72,7 @@ EOF
64
72
 
65
73
  LICENSE = "License: MIT"
66
74
 
67
- FLAGS = [
75
+ SUB_FLAGS = [
68
76
  # per substitution flags
69
77
  { flag: 'f', name: :first_match, desc: "Substitute first matching word only.",
70
78
  example: "sub wget https://wget.com -- wget/curl/f #=> curl https://wget.com",
@@ -84,7 +92,8 @@ FLAGS = [
84
92
  { flag: 'e', name: :expand_star, desc: "Expand * in commandline after replacements are made",
85
93
  example: [ "sub ls mydir -- mydir/*/e #=> ls bin README" ]
86
94
  },
87
- nil, # separator
95
+ ]
96
+ GLOBAL_FLAGS = [
88
97
  # global flags
89
98
  { flag: 'p', name: :print_only, desc: "Print the command instead of executing it (adds newline)" },
90
99
  { flag: 'P', name: :print_only_no_newline, desc: "Print the command instead of executing it (doesn't add newline)" },
@@ -93,28 +102,26 @@ FLAGS = [
93
102
  { flag: 'v', name: :verbose, desc: "Set verbose mode" },
94
103
  { flag: 'D', name: :debug, desc: "Set debug mode" },
95
104
  ]
96
- GLOBAL_FLAGS_MAP = {
97
- print_only: 'p',
98
- print_only_no_newline: 'P',
99
- copy_to_clipboard: 'c',
100
- interactive: 'I',
101
- verbose: 'v',
102
- debug: 'D',
103
- }
104
- GLOBAL_FLAGS = GLOBAL_FLAGS_MAP.values
105
+ OTHER_FLAGS = [
106
+ { flag: ['h', '--help'], name: :help, desc: "Show help (-h shows short help, --help shows full)", },
107
+ { flag: ['v', '--version'], name: :version, desc: "Show version followed by a newline" },
108
+ ]
109
+ FLAGS = SUB_FLAGS + GLOBAL_FLAGS + OTHER_FLAGS
110
+ FLAGS_BY_NAME = FLAGS.map do |f|
111
+ { f[:name] => f[:flag] }
112
+ end.inject(Hash.new) { |memo, h| memo.merge(h) }
113
+ GLOBAL_FLAGS_BY_NAME = GLOBAL_FLAGS.map do |f|
114
+ { f[:name] => f[:flag] }
115
+ end.inject(Hash.new) { |memo, h| memo.merge(h) }
116
+ RAW_GLOBAL_FLAGS = GLOBAL_FLAGS_BY_NAME.values
105
117
 
106
118
  def print_help(full: true)
107
119
  output = String.new
108
120
  output << "sub v#{VERSION}" << "\n"
109
121
  output << USAGE << "\n"
110
- output << "Flags:\n\n"
111
- output << "Substitution flags:\n"
112
- FLAGS.each do |fhash|
113
- if fhash.nil?
114
- output << "Global flags:\n"
115
- next
116
- end
117
- output << "-#{fhash[:flag]}:\t#{fhash[:desc]}\n"
122
+ output_flag_info = lambda do |fhash|
123
+ flags = Array(fhash[:flag])
124
+ output << "-#{flags.join(',')}:\t#{fhash[:desc]}\n"
118
125
  if ex = fhash[:example]
119
126
  case ex
120
127
  when String
@@ -126,6 +133,13 @@ def print_help(full: true)
126
133
  end
127
134
  end
128
135
  end
136
+ output << "Flags:\n\n"
137
+ output << "Substitution flags:\n"
138
+ SUB_FLAGS.each(&output_flag_info)
139
+ output << "Global flags:\n"
140
+ GLOBAL_FLAGS.each(&output_flag_info)
141
+ output << "Other flags:\n"
142
+ OTHER_FLAGS.each(&output_flag_info)
129
143
  if full
130
144
  output << "\n" << INSTALLATION
131
145
  output << "\n" << UNINSTALLATION
@@ -142,11 +156,8 @@ def parse_argv_and_sub_strs(argv)
142
156
  ret_argv = []
143
157
  sub_strs = []
144
158
  if argv.size == 0
145
- require "readline"
146
- line = Readline.readline "cmd: ", true
147
- ret_argv.replace line.strip.split(/\s+/)
148
- line = Readline.readline "pat/sub[/options]: ", true
149
- sub_strs << line.strip
159
+ print_help(full: true)
160
+ exit 1
150
161
  else
151
162
  last_dashdash_idx = argv.rindex('--')
152
163
  argv.each_with_index do |arg, i|
@@ -178,26 +189,28 @@ end
178
189
 
179
190
  argv, sub_strs = parse_argv_and_sub_strs(ARGV)
180
191
 
181
- def flag(flags_str, char)
192
+ def parse_simple_flag!(flags_str, char)
182
193
  flag = flags_str.include?(char)
183
194
  flags_str.delete!(char)
184
195
  flag
185
196
  end
186
197
 
187
198
  def flag_by_name(name)
188
- FLAGS.each do |fhash|
189
- next if fhash.nil?
190
- if fhash[:name] == name
191
- return fhash[:flag]
192
- end
193
- end
194
- raise ArgumentError, "bad flag: #{name}"
199
+ FLAGS_BY_NAME.fetch(name)
195
200
  end
196
201
 
197
- def raw_global_options?(raw_flags)
202
+ def raw_global_flags?(raw_flags)
198
203
  raw_flags = raw_flags.strip
199
204
  return false if raw_flags.empty?
200
- raw_flags.gsub(Regexp.new(GLOBAL_FLAGS.join('|')), '').empty?
205
+ raw_flags.gsub(Regexp.new(RAW_GLOBAL_FLAGS.join('|')), '').empty?
206
+ end
207
+
208
+ def parse_global_flag!(name, flags, global_flags)
209
+ if global_flags[name]
210
+ flags.delete!(GLOBAL_FLAGS_BY_NAME[name])
211
+ else
212
+ global_flags[name] = parse_simple_flag!(flags, flag_by_name(name))
213
+ end
201
214
  end
202
215
 
203
216
  def parse_sub_strs(sub_strs)
@@ -205,11 +218,11 @@ def parse_sub_strs(sub_strs)
205
218
  pats = []
206
219
  subs = []
207
220
  match_flags = []
208
- global_flags = GLOBAL_FLAGS_MAP.transform_values { nil }
221
+ global_flags = GLOBAL_FLAGS_BY_NAME.transform_values { nil }
209
222
  raw_flags = []
210
223
  sub_strs.each_with_index do |sub_str, sub_i|
211
224
  # global flags at end of substitutions list, starts with /, ex: /o
212
- if sub_strs[sub_i+1].nil? && sub_str[0] == '/' && raw_global_options?(sub_str[1..-1])
225
+ if sub_strs[sub_i+1].nil? && sub_str[0] == '/' && raw_global_flags?(sub_str[1..-1])
213
226
  flags = sub_str[1..-1]
214
227
  else
215
228
  pat, sub, flags = sub_str.split(/(?<!\\)\//)
@@ -219,48 +232,24 @@ def parse_sub_strs(sub_strs)
219
232
  flags.strip!
220
233
  raw_flags << flags.dup
221
234
  flags_hash = {
222
- first_match: flag(flags, flag_by_name(:first_match)),
223
- last_match: flag(flags, flag_by_name(:last_match)),
224
- expand_star: flag(flags, flag_by_name(:expand_star)),
225
- literal: flag(flags, flag_by_name(:literal)),
226
- ignorecase: flag(flags, flag_by_name(:ignorecase)),
227
- general: flag(flags, flag_by_name(:general)),
235
+ first_match: parse_simple_flag!(flags, flag_by_name(:first_match)),
236
+ last_match: parse_simple_flag!(flags, flag_by_name(:last_match)),
237
+ expand_star: parse_simple_flag!(flags, flag_by_name(:expand_star)),
238
+ literal: parse_simple_flag!(flags, flag_by_name(:literal)),
239
+ ignorecase: parse_simple_flag!(flags, flag_by_name(:ignorecase)),
240
+ general: parse_simple_flag!(flags, flag_by_name(:general)),
228
241
  }
229
242
  pats << pat
230
243
  subs << sub
231
244
  match_flags << flags_hash
232
245
  end
233
246
 
234
- if global_flags[:interactive]
235
- flags.delete!(GLOBAL_FLAGS_MAP[:interactive])
236
- else
237
- global_flags[:interactive] = flag(flags, flag_by_name(:interactive)) || ARGV.size == 0
238
- end
239
- if global_flags[:print_only]
240
- flags.delete!(GLOBAL_FLAGS_MAP[:print_only])
241
- else
242
- global_flags[:print_only] = flag(flags, flag_by_name(:print_only))
243
- end
244
- if global_flags[:print_only_no_newline]
245
- flags.delete!(GLOBAL_FLAGS_MAP[:print_only_no_newline])
246
- else
247
- global_flags[:print_only_no_newline] = flag(flags, flag_by_name(:print_only_no_newline))
248
- end
249
- if global_flags[:copy_to_clipboard]
250
- flags.delete!(GLOBAL_FLAGS_MAP[:copy_to_clipboard])
251
- else
252
- global_flags[:copy_to_clipboard] = flag(flags, flag_by_name(:copy_to_clipboard))
253
- end
254
- if global_flags[:verbose]
255
- flags.delete!(GLOBAL_FLAGS_MAP[:verbose])
256
- else
257
- global_flags[:verbose] = flag(flags, flag_by_name(:verbose))
258
- end
259
- if global_flags[:debug]
260
- flags.delete!(GLOBAL_FLAGS_MAP[:debug])
261
- else
262
- global_flags[:debug] = flag(flags, flag_by_name(:debug))
263
- end
247
+ parse_global_flag!(:interactive, flags, global_flags)
248
+ parse_global_flag!(:print_only, flags, global_flags)
249
+ parse_global_flag!(:print_only_no_newline, flags, global_flags)
250
+ parse_global_flag!(:copy_to_clipboard, flags, global_flags)
251
+ parse_global_flag!(:verbose, flags, global_flags)
252
+ parse_global_flag!(:debug, flags, global_flags)
264
253
  unless flags.empty?
265
254
  $stderr.puts "Warning: unknown flag#{'s' if flags.size != 1}: #{flags}"
266
255
  end
@@ -272,7 +261,7 @@ end
272
261
  pats, subs, flags_hashes, raw_flags, global_flags = parse_sub_strs(sub_strs)
273
262
 
274
263
  if pats.empty? && flags_hashes.empty? && global_flags.empty?
275
- $stderr.puts "Incorrect substitution, format is: pattern/substitution[/options]"
264
+ $stderr.puts "Incorrect substitution, format is: pattern/substitution[/flags]"
276
265
  exit 1
277
266
  end
278
267
 
@@ -398,6 +387,7 @@ def exec_cmd(argv, regexps, subs, raw_flags, num_replacements, global_flags)
398
387
  if global_flags.fetch(:interactive) && !global_flags.fetch(:print_only)
399
388
  $stdout.puts "Would you like to #{action} the following command? [y(es),n(o)]"
400
389
  $stdout.puts cmd_line
390
+ $stdout.flush
401
391
  ans = $stdin.gets().strip
402
392
  if ans !~ /y(es)?/i # treat as no
403
393
  exit 1
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cmdline-sub
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luke Gruber
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-11-20 00:00:00.000000000 Z
11
+ date: 2024-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: debug