select-locate 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #!/usr/bin/python
  2. # PYTHON_ARGCOMPLETE_OK
  3. import sys
  4. import osex
  5. import curses
  6. import pprint
  7. import locale
  8. import argparse
  9. import argcomplete
  10. import ioex, ioex.cursesex, ioex.selector
  11. class LocateRootNode(ioex.selector.Node):
  12. def __init__(
  13. self,
  14. window,
  15. patterns,
  16. match_all,
  17. ignore_case,
  18. database_path,
  19. update_database,
  20. update_require_visibility
  21. ):
  22. super(LocateRootNode, self).__init__()
  23. self._window = window
  24. self._patterns = [p for p in patterns if len(p) > 0]
  25. self._match_all = match_all
  26. self._ignore_case = ignore_case
  27. self._database_path = database_path
  28. self._update_database = update_database
  29. self._update_require_visibility = update_require_visibility
  30. self.refresh_children()
  31. def get_window_height(self):
  32. return self._window.getmaxyx()[0]
  33. def get_window_width(self):
  34. return self._window.getmaxyx()[1]
  35. def get_header_height(self):
  36. return self._header_height
  37. def show_patterns(self):
  38. self._window.addstr(0, 0, 'locate-select', curses.A_BOLD)
  39. self._window.refresh()
  40. self._header_height = 1
  41. def show_header(self):
  42. self.show_patterns()
  43. def refresh_children(self):
  44. self._window.clear()
  45. self.show_header()
  46. self._clear_children()
  47. if self._update_database:
  48. self._window.addstr(self.get_header_height(), 0, 'updating database... ')
  49. self._window.refresh()
  50. osex.update_locate_database(
  51. database_path = self._database_path,
  52. require_visibility = self._update_require_visibility
  53. )
  54. self._window.addstr(self.get_header_height(), 0, 'searching database... ')
  55. self._window.clrtoeol()
  56. self._window.refresh()
  57. paths = osex.locate(
  58. self._patterns,
  59. match_all = self._match_all,
  60. ignore_case = self._ignore_case,
  61. database_path = self._database_path
  62. )
  63. if len(paths) == 0:
  64. self._window.addstr(self.get_header_height(), 0, 'nothing found')
  65. self._window.clrtoeol()
  66. self._window.refresh()
  67. else:
  68. for path in paths:
  69. self._append_child(ioex.selector.StaticNode(path))
  70. def locate_select(stdscr, patterns, match_all, ignore_case, update_database, multiple, database_path, update_require_visibility):
  71. curses.curs_set(0)
  72. root = LocateRootNode(
  73. stdscr,
  74. patterns,
  75. match_all,
  76. ignore_case,
  77. database_path,
  78. update_database,
  79. update_require_visibility
  80. )
  81. selection = ioex.selector.select(
  82. stdscr,
  83. root,
  84. multiple = multiple
  85. )
  86. if selection is None:
  87. return None
  88. else:
  89. return [n.get_label() for n in selection]
  90. def _init_argparser():
  91. argparser = argparse.ArgumentParser(description = None)
  92. argparser.add_argument('--database-path')
  93. argparser.add_argument('--ignore-case', action='store_true')
  94. argparser.add_argument('--match-all', action='store_true')
  95. argparser.add_argument('--multiple', action='store_true')
  96. argparser.add_argument('--update-database', action='store_true')
  97. argparser.add_argument('--update-require-visibility', choices = ['yes', 'no'])
  98. argparser.add_argument('patterns', metavar = 'pattern', nargs = '+')
  99. return argparser
  100. def main(argv):
  101. argparser = _init_argparser()
  102. argcomplete.autocomplete(argparser)
  103. args = argparser.parse_args(argv)
  104. params = vars(args)
  105. if args.update_require_visibility == 'yes':
  106. args.update_require_visibility = True
  107. elif args.update_require_visibility == 'no':
  108. args.update_require_visibility = False
  109. paths = ioex.cursesex.tty_wrapper(locate_select, **vars(args))
  110. if paths is None:
  111. return 1
  112. else:
  113. print('\n'.join(paths).encode(locale.getpreferredencoding()))
  114. return 0
  115. if __name__ == "__main__":
  116. sys.exit(main(sys.argv[1:]))