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 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.draw_screen2(self.indexed_items, self.highlights)
669
+ self.draw_screen_(self.indexed_items, self.highlights)
667
670
  except:
668
671
  self.logger.warning(f"draw_screen function error")
669
- pass
670
- def draw_screen2(self, indexed_items: list[Tuple[int, list[str]]], highlights: list[dict] = [{}], clear: bool = True) -> None:
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=False)
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
- self.draw_screen(self.indexed_items, self.highlights)
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
- rows = self.get_visible_rows()
2371
- longest_row_str_len = 0
2372
- for i in range(len(rows)):
2373
- item = rows[i]
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
- # self.draw_screen(self.indexed_items, self.highlights)
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
- self.draw_screen(self.indexed_items, self.highlights, clear=clear_screen)
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
- # function_data["modes"] = [
3132
- # {
3133
- # 'filter': '',
3134
- # 'sort': 0,
3135
- # 'name': 'All',
3136
- # },
3137
- # {
3138
- # 'filter': '--2 miss',
3139
- # 'name': 'miss',
3140
- # },
3141
- # {
3142
- # 'filter': '--2 mp4',
3143
- # 'name': 'mp4',
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
- result = ''
50
- width = 0
51
- for char in text:
52
- w = wcwidth(char)
53
- if w < 0:
54
- continue
55
- if width + w > max_column_width:
56
- break
57
- result += char
58
- width += w
59
- # Pad if it's shorter
60
- padding = max_column_width - wcswidth(result)
61
- # return result + ' ' * padding
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
- widths = [max(wcswidth(str(row[i])) for row in items) for i in range(len(items[0]))]
104
- # widths = [max(len(str(row[i])) for row in items) for i in range(len(items[0]))]
105
- if header:
106
- header_widths = [wcswidth(f"{i}. {str(h)}") if number_columns else wcswidth(str(h)) for i, h in enumerate(header)]
107
- col_widths = [min(max_column_width, max(widths[i], header_widths[i])) for i in range(len(header))]
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
- col_widths = [min(max_column_width, width) for width in widths]
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
  Metadata-Version: 2.4
2
2
  Name: listpick
3
- Version: 0.1.13.29
3
+ Version: 0.1.13.31
4
4
  Summary: Listpick is a powerful TUI data tool for creating TUI apps or viewing/comparing tabulated data.
5
5
  Home-page: https://github.com/grimandgreedy/listpick
6
6
  Author: Grim
@@ -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=hbFMmpB1ywtH7Bqd46JSzAvekjvG9yUyTJhNdPyQhRw,163690
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=8nsjjTDQH13tHTU93YcKklLQ_uuMAz-rbDTmao83T4Q,12783
26
- listpick-0.1.13.29.dist-info/licenses/LICENSE.txt,sha256=2mP-MRHJptADDNE9VInMNg1tE-C6Qv93Z4CCQKrpg9w,1061
27
- listpick-0.1.13.29.dist-info/METADATA,sha256=QWB4YR-MM4G7ydMrKWGmf4iutRLJZ_pkk8BbOTH7_zc,7988
28
- listpick-0.1.13.29.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
29
- listpick-0.1.13.29.dist-info/entry_points.txt,sha256=-QCf_BKIkUz35Y9nkYpjZWs2Qg0KfRna2PAs5DnF6BE,43
30
- listpick-0.1.13.29.dist-info/top_level.txt,sha256=5mtsGEz86rz3qQDe0D463gGjAfSp6A3EWg4J4AGYr-Q,9
31
- listpick-0.1.13.29.dist-info/RECORD,,
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,,