From 9a978e23e17ffb2c94e5733b6ee9cd093ec6a743 Mon Sep 17 00:00:00 2001 From: Augusto Gunsch Date: Tue, 15 Nov 2022 18:27:47 +0100 Subject: [PATCH] Fix issues --- README.md | 26 +++++++++++++++++++++----- setup.cfg | 2 +- src/subprompt/subprompt.py | 32 ++++++++++++++++++-------------- 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 543a107..06c4580 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,25 @@ # subprompt -Substitute every match of a regex in multiple files - with confirmation prompts. Usage: -``` -subprompt [REGEX] [SUB] [FILES...] -``` -Install it through PyPi: +Interactively change every line matching a regex in multiple files. + +## Installation +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) +``` diff --git a/setup.cfg b/setup.cfg index 7a7d79e..a3dcc35 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = subprompt -version = 0.0.5 +version = 0.0.6 author = Augusto Lenz Gunsch author_email = augusto@augustogunsch.com description = Substitute Regex in files with prompt confirmation diff --git a/src/subprompt/subprompt.py b/src/subprompt/subprompt.py index b40283a..59eefd5 100644 --- a/src/subprompt/subprompt.py +++ b/src/subprompt/subprompt.py @@ -41,13 +41,13 @@ class Filter: self.regex = re.compile(args.regex) self.sub = args.r self.delete = args.d - self.spread = args.n + self.spread = args.n+1 self.lines_to_delete = [] def _number_lines(_, lines, start_n): return [Fore.YELLOW + Style.BRIGHT + - str(n + start_n) + + str(n + start_n + 1) + Fore.RESET + Style.RESET_ALL + ':' + line for (n, line) in enumerate(lines)] @@ -74,33 +74,34 @@ class Filter: return replaced_match 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] highlighted = line.replace(curr_match, Back.RED + curr_match + Back.RESET) cut_highlighted = cut - cut_highlighted[line_n] = highlighted + cut_highlighted[rel_line_n] = highlighted cut_highlighted = self._number_lines(cut_highlighted, start_n) cut_replaced = cut 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) else: - cut_replaced.pop(line_n) + cut_replaced.pop(rel_line_n) cut_replaced = self._number_lines(cut_replaced, start_n) print(Fore.GREEN + Style.BRIGHT + fname) - print('\n'.join(cut_highlighted)) + print(''.join(cut_highlighted)) print('Becomes the following:') - print('\n'.join(cut_replaced)) - print() + print(''.join(cut_replaced)) + while True: answer = input('Confirm the change? [Y/n/a/q] ').lower() @@ -135,7 +136,7 @@ class Filter: with open(fname, 'r') as file: contents = file.read() - lines = contents.splitlines() + lines = contents.splitlines(keepends=True) lines = [ self.regex.sub( @@ -145,10 +146,13 @@ class Filter: for (line_n, line) in enumerate(lines) ] - for line in reversed(self.lines_to_delete): - lines.pop(line) + if self.delete: + 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_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('-r', help='replace match with expression', 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)