diff --git a/modules/ags/config/scss/binto-widgets/clipboard.scss b/modules/ags/config/scss/binto-widgets/clipboard.scss index ca66b9a..9d9607d 100644 --- a/modules/ags/config/scss/binto-widgets/clipboard.scss +++ b/modules/ags/config/scss/binto-widgets/clipboard.scss @@ -13,6 +13,26 @@ all: unset; } + .header { + margin: 16.2px; + margin-bottom: 0; + + image, entry { + all: unset; + border-radius: 9px; + color: #f8f8f2; + background-color: rgba(#44475a, 0.6); + border: 1px solid #44475a; + padding: 4.5px; + } + + image { + margin-right: 9px; + -gtk-icon-transform: scale(0.8); + font-size: 25.6px; + } + } + scrolledwindow { padding: 10px; padding-bottom: 0; diff --git a/modules/ags/config/scss/wim-widgets/clipboard.scss b/modules/ags/config/scss/wim-widgets/clipboard.scss index d08f16e..5e40ade 100644 --- a/modules/ags/config/scss/wim-widgets/clipboard.scss +++ b/modules/ags/config/scss/wim-widgets/clipboard.scss @@ -14,6 +14,26 @@ all: unset; } + .header { + margin: 16.2px; + margin-bottom: 0; + + image, entry { + all: unset; + border-radius: 9px; + color: #f8f8f2; + background-color: rgba(#44475a, 0.6); + border: 1px solid #44475a; + padding: 4.5px; + } + + image { + margin-right: 9px; + -gtk-icon-transform: scale(0.8); + font-size: 25.6px; + } + } + scrolledwindow { padding: 10px; padding-bottom: 0; diff --git a/modules/ags/config/ts/clipboard/main.ts b/modules/ags/config/ts/clipboard/main.ts index 15e28be..79e0bf6 100644 --- a/modules/ags/config/ts/clipboard/main.ts +++ b/modules/ags/config/ts/clipboard/main.ts @@ -1,6 +1,7 @@ -const { Box, Icon, Label, ListBox, Scrollable } = Widget; +const { Box, Entry, Icon, Label, ListBox, Scrollable } = Widget; const { execAsync } = Utils; +import { Fzf, FzfResultItem } from 'fzf'; import Gtk from 'gi://Gtk?version=3.0'; import CursorBox from '../misc/cursorbox.ts'; @@ -9,14 +10,21 @@ import PopupWindow from '../misc/popup.ts'; const N_ITEMS = 30; +const copyOldItem = (key: string | number): void => { + execAsync([ + 'bash', '-c', `cliphist list | grep ${key} | cliphist decode | wl-copy`, + ]).then(() => { + App.closeWindow('win-clipboard'); + }); +}; + export default () => { + let CopiedItems = [] as [string, number][]; + + let fzfResults: FzfResultItem<[string, number]>[]; const list = ListBox(); - list.set_sort_func((row1, row2) => { - const getKey = (r: Gtk.ListBoxRow) => parseInt(r.get_child()?.name ?? ''); - - return getKey(row2) - getKey(row1); - }); + const getKey = (r: Gtk.ListBoxRow) => parseInt(r.get_child()?.name ?? ''); const updateItems = () => { (list.get_children() as Gtk.ListBoxRow[]).forEach((r) => { @@ -24,18 +32,36 @@ export default () => { }); }; + const setSort = (text: string) => { + if (text === '' || text === '-') { + list.set_sort_func((row1, row2) => getKey(row2) - getKey(row1)); + } + else { + const fzf = new Fzf(CopiedItems, { + selector: (item) => item[0], + + tiebreakers: [(a, b) => b[1] - a[1]], + }); + + fzfResults = fzf.find(text); + list.set_sort_func((a, b) => { + const row1 = fzfResults.find((f) => f.item[1] === getKey(a))?.score ?? 0; + const row2 = fzfResults.find((f) => f.item[1] === getKey(b))?.score ?? 0; + + return row2 - row1; + }); + } + updateItems(); + }; + const makeItem = (key: string, val: string) => { + CopiedItems.push([val, parseInt(key)]); + const widget = CursorBox({ class_name: 'item', name: key, - on_primary_click_release: () => { - execAsync([ - 'bash', '-c', `cliphist list | grep ${key} | cliphist decode | wl-copy`, - ]).then(() => { - App.closeWindow('win-clipboard'); - }); - }, + on_primary_click_release: () => copyOldItem(key), child: Box({ children: [ @@ -68,7 +94,30 @@ export default () => { }); }; + const entry = Entry({ + // Set some text so on-change works the first time + text: '-', + hexpand: true, + + on_accept: () => { + const copiedItem = CopiedItems.find((c) => c === fzfResults[0].item); + + if (copiedItem) { + copyOldItem(copiedItem[1]); + } + }, + + on_change: ({ text }) => { + if (text !== null) { + setSort(text); + } + }, + }); + const on_open = () => { + CopiedItems = []; + entry.text = ''; + execAsync('clipboard-manager').then((out) => { list.get_children()?.forEach((ch) => { ch.destroy(); @@ -91,11 +140,21 @@ export default () => { return PopupWindow({ name: 'clipboard', + keymode: 'on-demand', on_open, child: Box({ class_name: 'clipboard', + vertical: true, children: [ + Box({ + class_name: 'header', + children: [ + Icon('preferences-system-search-symbolic'), + entry, + ], + }), + Scrollable({ hscroll: 'never', vscroll: 'automatic',