mirror of
https://github.com/danbulant/dots-hyprland
synced 2026-05-24 12:22:09 +00:00
quickshell emoji picker
This commit is contained in:
parent
751e5ca543
commit
c940b72776
7 changed files with 119 additions and 4 deletions
|
|
@ -18,6 +18,7 @@ bind = Super, mouse_down,global, quickshell:overviewToggleReleaseInterrupt # [hi
|
|||
|
||||
bindit = ,Super_L, global, quickshell:workspaceNumber # [hidden]
|
||||
bindd = Super, V, Clipboard history >> clipboard, global, quickshell:overviewClipboardToggle # Clipboard history >> clipboard
|
||||
bindd = Super, Period, Clipboard history >> clipboard, global, quickshell:overviewEmojiToggle # Emoji >> clipboard
|
||||
bindd = Super, Tab, Toggle overview, global, quickshell:overviewToggle # [hidden] Toggle overview/launcher (alt)
|
||||
bindd = Super, A, Toggle left sidebar, global, quickshell:sidebarLeftToggle # Toggle left sidebar
|
||||
bind = Super+Alt, A, global, quickshell:sidebarLeftToggleDetach # [hidden]
|
||||
|
|
@ -52,7 +53,7 @@ bindd = Ctrl+Shift+Alt+Super, Delete, Shutdown, exec, systemctl poweroff || logi
|
|||
##! Utilities
|
||||
# Screenshot, Record, OCR, Color picker, Clipboard history
|
||||
bindd = Super, V, Copy clipboard history entry, exec, qs ipc call TEST_ALIVE || pkill fuzzel || cliphist list | fuzzel --match-mode fzf --dmenu | cliphist decode | wl-copy # Clipboard history >> clipboard
|
||||
bindd = Super, Period, Copy an emoji, exec, pkill fuzzel || ~/.config/hypr/hyprland/scripts/fuzzel-emoji.sh copy # Emoji
|
||||
bindd = Super, Period, Copy an emoji, exec, qs ipc call TEST_ALIVE || pkill fuzzel || ~/.config/hypr/hyprland/scripts/fuzzel-emoji.sh copy # [hidden] Emoji >> clipboard
|
||||
bindd = Super+Shift, S, Screen snip, exec, grimblast --freeze copy area # Screen snip >> clipboard
|
||||
bindd = Super+Shift+Alt, S, Screen snip and annotate, exec, grim -g "$(slurp)" - | swappy -f - # Screen snip and annotate
|
||||
# OCR
|
||||
|
|
|
|||
|
|
@ -84,7 +84,8 @@ Singleton {
|
|||
property bool sloppy: false // Uses levenshtein distance based scoring instead of fuzzy sort. Very weird.
|
||||
property QtObject prefix: QtObject {
|
||||
property string action: "/"
|
||||
property string clipboard: ":"
|
||||
property string clipboard: ";"
|
||||
property string emojis: ":"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -210,4 +210,27 @@ Scope {
|
|||
}
|
||||
}
|
||||
|
||||
GlobalShortcut {
|
||||
name: "overviewEmojiToggle"
|
||||
description: qsTr("Toggle emoji query on overview widget")
|
||||
|
||||
onPressed: {
|
||||
if (GlobalStates.overviewOpen && overviewScope.dontAutoCancelSearch) {
|
||||
GlobalStates.overviewOpen = false;
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < overviewVariants.instances.length; i++) {
|
||||
let panelWindow = overviewVariants.instances[i];
|
||||
if (panelWindow.modelData.name == Hyprland.focusedMonitor.name) {
|
||||
overviewScope.dontAutoCancelSearch = true;
|
||||
panelWindow.setSearchingText(
|
||||
ConfigOptions.search.prefix.emojis
|
||||
);
|
||||
GlobalStates.overviewOpen = true;
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ RippleButton {
|
|||
property var itemExecute: entry?.execute
|
||||
property string fontType: entry?.fontType ?? "main"
|
||||
property string itemClickActionName: entry?.clickActionName
|
||||
property string bigText: entry?.bigText ?? ""
|
||||
property string materialSymbol: entry?.materialSymbol ?? ""
|
||||
property string cliphistRawString: entry?.cliphistRawString ?? ""
|
||||
|
||||
|
|
@ -120,6 +121,7 @@ RippleButton {
|
|||
id: iconLoader
|
||||
active: true
|
||||
sourceComponent: root.materialSymbol !== "" ? materialSymbolComponent :
|
||||
root.bigText ? bigTextComponent :
|
||||
root.itemIcon !== "" ? iconImageComponent :
|
||||
null
|
||||
}
|
||||
|
|
@ -142,6 +144,15 @@ RippleButton {
|
|||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: bigTextComponent
|
||||
StyledText {
|
||||
text: root.bigText
|
||||
font.pixelSize: Appearance.font.pixelSize.larger
|
||||
color: Appearance.m3colors.m3onSurface
|
||||
}
|
||||
}
|
||||
|
||||
// Main text
|
||||
ColumnLayout {
|
||||
id: contentColumn
|
||||
|
|
|
|||
|
|
@ -302,7 +302,22 @@ Item { // Wrapper
|
|||
}
|
||||
};
|
||||
}).filter(Boolean);
|
||||
}
|
||||
}
|
||||
if (root.searchingText.startsWith(ConfigOptions.search.prefix.emojis)) { // Clipboard
|
||||
const searchString = root.searchingText.slice(ConfigOptions.search.prefix.emojis.length);
|
||||
return Emojis.fuzzyQuery(searchString).map(entry => {
|
||||
return {
|
||||
cliphistRawString: entry,
|
||||
bigText: entry.match(/^\s*(\S+)/)?.[1] || "",
|
||||
name: entry.replace(/^\s*\S+\s+/, ""),
|
||||
clickActionName: "",
|
||||
type: "Emoji",
|
||||
execute: () => {
|
||||
Hyprland.dispatch(`exec wl-copy '${StringUtils.shellSingleQuoteEscape(entry.match(/^\s*(\S+)/)?.[1])}'`);
|
||||
}
|
||||
};
|
||||
}).filter(Boolean);
|
||||
}
|
||||
|
||||
|
||||
////////////////// Init ///////////////////
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ pragma ComponentBehavior: Bound
|
|||
|
||||
import "root:/modules/common/functions/fuzzysort.js" as Fuzzy
|
||||
import "root:/modules/common/functions/levendist.js" as Levendist
|
||||
import "root:/modules/common/functions/string_utils.js" as StringUtils
|
||||
import "root:/modules/common"
|
||||
import "root:/"
|
||||
import QtQuick
|
||||
|
|
|
|||
65
.config/quickshell/services/Emojis.qml
Normal file
65
.config/quickshell/services/Emojis.qml
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
pragma Singleton
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import "root:/modules/common/functions/fuzzysort.js" as Fuzzy
|
||||
import "root:/modules/common/functions/levendist.js" as Levendist
|
||||
import "root:/modules/common"
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
|
||||
/**
|
||||
* Emojis.
|
||||
*/
|
||||
Singleton {
|
||||
id: root
|
||||
property string emojiScriptPath: `${Directories.config}/hypr/hyprland/scripts/fuzzel-emoji.sh`
|
||||
property string lineBeforeData: "### DATA ###"
|
||||
property list<var> list
|
||||
readonly property var preparedEntries: list.map(a => ({
|
||||
name: Fuzzy.prepare(`${a}`),
|
||||
entry: a
|
||||
}))
|
||||
function fuzzyQuery(search: string): var {
|
||||
if (root.sloppySearch) {
|
||||
const results = entries.slice(0, 100).map(str => ({
|
||||
entry: str,
|
||||
score: Levendist.computeTextMatchScore(str.toLowerCase(), search.toLowerCase())
|
||||
})).filter(item => item.score > root.scoreThreshold)
|
||||
.sort((a, b) => b.score - a.score)
|
||||
return results
|
||||
.map(item => item.entry)
|
||||
}
|
||||
|
||||
return Fuzzy.go(search, preparedEntries, {
|
||||
all: true,
|
||||
key: "name"
|
||||
}).map(r => {
|
||||
return r.obj.entry
|
||||
});
|
||||
}
|
||||
|
||||
function load() {
|
||||
emojiFileView.reload()
|
||||
}
|
||||
|
||||
function updateEmojis(fileContent) {
|
||||
const lines = fileContent.split("\n")
|
||||
const dataIndex = lines.indexOf(root.lineBeforeData)
|
||||
if (dataIndex === -1) {
|
||||
console.warn("No data section found in emoji script file.")
|
||||
return
|
||||
}
|
||||
const emojis = lines.slice(dataIndex + 1).filter(line => line.trim() !== "")
|
||||
root.list = emojis.map(line => line.trim())
|
||||
}
|
||||
|
||||
FileView {
|
||||
id: emojiFileView
|
||||
path: Qt.resolvedUrl(root.emojiScriptPath)
|
||||
onLoadedChanged: {
|
||||
const fileContent = emojiFileView.text()
|
||||
root.updateEmojis(fileContent)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue