Browse Source

Brave browser, BD, ranger select for chromium

main
Yiğit Çolakoğlu 4 years ago
parent
commit
36b5cab569
29 changed files with 2997 additions and 69 deletions
  1. +1
    -1
      browser/startpage/src/search/search.pug
  2. +3
    -3
      browser/vimium.json
  3. +3
    -1
      install.sh
  4. +1
    -0
      misc/BetterDiscord/.gitignore
  5. +0
    -1
      misc/BetterDiscord/BetterDiscord
  6. +350
    -0
      misc/BetterDiscord/plugins/APlatformIndicators.plugin.js
  7. +6
    -0
      misc/BetterDiscord/plugins/BetterCodeblocks.config.json
  8. +674
    -0
      misc/BetterDiscord/plugins/BetterCodeblocks.plugin.js
  9. +333
    -0
      misc/BetterDiscord/plugins/GameActivityToggle.plugin.js
  10. +6
    -0
      misc/BetterDiscord/plugins/ZeresPluginLibrary.config.json
  11. +114
    -0
      misc/BetterDiscord/themes/ClearVision_v6.theme.css
  12. +14
    -0
      misc/BetterDiscord/themes/DarkDiscord.theme.css
  13. +6
    -6
      misc/profile
  14. +18
    -0
      misc/ranger/plugins/chrome_chooser.py
  15. +2
    -0
      misc/ranger/rc.conf
  16. +36
    -0
      root/kdialog
  17. +3
    -0
      scripts/brave-start
  18. +1
    -1
      scripts/dmenu-killall
  19. +5
    -1
      scripts/dmenu-refresh
  20. +1
    -1
      scripts/st-copyout
  21. +1
    -2
      scripts/status-bar/arch
  22. +46
    -46
      scripts/status-bar/weather
  23. +5
    -4
      suckless/dwm/rules.h
  24. +279
    -0
      suckless/st/normalMode.c
  25. +7
    -0
      suckless/st/normalMode.h
  26. +1056
    -0
      suckless/st/st-vimBrowse-20200607-0.8.3.diff
  27. +23
    -0
      suckless/st/utils.h
  28. +2
    -1
      xorg/xinitrc
  29. +1
    -1
      zsh/profile

+ 1
- 1
browser/startpage/src/search/search.pug View File

@ -18,7 +18,7 @@ pp-search
viewBox='0 0 200 200',
data-state='active',
data-engine='google',
data-address='https://www.google.com/',
data-address='https://www.google.com/search',
fill-rule='evenodd',
fill='var(--main)'
)


+ 3
- 3
browser/vimium.json
File diff suppressed because it is too large
View File


+ 3
- 1
install.sh View File

@ -169,7 +169,9 @@ echo "*/30 * * * * vdirsyncer sync" >> /var/spool/cron/yigit
# Root
sudo cp ~/.dotfiles/root/dwm.desktop /usr/share/xsessions
sudo cp ~/.dotfiles/root/nancyj.flf /usr/share/figlet/fonts
sudo cp ~/.dotfiles/quark.service /usr/lib/systemd/system
sudo cp ~/.dotfiles/root/quark.service /usr/lib/systemd/system
sudo cp ~/.dotfiles/root/kdialog /usr/local/bin/kdialog
sudo chmod +x /usr/local/bin/kdialog
sudo systemctl daemon-reload
sudo systemctl enable quark


+ 1
- 0
misc/BetterDiscord/.gitignore View File

@ -1,2 +1,3 @@
bdstorage.json
emote_data.json
logs.log

+ 0
- 1
misc/BetterDiscord/BetterDiscord View File

@ -1 +0,0 @@
/home/yigit/.dotfiles/misc/BetterDiscord

+ 350
- 0
misc/BetterDiscord/plugins/APlatformIndicators.plugin.js View File

@ -0,0 +1,350 @@
/**
* @name PlatformIndicators
* @displayName PlatformIndicators
* @authorId 415849376598982656
* @invite gvA2ree
*/
/*@cc_on
@if (@_jscript)
// Offer to self-install for clueless users that try to run this directly.
var shell = WScript.CreateObject("WScript.Shell");
var fs = new ActiveXObject("Scripting.FileSystemObject");
var pathPlugins = shell.ExpandEnvironmentStrings("%APPDATA%\BetterDiscord\plugins");
var pathSelf = WScript.ScriptFullName;
// Put the user at ease by addressing them in the first person
shell.Popup("It looks like you've mistakenly tried to run me directly. \n(Don't do that!)", 0, "I'm a plugin for BetterDiscord", 0x30);
if (fs.GetParentFolderName(pathSelf) === fs.GetAbsolutePathName(pathPlugins)) {
shell.Popup("I'm in the correct folder already.", 0, "I'm already installed", 0x40);
} else if (!fs.FolderExists(pathPlugins)) {
shell.Popup("I can't find the BetterDiscord plugins folder.\nAre you sure it's even installed?", 0, "Can't install myself", 0x10);
} else if (shell.Popup("Should I copy myself to BetterDiscord's plugins folder for you?", 0, "Do you need some help?", 0x34) === 6) {
fs.CopyFile(pathSelf, fs.BuildPath(pathPlugins, fs.GetFileName(pathSelf)), true);
// Show the user where to put plugins in the future
shell.Exec("explorer " + pathPlugins);
shell.Popup("I'm installed!", 0, "Successfully installed", 0x40);
}
WScript.Quit();
@else@*/
module.exports = (() => {
const config = {
info: {
name: "PlatformIndicators",
authors: [
{
name: "Strencher",
discord_id: "415849376598982656",
github_username: "Strencher",
twitter_username: "Strencher3"
}
],
version: "0.0.5",
description: "Adds indicators for every platform that the user is using. Source code availble on the repo in the 'src' folder.",
github: "https://github.com/Strencher/BetterDiscordStuff/blob/master/PlatformIndicators/APlatformIndicators.plugin.js",
github_raw: "https://raw.githubusercontent.com/Strencher/BetterDiscordStuff/master/PlatformIndicators/APlatformIndicators.plugin.js"
},
changelog: [
{
title: "v0.0.5",
type: "fixed",
items: [
"Thanks to @qwert#1441 for fixing the padding issue in chat messages!",
"I still need ideas where to show all of them at one position that is not next to the username... join my Support server => https://discord.gg/gvA2ree to send me ideas!"
]
},
{
title: "v0.0.4",
type: "added",
items: [
"2 Attempt to fix conflicts with BetterRoleColors.",
"It'll probably require you to update 2 times because the filename has changed.",
"Bug fixes... styling fixes..."
]
}
],
defaultConfig: [
{
type: "switch",
name: "Show in MemberList",
note: "Shows the platform indicators in the memberlist",
id: "showInMemberList",
value: true
},
{
type: "switch",
name: "Show next to username",
note: "Shows the platform indicators next the username in messages.",
id: "showOnMessages",
value: true
},
{
type: "switch",
name: "Show in Dmd List",
note: "Shows the platform indicators in the dm list.",
id: "showInDmsList",
value: true
},
{
type: "switch",
name: "Show next to discord tags",
note: "Shows the platform indicators right next to the discord tag.",
id: "showOnTags",
value: true
},
{
type: "switch",
name: "Ignore Bots",
note: "Ignores the status of bots which is always web anyways.",
id: "ignoreBots",
value: true
},
{
type: "category",
name: "icons",
id: "icons",
settings: [
{
type: "switch",
name: "Web Icon",
note: "Show the Web icon.",
id: "web",
value: true
},
{
type: "switch",
name: "Desktop Icon",
note: "Show the Desktop icon.",
id: "desktop",
value: true
},
{
type: "switch",
name: "Mobile Icon",
note: "Show the Mobile icon.",
id: "mobile",
value: true
}
]
}
]
};
//@ts-ignore
const BdApi = window.BdApi;
// @ts-ignore
return !global.ZeresPluginLibrary ? class {
constructor() {
this._config = config;
}
getName() { return config.info.name; }
getAuthor() { return config.info.authors.map(a => a.name).join(", "); }
getDescription() { return config.info.description; }
getVersion() { return config.info.version; }
load() {
BdApi.showConfirmationModal("Library plugin is needed", [`The library plugin needed for ${config.info.name} is missing. Please click Download Now to install it.`], {
confirmText: "Download",
cancelText: "Cancel",
onConfirm: () => {
require("request").get("https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js", async (error, response, body) => {
if (error)
return require("electron").shell.openExternal("https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js");
await new Promise(r => require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0PluginLibrary.plugin.js"), body, r));
});
}
});
}
start() { }
stop() { }
} : (([Plugin, Api]) => {
const plugin = (Plugin, Api) => {
const { Utilities, WebpackModules, PluginUtilities, ReactTools, Patcher, Logger, DiscordModules: { React, UserStatusStore, Dispatcher, DiscordConstants: { ActionTypes } } } = Api;
const Utils = Object.assign(Utilities, {
joinClassNames: (...classNames) => classNames.filter(Boolean).join(" "),
capFirst(text) {
return text[0].toUpperCase() + text.slice(1);
}
});
const DesktopIcon = React.memo(props => (React.createElement("svg", Object.assign({ className: "PI-icon_desktop", width: "24", height: "24" }, props, { viewBox: "0 0 24 24" }),
React.createElement("path", { fill: "currentColor", d: "M4 2.5C2.897 2.5 2 3.397 2 4.5V15.5C2 16.604 2.897 17.5 4 17.5H11V19.5H7V21.5H17V19.5H13V17.5H20C21.103 17.5 22 16.604 22 15.5V4.5C22 3.397 21.103 2.5 20 2.5H4ZM20 4.5V13.5H4V4.5H20Z" }))));
const WebIcon = React.memo(props => (React.createElement("svg", Object.assign({ className: "PI-icon_web", width: "24", height: "24" }, props, { viewBox: "0 0 24 24" }),
React.createElement("path", { fill: "currentColor", d: "M12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2ZM11 19.93C7.05 19.44 4 16.08 4 12C4 11.38 4.08 10.79 4.21 10.21L9 15V16C9 17.1 9.9 18 11 18V19.93ZM17.9 17.39C17.64 16.58 16.9 16 16 16H15V13C15 12.45 14.55 12 14 12H8V10H10C10.55 10 11 9.55 11 9V7H13C14.1 7 15 6.1 15 5V4.59C17.93 5.78 20 8.65 20 12C20 14.08 19.2 15.97 17.9 17.39Z" }))));
const MobileIcon = React.memo(props => (React.createElement("svg", Object.assign({ className: "PI-icon_mobile", width: "24", height: "24" }, props, { viewBox: "0 0 24 24" }),
React.createElement("g", { fill: "none" },
React.createElement("path", { fill: "currentColor", d: "M15.5 1h-8C6.12 1 5 2.12 5 3.5v17C5 21.88 6.12 23 7.5 23h8c1.38 0 2.5-1.12 2.5-2.5v-17C18 2.12 16.88 1 15.5 1zm-4 21c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm4.5-4H7V4h9v14z" })))));
const Icons = {
mobile: MobileIcon,
web: WebIcon,
desktop: DesktopIcon
};
const getClass = (props = [], items = props, exclude = [], selector = false) => {
const module = WebpackModules.getModule(m => m && props.every(prop => m[prop] !== undefined) && exclude.every(e => m[e] == undefined));
if (!module)
return '';
return (selector ? '.' : '') + items.map(item => module[item]).join(selector ? '.' : ' ');
};
const { TooltipContainer: Tooltip } = WebpackModules.getByProps("TooltipContainer");
const StatusModule = WebpackModules.getByProps("Status", "getStatusMask");
const Flux = WebpackModules.getByProps("connectStores");
const MessageTimestamp = WebpackModules.getByProps("MessageTimestamp");
const { Messages } = WebpackModules.getByProps("Messages", "setLocale");
const AuthStore = WebpackModules.getByProps("getId", "getEmail");
let plugin, currentClientStatus;
const StatusIndicators = function StatusIndicators(props) {
if (!props)
return null;
return (React.createElement("div", { className: Utils.joinClassNames("PI-indicatorContainer", "PI-type_" + props.type) }, Object.keys(props).filter(e => plugin.settings.icons[e]).map(e => {
const color = StatusModule.getStatusColor(props[e]);
const Icon = Icons[e];
return React.createElement(Tooltip, { text: Utils.capFirst(e) + ": " + Messages[`STATUS_${(props[e] == "mobile" ? "mobile_online" : props[e]).toUpperCase()}`], position: "top" },
React.createElement(Icon, { style: { color }, width: "18", height: "18" }));
})));
};
return class PlatformIndicators extends Plugin {
constructor() {
super(...arguments);
this.css = `
.PI-indicatorContainer {
display: inline-flex;
}
.PI-indicatorContainer svg {
margin-left: 2px;
}
.header-23xsNx {
display: flex !important;
flex-direction: row !important;
}
.PI-container {
display: flex;
}
`;
this.getSettingsPanel = () => {
return this.buildSettingsPanel().getElement();
};
this.ON_PRESENCE_UPDATE = ({ user, clientStatus }) => {
if (user.id != AuthStore.getId())
return;
currentClientStatus = clientStatus;
UserStatusStore.emitChange();
};
}
getClients(userId) {
const isSelf = userId == AuthStore.getId();
const status = isSelf ? currentClientStatus : UserStatusStore.getState().clientStatuses[userId];
return status !== null && status !== void 0 ? status : {};
}
onStart() {
plugin = this;
PluginUtilities.addStyle(config.info.name, this.css);
Utils.suppressErrors(this.patchMessageHeader.bind(this))();
Utils.suppressErrors(this.patchMemberListItem.bind(this))();
Utils.suppressErrors(this.patchDmList.bind(this))();
Utils.suppressErrors(this.patchDiscordTag.bind(this))();
Dispatcher.subscribe(ActionTypes.PRESENCE_UPDATE, this.ON_PRESENCE_UPDATE);
}
async patchMemberListItem() {
const MemberListItem = WebpackModules.getByDisplayName("MemberListItem");
Patcher.after(MemberListItem.prototype, "renderDecorators", ({ props }, _, returnValue) => {
var _a;
if (!this.settings.showInMemberList)
return;
try {
const tree = (_a = returnValue === null || returnValue === void 0 ? void 0 : returnValue.props) === null || _a === void 0 ? void 0 : _a.children;
if (!Array.isArray(tree) || (this.settings.ignoreBots && props.user.bot))
return;
const FluxWrapper = Flux.connectStores([UserStatusStore], () => this.getClients(props.user.id))(clients => React.createElement(StatusIndicators, Object.assign({}, clients, { type: "memberList" })));
tree.unshift(React.createElement(FluxWrapper, null));
}
catch (error) {
Logger.error("Error while patching MemberListItem:", error);
}
});
this.forceUpdate(getClass(["member"], ["member"], [], true));
}
patchMessageHeader() {
Patcher.after(MessageTimestamp, "default", (_, [props], returnValue) => {
if (!this.settings.showOnMessages)
return;
try {
const tree = Utils.getNestedProp(returnValue, "props.children.1.props.children");
if (!Array.isArray(tree) || (this.settings.ignoreBots && props.message.author.bot))
return;
const FluxWrapper = Flux.connectStores([UserStatusStore], () => this.getClients(props.message.author.id))(clients => React.createElement(StatusIndicators, Object.assign({}, clients, { type: "chat" })));
tree.splice(2, 0, React.createElement(FluxWrapper, null));
}
catch (error) {
Logger.error("Error while patching MessageTimestammp:", error);
}
});
}
patchDmList() {
var _a;
const { default: PrivateChannel } = (_a = WebpackModules.getModule(m => { var _a; return ((_a = m === null || m === void 0 ? void 0 : m.default) === null || _a === void 0 ? void 0 : _a.displayName) === "PrivateChannel"; })) !== null && _a !== void 0 ? _a : {};
Patcher.after(PrivateChannel.prototype, "render", (_this, _, ret) => {
const unpatch = Patcher.after(ret.type, "render", (_, __, ret) => {
var _a, _b;
unpatch();
if (!this.settings.showInDmsList)
return;
const tree = Utils.findInReactTree(ret, m => { var _a; return ((_a = m === null || m === void 0 ? void 0 : m.className) === null || _a === void 0 ? void 0 : _a.indexOf("nameAndDecorators")) > -1; });
if (!tree)
return;
if (!Array.isArray(tree === null || tree === void 0 ? void 0 : tree.children) || (this.settings.ignoreBots && ((_b = (_a = _this.props) === null || _a === void 0 ? void 0 : _a.user) === null || _b === void 0 ? void 0 : _b.bot)))
return;
const FluxWrapper = Flux.connectStores([UserStatusStore], () => { var _a, _b; return this.getClients((_b = (_a = _this.props) === null || _a === void 0 ? void 0 : _a.user) === null || _b === void 0 ? void 0 : _b.id); })(clients => React.createElement(StatusIndicators, Object.assign({}, clients, { type: "dmList" })));
tree.children = [
tree.children,
React.createElement(FluxWrapper, null)
];
});
});
this.forceUpdate(getClass(["privateChannels"], ["privateChannels"], [], true));
}
forceUpdate(selector) {
const nodes = document.querySelectorAll(selector);
if (!nodes.length)
return;
for (const node of nodes) {
const instance = ReactTools.getOwnerInstance(node);
if (!instance)
return;
instance.forceUpdate();
}
}
patchDiscordTag() {
const DiscordTag = WebpackModules.getModule(m => { var _a; return ((_a = m === null || m === void 0 ? void 0 : m.default) === null || _a === void 0 ? void 0 : _a.displayName) === "DiscordTag"; });
const NameTag = WebpackModules.getModule(m => { var _a; return ((_a = m === null || m === void 0 ? void 0 : m.default) === null || _a === void 0 ? void 0 : _a.displayName) === "NameTag"; });
Patcher.after(DiscordTag, "default", (_, [{ user }], ret) => {
ret.props.user = user;
});
Patcher.after(NameTag, "default", (_, [args], ret) => {
if (!this.settings.showOnTags)
return;
const tree = ret === null || ret === void 0 ? void 0 : ret.props;
var { user } = args;
if (!Array.isArray(tree === null || tree === void 0 ? void 0 : tree.children) || (this.settings.ignoreBots && (user === null || user === void 0 ? void 0 : user.bot)))
return;
const FluxWrapper = Flux.connectStores([UserStatusStore], () => this.getClients(user === null || user === void 0 ? void 0 : user.id))(clients => React.createElement(StatusIndicators, Object.assign({}, clients, { type: "discordTag" })));
try {
tree.children.push(React.createElement(FluxWrapper, null));
}
catch (error) {
Logger.error("Failed to inject into NameTag:\n", error);
}
return ret;
});
}
onStop() {
Patcher.unpatchAll();
PluginUtilities.removeStyle(config.info.name);
Dispatcher.unsubscribe(ActionTypes.PRESENCE_UPDATE, this.ON_PRESENCE_UPDATE);
}
};
};
return plugin(Plugin, Api);
//@ts-ignore
})(global.ZeresPluginLibrary.buildPlugin(config));
})();
/*@end@*/

+ 6
- 0
misc/BetterDiscord/plugins/BetterCodeblocks.config.json View File

@ -0,0 +1,6 @@
{
"currentVersionInfo": {
"version": "1.0.0",
"hasShownChangelog": true
}
}

+ 674
- 0
misc/BetterDiscord/plugins/BetterCodeblocks.plugin.js View File

@ -0,0 +1,674 @@
/**
* @name BetterCodeblocks
* @invite undefined
* @authorLink undefined
* @donate undefined
* @patreon undefined
* @website https://github.com/vBread/BetterCodeblocks
* @source https://github.com/vBread/BetterCodeblocks/blob/master/BetterCodeblocks.plugin.js
*/
/*@cc_on
@if (@_jscript)
// Offer to self-install for clueless users that try to run this directly.
var shell = WScript.CreateObject("WScript.Shell");
var fs = new ActiveXObject("Scripting.FileSystemObject");
var pathPlugins = shell.ExpandEnvironmentStrings("%APPDATA%\BetterDiscord\plugins");
var pathSelf = WScript.ScriptFullName;
// Put the user at ease by addressing them in the first person
shell.Popup("It looks like you've mistakenly tried to run me directly. \n(Don't do that!)", 0, "I'm a plugin for BetterDiscord", 0x30);
if (fs.GetParentFolderName(pathSelf) === fs.GetAbsolutePathName(pathPlugins)) {
shell.Popup("I'm in the correct folder already.", 0, "I'm already installed", 0x40);
} else if (!fs.FolderExists(pathPlugins)) {
shell.Popup("I can't find the BetterDiscord plugins folder.\nAre you sure it's even installed?", 0, "Can't install myself", 0x10);
} else if (shell.Popup("Should I copy myself to BetterDiscord's plugins folder for you?", 0, "Do you need some help?", 0x34) === 6) {
fs.CopyFile(pathSelf, fs.BuildPath(pathPlugins, fs.GetFileName(pathSelf)), true);
// Show the user where to put plugins in the future
shell.Exec("explorer " + pathPlugins);
shell.Popup("I'm installed!", 0, "Successfully installed", 0x40);
}
WScript.Quit();
@else@*/
module.exports = (() => {
const config = { "info": { "name": "BetterCodeblocks", "authors": [{ "name": "Bread", "discord_id": "304260051915374603" }], "version": "1.0.0", "description": "Enhances the look and feel of Discord's codeblocks with customizable colors", "github": "https://github.com/vBread/BetterCodeblocks", "github_raw": "https://github.com/vBread/BetterCodeblocks/blob/master/BetterCodeblocks.plugin.js" }, "changelog": [], "main": "index.js" };
return !global.ZeresPluginLibrary ? class {
constructor() { this._config = config; }
getName() { return config.info.name; }
getAuthor() { return config.info.authors.map(a => a.name).join(", "); }
getDescription() { return config.info.description; }
getVersion() { return config.info.version; }
load() {
BdApi.showConfirmationModal("Library Missing", `The library plugin needed for ${config.info.name} is missing. Please click Download Now to install it.`, {
confirmText: "Download Now",
cancelText: "Cancel",
onConfirm: () => {
require("request").get("https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js", async (error, response, body) => {
if (error) return require("electron").shell.openExternal("https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js");
await new Promise(r => require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0PluginLibrary.plugin.js"), body, r));
});
}
});
}
start() {}
stop() {}
} : (([Plugin, Api]) => {
const plugin = (Plugin, Library) => {
const { Patcher, WebpackModules, DiscordModules, PluginUtilities, Settings } = Library;
const { SettingPanel, SettingGroup, Textbox } = Settings
const { React, hljs } = DiscordModules
return class BetterCodeblocks extends Plugin {
constructor() {
super()
this.defaults = {
addition: '#98c379',
attr_1: '#d19a66',
attr_2: '#d19a66',
attribute: '#98c379',
background: '#282c34',
built_in: '#e6c07b',
bullet: '#61aeee',
code: '#abb2bf',
comment: '#5c6370',
deletion: '#e06c75',
doctag: '#c678dd',
keyword: '#c678dd',
literal: '#56b6c2',
meta_string: '#98c379',
meta: '#61aeee',
name: '#e06c75',
nomarkup: '#98c379',
number: '#d19a66',
params: '#abb2bf',
quote: '#5c6370',
regexp: '#98c379',
section: '#e06c75',
selector_attr: '#d19a66',
selector_class: '#d19a66',
selector_id: '#61aeee',
selector_pseudo: '#d19a66',
selector_tag: '#e06c75',
string: '#98c379',
subst: '#e06c75',
symbol: '#61aeee',
tag: '#e06c75',
template_variable: '#d19a66',
text: '#abb2bf',
title: '#61aeee',
type: '#d19a66',
variable: '#d19a66'
}
this.hljs = PluginUtilities.loadSettings('BetterCodeblocks', this.defaults)
}
onStart() {
const parser = WebpackModules.getByProps('parse', 'parseTopic')
Patcher.after(parser.defaultRules.codeBlock, 'react', (_, args, res) => {
this.inject(args, res)
return res
});
PluginUtilities.addStyle('BetterCodeblocks', this.css)
}
onStop() {
PluginUtilities.removeStyle('BetterCodeblocks')
Patcher.unpatchAll();
}
getSettingsPanel() {
return SettingPanel.build(PluginUtilities.saveSettings('BetterCodeblocks', this.hljs),
new SettingGroup('Customization').append(
new Textbox('Additions', 'Changes the color of additions for Diff', this.hljs.addition, (color) => this.updateColor('addition', color)),
new Textbox('Annotation Tags', 'Changes the color of documentation/annotation tags', this.hljs.doctag, (color) => this.updateColor('doctag', color)),
new Textbox('Attributes', 'Changes the color of HTML tag attributes', this.hljs.attribute, (color) => this.updateColor('attribute', color)),
new Textbox('Background', 'Changes the color of the codeblock background', this.hljs.background, (color) => this.updateColor('background', color)),
new Textbox('Built-In', 'Changes the color of built-in keywords', this.hljs.built_in, (color) => this.updateColor('built_in', color)),
new Textbox('Bullets', 'Changes the color of bullet points for Markdown', this.hljs.bullet, (color) => this.updateColor('bullet', color)),
new Textbox('Comments', 'Changes the color of comments', this.hljs.comment, (color) => this.updateColor('comment', color)),
new Textbox('Deletions', 'Changes the color of deletions for Diff', this.hljs.deletion, (color) => this.updateColor('deletion', color)),
new Textbox('Keywords', 'Changes the color of keywords', this.hljs.keyword, (color) => this.updateColor('keyword', color)),
new Textbox('Literals', 'Changes the color of literal keywords', this.hljs.literal, (color) => this.updateColor('literal', color)),
new Textbox('Names', 'Changes the color of function names', this.hljs.title, (color) => this.updateColor('title', color)),
new Textbox('Number', 'Changes the color of numbers', this.hljs.number, (color) => this.updateColor('number', color)),
new Textbox('Parameters', 'Changes the color of function parameters', this.hljs.params, (color) => this.updateColor('params', color)),
new Textbox('Regular Expressions', 'Changes the color of regular expressions', this.hljs.regexp, (color) => this.updateColor('regexp', color)),
new Textbox('Selector Attributes', 'Changes the color of CSS selector attributes', this.hljs.selector_attr, (color) => this.updateColor('selector_attr', color)),
new Textbox('Selector Classes', 'Changes the color of CSS selector classes', this.hljs.selector_class, (color) => this.updateColor('selector_class', color)),
new Textbox('Selector IDs', 'Changes the color of CSS selector IDs', this.hljs.selector_id, (color) => this.updateColor('selector_id', color)),
new Textbox('Selector Pseudos', 'Changes the color of CSS selector pseudos', this.hljs.selector_pseudo, (color) => this.updateColor('selector_pseudo', color)),
new Textbox('Selector Tags', 'Changes the color of CSS selector tags', this.hljs.selector_tag, (color) => this.updateColor('selector_tag', color)),
new Textbox('Strings', 'Changes the color of strings', this.hljs.string, (color) => this.updateColor('string', color)),
new Textbox('Template Literals', 'Changes the color of template literals', this.hljs.template_variable, (color) => this.updateColor('template_variable', color)),
new Textbox('Types', 'Changes the color of types', this.hljs.type, (color) => this.updateColor('type', color)),
new Textbox('Variables', 'Changes the color of variables', this.hljs.variable, (color) => this.updateColor('variable', color)),
)
)
}
updateColor(property, color) {
let reset = false
if (!/#?\w{6}/.test(color) || color === '') {
color = this.defaults[property]
reset = true
}
if (!color.startsWith('#')) {
color = `#${color}`
}
this.hljs[property] = color
if (reset) PluginUtilities.saveSettings('BetterCodeblocks', this.hljs)
PluginUtilities.removeStyle('BetterCodeblocks')
PluginUtilities.addStyle('BetterCodeblocks', this.css)
}
inject(args, res) {
const { render } = res.props;
res.props.render = (props) => {
const codeblock = render(props);
const codeElement = codeblock.props.children;
const classes = codeElement.props.className.split(' ');
const lang = args ? args[0].lang : classes[classes.indexOf('hljs') + 1];
const lines = codeElement.props.dangerouslySetInnerHTML
? codeElement.props.dangerouslySetInnerHTML.__html
.replace(
/<span class="(hljs-[a-z]+)">([^<]*)<\/span>/g,
(_, className, code) => code.split('\n').map(l => `<span class="${className}">${l}</span>`).join('\n')
)
.split('\n')
: codeElement.props.children.split('\n');
delete codeElement.props.dangerouslySetInnerHTML;
codeElement.props.children = this.render(lang, lines);
return codeblock;
};
}
render(lang, lines) {
const { Messages } = WebpackModules.getByProps('Messages')
if (hljs && typeof hljs.getLanguage === 'function') {
lang = hljs.getLanguage(lang);
}
return React.createElement(React.Fragment, null,
lang && React.createElement('div', { className: 'bd-codeblock-lang' }, lang.name),
React.createElement('table', { className: 'bd-codeblock-table' },
...lines.map((line, i) => React.createElement('tr', null,
React.createElement('td', null, i + 1),
React.createElement('td',
lang ? {
dangerouslySetInnerHTML: {
__html: line
}
} : {
children: line
}
)
))
),
React.createElement('button', {
className: 'bd-codeblock-copy-btn',
onClick: this.clickHandler
}, Messages.COPY)
);
}
clickHandler({ target }) {
const { Messages } = WebpackModules.getByProps('Messages')
const { clipboard } = require('electron')
if (target.classList.contains('copied')) return;
target.innerText = Messages.ACCOUNT_USERNAME_COPY_SUCCESS_1;
target.classList.add('copied');
setTimeout(() => {
target.innerText = Messages.COPY;
target.classList.remove('copied');
}, 1e3);
const code = [...target.parentElement.querySelectorAll('td:last-child')].map(t => t.textContent).join('\n');
clipboard.writeText(code);
}
get css() {
return `
.hljs {
background-color: ${this.hljs.background} !important;
color: ${this.hljs.text};
position: relative;
}
.hljs:not([class$='hljs']) {
padding-top: 2px;
}
.bd-codeblock-lang {
color: var(--text-normal);
border-bottom: 1px solid var(--background-modifier-accent);
padding: 0 5px;
margin-bottom: 6px;
font-size: .8em;
font-family: 'Raleway', sans-serif;
font-weight: bold;
}
.bd-codeblock-table {
border-collapse: collapse;
}
.bd-codeblock-table tr {
height: 19px;
width: 100%;
}
.bd-codeblock-table td:first-child {
border-right: 1px solid var(--background-modifier-accent);
padding-left: 5px;
padding-right: 8px;
user-select: none;
}
.bd-codeblock-table td:last-child {
padding-left: 8px;
word-break: break-all;
}
.bd-codeblock-copy-btn {
color: #fff;
border-radius: 4px;
line-height: 20px;
padding: 0 10px;
font-family: 'Raleway', sans-serif;
font-size: .8em;
text-transform: uppercase;
font-weight: bold;
margin: 3px;
background: var(--background-floating);
position: absolute;
right: 0 !important;
bottom: 0 !important;
opacity: 0;
transition: .3s;
}
.bd-codeblock-copy-btn.copied {
background-color: #43b581;
opacity: 1;
}
.hljs:hover .bd-codeblock-copy-btn {
opacity: 1;
}
// HLJS Styling
.hljs > .bd-codeblock-table > tr > td > span > .hljs-tag {
color: ${this.hljs.tag};
}
.hljs > .bd-codeblock-table > tr > td > span > .hljs-tag > .hljs-name {
color: ${this.hljs.name};
}
.hljs > .bd-codeblock-table > tr > td > span > .hljs-tag > .hljs-attr {
color: ${this.hljs.attr_2};
}
.hljs > .bd-codeblock-table > tr > td > .bash > .hljs-built_in {
color: ${this.hljs.built_in};
}
.hljs > .bd-codeblock-table > tr > td > .bash > .hljs-variable {
color: ${this.hljs.variable};
}
.hljs > .bd-codeblock-table > tr > td > .hljs-tag {
color: ${this.hljs.tag} !important;
}
.hljs > .bd-codeblock-table > tr > td > .hljs-tag > .hljs-name {
color: ${this.hljs.tag};
}
.hljs > .bd-codeblock-table > tr > td > .hljs-tag > .hljs-attr {
color: ${this.hljs.tag};
}
.hljs > .bd-codeblock-table > tr > td > .hljs-function > .hljs-params {
color: ${this.hljs.params};
}
.hljs > .bd-codeblock-table > tr > td > .hljs-function > .hljs-params > .hljs-type {
color: ${this.hljs.type};
}
.hljs > .bd-codeblock-table > tr > td > .hljs-params {
color: ${this.hljs.params};
}
.hljs > .bd-codeblock-table > tr > td > .hljs-params > .hljs-built_in {
color: ${this.hljs.built_in};
}
.hljs > .bd-codeblock-table > tr > td > .hljs-selector-attr {
color: ${this.hljs.selector_attr};
}
.hljs > .bd-codeblock-table > tr > td > .hljs-type {
color: ${this.hljs.type};
}
.hljs > .bd-codeblock-table > tr > td > .hljs-selector-id {
color: ${this.hljs.selector_id};
}
.hljs > .bd-codeblock-table > tr > td > .hljs-selector-pseudo {
color: ${this.hljs.selector_pseudo};
}
.hljs > .bd-codeblock-table > tr > td > .hljs-bullet {
color: ${this.hljs.bullet};
}
.hljs > .bd-codeblock-table > tr > td > .hljs-addition {
color: ${this.hljs.addition};
}
.hljs > .bd-codeblock-table > tr > td > .hljs-deletion {
color: ${this.hljs.deletion};
}
.hljs > .bd-codeblock-table > tr > td > .hljs-regexp {
color: ${this.hljs.regexp};
}
.hljs > .bd-codeblock-table > tr > td > .hljs-doctag {
color: ${this.hljs.doctag};
}
.hljs > .bd-codeblock-table > tr > td > .hljs-built_in {
color: ${this.hljs.built_in};
}
.hljs > .bd-codeblock-table > tr > td > .hljs-attr {
color: ${this.hljs.attr_1};
}
.hljs > .bd-codeblock-table > tr > td .hljs-nomarkup > span {
color: ${this.hljs.nomarkup};
}
.hljs > .bd-codeblock-table > tr > td .hljs-section {
color: ${this.hljs.section};
}
.hljs > .bd-codeblock-table > tr > td .hljs-meta {
color: ${this.hljs.meta};
}
.hljs > .bd-codeblock-table > tr > td .hljs-literal {
color: ${this.hljs.literal};
}
.hljs > .bd-codeblock-table > tr > td .hljs-title {
color: ${this.hljs.title};
}
.hljs > .bd-codeblock-table > tr > td .hljs-keyword {
color: ${this.hljs.keyword};
}
.hljs > .bd-codeblock-table > tr > td .hljs-selector-tag {
color: ${this.hljs.selector_tag};
}
.hljs > .bd-codeblock-table > tr > td .hljs-selector-class {
color: ${this.hljs.selector_class};
}
.hljs > .bd-codeblock-table > tr > td .hljs-attribute {
color: ${this.hljs.attribute};
}
.hljs > .bd-codeblock-table > tr > td .hljs-symbol {
color: ${this.hljs.symbol};
}
.hljs > .bd-codeblock-table > tr > td .hljs-number {
color: ${this.hljs.number};
}
.hljs > .bd-codeblock-table > tr > td .hljs-string {
color: ${this.hljs.string};
}
.hljs > .bd-codeblock-table > tr > td .hljs-subst {
color: ${this.hljs.subst};
}
.hljs > .bd-codeblock-table > tr > td .hljs-code {
color: ${this.hljs.code};
}
.hljs > .bd-codeblock-table > tr > td .hljs-comment {
color: ${this.hljs.comment};
}
.hljs > .bd-codeblock-table > tr > td .hljs-quote {
color: ${this.hljs.quote};
}
.hljs > .bd-codeblock-table > tr > td .hljs-variable {
color: ${this.hljs.variable};
}
.hljs > .bd-codeblock-table > tr > td .hljs-template-variable {
color: ${this.hljs.template_variable};
}
.hljs > .bd-codeblock-table > tr > td .hljs-meta-string {
color: ${this.hljs.meta_string};
}
// Chat CB
.codeLine-14BKbG > span > span {
color: ${this.hljs.text};
}
.codeLine-14BKbG > span > span > span > .hljs-tag {
color: ${this.hljs.tag};
}
.codeLine-14BKbG > span > span > span > .hljs-tag > .hljs-name {
color: ${this.hljs.name};
}
.codeLine-14BKbG > span > span > span > .hljs-tag > .hljs-attr {
color: ${this.hljs.attr_2};
}
.codeLine-14BKbG > span > span > .bash > .hljs-built_in {
color: ${this.hljs.built_in};
}
.codeLine-14BKbG > span > span > .bash > .hljs-variable {
color: ${this.hljs.variable};
}
.codeLine-14BKbG > span > span > .hljs-tag {
color: ${this.hljs.tag} !important;
}
.codeLine-14BKbG > span > span > .hljs-tag > .hljs-name {
color: ${this.hljs.tag};
}
.codeLine-14BKbG > span > span > .hljs-tag > .hljs-attr {
color: ${this.hljs.tag};
}
.codeLine-14BKbG > span > span > .hljs-function > .hljs-params {
color: ${this.hljs.params};
}
.codeLine-14BKbG > span > span > .hljs-function > .hljs-params > .hljs-type {
color: ${this.hljs.type};
}
.codeLine-14BKbG > span > span > .hljs-params {
color: ${this.hljs.params};
}
.codeLine-14BKbG > span > span > .hljs-params > .hljs-built_in {
color: ${this.hljs.built_in};
}
.codeLine-14BKbG > span > span > .hljs-selector-attr {
color: ${this.hljs.selector_attr};
}
.codeLine-14BKbG > span > span > .hljs-type {
color: ${this.hljs.type};
}
.codeLine-14BKbG > span > span > .hljs-selector-id {
color: ${this.hljs.selector_id};
}
.codeLine-14BKbG > span > span > .hljs-selector-pseudo {
color: ${this.hljs.selector_pseudo};
}
.codeLine-14BKbG > span > span > .hljs-bullet {
color: ${this.hljs.bullet};
}
.codeLine-14BKbG > span > span > .hljs-addition {
color: ${this.hljs.addition};
}
.codeLine-14BKbG > span > span > .hljs-deletion {
color: ${this.hljs.deletion};
}
.codeLine-14BKbG > span > span > .hljs-regexp {
color: ${this.hljs.regexp};
}
.codeLine-14BKbG > span > span > .hljs-doctag {
color: ${this.hljs.doctag};
}
.codeLine-14BKbG > span > span > .hljs-built_in {
color: ${this.hljs.built_in};
}
.codeLine-14BKbG > span > span > .hljs-attr {
color: ${this.hljs.attr_1};
}
.codeLine-14BKbG > span > span .hljs-nomarkup > span {
color: ${this.hljs.nomarkup};
}
.codeLine-14BKbG > span > span .hljs-section {
color: ${this.hljs.section};
}
.codeLine-14BKbG > span > span .hljs-meta {
color: ${this.hljs.meta};
}
.codeLine-14BKbG > span > span .hljs-literal {
color: ${this.hljs.literal};
}
.codeLine-14BKbG > span > span .hljs-title {
color: ${this.hljs.title};
}
.codeLine-14BKbG > span > span .hljs-keyword {
color: ${this.hljs.keyword};
}
.codeLine-14BKbG > span > span .hljs-selector-tag {
color: ${this.hljs.selector_tag};
}
.codeLine-14BKbG > span > span .hljs-selector-class {
color: ${this.hljs.selector_class};
}
.codeLine-14BKbG > span > span .hljs-attribute {
color: ${this.hljs.attribute};
}
.codeLine-14BKbG > span > span .hljs-symbol {
color: ${this.hljs.symbol};
}
.codeLine-14BKbG > span > span .hljs-number {
color: ${this.hljs.number};
}
.codeLine-14BKbG > span > span .hljs-string {
color: ${this.hljs.string};
}
.codeLine-14BKbG > span > span .hljs-subst {
color: ${this.hljs.subst};
}
.codeLine-14BKbG > span > span .hljs-code {
color: ${this.hljs.code};
}
.codeLine-14BKbG > span > span .hljs-comment {
color: ${this.hljs.comment};
}
.codeLine-14BKbG > span > span .hljs-quote {
color: ${this.hljs.quote};
}
.codeLine-14BKbG > span > span .hljs-variable {
color: ${this.hljs.variable};
}
.codeLine-14BKbG > span > span .hljs-template-variable {
color: ${this.hljs.template_variable};
}
.codeLine-14BKbG > span > span .hljs-meta-string {
color: ${this.hljs.meta_string};
}
`
}
};
};
return plugin(Plugin, Api);
})(global.ZeresPluginLibrary.buildPlugin(config));
})();
/*@end@*/

+ 333
- 0
misc/BetterDiscord/plugins/GameActivityToggle.plugin.js View File

@ -0,0 +1,333 @@
/**
* @name GameActivityToggle
* @version 1.2.6
* @description Simple plugin that adds the \"display game activity\" setting
* on the home toolbar so you can toggle it easier when you don't want your friends knowing how much you play video games.
*
* @authorLink https://github.com/Egrodo
* @source https://github.com/Egrodo/DiscordPlugins/blob/master/GameActivityToggle.plugin.js
*/
/*@cc_on
@if (@_jscript)
// Offer to self-install for clueless users that try to run this directly.
var shell = WScript.CreateObject("WScript.Shell");
var fs = new ActiveXObject("Scripting.FileSystemObject");
var pathPlugins = shell.ExpandEnvironmentStrings("%APPDATA%\BetterDiscord\plugins");
var pathSelf = WScript.ScriptFullName;
// Put the user at ease by addressing them in the first person
shell.Popup("It looks like you've mistakenly tried to run me directly. \n(Don't do that!)", 0, "I'm a plugin for BetterDiscord", 0x30);
if (fs.GetParentFolderName(pathSelf) === fs.GetAbsolutePathName(pathPlugins)) {
shell.Popup("I'm in the correct folder already.", 0, "I'm already installed", 0x40);
} else if (!fs.FolderExists(pathPlugins)) {
shell.Popup("I can't find the BetterDiscord plugins folder.\nAre you sure it's even installed?", 0, "Can't install myself", 0x10);
} else if (shell.Popup("Should I copy myself to BetterDiscord's plugins folder for you?", 0, "Do you need some help?", 0x34) === 6) {
fs.CopyFile(pathSelf, fs.BuildPath(pathPlugins, fs.GetFileName(pathSelf)), true);
// Show the user where to put plugins in the future
shell.Exec("explorer " + pathPlugins);
shell.Popup("I'm installed!", 0, "Successfully installed", 0x40);
}
WScript.Quit();
@else@*/
const enabledIcon =
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 24 24" width="20" height="20" xml:space="preserve"><style type="text/css">.st0{fill:#B9BBBE;}</style><g><path class="st0" d="M20.8,7.7c-0.6-1.2-1.8-1.9-3.1-1.9H6.3C5,5.7,3.8,6.5,3.2,7.6l-2.8,5.8c0,0,0,0,0,0C-0.3,15.1,0.4,17,2,17.8L2.3,18C4,18.7,5.9,18,6.7,16.4l0.1-0.3c0.3-0.6,0.9-1,1.6-1h7.1c0.7,0,1.3,0.4,1.6,1l0.1,0.3c0.8,1.6,2.7,2.4,4.4,1.6l0.3-0.1c1.6-0.8,2.3-2.7,1.6-4.4L20.8,7.7z M8.6,10.5c0,0.2-0.2,0.4-0.4,0.4H7.3c-0.2,0-0.4,0.2-0.4,0.4v0.9c0,0.2-0.2,0.4-0.4,0.4H5.7c-0.2,0-0.4-0.2-0.4-0.4v-0.9c0-0.2-0.2-0.4-0.4-0.4c0,0,0,0,0,0H4.1c-0.2,0-0.4-0.2-0.4-0.4V9.7c0-0.2,0.2-0.4,0.4-0.4h0.9c0.2,0,0.4-0.2,0.4-0.4c0,0,0,0,0,0V8.1c0-0.2,0.2-0.4,0.4-0.4h0.8C6.8,7.7,7,7.9,7,8.1V9c0,0.2,0.2,0.4,0.4,0.4h0.9c0.2,0,0.3,0.2,0.3,0.4V10.5z M15.6,10.9c-0.4,0-0.8-0.3-0.8-0.8c0-0.4,0.3-0.8,0.8-0.8c0,0,0,0,0,0c0.4,0,0.8,0.3,0.8,0.8C16.4,10.5,16.1,10.9,15.6,10.9z M17.2,7.7C17.2,7.7,17.2,7.7,17.2,7.7c0.4,0,0.8,0.3,0.8,0.8c0,0,0,0,0,0c0,0.4-0.4,0.8-0.8,0.8c-0.4,0-0.8-0.4-0.8-0.8S16.8,7.7,17.2,7.7z M18,11.7L18,11.7C18,11.7,18,11.7,18,11.7c0,0.4-0.3,0.8-0.8,0.8c-0.4,0-0.8-0.3-0.8-0.8c0-0.4,0.3-0.8,0.8-0.8c0,0,0,0,0,0C17.7,10.9,18,11.3,18,11.7C18,11.7,18,11.7,18,11.7L18,11.7C18,11.7,18,11.7,18,11.7C18,11.7,18,11.7,18,11.7z M18.9,10.9c-0.4,0-0.8-0.3-0.8-0.8c0-0.4,0.3-0.8,0.8-0.8c0,0,0,0,0,0c0.4,0,0.8,0.3,0.8,0.8C19.6,10.5,19.3,10.9,18.9,10.9z"/><polygon points="19.3,11.2 19.3,11.2 19.3,11.2 "/><polygon points="19.3,11.2 19.3,11.2 19.3,11.2 "/></g></svg>';
const enabledIconHover =
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 24 24" width="20" height="20" xml:space="preserve"><style type="text/css">.st0{fill:#dcddde;}</style><g><path class="st0" d="M20.8,7.7c-0.6-1.2-1.8-1.9-3.1-1.9H6.3C5,5.7,3.8,6.5,3.2,7.6l-2.8,5.8c0,0,0,0,0,0C-0.3,15.1,0.4,17,2,17.8L2.3,18C4,18.7,5.9,18,6.7,16.4l0.1-0.3c0.3-0.6,0.9-1,1.6-1h7.1c0.7,0,1.3,0.4,1.6,1l0.1,0.3c0.8,1.6,2.7,2.4,4.4,1.6l0.3-0.1c1.6-0.8,2.3-2.7,1.6-4.4L20.8,7.7z M8.6,10.5c0,0.2-0.2,0.4-0.4,0.4H7.3c-0.2,0-0.4,0.2-0.4,0.4v0.9c0,0.2-0.2,0.4-0.4,0.4H5.7c-0.2,0-0.4-0.2-0.4-0.4v-0.9c0-0.2-0.2-0.4-0.4-0.4c0,0,0,0,0,0H4.1c-0.2,0-0.4-0.2-0.4-0.4V9.7c0-0.2,0.2-0.4,0.4-0.4h0.9c0.2,0,0.4-0.2,0.4-0.4c0,0,0,0,0,0V8.1c0-0.2,0.2-0.4,0.4-0.4h0.8C6.8,7.7,7,7.9,7,8.1V9c0,0.2,0.2,0.4,0.4,0.4h0.9c0.2,0,0.3,0.2,0.3,0.4V10.5z M15.6,10.9c-0.4,0-0.8-0.3-0.8-0.8c0-0.4,0.3-0.8,0.8-0.8c0,0,0,0,0,0c0.4,0,0.8,0.3,0.8,0.8C16.4,10.5,16.1,10.9,15.6,10.9z M17.2,7.7C17.2,7.7,17.2,7.7,17.2,7.7c0.4,0,0.8,0.3,0.8,0.8c0,0,0,0,0,0c0,0.4-0.4,0.8-0.8,0.8c-0.4,0-0.8-0.4-0.8-0.8S16.8,7.7,17.2,7.7z M18,11.7L18,11.7C18,11.7,18,11.7,18,11.7c0,0.4-0.3,0.8-0.8,0.8c-0.4,0-0.8-0.3-0.8-0.8c0-0.4,0.3-0.8,0.8-0.8c0,0,0,0,0,0C17.7,10.9,18,11.3,18,11.7C18,11.7,18,11.7,18,11.7L18,11.7C18,11.7,18,11.7,18,11.7C18,11.7,18,11.7,18,11.7z M18.9,10.9c-0.4,0-0.8-0.3-0.8-0.8c0-0.4,0.3-0.8,0.8-0.8c0,0,0,0,0,0c0.4,0,0.8,0.3,0.8,0.8C19.6,10.5,19.3,10.9,18.9,10.9z"/><polygon points="19.3,11.2 19.3,11.2 19.3,11.2 "/><polygon points="19.3,11.2 19.3,11.2 19.3,11.2 "/></g></svg>';
const disabledIcon =
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 24 24" width="20" height="20" xml:space="preserve"><style type="text/css">.st0{fill:#B9BBBE;}.st1{fill:#F04747;}</style><g><path class="st0" d="M17.7,5.7h-0.8L4.4,18.1c1-0.2,1.9-0.8,2.3-1.8l0.1-0.3c0.3-0.6,0.9-1,1.6-1h1.9l4.7-4.6v0c-0.1-0.1-0.1-0.2-0.1-0.4c0-0.4,0.3-0.8,0.8-0.8c0,0,0,0,0,0c0.1,0,0.2,0,0.3,0.1l0.5-0.5c-0.1-0.1-0.1-0.2-0.1-0.4c0-0.4,0.3-0.8,0.8-0.8c0.1,0,0.3,0,0.4,0.1l1.7-1.7C18.8,5.8,18.3,5.7,17.7,5.7z M23.5,13.4l-2.8-5.8c0,0,0-0.1-0.1-0.1l-1.8,1.8c0.4,0,0.7,0.4,0.7,0.8c0,0.4-0.3,0.8-0.8,0.8c-0.4,0-0.8-0.3-0.8-0.7l-0.8,0.8c0.4,0,0.7,0.4,0.7,0.8c0,0.4-0.4,0.8-0.8,0.8c-0.4,0-0.8-0.3-0.8-0.7L13.1,15h2.4c0.7,0,1.3,0.4,1.6,1l0.1,0.3c0.8,1.6,2.7,2.3,4.4,1.6l0.3-0.1C23.6,17,24.3,15,23.5,13.4z M6.3,5.7C5,5.7,3.8,6.4,3.3,7.6l-2.8,5.8c0,0,0,0,0,0C-0.3,15,0.4,16.9,2,17.7L14,5.7H6.3z M8.2,10.8H7.3c-0.2,0-0.4,0.2-0.4,0.3v0.9c0,0.2-0.2,0.3-0.3,0.3H5.7c-0.2,0-0.3-0.2-0.3-0.3v-0.9c0-0.2-0.2-0.3-0.4-0.3H4.1c-0.2,0-0.4-0.2-0.4-0.4V9.6c0-0.2,0.2-0.4,0.4-0.4H5c0.2,0,0.4-0.2,0.4-0.4V8c0-0.2,0.2-0.4,0.4-0.4h0.8C6.8,7.7,7,7.8,7,8v0.9c0,0.2,0.2,0.4,0.4,0.4h0.9c0.2,0,0.3,0.2,0.3,0.4v0.8C8.6,10.7,8.4,10.8,8.2,10.8z"/><polygon points="19.3,11.1 19.3,11.1 19.3,11.1 "/><polygon points="19.3,11.2 19.3,11.1 19.3,11.1 "/></g><polygon class="st1" points="22.6,2.7 22.6,2.8 19.3,6.1 16,9.3 16,9.4 15,10.4 15,10.4 10.3,15 2.8,22.5 1.4,21.1 21.2,1.3 "/></svg>';
const disabledIconHover =
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 24 24" width="20" height="20" xml:space="preserve"><style type="text/css">.st0{fill:#dcddde;}.st1{fill:#F04747;}</style><g><path class="st0" d="M17.7,5.7h-0.8L4.4,18.1c1-0.2,1.9-0.8,2.3-1.8l0.1-0.3c0.3-0.6,0.9-1,1.6-1h1.9l4.7-4.6v0c-0.1-0.1-0.1-0.2-0.1-0.4c0-0.4,0.3-0.8,0.8-0.8c0,0,0,0,0,0c0.1,0,0.2,0,0.3,0.1l0.5-0.5c-0.1-0.1-0.1-0.2-0.1-0.4c0-0.4,0.3-0.8,0.8-0.8c0.1,0,0.3,0,0.4,0.1l1.7-1.7C18.8,5.8,18.3,5.7,17.7,5.7z M23.5,13.4l-2.8-5.8c0,0,0-0.1-0.1-0.1l-1.8,1.8c0.4,0,0.7,0.4,0.7,0.8c0,0.4-0.3,0.8-0.8,0.8c-0.4,0-0.8-0.3-0.8-0.7l-0.8,0.8c0.4,0,0.7,0.4,0.7,0.8c0,0.4-0.4,0.8-0.8,0.8c-0.4,0-0.8-0.3-0.8-0.7L13.1,15h2.4c0.7,0,1.3,0.4,1.6,1l0.1,0.3c0.8,1.6,2.7,2.3,4.4,1.6l0.3-0.1C23.6,17,24.3,15,23.5,13.4z M6.3,5.7C5,5.7,3.8,6.4,3.3,7.6l-2.8,5.8c0,0,0,0,0,0C-0.3,15,0.4,16.9,2,17.7L14,5.7H6.3z M8.2,10.8H7.3c-0.2,0-0.4,0.2-0.4,0.3v0.9c0,0.2-0.2,0.3-0.3,0.3H5.7c-0.2,0-0.3-0.2-0.3-0.3v-0.9c0-0.2-0.2-0.3-0.4-0.3H4.1c-0.2,0-0.4-0.2-0.4-0.4V9.6c0-0.2,0.2-0.4,0.4-0.4H5c0.2,0,0.4-0.2,0.4-0.4V8c0-0.2,0.2-0.4,0.4-0.4h0.8C6.8,7.7,7,7.8,7,8v0.9c0,0.2,0.2,0.4,0.4,0.4h0.9c0.2,0,0.3,0.2,0.3,0.4v0.8C8.6,10.7,8.4,10.8,8.2,10.8z"/><polygon points="19.3,11.1 19.3,11.1 19.3,11.1 "/><polygon points="19.3,11.2 19.3,11.1 19.3,11.1 "/></g><polygon class="st1" points="22.6,2.7 22.6,2.8 19.3,6.1 16,9.3 16,9.4 15,10.4 15,10.4 10.3,15 2.8,22.5 1.4,21.1 21.2,1.3 "/></svg>';
const micIconPath = `M6.7 11H5C5 12.19 5.34 13.3 5.9 14.28L7.13 13.05C6.86 12.43 6.7 11.74 6.7 11Z`;
const muteIconPath = `M14.99 11C14.99 12.66 13.66 14 12 14C10.34 14 9 12.66 9 11V5C9 3.34 10.34 2 12 2C13.66 2 15 3.34 15 5L14.99 11ZM12 16.1C14.76 16.1 17.3 14 17.3 11H19C19 14.42 16.28 17.24 13 17.72V21H11V17.72C7.72 17.23 5 14.41 5 11H6.7C6.7 14 9.24 16.1 12 16.1ZM12 4C11.2 4 11 4.66667 11 5V11C11 11.3333 11.2 12 12 12C12.8 12 13 11.3333 13 11V5C13 4.66667 12.8 4 12 4Z`;
class GameActivityToggle {
btnReference = null;
tooltipReference = null;
soundReference = null;
observer = null;
soundToggled = true;
gameActivity = true;
constructor() {
this.onToggle = this.onToggle.bind(this);
this.onButtonMouseOut = this.onButtonMouseOut.bind(this);
this.onButtonMouseOver = this.onButtonMouseOver.bind(this);
this.checkForRemoval = this.checkForRemoval.bind(this);
this.checkForChange = this.checkForChange.bind(this);
}
getName() {
return "Game Activity Toggle";
}
getDescription() {
return 'Simple plugin that adds a "Display Game Activity" button on the main toolbar so you can toggle it easier.';
}
getVersion() {
return "1.2.6";
}
getAuthor() {
return "egrodo";
}
load() {
// Not required, but if the user has ZLibrary installed then support auto update.
if (window.ZLibrary) {
ZLibrary.PluginUpdater.checkForUpdate(
this.getName(),
this.getVersion(),
"https://raw.githubusercontent.com/Egrodo/DiscordPlugins/master/GameActivityToggle.plugin.js"
);
}
}
start() {
// On start check what game activity is currently set to.
this.gameActivity = BdApi.findModuleByProps("guildPositions").showCurrentGame;
this.soundReference = BdApi.findModuleByProps("playSound");
// Check if there's a sound setting saved
// For some reason BdApi interprets boolean false's as undefined, so we're storing the toggle as a string and converting it.
const savedSoundSetting = BdApi.loadData(this.getName(), "soundToggled");
if (!savedSoundSetting) {
this.soundToggled = true;
} else if (savedSoundSetting === "true") {
this.savedSoundSetting = true;
} else if (savedSoundSetting === "false") {
this.savedSoundSetting = false;
} else {
console.error(
`Game Activity Toggle Error: soundToggle data somehow corrupted, not true/false: ${savedSoundSetting}`
);
this.savedSoundSetting = true;
BdApi.saveData(this.getName(), "soundToggled", "true");
}
// Create our DOM elements
this.createButton();
this.createTooltip();
// Watch for change
BdApi.findModuleByProps("guildPositions").addChangeListener(this.checkForChange);
}
createButton() {
// Use flexMarginReset prop to find the selector for the taskbar row.
const selector = (BdApi.findModuleByProps("flexMarginReset", "flex").flex || "").split(" ")[0];
if (!selector) {
console.error("GameActivityToggle failed to start up: Selector not found?");
return;
}
// If there are multiple elements found with this selector then the user is most likely in a call. Use the appropriate one
const rows = document.querySelectorAll(`.${selector}`);
let row;
if (rows.length) {
// Find the correct row by looking for one who's DOM structure matches what we expect
for (let i = 0; i < rows.length; ++i) {
try {
if (
rows[i].firstElementChild.firstElementChild.firstElementChild.firstElementChild.getAttribute("d") ===
muteIconPath ||
rows[i].firstElementChild.firstElementChild.firstElementChild.firstElementChild.getAttribute("d") ===
micIconPath
) {
row = rows[i];
break;
}
} catch (err) {
// If the above firstELementChild accessing fails assume it's not the correct row and continue
continue;
}
}
} else {
row = rows[0];
}
if (!row) {
console.log(rows);
throw new Error("Could not find correct row?");
}
this.btnReference = row.firstElementChild.cloneNode(true);
this.btnReference.firstElementChild.innerHTML = this.gameActivity ? enabledIcon : disabledIcon;
this.btnReference.firstElementChild.style.pointerEvents = "none"; // Ignore pointer events to fix bug that was causing repeated clicks to be ignored.
this.btnReference.id = "GameActivityToggleBtn";
this.btnReference.setAttribute("aria-label", "Toggle Game Activity");
this.btnReference.setAttribute("aria-checked", `${this.gameActivity ? "true" : "false"}`);
this.btnReference.addEventListener("click", this.onToggle);
this.btnReference.addEventListener("mouseenter", this.onButtonMouseOver);
this.btnReference.addEventListener("mouseleave", this.onButtonMouseOut);
row.prepend(this.btnReference);
// Observe changes on the row to watch for our element being overwritten.
if (!this.observer) {
this.observer = new MutationObserver(this.checkForRemoval);
this.observer.observe(row, {
attributes: false,
childList: true,
subtree: false,
});
}
}
createTooltip() {
// Also setup my recreated tooltip that uses Discord's classes.
const tooltipClasses = BdApi.findModuleByProps("tooltipBottom");
const wrapperDiv = document.createElement("div");
this.tooltipReference = wrapperDiv;
wrapperDiv.style.visibility = "hidden";
wrapperDiv.style.position = "absolute";
// wrapperDiv.style.zIndex = "1003";
wrapperDiv.className = [
tooltipClasses.tooltip,
tooltipClasses.tooltipTop,
tooltipClasses.tooltipBlack,
tooltipClasses.tooltipDisablePointerEvents,
].join(" ");
const textWrapper = document.createElement("div");
textWrapper.className = tooltipClasses.tooltipContent;
textWrapper.innerText = `Turn ${this.gameActivity ? "off" : "on"} game activity`;
const bottomArrow = document.createElement("div");
bottomArrow.className = tooltipClasses.tooltipPointer;
wrapperDiv.appendChild(textWrapper);
wrapperDiv.appendChild(bottomArrow);
document.body.appendChild(wrapperDiv);
}
onToggle() {
this.gameActivity = !this.gameActivity;
BdApi.findModuleByProps("updateRemoteSettings").updateLocalSettings({
showCurrentGame: this.gameActivity,
});
BdApi.findModuleByProps("updateRemoteSettings").updateRemoteSettings({
showCurrentGame: this.gameActivity,
});
this.btnReference.firstElementChild.innerHTML = this.gameActivity ? enabledIcon : disabledIcon;
// In order to preserve the tooltipPointer but also change the message we have to do this
const innerTooltipHTML = this.tooltipReference.firstElementChild.innerHTML.split("Turn");
this.tooltipReference.firstElementChild.innerHTML = `${innerTooltipHTML[0]} Turn ${
this.gameActivity ? "off" : "on"
} game activity`;
this.btnReference.setAttribute("aria-checked", `${this.gameActivity ? "true" : "false"}`);
// If enabled, play the mute / unmute sound on toggle.
if (this.soundToggled) {
if (this.gameActivity) {
this.soundReference.playSound("unmute", 0.4);
} else this.soundReference.playSound("mute", 0.4);
}
}
// On mouse over swap icons to highlight and display tooltip in correct position.
onButtonMouseOver({ target }) {
this.btnReference.firstElementChild.innerHTML = this.gameActivity ? enabledIconHover : disabledIconHover;
const { x, y } = target.getBoundingClientRect();
const tooltipXPos = x + target.clientWidth / 2 - this.tooltipReference.offsetWidth / 2;
const tooltipYPos = y - target.clientHeight - 8; // 8 being a constant amount of space to hover above the btn.
this.tooltipReference.style.left = `${tooltipXPos}px`;
this.tooltipReference.style.visibility = "visible";
this.tooltipReference.style.top = `${tooltipYPos}px`;
this.tooltipReference.visibility = "visible";
}
onButtonMouseOut() {
this.btnReference.firstElementChild.innerHTML = this.gameActivity ? enabledIcon : disabledIcon;
this.tooltipReference.style.visibility = "hidden";
}
// Certain UI actions can result in the row being re-rendered and the button removed. Watch the row and re-add the button when necessary.
checkForRemoval() {
if (!document.getElementById("GameActivityToggleBtn")) {
this.createButton();
}
}
// We need to check for the user toggling game activity in the actual settings menu as well, because we have no event for that.
checkForChange() {
if (this.gameActivity !== BdApi.findModuleByProps("guildPositions").showCurrentGame) {
this.gameActivity = BdApi.findModuleByProps("guildPositions").showCurrentGame;
this.btnReference.firstElementChild.innerHTML = this.gameActivity ? enabledIcon : disabledIcon;
const innerTooltipHTML = this.tooltipReference.firstElementChild.innerHTML.split("Turn");
this.tooltipReference.firstElementChild.innerHTML = `${innerTooltipHTML[0]} Turn ${
this.gameActivity ? "off" : "on"
} game activity`;
this.btnReference.setAttribute("aria-checked", `${this.gameActivity ? "true" : "false"}`);
this.btnReference.addEventListener("click", this.onToggle);
}
}
// Create settings panel that allows users to disable the alert sound
getSettingsPanel() {
// Create wrapper row
const wrapper = document.createElement("div");
wrapper.className = "ui-flex flex-vertical flex-justify-start flex-align-stretch flex-nowrap ui-switch-item";
wrapper.style.marginTop = "1.5rem";
const titleContainer = document.createElement("div");
titleContainer.className = 'class="ui-flex flex-horizontal flex-justify-start flex-align-stretch flex-nowrap"';
titleContainer.style.display = "flex";
const title = document.createElement("h3");
title.innerText = "Alert Sound";
title.className = "ui-form-title h3 margin-reset margin-reset ui-flex-child";
titleContainer.appendChild(title);
// Create switch
const button = document.createElement("div");
button.classList.add("bd-switch", ...(this.soundToggled ? ["bd-switch-checked"] : []));
const input = document.createElement("input");
input.type = "checkbox";
input.className = "bd-checkbox";
button.appendChild(input);
button.style.float = "right";
input.onclick = () => {
this.soundToggled = !this.soundToggled;
BdApi.saveData(this.getName(), "soundToggled", this.soundToggled.toString());
button.classList.remove(...(this.soundToggled ? [] : ["bd-switch-checked"]));
button.classList.add(...(this.soundToggled ? ["bd-switch-checked"] : []));
};
// Create description box and append button to it
const description = document.createElement("div");
description.className = "ui-form-text style-description margin-top-4";
description.innerText = "Toggle the alert sound that plays on button click";
description.style.borderBottom = "none";
description.appendChild(button);
wrapper.appendChild(titleContainer);
wrapper.appendChild(description);
return wrapper;
}
stop() {
this.observer.disconnect();
this.btnReference.removeEventListener("mouseenter", this.onButtonMouseOver);
this.btnReference.removeEventListener("mouseleave", this.onButtonMouseOut);
this.btnReference.parentNode.removeChild(this.btnReference);
this.tooltipReference.parentNode.removeChild(this.tooltipReference);
}
}

+ 6
- 0
misc/BetterDiscord/plugins/ZeresPluginLibrary.config.json View File

@ -0,0 +1,6 @@
{
"currentVersionInfo": {
"version": "1.2.29",
"hasShownChangelog": true
}
}

+ 114
- 0
misc/BetterDiscord/themes/ClearVision_v6.theme.css View File

@ -0,0 +1,114 @@
/**
* @name ClearVision
* @author ClearVision Team
* @version 6
* @description Highly customizable theme for BetterDiscord.
* @source https://github.com/ClearVision/ClearVision-v6
* @website https://clearvision.gitlab.io
* @invite 2fKpjAR
*/
/* Credits to Zerthox for making the original theme. */
/* IMPORT CSS */
@import url(https://clearvision.gitlab.io/v6/main.css);
/* SETTINGS */
:root {
/* ACCENT COLORS */
--main-color: #2780e6; /* main accent color (hex, rgb or hsl) [default: #2780e6] */
--hover-color: #1e63b3; /* hover accent color (hex, rgb or hsl) [default: #1e63b3] */
--success-color: #43b581; /* success accent color (hex, rgb or hsl) [default: #43b581] */
--danger-color: #982929; /* danger accent color (hex, rgb or hsl) [default: #982929] */
/* Customization Patch */
--channel-unread: var(--main-color); /* Unread Server channel color. [default: var(--main-color)] THIS OVERRIDES YOUR MAIN COLOR*/
--channel-color: rgba(255,255,255,0.3); /*Read Server channel color [default: rgba(255,255,255,0.3);]*/
--muted-color: rgba(255,255,255,0.1); /*Muted channel color [default: rgba(255,255,255,0.1);]*/
--url-color: var(--main-color); /*The color of url links [default: var(--main-color)]*/
/* STATUS COLORS */
--online-color: #43b581; /* online status color (hex, rgb or hsl) [default: #43b581] */
--idle-color: #faa61a; /* idle status color (hex, rgb or hsl) [default: #faa61a] */
--dnd-color: #982929; /* dnd status color (hex, rgb or hsl) [default: #982929] */
--streaming-color: #593695; /* streaming status color (hex, rgb or hsl) [default: #593695] */
--offline-color: #808080; /* offline/invisible status color (hex, rgb or hsl) [default: #808080] */
/* GENERAL */
--main-font: Whitney, Helvetica Neue, Helvetica, Arial, sans-serif; /* main font for app (font must be installed) [default: Whitney, Helvetica Neue, Helvetica, Arial, sans-serif] */
--code-font: Consolas, Liberation Mono, Menlo, Courier, monospace; /* font for codeblocks (font must be installed) [default: Consolas, Liberation Mono, Menlo, Courier, monospace] */
--server-columns: 1; /* amount of server list columns [default: 1] */
--channels-width: 220px; /* channel list width (240px for Discord default) [default: 220px] */
--members-width: 240px; /* member list width [default: 240px] */
--avatar-roundness: 50%; /* avatar roundness (0% for squares, 50% for circles) [default: 50%] */
/* APP BACKGROUND */
--background-shading: 100%; /* app background shading (0 for complete smoothness) [default: 100%] */
--background-overlay: rgba(0, 0, 0, 0.6); /* app background overlay color/gradient [default: rgba(0, 0, 0, 0.6)] */
--background-image: url(https://clearvision.gitlab.io/images/sapphire.jpg); /* app background image (link must be HTTPS) [default: url(https://clearvision.gitlab.io/images/sapphire.jpg)]*/
--background-position: center; /* app background position [default: center] */
--background-size: cover; /* app background size [default: cover] */
--background-repeat: no-repeat; /* app background repeat [default: no-repeat] */
--background-attachment: fixed; /* app background attachment [default: fixed] */
--background-brightness: 100%; /* app background brightness (< 100% for darken, > 100% for lighten) [default: 100%] */
--background-contrast: 100%; /* app background contrast [default: 100%] */
--background-saturation: 100%; /* app background saturation [default: 100%] */
--background-invert: 0%; /* app background invert (0 - 100%) [default: 0%] */
--background-grayscale: 0%; /* app background grayscale ( 0 - 100%) [default: 0%] */
--background-sepia: 0%; /* app background sepia (0 - 100%) [default: 0%] */
--background-blur: 0px; /* app background blur [default: 0px] */
/* HOME BUTTON ICON */
--home-icon: url(https://clearvision.gitlab.io/icons/discord.svg); /* home button icon (link must be HTTPS) [default: url(https://clearvision.gitlab.io/icons/discord.svg)]*/
--home-position: center; /* home button icon position [default: center] */
--home-size: 40px; /* home button icon size [default: 40px] */
/* MODAL BACKDROP */
--backdrop-overlay: rgba(0, 0, 0, 0.8); /* modal backdrop overlay color/gradient [default: rgba(0, 0, 0, 0.8)] */
--backdrop-image: var(--background-image); /* modal backdrop image (link must be HTTPS) [default: var(---background-image)] */
--backdrop-position: var(--background-position); /* modal backdrop position [default: var(---background-position)] */
--backdrop-size: var(--background-size); /* modal backdrop size [default: var(---background-size)] */
--backdrop-repeat: var(--background-repeat); /* modal backdrop repeat [default: var(---background-repeat)] */
--backdrop-attachment: var(--background-attachment); /* modal backdrop attachment [default: var(--background-attachment)] */
--backdrop-brightness: var(--background-brightness); /* modal backdrop brightness (< 100% for darken, > 100% for lighten) [default: var(---background-brightness)] */
--backdrop-contrast: var(--background-contrast); /* modal backdrop contrast [default: var(---background-contrast)] */
--backdrop-saturation: var(--background-saturation); /* modal backdrop saturation [default: var(---background-saturation)] */
--backdrop-invert: var(--background-invert); /* modal backdrop invert (0 - 100%) [default: var(---background-invert)] */
--backdrop-grayscale: var(--background-grayscale); /* modal backdrop grayscale ( 0 - 100%) [default: var(---background-grayscale)] */
--backdrop-sepia: var(--background-sepia); /* modal backdrop sepia (0 - 100%) [default: var(---background-sepia)] */
--backdrop-blur: var(--background-blur); /* modal backdrop blur [default: var(--background-blur)] */
/* USER POPOUT BACKGROUND */
--user-popout-image: var(--background-image); /* app background image (link must be HTTPS) [default: var(---background-image)] */
--user-popout-position: var(--background-position); /* user popout background position [default: var(---background-position)] */
--user-popout-size: var(--background-size); /* user popout background size [default: var(---background-size)] */
--user-popout-repeat: var(--background-repeat); /* user popout background repeat [default: var(---background-repeat)] */
--user-popout-attachment: var(--background-attachment); /* user popout background attachment [default: var(--background-attachment)] */
--user-popout-brightness: var(--background-brightness); /* user popout background brightness (< 100% for darken, > 100% for lighten) [default: var(---background-brightness)] */
--user-popout-contrast: var(--background-contrast); /* user popout background contrast [default: var(---background-contrast)] */
--user-popout-saturation: var(--background-saturation); /* user popout background saturation [default: var(---background-saturation)] */
--user-popout-invert: var(--background-invert); /* user popout background invert (0 - 100%) [default: var(---background-invert)] */
--user-popout-grayscale: var(--background-grayscale); /* user popout background grayscale (0 - 100%) [default: var(---background-grayscale)] */
--user-popout-sepia: var(--background-sepia); /* user popout background sepia (0 - 100%) [default: var(---background-sepia)] */
--user-popout-blur: calc(var(--background-blur) + 3px); /* user popout background blur [default: calc(var(--background-blur) + 3px)] */
/* USER MODAL BACKGROUND */
--user-modal-image: var(--background-image); /* app background image (link must be HTTPS) [default: var(---background-image)] */
--user-modal-position: var(--background-position); /* user modal background position [default: var(---background-position)] */
--user-modal-size: var(--background-size); /* user modal background size [default: var(---background-size)] */
--user-modal-repeat: var(--background-repeat); /* user modal background repeat [default: var(---background-repeat)] */
--user-modal-attachment: var(--background-attachment); /* user modal background attachment [default: var(--background-attachment)] */
--user-modal-brightness: var(--background-brightness); /* user modal background brightness (< 100% for darken, > 100% for lighten) [default: var(---background-brightness)] */
--user-modal-contrast: var(--background-contrast); /* user modal background contrast [default: var(---background-contrast)] */
--user-modal-saturation: var(--background-saturation); /* user modal background saturation [default: var(---background-saturation)] */
--user-modal-invert: var(--background-invert); /* user modal background invert (0 - 100%) [default: var(---background-invert)] */
--user-modal-grayscale: var(--background-grayscale); /* user modal background grayscale (0 - 100%) [default: var(---background-grayscale)] */
--user-modal-sepia: var(--background-sepia); /* user modal background sepia (0 - 100%) [default: var(---background-sepia)] */
--user-modal-blur: calc(var(--background-blur) + 3px); /* user modal background blur [default: calc(var(--background-blur) + 3px)] */
/* THEME BD COLORS */
--bd-blue: var(--main-color); /* betterdiscord main color [default: var(--main-color)] */
--bd-blue-hover: var(--hover-color); /* betterdiscord hover color [default: var(--hover-color)] */
--bd-blue-active: var(--hover-color); /* betterdiscord active color [default: var(--hover-color)] */
}

+ 14
- 0
misc/BetterDiscord/themes/DarkDiscord.theme.css View File

@ -0,0 +1,14 @@
/**
* @name Dark Discord
* @version 1.0
* @description An actual dark mode for discord.
* @source https://github.com/zzzmario/dark-discord
* @authorId 583062692596547585
* @author mario
* @donate https://paypal.me/zzzmario
* @invite 7JceW7S
**/
@import url(https://zzzmario.github.io/dark-discord/src/source.css);

+ 6
- 6
misc/profile View File

@ -13,12 +13,12 @@ export BROWSER=firefox-developer-edition
export EDITOR=vim
export GOPATH=$HOME/go
export ANDROID_HOME=/home/yigit/Android
export DEFAULT_RECIPIENT="yigitcolakoglu@hotmail.com"
export CM_SYNC_PRIMARY_TO_CLIPBOARD=1
# Setup PATH
export CM_SYNC_PRIMARY_TO_CLIPBOARD=1
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/platform-tools
export PATH=$PATH:$FLUTTER_HOME/bin
export DEFAULT_RECIPIENT="yigitcolakoglu@hotmail.com"
export PATH="$PATH:/home/yigit/.scripts:/home/yigit/.local/bin:/home/yigit/.gem/ruby/2.7.0/bin:$GOPATH/bin:$GOPATH/binexport:/home/yigit/.local/bin"
export PATH=$ANDROID_HOME/tools:$PATH
export PATH=$ANDROID_HOME/platform-tools:$PATH
export PATH=$FLUTTER_HOME/bin:$PATH
export PATH="/home/yigit/.scripts:/home/yigit/.local/bin:/home/yigit/.gem/ruby/2.7.0/bin:$GOPATH/bin:$GOPATH/binexport:/home/yigit/.local/bin:$PATH"
export CPATH=/usr/include/opencv4

+ 18
- 0
misc/ranger/plugins/chrome_chooser.py View File

@ -0,0 +1,18 @@
import os
import sys
from ranger.core.loader import CommandLoader
from ranger.api.commands import Command
class chrome_choose(Command):
def execute(self):
""" Extract copied files to current directory """
filename = self.arg(1)
cwd = self.fm.thisdir
if filename == '.':
with open('/tmp/ranger-chrome-choosed', 'w') as f:
f.write(cwd.path + '/')
sys.exit(0)
with open('/tmp/ranger-chrome-choosed', 'w') as f:
f.write(os.path.join(cwd.path, filename))
sys.exit(0)

+ 2
- 0
misc/ranger/rc.conf View File

@ -399,6 +399,8 @@ map oT chain set sort=type; set sort_reverse=True
map oE chain set sort=extension; set sort_reverse=True
map dc get_cumulative_size
map dh chrome_choose .
map dn console chrome_choose
# Settings
map zc set collapse_preview!


+ 36
- 0
root/kdialog View File

@ -0,0 +1,36 @@
#!/bin/sh
for ((i=1;i<=$#;i++));
do
if [ ${!i} = "--getsavefilename" ]
then ((i++))
filename=${!i};
fi
if [ ${!i} = "--version" ]
then
echo "someversion"
exit
fi
done;
path=$( echo ${filename%/*} )
file=$( echo ${filename##/*/} )
rm /tmp/ranger-chrome-choosed
st -c ranger -n ranger -e "ranger" -t file-chooser-ranger
selected=$(cat /tmp/ranger-chrome-choosed 2> /dev/null)
if [ ! $? = 0 ]
then
exit 1
fi
if [ -d $selected ]
then
echo "$selected$file"
else
echo $selected
fi

+ 3
- 0
scripts/brave-start View File

@ -0,0 +1,3 @@
#!/bin/sh
export XDG_CURRENT_DESKTOP=KDE
brave $@

+ 1
- 1
scripts/dmenu-killall View File

@ -9,7 +9,7 @@ progname="$(expr "${0}" : '.*/\([^/]*\)')"
#variables are impractical to save complex cmds because of shell expantion
#therefore functions are required: http://mywiki.wooledge.org/BashFAQ/050
DMENU() { dmenu -p 'Kill'; }
DMENU() { dmenu -i -p 'Kill'; }
#looks better on xft powered dmenu:
#https://bugs.launchpad.net/ubuntu/+source/suckless-tools/+bug/1093745


+ 5
- 1
scripts/dmenu-refresh View File

@ -17,7 +17,8 @@ items="dwm
dwmblocks
mconnect
dunst
clipmenud"
clipmenud
quark"
# Open menu
selection=$(printf '%s' "$items" | $DMENU)
@ -43,6 +44,9 @@ case $selection in
kill -9 $(pidof dunst)
dunst &
;;
quark)
sudo systemctl restart quark
;;
esac
exit

+ 1
- 1
scripts/st-copyout View File

@ -11,4 +11,4 @@ sed -i 's/\x0//g' "$tmpfile"
ps1="λ"
chosen="$(grep -F "$ps1" "$tmpfile" | sed '$ d' | tac | grep -E -v "λ $"| dmenu -p "Copy which command's output?" -i -l 10 | sed 's/[^^]/[&]/g; s/\^/\\^/g')"
eps1="$(echo "$ps1" | sed 's/[^^]/[&]/g; s/\^/\\^/g')"
awk "/^$chosen$/{p=1;print;next} p&&/$eps1/{p=0};p" "$tmpfile" | xclip -selection clipboard
awk "/^$chosen$/{p=1;print;next} p&&/$eps1/{p=0};p" "$tmpfile" | tail -n +2 | xclip -selection clipboard

+ 1
- 2
scripts/status-bar/arch View File

@ -5,9 +5,8 @@ icon=
if ! updates=$(checkupdates 2> /dev/null | wc -l ); then
updates=0
fi
case $BLOCK_BUTTON in
1) setsid -f "$TERMINAL" -c center -n center -e yay -Syu;;
1) PATH="/opt/google-cloud-sdk/bin:/sbin:/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl" setsid -f "$TERMINAL" -c center -n center -e yay -Syu;;
6) "$TERMINAL" -e "$EDITOR" "$0" ;;
esac


+ 46
- 46
scripts/status-bar/weather View File

@ -6,54 +6,54 @@ weatherreport="${XDG_DATA_HOME:-$HOME/.local/share}/weatherreport"
weatherreportjson="${XDG_DATA_HOME:-$HOME/.local/share}/weatherreportjson"
WCODES=(
["113"]="^c#ebcb8b^"
["113"]="^c#ebcb8b^ "
["116"]="^c#ebcb8b^杖"
["119"]="摒"
["122"]=""
["143"]=""
["176"]="^c#81a1c1^"
["179"]="^c#81a1c1^"
["182"]="^c#81a1c1^"
["185"]="^c#81a1c1^"
["119"]="^c#ffffff^摒"
["122"]="^c#ffffff^ "
["143"]="^c#ffffff^ "
["176"]="^c#81a1c1^ "
["179"]="^c#81a1c1^ "
["182"]="^c#81a1c1^ "
["185"]="^c#81a1c1^ "
["200"]="^c#81a1c1^ "
["227"]=""
["230"]=""
["248"]=""
["260"]=""
["263"]="^c#81a1c1^"
["266"]="^c#81a1c1^"
["281"]="^c#81a1c1^"
["284"]="^c#81a1c1^"
["293"]="^c#81a1c1^"
["296"]="^c#81a1c1^"
["299"]="^c#81a1c1^"
["302"]="^c#81a1c1^"
["305"]="^c#81a1c1^"
["308"]="^c#81a1c1^"
["311"]="^c#81a1c1^"
["314"]="^c#81a1c1^"
["317"]="^c#81a1c1^"
["320"]=""
["323"]="^c#81a1c1^"
["326"]="^c#81a1c1^"
["329"]=""
["332"]=""
["335"]="^c#81a1c1^"
["338"]=""
["350"]="^c#81a1c1^"
["353"]="^c#81a1c1^"
["356"]="^c#81a1c1^"
["359"]="^c#81a1c1^"
["362"]="^c#81a1c1^"
["365"]="^c#81a1c1^"
["368"]="^c#81a1c1^"
["371"]="^c#81a1c1^"
["374"]="^c#81a1c1^"
["377"]="^c#81a1c1^"
["386"]="^c#81a1c1^"
["389"]="^c#81a1c1^"
["392"]="^c#81a1c1^"
["395"]="^c#81a1c1^"
["227"]="^c#ffffff^ "
["230"]="^c#ffffff^ "
["248"]="^c#ffffff^ "
["260"]="^c#ffffff^ "
["263"]="^c#81a1c1^ "
["266"]="^c#81a1c1^ "
["281"]="^c#81a1c1^ "
["284"]="^c#81a1c1^ "
["293"]="^c#81a1c1^ "
["296"]="^c#81a1c1^ "
["299"]="^c#81a1c1^ "
["302"]="^c#81a1c1^ "
["305"]="^c#81a1c1^ "
["308"]="^c#81a1c1^ "
["311"]="^c#81a1c1^ "
["314"]="^c#81a1c1^ "
["317"]="^c#81a1c1^ "
["320"]="^c#ffffff^ "
["323"]="^c#81a1c1^ "
["326"]="^c#81a1c1^ "
["329"]="^c#ffffff^ "
["332"]="^c#ffffff^ "
["335"]="^c#81a1c1^ "
["338"]="^c#ffffff^ "
["350"]="^c#81a1c1^ "
["353"]="^c#81a1c1^ "
["356"]="^c#81a1c1^ "
["359"]="^c#81a1c1^ "
["362"]="^c#81a1c1^ "
["365"]="^c#81a1c1^ "
["368"]="^c#81a1c1^ "
["371"]="^c#81a1c1^ "
["374"]="^c#81a1c1^ "
["377"]="^c#81a1c1^ "
["386"]="^c#81a1c1^ "
["389"]="^c#81a1c1^ "
["392"]="^c#81a1c1^ "
["395"]="^c#81a1c1^ "
)
getforecast() { curl -sf "wttr.in/$LOCATION" > "$weatherreport" || exit 1 ;}


+ 5
- 4
suckless/dwm/rules.h View File

@ -26,17 +26,18 @@ static const Rule rules[] = {
RULE(.class = "Spotify", .tags = 1 << 9)
RULE(.instance = "spterm", .tags = SPTAG(0), .isfloating = 1)
RULE(.class = "spfeh", .tags = SPTAG(1), .isfloating = 1)
/* Terminal Window Rules */
RULE(.instance = "spmutt", .tags = SPTAG(2), .isfloating = 1)
RULE(.class = "ranger", 0, .isfloating = 1, .floatpos="50% 50% 800W 560H")
RULE(.class = "vim", 0, .isfloating = 1, .floatpos="50% 50% 800W 560H")
RULE(.class = "vim", 0, .isfloating = 1, .floatpos="50% 50% 1000W 700H")
RULE(.class = "stpulse", 0, .isfloating = 1, .floatpos="50% 50% 800W 560H")
RULE(.class = "mpv", 0, .isfloating = 1, .floatpos="100% 1% 600W 350H")
RULE(.instance = "sxiv", 0, .isfloating = 1, .floatpos="100% 1% 600W 350H")
RULE(.class = "neomutt-send", 0, .isfloating = 1, .floatpos="50% 50% 1000W 700H")
RULE(.class = "Zathura", 0, .isfloating = 1, .floatpos="100% 50% 700W 1000H")
RULE(.class = "weather", 0, .isfloating = 1, .floatpos="50% 50% 1200W 800H") // Why did I put this here?
RULE(.class = "center", 0, .isfloating = 1, .floatpos="50% 50% 1000W 600H") // Why did I put this here?
RULE(.class = "htop", 0, .isfloating = 1, .floatpos="50% 50% 1200W 600H") // Why did I put this here?
RULE(.class = "weather", 0, .isfloating = 1, .floatpos="50% 50% 1200W 800H")
RULE(.class = "center", 0, .isfloating = 1, .floatpos="50% 50% 1000W 600H")
RULE(.class = "htop", 0, .isfloating = 1, .floatpos="50% 50% 1200W 600H")
RULE(.title = "SimCrop", 0, .isfloating = 1, .floatpos="50% 50% 800W 500H")
};

+ 279
- 0
suckless/st/normalMode.c View File

@ -0,0 +1,279 @@
#include <X11/keysym.h>
#include <X11/XKBlib.h>
#include "normalMode.h"
#include "utils.h"
extern Glyph const styleSearch, style[];
extern char const wDelS[], wDelL[], *nmKeys[];
extern unsigned int bg[], fg, currentBg, highlightBg, highlightFg, amountNmKeys;
typedef struct { int p[3]; } Pos;
struct NormalModeState {
struct OperationState {
enum Op {noop=0, visual='v', visualLine='V', yank = 'y'} op;
enum Infix {infix_none=0, infix_i='i', infix_a='a'} infix;
} cmd;
struct MotionState {
uint32_t c; int active; Pos searchPos;
enum Search {none=0, fw='/', bw='?'} search;
} m;
} defaultNormalMode, state;
DynamicArray searchStr=UTF8_ARRAY, cCmd=UTF8_ARRAY, lCmd=UTF8_ARRAY;
Glyph styleCmd;
char posBuffer[10], brack[6][2] = { {"()"}, {"<>"}, {"{}"}, {"[]"}, {"\"\""}, {"''"}};
int exited=1, overlay=1;
static inline uint32_t cchar() { return term.line[term.c.y][term.c.x].u; }
static inline int pos(int p, int h) {return IS_SET(MODE_ALTSCREEN)?p:rangeY(p+h*histOff-insertOff);}
static inline int contains(char c, char const * values, uint32_t memSize) {
for (uint32_t i = 0; i < memSize; ++i) if (c == values[i]) return 1;
return 0;
}
static inline void decodeTo(char const *cs, int len, DynamicArray *darr) {
char *var = expand(darr);
if (!var) empty(darr); else utf8decode(cs, (Rune*)(var), len);
}
static inline void applyPos(Pos p) {
term.c.x = p.p[0], term.c.y = p.p[1];
if (!IS_SET(MODE_ALTSCREEN) && histOp) term.line = &buf[histOff = p.p[2]];
}
/// Find string in history buffer, and provide string-match-lookup for highlighting matches
static int highlighted(int x, int y) {
int const s=term.row*term.col, i=y*term.col+x, sz=size(&searchStr);
return sz && i<s && mark[i]!=sz && i+mark[i]<s && !mark[i+mark[i]];
}
static void markSearchMatches(int all) {
int sz = size(&searchStr), ox = 0, oy = 0, oi=0;
for (int y=0; sz && all && y<term.row; ++y)
for (int x=0; x<term.col; ++x) term.dirty[y] |= highlighted(x, y);
for (int y = 0, wi=0, owi=0, i=0; sz && y < term.row; ++y)
for (int x=0; x<term.col; ++x, wi%=sz, ++i, owi=wi)
if (all || term.dirty[y]) {
mark[i]=sz-(wi=(getU32(&searchStr,wi,1)==term.line[y][x].u?wi+1:0));
if (wi==1) ox=x, oy=y, oi=i; else if (!wi && owi) x=ox, y=oy, i=oi;
}
for (int y=0; sz &&all &&y<term.row; ++y)
for (int x=0; x<term.col; ++x) term.dirty[y] |= highlighted(x, y);
}
static int findString(int8_t s, int all) {
Pos p = (Pos) {.p={term.c.x, term.c.y, IS_SET(MODE_ALTSCREEN) ? 0 : histOff}};
historyMove(s, 0, 0);
uint32_t strSz=size(&searchStr), maxIter=rows()*term.col+strSz, widx=0;
for (uint32_t i=0, wi = 0; widx<strSz && ++i<=maxIter; historyMove(s, 0, 0), wi=widx) {
widx = (getU32(&searchStr, widx, s>0)==cchar())?widx+1:0;
if (wi && !widx) historyMove(-s*wi, 0, 0);
}
if (widx == strSz && widx) historyMove(-s * strSz, 0, 0);
else applyPos(p);
markSearchMatches(all);
return widx == strSz;
}
/// Execute series of normal-mode commands from char array / decoded from dynamic array
static ExitState pressKeys(char const* s, size_t e) {
ExitState x=succ;
for (size_t i=0; i<e && (x=(!s[i] ? x : kpressHist(&s[i], 1, 0, NULL))); ++i);
return x;
}
static ExitState executeCommand(uint32_t *c, size_t z) {
ExitState x=succ;
char dc [32];
for (size_t i=0; i<z && (x=kpressHist(dc,utf8encode(c[i],dc),0,NULL));++i);
return x;
}
/// Get character for overlay, if the overlay (st) has something to show, else normal char.
static void getChar(DynamicArray *st, Glyph *glyphChange, int y, int xEnd, int width, int x) {
if (x < xEnd - min(width=min(width,xEnd), size(st))) *glyphChange = term.line[y][x];
else if (x<xEnd) glyphChange->u = *((Rune*)(st->content + (size(st)+x-xEnd)*st->elSize));
}
/// Expand "infix" expression: for instance (w =>) l b | | v e | | y
static ExitState expandExpression(char c) { // ({ =>) l ? { \n | l | v / } \n | h | y
int a=state.cmd.infix==infix_a, yank=state.cmd.op=='y', lc=tolower(c), found=1;
state.cmd.infix = infix_none;
if(!yank && state.cmd.op!=visual && state.cmd.op!=visualLine) return failed;
char mot[11] = {'l', 0, 'b', 0, 0, 'v', 0, 'e', 0, 0, yank ? 'y' : 0};
if (lc == 'w') mot[2] = 'b' - lc + c, mot[7] = (a ? 'w' : 'e') - lc + c, mot[9]=a?'h':0;
else {
mot[1]='?', mot[3]=mot[8]='\n', mot[6]='/', mot[4]=a?0:'l', mot[9]=a?0:'h';
for (int i=found=0; !found && i < 6; ++i)
if ((found=contains(c,brack[i],2))) mot[2]=brack[i][0], mot[7]=brack[i][1];
}
if (!found) return failed;
assign(&lCmd, &cCmd);
empty(&cCmd);
state.cmd = defaultNormalMode.cmd;
return pressKeys(mot, 11);
}
int executeMotion(char const cs, int len, KeySym const *const ks) {
state.m.c = max(state.m.c, 1);
if (ks && *ks == XK_d) historyMove(0, 0, term.row / 2);
else if (ks && *ks == XK_u) historyMove(0, 0, -term.row / 2);
else if (ks && *ks == XK_f) historyMove(0, 0, term.row-1+(term.c.y=0));
else if (ks && *ks == XK_b) historyMove(0, 0, -(term.c.y=term.row-1));
else if (ks && *ks == XK_h) overlay = !overlay;
else if (!len) return failed;
else if (cs == 'K') historyMove(0, 0, -state.m.c);
else if (cs == 'J') historyMove(0, 0, state.m.c);
else if (cs == 'k') historyMove(0, -state.m.c, 0);
else if (cs == 'j') historyMove(0, state.m.c, 0);
else if (cs == 'h') historyMove(-state.m.c, 0, 0);
else if (cs == 'l') historyMove( state.m.c, 0, 0);
else if (cs == 'H') term.c.y = 0;
else if (cs == 'M') term.c.y = term.bot / 2;
else if (cs == 'L') term.c.y = term.bot;
else if (cs == 's' || cs == 'S') altToggle = cs == 's' ? !altToggle : 1;
else if (cs == 'G' || cs == 'g') {
if (cs == 'G') term.c = c[0] = c[IS_SET(MODE_ALTSCREEN)+1];
if (!IS_SET(MODE_ALTSCREEN)) term.line = &buf[histOff=insertOff];
} else if (cs == '0') term.c.x = 0;
else if (cs == '$') term.c.x = term.col-1;
else if (cs == 't') sel.type = sel.type==SEL_REGULAR ? SEL_RECTANGULAR : SEL_REGULAR;
else if (cs == 'n' || cs == 'N') {
int const d = ((cs=='N')!=(state.m.search==bw))?-1:1;
for (int i = state.m.c; i && findString(d, 0); --i);
} else if (contains(cs, "wWeEbB", 6)) {
int const low=cs<=90, off=tolower(cs)!='w', sgn=(tolower(cs)=='b')?-1:1,
l=strlen(wDelL), s=strlen(wDelS), mit=rows()*term.col;
for (int it=0, on=0; state.m.c > 0; ++it) {
if (off || it) if (!historyMove(sgn, 0, 0)) it = mit; //< offset move
int n = 1<<(contains(cchar(),wDelS,s) ?(2-low) :!contains(cchar(),wDelL,l)),
found = (on|=n)^n && ((off ?on^n :n)!=1); //< state change &letter state
if (found && off) historyMove(-sgn, 0, 0); //< offset move if required
if (found || it>mit) it=-1, on=0, --state.m.c; //< terminate iteration
}
} else return failed;
state.m.c = 0;
return state.cmd.op == yank ? exitMotion : succ;
}
ExitState kpressHist(char const *cs, int len, int ctrl, KeySym const *ksym) {
historyOpToggle(1, 1);
int const prevYOff=IS_SET(MODE_ALTSCREEN)?0:histOff, search=state.m.search&&state.m.active,
prevAltToggle=altToggle, prevOverlay=overlay;
int const noOp=!state.cmd.op&&!state.cmd.infix, num=len==1&&BETWEEN(cs[0],48,57),
esc=ksym&&*ksym==XK_Escape, ret=(ksym&&*ksym==XK_Return)||(len==1&&cs[0]=='\n'),
quantifier=num&&(cs[0]!='0'||state.m.c), ins=!search &&noOp &&len &&cs[0]=='i';
exited = 0;
ExitState result = succ;
if (esc || ret || ins) { result = exitMotion, len = 0;
} else if (ksym && *ksym == XK_BackSpace) {
if ((search || state.m.c) && size(&cCmd)) pop(&cCmd);
if (search) {
if (size(&searchStr)) pop(&searchStr);
else result = exitMotion;
if (!size(&searchStr)) tfulldirt();
applyPos(state.m.searchPos);
findString(state.m.search==fw ? 1 : -1, 1);
} else if (state.m.c) state.m.c /= 10;
len = 0;
} else if (search) {
if (len >= 1) decodeTo(cs, len, &searchStr);
applyPos(state.m.searchPos);
findString(state.m.search==fw ? 1 : -1, 1);
} else if (len == 0) { result = failed;
} else if (quantifier) { state.m.c = min(SHRT_MAX, state.m.c*10+cs[0]-48);
} else if (state.cmd.infix && state.cmd.op && (result = expandExpression(cs[0]), len=0)) {
} else if (cs[0] == '.') {
if (size(&cCmd)) assign(&lCmd, &cCmd);
empty(&cCmd);
executeCommand((uint32_t*) lCmd.content, size(&lCmd));
empty(&cCmd);
len = 0;
} else if (cs[0] == 'r') { tfulldirt();
} else if (cs[0] == 'c') {
empty(&lCmd);
empty(&cCmd);
empty(&searchStr);
tfulldirt();
len = 0;
} else if (cs[0] == fw || cs[0] == bw) {
empty(&searchStr);
state.m.search = cs[0];
state.m.searchPos = (Pos){.p={term.c.x, term.c.y, prevYOff}};
state.m.active = 1;
} else if (cs[0]==infix_i || cs[0]==infix_a) { state.cmd.infix=cs[0];
} else if (cs[0] == 'y') {
if (state.cmd.op) {
result = (state.cmd.op == yank) ? exitOp : exitMotion;
if (state.cmd.op == yank) selstart(0, term.c.y, 0);
} else selstart(term.c.x, term.c.y, 0);
state.cmd.op = yank;
} else if (cs[0] == visual || cs[0] == visualLine) {
if (state.cmd.op != (unsigned char) cs[0]) {
state.cmd = defaultNormalMode.cmd;
state.cmd.op = cs[0];
selstart(cs[0] == visualLine ?0 :term.c.x, term.c.y, 0);
} else result = exitOp;
} else if (!(result =executeMotion(len?cs[0]:0, len, ctrl?ksym:NULL))) {
result=failed;
for (size_t i = 0; !ctrl && i < amountNmKeys; ++i)
if (cs[0]==nmKeys[i][0] &&
failed!=(result=pressKeys(&nmKeys[i][1], strlen(nmKeys[i])-1))) goto end;
} // Operation/Motion finished if valid: update cmd string, extend selection, update search
if (result != failed) {
if (len == 1 && !ctrl) decodeTo(cs, len, &cCmd);
if ((state.cmd.op == visualLine) || ((state.cmd.op == yank) && (result == exitOp))) {
int const off = pos(term.c.y, 1) < pos(sel.ob.y, 0);
sel.ob.x = off ? term.col - 1 : 0;
selextend(off ? 0 : term.col-1, term.c.y, sel.type, 0);
} else if (sel.oe.x != -1) selextend(term.c.x, term.c.y, sel.type, 0);
} // Set repaint for motion or status bar
if (!IS_SET(MODE_ALTSCREEN) && prevYOff != histOff) tfulldirt();
// Terminate Motion / operation if thus indicated
if (result == exitMotion) {
if (!state.m.active) result = (exited=noOp) ? finished : exitOp;
state.m.active = state.m.c = 0;
}
if (result == exitOp || result == finished) {
if (state.cmd.op == yank) {
xsetsel(getsel());
xclipcopy();
}
state = defaultNormalMode;
selclear();
if (!esc) assign(&lCmd, &cCmd);
empty(&cCmd);
} // Update the content displayed in the history overlay
styleCmd = style[state.cmd.op==yank ? 1 : (state.cmd.op==visual ? 2 :
(state.cmd.op==visualLine ? 3 :0))];
int const posLin = !IS_SET(MODE_ALTSCREEN) ? rangeY(insertOff-histOff):0, h=rows()-term.row;
if (!posLin || posLin==h || !h) strcpy(posBuffer, posLin ? " [BOT] " : " [TOP] ");
else sprintf(posBuffer, " % 3d%c ", min(100, max(0, .5 + posLin * 100. / h)),'%');
if ((overlay || overlay!=prevOverlay) && term.col>9 && term.row>4) {
if (!term.dirty[term.row-1]) xdrawline(term.line[term.row-1], term.col*2/3, term.row-1, term.col-1);
if (!term.dirty[term.row-2]) xdrawline(term.line[term.row-2], term.col*2/3, term.row-2, term.col-1);
}
if (result==finished) altToggle = 0;
if (altToggle != prevAltToggle) tswapscreen();
end:
historyOpToggle(-1, 1);
return result;
}
void historyOverlay(int x, int y, Glyph* g) {
if (!histMode) return;
TCursor const *cHist = histOp ? &term.c : &c[0];
if(overlay && term.col > 9 && term.row > 4 && (x > (2*term.col/3)) && (y >= (term.row-2))) {
*g = (y == term.row - 2) ? styleSearch : styleCmd;
if (y == term.row-2) getChar(&searchStr, g, term.row-2, term.col-2, term.col/3, x);
else if (x > term.col - 7) g->u = posBuffer[x - term.col + 7];
else getChar(size(&cCmd) ?&cCmd :&lCmd, g, term.row-1, term.col-7, term.col/3-6, x);
} else if (highlighted(x, y)) g->bg = highlightBg, g->fg = highlightFg;
else if ((x==cHist->x) ^ (y==cHist->y)) g->bg = currentBg;
else if (x==cHist->x) g->mode^=ATTR_REVERSE;
}
void historyPreDraw() {
static Pos op = {.p={0, 0, 0}};
historyOpToggle(1, 0);
// Draw the cursor cross if changed
if (term.c.y >= term.row || op.p[1] >= term.row) tfulldirt();
else if (exited || (op.p[1] != term.c.y)) term.dirty[term.c.y] = term.dirty[op.p[1]] = 1;
for (int i=0; (exited || term.c.x != op.p[0]) && i<term.row; ++i) if (!term.dirty[i]) {
xdrawline(term.line[i], term.c.x, i, term.c.x + 1);
xdrawline(term.line[i], op.p[0], i, op.p[0] + 1);
}
// Update search results either only for lines with new content or all results if exiting
markSearchMatches(exited);
op = (Pos){.p = {term.c.x, term.c.y, 0}};
historyOpToggle(-1, 0);
}

+ 7
- 0
suckless/st/normalMode.h View File

@ -0,0 +1,7 @@
void normalMode();
void historyPreDraw();
void historyOverlay(int x, int y, Glyph* g);
void historyModeToggle(int start);
/// Handles keys in normal mode.
typedef enum {failed=0, succ=1, exitMotion=2, exitOp=3, finished=4} ExitState;
ExitState kpressHist(char const *txt, int len, int ctrl, KeySym const *kSym);

+ 1056
- 0
suckless/st/st-vimBrowse-20200607-0.8.3.diff
File diff suppressed because it is too large
View File


+ 23
- 0
suckless/st/utils.h View File

@ -0,0 +1,23 @@
/// Dynamic memory-chunk, with (1) datatype size, (2/3) initialized / allocated chunk, (4) content
typedef struct { uint8_t const elSize; uint32_t init, alloc; char* content; } DynamicArray;
#define UTF8_ARRAY {4, 0, 0, NULL}
static inline int p_alloc(DynamicArray *s, uint32_t amount) {
uint32_t const diff=s->init+s->elSize*amount-s->alloc, nas=s->alloc+max(diff,15)*s->elSize;
if (s->alloc < s->init + s->elSize * amount) {
char* tmp = realloc(s->content, nas);
if (!tmp) return 0;
s->alloc = nas, s->content = tmp;
}
return 1;
}
static inline char *view(DynamicArray * s, uint32_t i) { return s->content + i*s->elSize; }
static inline char *end(DynamicArray *s, uint32_t i) { return s->content +s->init-(i+1)*s->elSize; }
static inline uint32_t getU32(DynamicArray* s, uint32_t i, int b) { return *((uint32_t*) (b ?view(s,i) :end(s,i))); }
static char *expand(DynamicArray *s) { if (!p_alloc(s, 1)) return NULL; s->init += s->elSize; return end(s, 0); }
static inline void pop(DynamicArray* s) { s->init -= s->elSize; }
static inline void empty(DynamicArray* s) { s->init = 0; }
static inline int size(DynamicArray const * s) { return s->init / s->elSize; }
static inline void assign(DynamicArray* s, DynamicArray const *o) {
if (p_alloc(s, size(o))) memcpy(s->content, o->content, (s->init=o->init));
}

+ 2
- 1
xorg/xinitrc View File

@ -4,6 +4,7 @@ pkill -f clipmenud
pkill -f "bash /sbin/clipmenud"
pkill -f "/usr/bin/gnome-keyring-daemon --start --components=pkcs11,secrets,ssh"
pkill -f "/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1"
rm -rf /tmp/day_cache
source ~/.config.env
eval $(/usr/bin/gnome-keyring-daemon --start --components=pkcs11,secrets,ssh)
@ -38,7 +39,7 @@ echo "on" > ~/.cache/dunst
echo "on" > ~/.cache/screensaver
dbus-update-activation-environment --systemd DISPLAY
picom --no-fading-openclose &
brave &
brave-start &
bitwarden-desktop &
curl 'http://yeetclock/setcolor?R=136&G=192&B=208' &
xbanish -t 2000 -s &


+ 1
- 1
zsh/profile View File

@ -15,4 +15,4 @@ export EDITOR=vim
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/platform-tools
export PATH=$PATH:$FLUTTER_HOME/bin
export PATH="/home/yigit/.scripts:/home/yigit/.gem/ruby/2.7.0/bin:$GOPATH/bin:$GOPATH/binexport:/home/yigit/.local/bin:$PATH"
export PATH="$PATH:/home/yigit/.scripts:/home/yigit/.gem/ruby/2.7.0/bin:$GOPATH/bin:$GOPATH/binexport:/home/yigit/.local/bin"

Loading…
Cancel
Save