autocomplete.js 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import GLib from 'gi://GLib';
  2. import Gio from 'gi://Gio';
  3. import Shell from 'gi://Shell';
  4. var executables = null;
  5. export var gnomeExecutables = null;
  6. var sourceId = null;
  7. /** Load executables accessible from path and
  8. * desktop app names from Shell.AppSystem API
  9. *
  10. * @returns void
  11. */
  12. export function loadExecutables() {
  13. let path = GLib.getenv('PATH');
  14. if (!path)
  15. return;
  16. let paths = path?.split(':');
  17. if (executables === null)
  18. executables = new Set();
  19. if (gnomeExecutables === null)
  20. gnomeExecutables = new Map();
  21. paths.forEach(el => {
  22. let dir = Gio.File.new_for_path(el);
  23. dir.enumerate_children_async('standard::*', Gio.FileQueryInfoFlags.NONE, GLib.PRIORITY_LOW, null, (source, result) => {
  24. try {
  25. if (!source)
  26. return;
  27. let e = source.enumerate_children_finish(result);
  28. let file;
  29. while ((file = e.next_file(null)) !== null) {
  30. let name = file.get_name();
  31. if (!executables?.has(name))
  32. executables?.add(name);
  33. }
  34. e.close(null);
  35. } catch (e) {
  36. }
  37. });
  38. });
  39. if (sourceId !== null)
  40. GLib.Source.remove(sourceId);
  41. sourceId = GLib.idle_add(GLib.PRIORITY_LOW, () => {
  42. Shell.AppSystem.get_default().get_installed().forEach(app => {
  43. let name = app.get_display_name() ?? app.get_name();
  44. let exe = app.get_commandline() ?? null;
  45. if (!gnomeExecutables?.has(name) && exe)
  46. gnomeExecutables?.set(name.toLowerCase(), app);
  47. });
  48. sourceId = null;
  49. return GLib.SOURCE_REMOVE;
  50. });
  51. }
  52. /** Returns a list of apps beginning with `word`
  53. *
  54. * @param {string} word
  55. * @returns
  56. */
  57. export function autocomplete(word) {
  58. word = word.toLowerCase();
  59. let matches = [];
  60. gnomeExecutables?.forEach((e, w) => w.startsWith(word) && w !== word && e !== null ? matches.push(w) : -1);
  61. executables?.forEach(w => w.startsWith(word) && w !== word ? matches.push(w) : -1);
  62. matches.sort((a, b) => a.length < b.length ? -1 : 1);
  63. return matches;
  64. }
  65. export function clear() {
  66. if (sourceId !== null)
  67. GLib.Source.remove(sourceId);
  68. sourceId = null;
  69. }
  70. export function destroy() {
  71. executables = null;
  72. gnomeExecutables = null;
  73. }