Skip to content

Commit

Permalink
search and replace highlighting in (hex-)editor
Browse files Browse the repository at this point in the history
  • Loading branch information
SilenZcience committed Nov 21, 2024
1 parent 5f54ffa commit 6f43d0c
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 8 deletions.
6 changes: 5 additions & 1 deletion cat_win/src/service/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -901,7 +901,7 @@ def _action_find(self) -> bool:
tmp_error = str(exc)
continue
self.cpos.set_pos(next(search))
self.search_items.append((self.cpos.row, self.cpos.col, search.s_len))
self.search_items.append((*self.cpos.get_pos(), search.s_len))
break
except StopIteration:
if self.selecting:
Expand Down Expand Up @@ -1289,6 +1289,10 @@ def _render_scr(self) -> None:
self.curse_window.clrtoeol()
self.curse_window.move(row+1, 0)
for row, col, length in self.search_items:
if row < self.wpos.row or row >= self.wpos.row+max_y:
continue
if col+length < self.wpos.col or col >= self.wpos.col+max_x:
continue
self.curse_window.chgat(row-self.wpos.row, col-self.wpos.col,
length, self._get_color(6))
self.search_items.clear()
Expand Down
45 changes: 38 additions & 7 deletions cat_win/src/service/hexeditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def __init__(self, file: Path, display_name: str) -> None:
self.edited_byte_pos = 0

self.search = ''
self.search_items = []

self.status_bar_size = 1
self.error_bar = ''
Expand Down Expand Up @@ -584,6 +585,7 @@ def find_bytes(row: int, col: int = 0) -> int:
continue
if search_result >= 0:
self.cpos.col += search_result+1-self.selecting
self.search_items.append((*self.cpos.get_pos(), len(self.search)))
break
# check rest of file until back at current line
c_row = self.cpos.row
Expand All @@ -598,6 +600,7 @@ def find_bytes(row: int, col: int = 0) -> int:
if search_result >= 0:
self.cpos.row = c_row_wrapped
self.cpos.col = search_result
self.search_items.append((*self.cpos.get_pos(), len(self.search)))
break
else:
tmp_error = 'no matches were found!'
Expand Down Expand Up @@ -890,6 +893,31 @@ def _render_highlight_selected_area(self, max_y: int) -> None:
except curses.error:
pass

def _render_search_items(self, max_y: int) -> None:
# Highlight Search Items
for row, col, length in self.search_items:
e_row = row + (col+length//2 - 1) // HexEditor.columns
e_col = (col+length//2 - 1) % HexEditor.columns

for p_row, p_col in HexEditor.pos_between((row, col), (e_row, e_col)):
if p_row < self.wpos.row or p_row >= self.wpos.row+max_y:
break
self.curse_window.chgat(p_row-self.wpos.row+2, 13 + p_col*3,
2, self._get_color(9))
self.curse_window.chgat(p_row-self.wpos.row+2, 15 + HexEditor.columns*3 + p_col,
1, self._get_color(9))
if length%2:
e_row = row + (col+length//2) // HexEditor.columns
e_col = (col+length//2) % HexEditor.columns
if e_row < self.wpos.row or e_row >= self.wpos.row+max_y:
continue
self.curse_window.chgat(e_row-self.wpos.row+2, 13 + e_col*3,
1, self._get_color(9))
self.curse_window.chgat(e_row-self.wpos.row+2, 15 + HexEditor.columns*3 + e_col,
1, self._get_color(9))

self.search_items.clear()

def _render_status_bar(self, max_y: int, max_x: int) -> None:
# Draw status/error_bar
try:
Expand Down Expand Up @@ -932,6 +960,7 @@ def _render_scr(self) -> None:
self._render_highlight_selection()
self._render_highlight_edits(max_y)
self._render_highlight_selected_area(max_y)
self._render_search_items(max_y)
self._render_status_bar(max_y, max_x)

self.curse_window.refresh()
Expand Down Expand Up @@ -996,21 +1025,23 @@ def _init_screen(self) -> None:
if curses.can_change_color():
curses.use_default_colors()
# status_bar
curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_WHITE)
curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_WHITE )
# error_bar
curses.init_pair(2, curses.COLOR_RED , curses.COLOR_WHITE)
curses.init_pair(2, curses.COLOR_RED , curses.COLOR_WHITE )
# prompts
curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_RED )
curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_RED )
# selected byte
curses.init_pair(4, curses.COLOR_BLACK, curses.COLOR_WHITE)
curses.init_pair(4, curses.COLOR_BLACK, curses.COLOR_WHITE )
# edited byte
curses.init_pair(5, curses.COLOR_RED , curses.COLOR_BLACK)
curses.init_pair(5, curses.COLOR_RED , curses.COLOR_BLACK )
# selected and edited byte
curses.init_pair(6, curses.COLOR_RED , curses.COLOR_WHITE)
curses.init_pair(6, curses.COLOR_RED , curses.COLOR_WHITE )
# selected area
curses.init_pair(7, curses.COLOR_BLACK, curses.COLOR_YELLOW)
# selected area and edited byte
curses.init_pair(8, curses.COLOR_RED, curses.COLOR_YELLOW)
curses.init_pair(8, curses.COLOR_RED , curses.COLOR_YELLOW)
# find (& replace)
curses.init_pair(9, curses.COLOR_WHITE, curses.COLOR_BLUE )
curses.raw()
self.curse_window.nodelay(False)

Expand Down

0 comments on commit 6f43d0c

Please sign in to comment.