Compare commits

..

No commits in common. "9616c26cb83c56e834ad2b450f8a17da6249da8d" and "de278ae0ba849c341e3e06702cc3d00443f6e29e" have entirely different histories.

4 changed files with 21 additions and 42 deletions

View File

@ -1,25 +1,9 @@
# subprompt
Interactively change every line matching a regex in multiple files.
## Installation
Through PyPI:
Substitute every match of a regex in multiple files - with confirmation prompts. Usage:
```
subprompt [REGEX] [SUB] [FILES...]
```
Install it through PyPi:
```
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,3 +1 @@
colorama==0.4.3
build==0.9.0
twine==4.0.1

View File

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

View File

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