Fix issues

This commit is contained in:
Augusto Gunsch 2022-11-15 18:27:47 +01:00
parent b57e0b0597
commit 9a978e23e1
No known key found for this signature in database
GPG Key ID: F7EEFE29825C72DC
3 changed files with 40 additions and 20 deletions

View File

@ -1,9 +1,25 @@
# subprompt # subprompt
Substitute every match of a regex in multiple files - with confirmation prompts. Usage: Interactively change every line matching a regex in multiple files.
```
subprompt [REGEX] [SUB] [FILES...] ## Installation
``` Through PyPI:
Install it through PyPi:
``` ```
python3.9 -m pip install subprompt python3.9 -m pip install subprompt
``` ```
## Usage
```
usage: subprompt.py [-h] (-d | -r R) [-n N] REGEX FILES [FILES ...]
Modifies lines matched by a regex interactively
positional arguments:
REGEX
FILES
optional arguments:
-h, --help show this help message and exit
-d delete line
-r R replace match with expression
-n N size of lines preview (default=3)
```

View File

@ -1,6 +1,6 @@
[metadata] [metadata]
name = subprompt name = subprompt
version = 0.0.5 version = 0.0.6
author = Augusto Lenz Gunsch author = Augusto Lenz Gunsch
author_email = augusto@augustogunsch.com author_email = augusto@augustogunsch.com
description = Substitute Regex in files with prompt confirmation description = Substitute Regex in files with prompt confirmation

View File

@ -41,13 +41,13 @@ class Filter:
self.regex = re.compile(args.regex) self.regex = re.compile(args.regex)
self.sub = args.r self.sub = args.r
self.delete = args.d self.delete = args.d
self.spread = args.n self.spread = args.n+1
self.lines_to_delete = [] self.lines_to_delete = []
def _number_lines(_, lines, start_n): def _number_lines(_, lines, start_n):
return [Fore.YELLOW + Style.BRIGHT + return [Fore.YELLOW + Style.BRIGHT +
str(n + start_n) + str(n + start_n + 1) +
Fore.RESET + Style.RESET_ALL + Fore.RESET + Style.RESET_ALL +
':' + line ':' + line
for (n, line) in enumerate(lines)] for (n, line) in enumerate(lines)]
@ -74,33 +74,34 @@ class Filter:
return replaced_match return replaced_match
start_n = max(0, line_n - self.spread) start_n = max(0, line_n - self.spread)
end_n = min(len(lines), line_n + self.spread) end_n = min(len(lines)+1, line_n + self.spread)
rel_line_n = line_n-start_n
cut = lines[start_n:end_n] cut = lines[start_n:end_n]
highlighted = line.replace(curr_match, highlighted = line.replace(curr_match,
Back.RED + curr_match + Back.RESET) Back.RED + curr_match + Back.RESET)
cut_highlighted = cut cut_highlighted = cut
cut_highlighted[line_n] = highlighted cut_highlighted[rel_line_n] = highlighted
cut_highlighted = self._number_lines(cut_highlighted, start_n) cut_highlighted = self._number_lines(cut_highlighted, start_n)
cut_replaced = cut cut_replaced = cut
if not self.delete: if not self.delete:
cut_replaced[line_n] = line.replace(curr_match, cut_replaced[rel_line_n] = line.replace(curr_match,
Back.YELLOW + Fore.BLACK + replaced_match + Back.RESET + Fore.RESET) Back.YELLOW + Fore.BLACK + replaced_match + Back.RESET + Fore.RESET)
else: else:
cut_replaced.pop(line_n) cut_replaced.pop(rel_line_n)
cut_replaced = self._number_lines(cut_replaced, start_n) cut_replaced = self._number_lines(cut_replaced, start_n)
print(Fore.GREEN + Style.BRIGHT + fname) print(Fore.GREEN + Style.BRIGHT + fname)
print('\n'.join(cut_highlighted)) print(''.join(cut_highlighted))
print('Becomes the following:') print('Becomes the following:')
print('\n'.join(cut_replaced))
print() print()
print(''.join(cut_replaced))
while True: while True:
answer = input('Confirm the change? [Y/n/a/q] ').lower() answer = input('Confirm the change? [Y/n/a/q] ').lower()
@ -135,7 +136,7 @@ class Filter:
with open(fname, 'r') as file: with open(fname, 'r') as file:
contents = file.read() contents = file.read()
lines = contents.splitlines() lines = contents.splitlines(keepends=True)
lines = [ lines = [
self.regex.sub( self.regex.sub(
@ -145,10 +146,13 @@ class Filter:
for (line_n, line) in enumerate(lines) for (line_n, line) in enumerate(lines)
] ]
for line in reversed(self.lines_to_delete): if self.delete:
lines.pop(line) for line in reversed(self.lines_to_delete):
lines.pop(line)
new_contents = '\n'.join(lines) self.lines_to_delete = []
new_contents = ''.join(lines)
hash_old = hashlib.md5(contents.encode()) hash_old = hashlib.md5(contents.encode())
hash_new = hashlib.md5(new_contents.encode()) hash_new = hashlib.md5(new_contents.encode())
@ -165,7 +169,7 @@ def run(args):
action.add_argument('-d', help='delete line', action='store_true') action.add_argument('-d', help='delete line', action='store_true')
action.add_argument('-r', help='replace match with expression', type=str) action.add_argument('-r', help='replace match with expression', type=str)
parser.add_argument('files', metavar='FILES', nargs='+', type=str) parser.add_argument('files', metavar='FILES', nargs='+', type=str)
parser.add_argument('-n', help='size lines preview (default=3)', type=int, default=3) parser.add_argument('-n', help='size of lines preview (default=3)', type=int, default=3)
args = parser.parse_args(args) args = parser.parse_args(args)