listpick 0.1.13.29__py3-none-any.whl → 0.1.13.31__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- listpick/listpick_app.py +62 -61
- listpick/utils/utils.py +45 -24
- {listpick-0.1.13.29.dist-info → listpick-0.1.13.31.dist-info}/METADATA +1 -1
- {listpick-0.1.13.29.dist-info → listpick-0.1.13.31.dist-info}/RECORD +8 -8
- {listpick-0.1.13.29.dist-info → listpick-0.1.13.31.dist-info}/WHEEL +0 -0
- {listpick-0.1.13.29.dist-info → listpick-0.1.13.31.dist-info}/entry_points.txt +0 -0
- {listpick-0.1.13.29.dist-info → listpick-0.1.13.31.dist-info}/licenses/LICENSE.txt +0 -0
- {listpick-0.1.13.29.dist-info → listpick-0.1.13.31.dist-info}/top_level.txt +0 -0
listpick/listpick_app.py
CHANGED
|
@@ -140,6 +140,7 @@ class Picker:
|
|
|
140
140
|
footer_string_refresh_function: Optional[Callable] = None,
|
|
141
141
|
footer_timer: float=1,
|
|
142
142
|
get_footer_string_startup=False,
|
|
143
|
+
unicode_char_width: bool = False,
|
|
143
144
|
|
|
144
145
|
colours_start: int =0,
|
|
145
146
|
colours_end: int =-1,
|
|
@@ -256,6 +257,7 @@ class Picker:
|
|
|
256
257
|
self.footer_string_refresh_function = footer_string_refresh_function
|
|
257
258
|
self.footer_timer = footer_timer
|
|
258
259
|
self.get_footer_string_startup = get_footer_string_startup,
|
|
260
|
+
self.unicode_char_width = unicode_char_width
|
|
259
261
|
|
|
260
262
|
|
|
261
263
|
|
|
@@ -662,12 +664,13 @@ class Picker:
|
|
|
662
664
|
self.stdscr.refresh()
|
|
663
665
|
|
|
664
666
|
def draw_screen(self, indexed_items: list[Tuple[int, list[str]]], highlights: list[dict] = [{}], clear: bool = True) -> None:
|
|
667
|
+
""" Try-except wrapper for the draw_screen_() method to prevent crashes when rapidly resizing the terminal. """
|
|
665
668
|
try:
|
|
666
|
-
self.
|
|
669
|
+
self.draw_screen_(self.indexed_items, self.highlights)
|
|
667
670
|
except:
|
|
668
671
|
self.logger.warning(f"draw_screen function error")
|
|
669
|
-
|
|
670
|
-
def
|
|
672
|
+
|
|
673
|
+
def draw_screen_(self, indexed_items: list[Tuple[int, list[str]]], highlights: list[dict] = [{}], clear: bool = True) -> None:
|
|
671
674
|
""" Draw Picker screen. """
|
|
672
675
|
self.logger.debug("Draw screen.")
|
|
673
676
|
|
|
@@ -696,7 +699,7 @@ class Picker:
|
|
|
696
699
|
# rows = [v[1] for v in self.indexed_items] if len(self.indexed_items) else self.items
|
|
697
700
|
# Determine widths based only on the currently displayed indexed rows
|
|
698
701
|
rows = [v[1] for v in self.indexed_items[start_index:end_index]] if len(self.indexed_items) else self.items
|
|
699
|
-
self.column_widths = get_column_widths(rows, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w)
|
|
702
|
+
self.column_widths = get_column_widths(rows, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w, unicode_char_width=self.unicode_char_width)
|
|
700
703
|
visible_column_widths = [c for i,c in enumerate(self.column_widths) if i not in self.hidden_columns]
|
|
701
704
|
visible_columns_total_width = sum(visible_column_widths) + len(self.separator)*(len(visible_column_widths)-1)
|
|
702
705
|
|
|
@@ -795,10 +798,10 @@ class Picker:
|
|
|
795
798
|
else:
|
|
796
799
|
cell_value = self.indexed_items[row][1][col] + self.separator
|
|
797
800
|
# cell_value = cell_value[:min(cell_width, cell_max_width)-len(self.separator)]
|
|
798
|
-
cell_value = truncate_to_display_width(cell_value, min(cell_width, cell_max_width)-len(self.separator))
|
|
801
|
+
cell_value = truncate_to_display_width(cell_value, min(cell_width, cell_max_width)-len(self.separator), self.unicode_char_width)
|
|
799
802
|
cell_value = cell_value + self.separator
|
|
800
803
|
# cell_value = cell_value
|
|
801
|
-
cell_value = truncate_to_display_width(cell_value, min(cell_width, cell_max_width))
|
|
804
|
+
cell_value = truncate_to_display_width(cell_value, min(cell_width, cell_max_width), self.unicode_char_width)
|
|
802
805
|
# row_str = truncate_to_display_width(row_str_left_adj, min(w-self.startx, visible_columns_total_width))
|
|
803
806
|
self.stdscr.addstr(y, cell_pos, cell_value, curses.color_pair(self.colours_start+colour_pair_number) | curses.A_BOLD)
|
|
804
807
|
# Part of the cell is on screen
|
|
@@ -840,7 +843,7 @@ class Picker:
|
|
|
840
843
|
def draw_highlights(highlights: list[dict], idx: int, y: int, item: tuple[int, list[str]]):
|
|
841
844
|
self.logger.debug(f"function: draw_highlights()")
|
|
842
845
|
if len(highlights) == 0: return None
|
|
843
|
-
full_row_str = format_row(item[1], self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols)
|
|
846
|
+
full_row_str = format_row(item[1], self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols, self.unicode_char_width)
|
|
844
847
|
row_str = full_row_str[self.leftmost_char:]
|
|
845
848
|
for highlight in highlights:
|
|
846
849
|
if "row" in highlight:
|
|
@@ -856,13 +859,13 @@ class Picker:
|
|
|
856
859
|
continue
|
|
857
860
|
|
|
858
861
|
elif type(highlight["field"]) == type(0) and highlight["field"] not in self.hidden_columns:
|
|
859
|
-
match = re.search(highlight["match"], truncate_to_display_width(item[1][highlight["field"]], self.column_widths[highlight["field"]], centre=False), re.IGNORECASE)
|
|
862
|
+
match = re.search(highlight["match"], truncate_to_display_width(item[1][highlight["field"]], self.column_widths[highlight["field"]], centre=False, unicode_char_width=self.unicode_char_width), re.IGNORECASE)
|
|
860
863
|
if not match: continue
|
|
861
864
|
field_start = sum([width for i, width in enumerate(self.column_widths[:highlight["field"]]) if i not in self.hidden_columns]) + sum([1 for i in range(highlight["field"]) if i not in self.hidden_columns])*wcswidth(self.separator)
|
|
862
865
|
|
|
863
866
|
## We want to search the non-centred values but highlight the centred values.
|
|
864
867
|
if self.centre_in_cols:
|
|
865
|
-
tmp = truncate_to_display_width(item[1][highlight["field"]], self.column_widths[highlight["field"]], self.centre_in_cols)
|
|
868
|
+
tmp = truncate_to_display_width(item[1][highlight["field"]], self.column_widths[highlight["field"]], self.centre_in_cols, self.unicode_char_width)
|
|
866
869
|
field_start += (len(tmp) - len(tmp.lstrip()))
|
|
867
870
|
|
|
868
871
|
highlight_start = field_start + match.start()
|
|
@@ -884,11 +887,11 @@ class Picker:
|
|
|
884
887
|
item = self.indexed_items[idx]
|
|
885
888
|
y = idx - start_index + self.top_space
|
|
886
889
|
|
|
887
|
-
row_str = format_row(item[1], self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols)[self.leftmost_char:]
|
|
890
|
+
# row_str = format_row(item[1], self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols)[self.leftmost_char:]
|
|
888
891
|
# row_str = truncate_to_display_width(row_str, min(w-self.startx, visible_columns_total_width))
|
|
889
|
-
row_str_orig = format_row(item[1], self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols)
|
|
892
|
+
row_str_orig = format_row(item[1], self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols, self.unicode_char_width)
|
|
890
893
|
row_str_left_adj = clip_left(row_str_orig, self.leftmost_char)
|
|
891
|
-
row_str = truncate_to_display_width(row_str_left_adj, min(w-self.startx, visible_columns_total_width))
|
|
894
|
+
row_str = truncate_to_display_width(row_str_left_adj, min(w-self.startx, visible_columns_total_width), self.unicode_char_width)
|
|
892
895
|
# row_str = truncate_to_display_width(row_str, min(w-self.startx, visible_columns_total_width))[self.leftmost_char:]
|
|
893
896
|
|
|
894
897
|
## Display the standard row
|
|
@@ -1153,6 +1156,7 @@ class Picker:
|
|
|
1153
1156
|
"debug": self.debug,
|
|
1154
1157
|
"debug_level": self.debug_level,
|
|
1155
1158
|
"reset_colours": self.reset_colours,
|
|
1159
|
+
"unicode_char_width": self.unicode_char_width,
|
|
1156
1160
|
}
|
|
1157
1161
|
return function_data
|
|
1158
1162
|
|
|
@@ -1250,7 +1254,7 @@ class Picker:
|
|
|
1250
1254
|
while True:
|
|
1251
1255
|
h, w = stdscr.getmaxyx()
|
|
1252
1256
|
|
|
1253
|
-
choose_opts_widths = get_column_widths(options)
|
|
1257
|
+
choose_opts_widths = get_column_widths(options, unicode_char_width=self.unicode_char_width)
|
|
1254
1258
|
window_width = min(max(sum(choose_opts_widths) + 6, 50) + 6, w)
|
|
1255
1259
|
window_height = min(h//2, max(6, len(options)+3))
|
|
1256
1260
|
|
|
@@ -1405,6 +1409,8 @@ class Picker:
|
|
|
1405
1409
|
self.initialise_variables()
|
|
1406
1410
|
elif setting == "pc":
|
|
1407
1411
|
self.pin_cursor = not self.pin_cursor
|
|
1412
|
+
elif setting == "unicode":
|
|
1413
|
+
self.unicode_char_width = not self.unicode_char_width
|
|
1408
1414
|
|
|
1409
1415
|
elif setting.startswith("ft"):
|
|
1410
1416
|
if len(setting) > 2 and setting[2:].isnumeric():
|
|
@@ -1468,7 +1474,6 @@ class Picker:
|
|
|
1468
1474
|
self.draw_screen(self.indexed_items, self.highlights)
|
|
1469
1475
|
self.notification(self.stdscr, message=f"Theme {self.colour_theme_number} applied.")
|
|
1470
1476
|
|
|
1471
|
-
|
|
1472
1477
|
else:
|
|
1473
1478
|
self.user_settings = ""
|
|
1474
1479
|
return None
|
|
@@ -1702,12 +1707,10 @@ class Picker:
|
|
|
1702
1707
|
if not acceptable_data_type:
|
|
1703
1708
|
break
|
|
1704
1709
|
if not acceptable_data_type:
|
|
1705
|
-
self.draw_screen(self.indexed_items, self.highlights)
|
|
1706
1710
|
self.notification(self.stdscr, message="Error pasting data.")
|
|
1707
1711
|
return None
|
|
1708
1712
|
|
|
1709
1713
|
except:
|
|
1710
|
-
self.draw_screen(self.indexed_items, self.highlights)
|
|
1711
1714
|
self.notification(self.stdscr, message="Error pasting data.")
|
|
1712
1715
|
return None
|
|
1713
1716
|
if type(pasta) == type([]) and len(pasta) > 0 and type(pasta[0]) == type([]):
|
|
@@ -1813,6 +1816,7 @@ class Picker:
|
|
|
1813
1816
|
with self.data_lock:
|
|
1814
1817
|
self.items, self.header = tmp_items, tmp_header
|
|
1815
1818
|
self.data_ready = True
|
|
1819
|
+
self.draw_screen(self.indexed_items, self.highlights)
|
|
1816
1820
|
|
|
1817
1821
|
def save_input_history(self, file_path: str) -> bool:
|
|
1818
1822
|
""" Save input field history. Returns True if successful save. """
|
|
@@ -1977,7 +1981,7 @@ class Picker:
|
|
|
1977
1981
|
initial_time = time.time()
|
|
1978
1982
|
|
|
1979
1983
|
try:
|
|
1980
|
-
self.draw_screen(self.indexed_items, self.highlights, clear=
|
|
1984
|
+
self.draw_screen(self.indexed_items, self.highlights, clear=True)
|
|
1981
1985
|
except:
|
|
1982
1986
|
pass
|
|
1983
1987
|
|
|
@@ -2099,6 +2103,7 @@ class Picker:
|
|
|
2099
2103
|
options += [["rh", "Toggle row header"]]
|
|
2100
2104
|
options += [["modes", "Toggle modes"]]
|
|
2101
2105
|
options += [["ft", "Cycle through footer styles (accepts ft#)"]]
|
|
2106
|
+
options += [["unicode", "Toggle b/w using len and wcwidth to calculate char width."]]
|
|
2102
2107
|
options += [[f"s{i}", f"Select col. {i}"] for i in range(len(self.items[0]))]
|
|
2103
2108
|
options += [[f"!{i}", f"Toggle col. {i}"] for i in range(len(self.items[0]))]
|
|
2104
2109
|
options += [["ara", "Add empty row after cursor."]]
|
|
@@ -2203,8 +2208,6 @@ class Picker:
|
|
|
2203
2208
|
if new_pos < len(self.indexed_items):
|
|
2204
2209
|
self.cursor_pos = new_pos
|
|
2205
2210
|
|
|
2206
|
-
self.draw_screen(self.indexed_items, self.highlights)
|
|
2207
|
-
|
|
2208
2211
|
elif self.check_key("cursor_bottom", key, self.keys_dict):
|
|
2209
2212
|
new_pos = len(self.indexed_items)-1
|
|
2210
2213
|
while True:
|
|
@@ -2212,12 +2215,7 @@ class Picker:
|
|
|
2212
2215
|
else: break
|
|
2213
2216
|
if new_pos < len(self.items) and new_pos >= 0:
|
|
2214
2217
|
self.cursor_pos = new_pos
|
|
2215
|
-
|
|
2216
|
-
# current_row = items_per_page - 1
|
|
2217
|
-
# if current_page + 1 == (len(self.indexed_items) + items_per_page - 1) // items_per_page:
|
|
2218
|
-
#
|
|
2219
|
-
# current_row = (len(self.indexed_items) +items_per_page - 1) % items_per_page
|
|
2220
|
-
# self.draw_screen(self.indexed_items, self.highlights)
|
|
2218
|
+
|
|
2221
2219
|
elif self.check_key("enter", key, self.keys_dict):
|
|
2222
2220
|
self.logger.info(f"key_function enter")
|
|
2223
2221
|
# Print the selected indices if any, otherwise print the current index
|
|
@@ -2297,7 +2295,6 @@ class Picker:
|
|
|
2297
2295
|
if len(self.indexed_items) > 0:
|
|
2298
2296
|
current_index = self.indexed_items[self.cursor_pos][0]
|
|
2299
2297
|
sort_items(self.indexed_items, sort_method=self.columns_sort_method[self.sort_column], sort_column=self.sort_column, sort_reverse=self.sort_reverse[self.sort_column]) # Re-sort self.items based on new column
|
|
2300
|
-
self.draw_screen(self.indexed_items, self.highlights)
|
|
2301
2298
|
self.cursor_pos = [row[0] for row in self.indexed_items].index(current_index)
|
|
2302
2299
|
self.logger.info(f"key_function cycle_sort_order. (sort_column, sort_method, sort_reverse) = ({self.sort_column}, {self.columns_sort_method[self.sort_column]}, {self.sort_reverse[self.sort_column]})")
|
|
2303
2300
|
elif self.check_key("col_select", key, self.keys_dict):
|
|
@@ -2321,7 +2318,7 @@ class Picker:
|
|
|
2321
2318
|
|
|
2322
2319
|
## Scroll with column select
|
|
2323
2320
|
rows = self.get_visible_rows()
|
|
2324
|
-
self.column_widths = get_column_widths(rows, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w)
|
|
2321
|
+
self.column_widths = get_column_widths(rows, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w, unicode_char_width=self.unicode_char_width)
|
|
2325
2322
|
visible_column_widths = [c for i,c in enumerate(self.column_widths) if i not in self.hidden_columns]
|
|
2326
2323
|
column_set_width = sum(visible_column_widths)+len(self.separator)*len(visible_column_widths)
|
|
2327
2324
|
start_of_cell = sum(visible_column_widths[:self.selected_column])+len(self.separator)*self.selected_column
|
|
@@ -2348,7 +2345,7 @@ class Picker:
|
|
|
2348
2345
|
|
|
2349
2346
|
## Scroll with column select
|
|
2350
2347
|
rows = self.get_visible_rows()
|
|
2351
|
-
self.column_widths = get_column_widths(rows, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w)
|
|
2348
|
+
self.column_widths = get_column_widths(rows, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w, unicode_char_width=self.unicode_char_width)
|
|
2352
2349
|
|
|
2353
2350
|
visible_column_widths = [c for i,c in enumerate(self.column_widths) if i not in self.hidden_columns]
|
|
2354
2351
|
column_set_width = sum(visible_column_widths)+len(self.separator)*len(visible_column_widths)
|
|
@@ -2367,15 +2364,11 @@ class Picker:
|
|
|
2367
2364
|
#
|
|
2368
2365
|
elif self.check_key("scroll_right", key, self.keys_dict):
|
|
2369
2366
|
self.logger.info(f"key_function scroll_right")
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
row_str = format_row(item, self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols)[self.leftmost_char:]
|
|
2375
|
-
if len(row_str) > longest_row_str_len: longest_row_str_len=len(row_str)
|
|
2367
|
+
if len(self.indexed_items):
|
|
2368
|
+
row_width = sum(self.column_widths) + len(self.separator)*(len(self.column_widths)-1)
|
|
2369
|
+
if row_width-self.leftmost_char >= w-self.startx:
|
|
2370
|
+
self.leftmost_char = self.leftmost_char+5
|
|
2376
2371
|
|
|
2377
|
-
if longest_row_str_len >= w-self.startx:
|
|
2378
|
-
self.leftmost_char = self.leftmost_char+5
|
|
2379
2372
|
|
|
2380
2373
|
elif self.check_key("scroll_left", key, self.keys_dict):
|
|
2381
2374
|
self.logger.info(f"key_function scroll_left")
|
|
@@ -2392,7 +2385,7 @@ class Picker:
|
|
|
2392
2385
|
rows = self.get_visible_rows()
|
|
2393
2386
|
for i in range(len(rows)):
|
|
2394
2387
|
item = rows[i]
|
|
2395
|
-
row_str = format_row(item, self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols)
|
|
2388
|
+
row_str = format_row(item, self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols, self.unicode_char_width)
|
|
2396
2389
|
if len(row_str) > longest_row_str_len: longest_row_str_len=len(row_str)
|
|
2397
2390
|
# for i in range(len(self.indexed_items)):
|
|
2398
2391
|
# item = self.indexed_items[i]
|
|
@@ -2463,11 +2456,10 @@ class Picker:
|
|
|
2463
2456
|
|
|
2464
2457
|
# elif self.check_key("increase_lines_per_page", key, self.keys_dict):
|
|
2465
2458
|
# self.items_per_page += 1
|
|
2466
|
-
# self.draw_screen(self.indexed_items, self.highlights)
|
|
2467
2459
|
# elif self.check_key("decrease_lines_per_page", key, self.keys_dict):
|
|
2468
2460
|
# if self.items_per_page > 1:
|
|
2469
2461
|
# self.items_per_page -= 1
|
|
2470
|
-
|
|
2462
|
+
|
|
2471
2463
|
elif self.check_key("decrease_column_width", key, self.keys_dict):
|
|
2472
2464
|
self.logger.info(f"key_function decrease_column_width")
|
|
2473
2465
|
if self.max_column_width > 10:
|
|
@@ -2489,7 +2481,7 @@ class Picker:
|
|
|
2489
2481
|
elif key == curses.KEY_RESIZE: # Terminal resize signal
|
|
2490
2482
|
|
|
2491
2483
|
self.calculate_section_sizes()
|
|
2492
|
-
self.column_widths = get_column_widths(self.items, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w)
|
|
2484
|
+
self.column_widths = get_column_widths(self.items, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w, unicode_char_width=self.unicode_char_width)
|
|
2493
2485
|
|
|
2494
2486
|
|
|
2495
2487
|
|
|
@@ -2884,11 +2876,10 @@ class Picker:
|
|
|
2884
2876
|
self.stdscr.clear()
|
|
2885
2877
|
self.stdscr.refresh()
|
|
2886
2878
|
self.initialise_variables()
|
|
2887
|
-
# self.draw_screen(self.indexed_items, self.highlights)
|
|
2888
2879
|
|
|
2889
2880
|
|
|
2890
|
-
|
|
2891
|
-
|
|
2881
|
+
if key != -1:
|
|
2882
|
+
self.draw_screen(self.indexed_items, self.highlights, clear=clear_screen)
|
|
2892
2883
|
|
|
2893
2884
|
|
|
2894
2885
|
|
|
@@ -3128,21 +3119,28 @@ def main() -> None:
|
|
|
3128
3119
|
pass
|
|
3129
3120
|
|
|
3130
3121
|
function_data["colour_theme_number"] = 3
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3122
|
+
function_data["modes"] = [
|
|
3123
|
+
{
|
|
3124
|
+
'filter': '',
|
|
3125
|
+
'sort': 0,
|
|
3126
|
+
'name': 'All',
|
|
3127
|
+
},
|
|
3128
|
+
{
|
|
3129
|
+
'filter': '--2 miss',
|
|
3130
|
+
'name': 'miss',
|
|
3131
|
+
},
|
|
3132
|
+
{
|
|
3133
|
+
'filter': '--2 mp4',
|
|
3134
|
+
'name': 'mp4',
|
|
3135
|
+
},
|
|
3136
|
+
]
|
|
3137
|
+
highlights = [
|
|
3138
|
+
{
|
|
3139
|
+
"field": 1,
|
|
3140
|
+
"match": "a",
|
|
3141
|
+
"color": 8,
|
|
3142
|
+
}
|
|
3143
|
+
]
|
|
3146
3144
|
function_data["cell_cursor"] = True
|
|
3147
3145
|
function_data["display_modes"] = True
|
|
3148
3146
|
function_data["centre_in_cols"] = True
|
|
@@ -3153,15 +3151,18 @@ def main() -> None:
|
|
|
3153
3151
|
function_data["centre_in_terminal_vertical"] = True
|
|
3154
3152
|
function_data["highlight_full_row"] = True
|
|
3155
3153
|
function_data["pin_cursor"] = True
|
|
3156
|
-
function_data["display_infobox"] = True
|
|
3157
|
-
function_data["infobox_items"] = [["1"], ["2"], ["3"]]
|
|
3158
|
-
function_data["infobox_title"] = "Title"
|
|
3154
|
+
# function_data["display_infobox"] = True
|
|
3155
|
+
# function_data["infobox_items"] = [["1"], ["2"], ["3"]]
|
|
3156
|
+
# function_data["infobox_title"] = "Title"
|
|
3159
3157
|
function_data["footer_string"] = "Title"
|
|
3158
|
+
function_data["highlights"] = highlights
|
|
3160
3159
|
|
|
3161
3160
|
|
|
3162
3161
|
# function_data["debug"] = True
|
|
3163
3162
|
# function_data["debug_level"] = 1
|
|
3164
3163
|
stdscr = start_curses()
|
|
3164
|
+
# h, w = stdscr.getmaxyx()
|
|
3165
|
+
# win = stdscr.derwin(h, w//2, 0, 0)
|
|
3165
3166
|
try:
|
|
3166
3167
|
# Run the Picker
|
|
3167
3168
|
# h, w = stdscr.getmaxyx()
|
listpick/utils/utils.py
CHANGED
|
@@ -36,7 +36,7 @@ def clip_left(text, n):
|
|
|
36
36
|
width += char_width
|
|
37
37
|
return text # If the total width is less than n, return the full string
|
|
38
38
|
|
|
39
|
-
def truncate_to_display_width(text: str, max_column_width: int, centre=False) -> str:
|
|
39
|
+
def truncate_to_display_width(text: str, max_column_width: int, centre=False, unicode_char_width:bool = True) -> str:
|
|
40
40
|
"""
|
|
41
41
|
Truncate and/or pad text to max_column_width using wcwidth to ensure visual width is correct
|
|
42
42
|
with foreign character sets.
|
|
@@ -46,19 +46,31 @@ def truncate_to_display_width(text: str, max_column_width: int, centre=False) ->
|
|
|
46
46
|
|
|
47
47
|
"""
|
|
48
48
|
# logger.debug("function: truncate_to_display_width (utils.py)")
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
49
|
+
if unicode_char_width:
|
|
50
|
+
result = ''
|
|
51
|
+
width = 0
|
|
52
|
+
test_str = text[:max_column_width]
|
|
53
|
+
while True:
|
|
54
|
+
width = wcswidth(test_str)
|
|
55
|
+
if width < max_column_width or width == 0:
|
|
56
|
+
break
|
|
57
|
+
test_str = test_str[:-1]
|
|
58
|
+
# for char in text:
|
|
59
|
+
# w = wcwidth(char)
|
|
60
|
+
# if w < 0:
|
|
61
|
+
# continue
|
|
62
|
+
# if width + w > max_column_width:
|
|
63
|
+
# break
|
|
64
|
+
# result += char
|
|
65
|
+
# width += w
|
|
66
|
+
# Pad if it's shorter
|
|
67
|
+
# padding = max_column_width - wcswidth(result)
|
|
68
|
+
result = test_str
|
|
69
|
+
# return result + ' ' * padding
|
|
70
|
+
else:
|
|
71
|
+
result = text[:max_column_width]
|
|
72
|
+
width = len(result)
|
|
73
|
+
padding = max_column_width - width
|
|
62
74
|
if centre:
|
|
63
75
|
result = ' '*(padding//2) + result + ' '*(padding//2 + padding%2)
|
|
64
76
|
else:
|
|
@@ -83,7 +95,7 @@ def format_full_row(row:str) -> str:
|
|
|
83
95
|
return '\t'.join(row)
|
|
84
96
|
|
|
85
97
|
|
|
86
|
-
def format_row(row: list[str], hidden_columns: list, column_widths: list[int], separator: str, centre:bool=False) -> str:
|
|
98
|
+
def format_row(row: list[str], hidden_columns: list, column_widths: list[int], separator: str, centre:bool=False, unicode_char_width:bool = True) -> str:
|
|
87
99
|
""" Format list of strings as a single string. Requires separator string and the maximum width of the columns. """
|
|
88
100
|
row_str = ""
|
|
89
101
|
for i, cell in enumerate(row):
|
|
@@ -91,20 +103,22 @@ def format_row(row: list[str], hidden_columns: list, column_widths: list[int], s
|
|
|
91
103
|
# if is_formula_cell(cell):
|
|
92
104
|
# cell = evaluate_cell(cell)
|
|
93
105
|
|
|
94
|
-
val = truncate_to_display_width(str(cell), column_widths[i], centre)
|
|
106
|
+
val = truncate_to_display_width(str(cell), column_widths[i], centre, unicode_char_width)
|
|
95
107
|
row_str += val + separator
|
|
96
108
|
return row_str
|
|
97
|
-
# return row_str.strip()
|
|
98
109
|
|
|
99
|
-
def get_column_widths(items: list[list[str]], header: list[str]=[], max_column_width:int=70, number_columns:bool=True, max_total_width=-1, separator = " ") -> list[int]:
|
|
110
|
+
def get_column_widths(items: list[list[str]], header: list[str]=[], max_column_width:int=70, number_columns:bool=True, max_total_width=-1, separator = " ", unicode_char_width:bool=True) -> list[int]:
|
|
100
111
|
""" Calculate maximum width of each column with clipping. """
|
|
101
112
|
if len(items) == 0: return [0]
|
|
102
113
|
assert len(items) > 0
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
114
|
+
|
|
115
|
+
if unicode_char_width:
|
|
116
|
+
widths = [max(wcswidth(str(row[i])) for row in items) for i in range(len(items[0]))]
|
|
117
|
+
# widths = [max(len(str(row[i])) for row in items) for i in range(len(items[0]))]
|
|
118
|
+
if header:
|
|
119
|
+
header_widths = [wcswidth(f"{i}. {str(h)}") if number_columns else wcswidth(str(h)) for i, h in enumerate(header)]
|
|
120
|
+
col_widths = [min(max_column_width, max(widths[i], header_widths[i])) for i in range(len(header))]
|
|
121
|
+
|
|
108
122
|
# actual_max_widths = [max(header_widths[i], widths[i]) for i in range(len(widths))]
|
|
109
123
|
#
|
|
110
124
|
# if sum(col_widths) + len(separator)*(len(col_widths)-1) < max_total_width:
|
|
@@ -124,8 +138,15 @@ def get_column_widths(items: list[list[str]], header: list[str]=[], max_column_w
|
|
|
124
138
|
# else:
|
|
125
139
|
# # Maximise balance.....
|
|
126
140
|
# pass
|
|
141
|
+
else:
|
|
142
|
+
col_widths = [min(max_column_width, width) for width in widths]
|
|
127
143
|
else:
|
|
128
|
-
|
|
144
|
+
widths = [max(len(str(row[i])) for row in items) for i in range(len(items[0]))]
|
|
145
|
+
if header:
|
|
146
|
+
header_widths = [len(f"{i}. {str(h)}") if number_columns else len(str(h)) for i, h in enumerate(header)]
|
|
147
|
+
col_widths = [min(max_column_width, max(widths[i], header_widths[i])) for i in range(len(header))]
|
|
148
|
+
else:
|
|
149
|
+
col_widths = [min(max_column_width, width) for width in widths]
|
|
129
150
|
return col_widths
|
|
130
151
|
|
|
131
152
|
def get_mode_widths(item_list: list[str]) -> list[int]:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
listpick/__init__.py,sha256=ExXc97-bibodH--wlwpQivl0zCNR5D1hvpvrf7OBofU,154
|
|
2
2
|
listpick/__main__.py,sha256=wkCjDdqw093W27yWwnlC3nG_sMRKaIad7hHHWy0RBgY,193
|
|
3
|
-
listpick/listpick_app.py,sha256=
|
|
3
|
+
listpick/listpick_app.py,sha256=hWYvm3MI4HrsPu7MmS7OprI-FpznlPNR6Kzl0oX-8-g,163779
|
|
4
4
|
listpick/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
listpick/ui/build_help.py,sha256=_rVKKrX3HfFJtw-pyeNb2lQWbml4-AAw8sZIUYGn97Y,8731
|
|
6
6
|
listpick/ui/footer.py,sha256=4PO7gS-NSk6zfc2DAwSFPU6Ch_HYfu0L_57u93zfyjk,10711
|
|
@@ -22,10 +22,10 @@ listpick/utils/search_and_filter_utils.py,sha256=XxGfkyDVXO9OAKcftPat8IReMTFIuTH
|
|
|
22
22
|
listpick/utils/searching.py,sha256=Xk5UIqamNHL2L90z3ACB_Giqdpi9iRKoAJ6pKaqaD7Q,3093
|
|
23
23
|
listpick/utils/sorting.py,sha256=WZZiVlVA3Zkcpwji3U5SNFlQ14zVEk3cZJtQirBkecQ,5329
|
|
24
24
|
listpick/utils/table_to_list_of_lists.py,sha256=T-i-nV1p6g8UagdgUPKrhIGpKY_YXZDxf4xZzcPepNA,7635
|
|
25
|
-
listpick/utils/utils.py,sha256=
|
|
26
|
-
listpick-0.1.13.
|
|
27
|
-
listpick-0.1.13.
|
|
28
|
-
listpick-0.1.13.
|
|
29
|
-
listpick-0.1.13.
|
|
30
|
-
listpick-0.1.13.
|
|
31
|
-
listpick-0.1.13.
|
|
25
|
+
listpick/utils/utils.py,sha256=eq4aOkYmBfEGk7mWDV-AI_osf_zowe8GiS5O0GhvSHo,13819
|
|
26
|
+
listpick-0.1.13.31.dist-info/licenses/LICENSE.txt,sha256=2mP-MRHJptADDNE9VInMNg1tE-C6Qv93Z4CCQKrpg9w,1061
|
|
27
|
+
listpick-0.1.13.31.dist-info/METADATA,sha256=6Fxu53921VfXkq9KQsvEqDyyrJyJ97jCJynFr9ZSjq8,7988
|
|
28
|
+
listpick-0.1.13.31.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
29
|
+
listpick-0.1.13.31.dist-info/entry_points.txt,sha256=-QCf_BKIkUz35Y9nkYpjZWs2Qg0KfRna2PAs5DnF6BE,43
|
|
30
|
+
listpick-0.1.13.31.dist-info/top_level.txt,sha256=5mtsGEz86rz3qQDe0D463gGjAfSp6A3EWg4J4AGYr-Q,9
|
|
31
|
+
listpick-0.1.13.31.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|