♻️ Convert plugin to c++

This commit is contained in:
2026-03-01 10:59:13 +01:00
parent 67b64c67ee
commit 04823e1a7a
10 changed files with 791 additions and 0 deletions

55
src/configwidget.ui Normal file
View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ConfigWidget</class>
<widget class="QWidget" name="ConfigWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>100</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Select what to copy to clipboard:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox">
<property name="currentText">
<string>Emoji</string>
</property>
<item>
<property name="text">
<string>Emoji</string>
</property>
</item>
<item>
<property name="text">
<string>Gitmoji code</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

437
src/gitmojis.json Normal file
View File

@@ -0,0 +1,437 @@
{
"gitmojis":[
{
"emoji":"🎨",
"entity":"&#x1f3a8;",
"code":":art:",
"description":"Improving structure / format of the code.",
"name":"art"
},
{
"emoji":"⚡️",
"entity":"&#x26a1;",
"code":":zap:",
"description":"Improving performance.",
"name":"zap"
},
{
"emoji":"🔥",
"entity":"&#x1f525;",
"code":":fire:",
"description":"Removing code or files.",
"name":"fire"
},
{
"emoji":"🐛",
"entity":"&#x1f41b;",
"code":":bug:",
"description":"Fixing a bug.",
"name":"bug"
},
{
"emoji": "🚑",
"entity": "&#128657;",
"code": ":ambulance:",
"description": "Critical hotfix.",
"name": "ambulance"
},
{
"emoji":"✨",
"entity":"&#x2728;",
"code":":sparkles:",
"description":"Introducing new features.",
"name":"sparkles"
},
{
"emoji":"📝",
"entity":"&#x1f4dd;",
"code":":memo:",
"description":"Writing docs.",
"name":"memo"
},
{
"emoji":"🚀",
"entity":"&#x1f680;",
"code":":rocket:",
"description":"Deploying stuff.",
"name":"rocket"
},
{
"emoji":"💄",
"entity":"&#ff99cc;",
"code":":lipstick:",
"description":"Updating the UI and style files.",
"name":"lipstick"
},
{
"emoji":"🎉",
"entity":"&#127881;",
"code":":tada:",
"description":"Initial commit.",
"name":"tada"
},
{
"emoji":"✅",
"entity":"&#x2705;",
"code":":white_check_mark:",
"description":"Adding tests.",
"name":"white-check-mark"
},
{
"emoji":"🔒",
"entity":"&#x1f512;",
"code":":lock:",
"description":"Fixing security issues.",
"name":"lock"
},
{
"emoji":"🍎",
"entity":"&#x1f34e;",
"code":":apple:",
"description":"Fixing something on macOS.",
"name":"apple"
},
{
"emoji":"🐧",
"entity":"&#x1f427;",
"code":":penguin:",
"description":"Fixing something on Linux.",
"name":"penguin"
},
{
"emoji":"🏁",
"entity":"&#x1f3c1;",
"code":":checkered_flag:",
"description":"Fixing something on Windows.",
"name":"checkered-flag"
},
{
"emoji":"🤖",
"entity":"&#129302;",
"code":":robot:",
"description":"Fixing something on Android.",
"name":"robot"
},
{
"emoji":"🍏",
"entity":"&#127823;",
"code":":green_apple:",
"description":"Fixing something on iOS.",
"name":"green-apple"
},
{
"emoji":"🔖",
"entity":"&#x1f516;",
"code":":bookmark:",
"description":"Releasing / Version tags.",
"name":"bookmark"
},
{
"emoji":"🚨",
"entity":"&#x1f6a8;",
"code":":rotating_light:",
"description":"Removing linter warnings.",
"name":"rotating-light"
},
{
"emoji":"🚧",
"entity":"&#x1f6a7;",
"code":":construction:",
"description":"Work in progress.",
"name":"construction"
},
{
"emoji":"💚",
"entity":"&#x1f49a;",
"code":":green_heart:",
"description":"Fixing CI Build.",
"name":"green-heart"
},
{
"emoji":"⬇️",
"entity":"⬇️",
"code":":arrow_down:",
"description":"Downgrading dependencies.",
"name":"arrow-down"
},
{
"emoji":"⬆️",
"entity":"⬆️",
"code":":arrow_up:",
"description":"Upgrading dependencies.",
"name":"arrow-up"
},
{
"emoji": "📌",
"entity": "&#x1F4CC;",
"code": ":pushpin:",
"description": "Pinning dependencies to specific versions.",
"name": "pushpin"
},
{
"emoji":"👷",
"entity":"&#x1f477;",
"code":":construction_worker:",
"description":"Adding CI build system.",
"name":"construction-worker"
},
{
"emoji":"📈",
"code":":chart_with_upwards_trend:",
"description":"Adding analytics or tracking code.",
"name":"chart-with-upwards-trend"
},
{
"emoji":"♻️",
"entity":"&#x2672;",
"code":":recycle:",
"description":"Refactoring code.",
"name":"recycle"
},
{
"emoji":"🐳",
"entity":"&#x1f433;",
"code":":whale:",
"description":"Work about Docker.",
"name":"whale"
},
{
"emoji":"",
"entity":"&#10133;",
"code":":heavy_plus_sign:",
"description":"Adding a dependency.",
"name":"heavy-plus-sign"
},
{
"emoji":"",
"entity":"&#10134;",
"code":":heavy_minus_sign:",
"description":"Removing a dependency.",
"name":"heavy-minus-sign"
},
{
"emoji":"🔧",
"entity":"&#x1f527;",
"code":":wrench:",
"description":"Changing configuration files.",
"name":"wrench"
},
{
"emoji": "🌐",
"entity": "&#127760;",
"code": ":globe_with_meridians:",
"description": "Internationalization and localization.",
"name": "globe-with-meridians"
},
{
"emoji":"✏️",
"entity":"&#59161;",
"code":":pencil2:",
"description":"Fixing typos.",
"name":"pencil"
},
{
"emoji":"💩",
"entity":"&#58613;",
"code":":hankey:",
"description":"Writing bad code that needs to be improved.",
"name":"hankey"
},
{
"emoji":"⏪",
"entity":"&#9194;",
"code":":rewind:",
"description":"Reverting changes.",
"name":"rewind"
},
{
"emoji":"🔀",
"entity":"&#128256;",
"code":":twisted_rightwards_arrows:",
"description":"Merging branches.",
"name":"twisted-rightwards-arrows"
},
{
"emoji":"📦",
"entity":"&#1F4E6;",
"code":":package:",
"description":"Updating compiled files or packages.",
"name":"package"
},
{
"emoji":"👽",
"entity":"&#1F47D;",
"code":":alien:",
"description":"Updating code due to external API changes.",
"name":"alien"
},
{
"emoji":"🚚",
"entity":"&#1F69A;",
"code":":truck:",
"description":"Moving or renaming files.",
"name":"truck"
},
{
"emoji":"📄",
"entity":"&#1F4C4;",
"code":":page_facing_up:",
"description":"Adding or updating license.",
"name":"page-facing-up"
},
{
"emoji":"💥",
"entity":"&#x1f4a5;",
"code":":boom:",
"description":"Introducing breaking changes.",
"name":"boom"
},
{
"emoji":"🍱",
"entity":"&#1F371",
"code":":bento:",
"description":"Adding or updating assets.",
"name":"bento"
},
{
"emoji":"👌",
"entity":"&#x1f44c;",
"code":":ok_hand:",
"description":"Updating code due to code review changes.",
"name":"ok-hand"
},
{
"emoji": "♿️",
"entity":"&#9855;",
"code": ":wheelchair:",
"description":"Improving accessibility.",
"name":"wheelchair"
},
{
"emoji": "💡",
"entity":"&#128161;",
"code": ":bulb:",
"description":"Documenting source code.",
"name":"bulb"
},
{
"emoji": "🍻",
"entity":"&#x1f37b;",
"code": ":beers:",
"description": "Writing code drunkenly.",
"name":"beers"
},
{
"emoji": "💬",
"entity":"&#128172;",
"code": ":speech_balloon:",
"description": "Updating text and literals.",
"name":"speech-balloon"
},
{
"emoji": "🗃",
"entity":"&#128451;",
"code": ":card_file_box:",
"description": "Performing database related changes.",
"name":"card-file-box"
},
{
"emoji":"🔊",
"entity":"&#128266;",
"code":":loud_sound:",
"description":"Adding logs.",
"name":"loud-sound"
},
{
"emoji":"🔇",
"entity":"&#128263;",
"code":":mute:",
"description":"Removing logs.",
"name":"mute"
},
{
"emoji": "👥",
"entity": "&#128101;",
"code": ":busts_in_silhouette:",
"description": "Adding contributor(s).",
"name": "busts-in-silhouette"
},
{
"emoji": "🚸",
"entity": "&#128696;",
"code": ":children_crossing:",
"description": "Improving user experience / usability.",
"name": "children-crossing"
},
{
"emoji": "🏗",
"entity": "&#1f3d7;",
"code": ":building_construction:",
"description": "Making architectural changes.",
"name": "building-construction"
},
{
"emoji": "📱",
"entity": "&#128241;" ,
"code": ":iphone:",
"description": "Working on responsive design.",
"name": "iphone"
},
{
"emoji": "🤡",
"entity": "&#129313;" ,
"code": ":clown_face:",
"description": "Mocking things.",
"name": "clown-face"
},
{
"emoji": "🥚",
"entity": "&#129370;",
"code": ":egg:",
"description": "Adding an easter egg.",
"name": "egg"
},
{
"emoji": "🙈",
"entity": "&#8bdfe7;" ,
"code": ":see_no_evil:",
"description": "Adding or updating a .gitignore file",
"name": "see-no-evil"
},
{
"emoji": "📸",
"entity": "&#128248;" ,
"code": ":camera_flash:",
"description": "Adding or updating snapshots",
"name": "camera-flash"
},
{
"emoji": "⚗",
"entity": "&#128248;" ,
"code": ":alembic:",
"description": "Experimenting new things",
"name": "alembic"
},
{
"emoji": "🔍",
"entity": "&#128269;" ,
"code": ":mag:",
"description": "Improving SEO",
"name": "mag"
},
{
"emoji":"☸️",
"entity":"&#9784;",
"code":":wheel_of_dharma:",
"description":"Work about Kubernetes",
"name":"wheel-of-dharma"
},
{
"emoji": "🏷️",
"entity": "&#127991;",
"code": ":label:",
"description": "Adding or updating types (Flow, TypeScript)",
"name": "label"
}
]
}

5
src/gitmojis.qrc Normal file
View File

@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>gitmojis.json</file>
</qresource>
</RCC>

169
src/plugin.cpp Normal file
View File

@@ -0,0 +1,169 @@
#include "plugin.h"
#include "ui_configwidget.h"
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QSettings>
#include <albert/icon.h>
#include <albert/logging.h>
#include <albert/standarditem.h>
#include <albert/systemutil.h>
ALBERT_LOGGING_CATEGORY("gitmoji")
using namespace Qt::StringLiterals;
using namespace albert;
using namespace std;
static const QString CONFIG_KEY = u"copy_format"_s;
static const QString VALUE_EMOJI = u"emoji"_s;
static const QString VALUE_CODE = u"code"_s;
struct GitmojiItem : Item
{
QString id_;
QString emoji_;
QString code_;
QString description_;
GitmojiItem(const QString& emoji, const QString& code, const QString& description)
: emoji_(emoji), code_(code), description_(description)
{
id_ = code.mid(1, code.length() - 2);
}
QString id() const override { return id_; }
QString text() const override
{
return u"%1 %2"_s.arg(emoji_, code_);
}
QString subtext() const override
{
return description_;
}
std::unique_ptr<Icon> icon() const override
{
return Icon::grapheme(emoji_);
}
vector<Action> actions() const override
{
vector<Action> actions;
QSettings settings;
QString copyFormat = settings.value(CONFIG_KEY, VALUE_EMOJI).toString();
if (copyFormat == VALUE_EMOJI)
{
actions.emplace_back(u"emoji"_s, u"Copy emoji"_s,
[this] { setClipboardText(emoji_); });
}
else
{
actions.emplace_back(u"code"_s, u"Copy gitmoji code"_s,
[this] { setClipboardText(code_); });
}
return actions;
}
};
Plugin::Plugin()
{
indexer.parallel = [this](const bool &abort)
{
vector<IndexItem> r;
QFile file(u":/gitmojis.json"_s);
if (!file.open(QIODevice::ReadOnly))
{
WARN << "Failed to open gitmojis.json";
return r;
}
QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
file.close();
if (!doc.isObject())
{
WARN << "Invalid gitmojis.json format";
return r;
}
QJsonObject root = doc.object();
QJsonArray gitmojis = root[u"gitmojis"_s].toArray();
for (const QJsonValue& value : gitmojis)
{
if (abort) return r;
QJsonObject gitmoji = value.toObject();
QString emoji = gitmoji[u"emoji"_s].toString();
QString code = gitmoji[u"code"_s].toString();
QString description = gitmoji[u"description"_s].toString();
if (emoji.isEmpty() || code.isEmpty())
continue;
auto item = make_shared<GitmojiItem>(emoji, code, description);
QString name = gitmoji[u"name"_s].toString();
QString searchable = u"%1 %2"_s.arg(name, description);
r.emplace_back(item, searchable);
}
INFO << u"Indexed %1 gitmojis."_s.arg(r.size());
return r;
};
indexer.finish = [this]
{
auto index_items = indexer.takeResult();
setIndexItems(::move(index_items));
};
}
QString Plugin::defaultTrigger() const
{
return u"g:"_s;
}
QString Plugin::synopsis(const QString &) const
{
return tr("<gitmoji name>|<gitmoji description>|*");
}
void Plugin::updateIndexItems()
{
indexer.run();
}
vector<RankItem> Plugin::rankItems(QueryContext &ctx)
{
return IndexQueryHandler::rankItems(ctx);
}
QWidget *Plugin::buildConfigWidget()
{
auto *widget = new QWidget;
Ui::ConfigWidget ui;
ui.setupUi(widget);
QSettings settings;
QString currentFormat = settings.value(CONFIG_KEY, VALUE_EMOJI).toString();
int index = (currentFormat == VALUE_CODE) ? 1 : 0;
ui.comboBox->setCurrentIndex(index);
connect(ui.comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
[ui](int comboBoxIndex) {
QSettings pluginSettings;
pluginSettings.setValue(CONFIG_KEY, (comboBoxIndex == 1) ? VALUE_CODE : VALUE_EMOJI);
});
return widget;
}

25
src/plugin.h Normal file
View File

@@ -0,0 +1,25 @@
#pragma once
#include <albert/backgroundexecutor.h>
#include <albert/extensionplugin.h>
#include <albert/indexqueryhandler.h>
class QWidget;
class Plugin : public albert::ExtensionPlugin,
public albert::IndexQueryHandler
{
ALBERT_PLUGIN
public:
Plugin();
private:
QString defaultTrigger() const override;
QWidget* buildConfigWidget() override;
void updateIndexItems() override;
QString synopsis(const QString &) const override;
std::vector<albert::RankItem> rankItems(albert::QueryContext &) override;
albert::BackgroundExecutor<std::vector<albert::IndexItem>> indexer;
};