[Misc] switching to new repo for org files
5
docs/.dir-locals.el
Normal file
@@ -0,0 +1,5 @@
|
||||
;;; Directory Local Variables -*- no-byte-compile: t -*-
|
||||
;;; For more information see (info "(emacs) Directory Variables")
|
||||
|
||||
((org-mode . ((org-list-allow-alphabetical . nil)
|
||||
(org-confirm-babel-evaluate . nil))))
|
||||
11
docs/.vuepress/client.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { defineClientConfig } from '@vuepress/client';
|
||||
import ImgFigure from './components/ImgFigure.vue';
|
||||
|
||||
export default defineClientConfig({
|
||||
enhance({ app }) {
|
||||
app.component('ImgFigure', ImgFigure);
|
||||
},
|
||||
setup() {},
|
||||
layouts: {},
|
||||
rootComponents: [],
|
||||
});
|
||||
19
docs/.vuepress/components/ImgFigure.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<img :alt="alt" :src="src" />
|
||||
<figcaption><slot></slot></figcaption>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{
|
||||
src: string;
|
||||
alt?: string;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<style>
|
||||
figcaption {
|
||||
text-align: center;
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
</style>
|
||||
132
docs/.vuepress/config.ts
Normal file
@@ -0,0 +1,132 @@
|
||||
import { defineUserConfig, defaultTheme } from 'vuepress';
|
||||
import { removeHtmlExtensionPlugin } from 'vuepress-plugin-remove-html-extension';
|
||||
import head from './head';
|
||||
|
||||
export default defineUserConfig({
|
||||
lang: 'en-US',
|
||||
title: "Phundrak's Dotfiles",
|
||||
head: head,
|
||||
description: "Documentation of the GNU/Linux configuration of P'undrak",
|
||||
markdown: {
|
||||
html: false,
|
||||
linkify: true,
|
||||
typographer: true,
|
||||
headers: {
|
||||
level: [1, 2, 3, 4, 5],
|
||||
},
|
||||
},
|
||||
plugins: [removeHtmlExtensionPlugin()],
|
||||
theme: defaultTheme({
|
||||
sidebarDepth: 5,
|
||||
repo: 'https://labs.phundrak.com/phundrak/config.phundrak.com',
|
||||
sidebar: [
|
||||
'/',
|
||||
'/about',
|
||||
{
|
||||
text: 'Emacs',
|
||||
link: '/emacs/',
|
||||
collapsible: true,
|
||||
children: [
|
||||
{
|
||||
text: 'Basic Configuration',
|
||||
link: '/emacs/basic-config',
|
||||
},
|
||||
{
|
||||
text: 'Custom Elisp',
|
||||
link: '/emacs/custom-elisp',
|
||||
},
|
||||
{
|
||||
text: 'Package Manager',
|
||||
link: '/emacs/package-manager',
|
||||
},
|
||||
{
|
||||
text: 'Keybindings Managers',
|
||||
link: '/emacs/keybinding-managers',
|
||||
},
|
||||
{
|
||||
text: 'Packages - Autocompletion',
|
||||
link: '/emacs/packages/autocompletion',
|
||||
},
|
||||
{
|
||||
text: 'Packages - Applications',
|
||||
link: '/emacs/packages/applications',
|
||||
},
|
||||
{
|
||||
text: 'Packages - Editing',
|
||||
link: '/emacs/packages/editing',
|
||||
},
|
||||
{
|
||||
text: 'Packages - Emacs Built-ins',
|
||||
link: '/emacs/packages/emacs-builtin',
|
||||
},
|
||||
{
|
||||
text: 'Packages - Making My Life Easier',
|
||||
link: '/emacs/packages/helpful',
|
||||
},
|
||||
{
|
||||
text: 'Packages - LaTeX',
|
||||
link: '/emacs/packages/latex',
|
||||
},
|
||||
{
|
||||
text: 'Packages - Org Mode',
|
||||
link: '/emacs/packages/org',
|
||||
},
|
||||
{
|
||||
text: 'Packages - Programming',
|
||||
link: '/emacs/packages/programming',
|
||||
},
|
||||
{
|
||||
text: 'Packages - Visual Configuration',
|
||||
link: '/emacs/packages/visual-config',
|
||||
},
|
||||
{
|
||||
text: 'Packages - Misc',
|
||||
link: '/emacs/packages/misc',
|
||||
},
|
||||
{
|
||||
text: 'Keybindings',
|
||||
link: '/emacs/keybindings',
|
||||
},
|
||||
],
|
||||
},
|
||||
'/scripts',
|
||||
'/desktop',
|
||||
// '/fish',
|
||||
// '/git',
|
||||
// '/mpd',
|
||||
'/neofetch',
|
||||
'/picom',
|
||||
'/rustfmt',
|
||||
'/stumpwm',
|
||||
// '/tmux',
|
||||
'/bootstrap',
|
||||
{
|
||||
text: 'Deprecated Configs',
|
||||
link: '/deprecated/',
|
||||
collapsible: true,
|
||||
children: [
|
||||
{
|
||||
text: 'AwesomeWM',
|
||||
link: '/deprecated/awesome',
|
||||
},
|
||||
{
|
||||
text: 'i3',
|
||||
link: '/deprecated/i3',
|
||||
},
|
||||
{
|
||||
text: 'Nano',
|
||||
link: '/deprecated/nano',
|
||||
},
|
||||
{
|
||||
text: 'Polybar',
|
||||
link: '/deprecated/polybar',
|
||||
},
|
||||
{
|
||||
text: 'Spacemacs',
|
||||
link: '/deprecated/spacemacs',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}),
|
||||
});
|
||||
145
docs/.vuepress/head.ts
Normal file
@@ -0,0 +1,145 @@
|
||||
interface SimplifiedHeader {
|
||||
tag: string;
|
||||
content: [any];
|
||||
}
|
||||
|
||||
const matomoTrackingCode = `var _paq = window._paq = window._paq || [];
|
||||
_paq.push(['trackPageView']);
|
||||
_paq.push(['enableLinkTracking']);
|
||||
(function() {
|
||||
var u="https://matomo.phundrak.com/";
|
||||
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
||||
_paq.push(['setSiteId', '2']);
|
||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
||||
})();`;
|
||||
|
||||
const simplifiedHead = [
|
||||
{
|
||||
tag: "meta",
|
||||
content: [
|
||||
{
|
||||
name: "author",
|
||||
content: "Lucien Cartier-Tilet",
|
||||
},
|
||||
{
|
||||
property: "og:image",
|
||||
content: "https://cdn.phundrak.com/img/rich_preview.png",
|
||||
},
|
||||
{
|
||||
property: "og:title",
|
||||
content: "P’undrak’s GNU/Linux Config",
|
||||
},
|
||||
{
|
||||
property: "og:description",
|
||||
content: "Documentation of P’undrak’s GNU/Linux configuration files",
|
||||
},
|
||||
{
|
||||
name: "twitter:card",
|
||||
content: "summary",
|
||||
},
|
||||
{
|
||||
name: "twitter:site",
|
||||
content: "@phundrak",
|
||||
},
|
||||
{
|
||||
name: "twitter:creator",
|
||||
content: "@phundrak",
|
||||
},
|
||||
{ name: "msapplication-TileColor", content: "#3b4252" },
|
||||
{ name: "msapplication-TileImage", content: "/ms-icon-144x144.png" },
|
||||
{ name: "theme-color", content: "#3b4252" },
|
||||
],
|
||||
},
|
||||
{
|
||||
tag: "link",
|
||||
content: [
|
||||
{
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "57x57",
|
||||
href: "/apple-icon-57x57.png",
|
||||
},
|
||||
{
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "60x60",
|
||||
href: "/apple-icon-60x60.png",
|
||||
},
|
||||
{
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "72x72",
|
||||
href: "/apple-icon-72x72.png",
|
||||
},
|
||||
{
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "76x76",
|
||||
href: "/apple-icon-76x76.png",
|
||||
},
|
||||
{
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "114x114",
|
||||
href: "/apple-icon-114x114.png",
|
||||
},
|
||||
{
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "120x120",
|
||||
href: "/apple-icon-120x120.png",
|
||||
},
|
||||
{
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "144x144",
|
||||
href: "/apple-icon-144x144.png",
|
||||
},
|
||||
{
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "152x152",
|
||||
href: "/apple-icon-152x152.png",
|
||||
},
|
||||
{
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "180x180",
|
||||
href: "/apple-icon-180x180.png",
|
||||
},
|
||||
{
|
||||
rel: "icon",
|
||||
type: "image/png",
|
||||
sizes: "192x192",
|
||||
href: "/android-icon-192x192.png",
|
||||
},
|
||||
{
|
||||
rel: "icon",
|
||||
type: "image/png",
|
||||
sizes: "32x32",
|
||||
href: "/favicon-32x32.png",
|
||||
},
|
||||
{
|
||||
rel: "icon",
|
||||
type: "image/png",
|
||||
sizes: "96x96",
|
||||
href: "/favicon-96x96.png",
|
||||
},
|
||||
{
|
||||
rel: "icon",
|
||||
type: "image/png",
|
||||
sizes: "16x16",
|
||||
href: "/favicon-16x16.png",
|
||||
},
|
||||
{ rel: "manifest", href: "/manifest.json" },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
let head = [];
|
||||
simplifiedHead.forEach((tag: SimplifiedHeader) => {
|
||||
let tagName = tag.tag;
|
||||
tag.content.forEach((element) => {
|
||||
head.push([tagName, element]);
|
||||
});
|
||||
});
|
||||
head.push([
|
||||
"a",
|
||||
{ rel: "me", href: "https://mastodon.phundrak.com/@phundrak" },
|
||||
"Mastodon",
|
||||
]);
|
||||
head.push(["script", {}, matomoTrackingCode]);
|
||||
|
||||
export default head;
|
||||
BIN
docs/.vuepress/public/android-icon-144x144.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
docs/.vuepress/public/android-icon-192x192.png
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
docs/.vuepress/public/android-icon-36x36.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
docs/.vuepress/public/android-icon-48x48.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
docs/.vuepress/public/android-icon-72x72.png
Normal file
|
After Width: | Height: | Size: 9.8 KiB |
BIN
docs/.vuepress/public/android-icon-96x96.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
docs/.vuepress/public/apple-icon-114x114.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
docs/.vuepress/public/apple-icon-120x120.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
docs/.vuepress/public/apple-icon-144x144.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
docs/.vuepress/public/apple-icon-152x152.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
docs/.vuepress/public/apple-icon-180x180.png
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
docs/.vuepress/public/apple-icon-57x57.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
docs/.vuepress/public/apple-icon-60x60.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
docs/.vuepress/public/apple-icon-72x72.png
Normal file
|
After Width: | Height: | Size: 9.8 KiB |
BIN
docs/.vuepress/public/apple-icon-76x76.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
docs/.vuepress/public/apple-icon-precomposed.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
docs/.vuepress/public/apple-icon.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
2
docs/.vuepress/public/browserconfig.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig><msapplication><tile><square70x70logo src="/ms-icon-70x70.png"/><square150x150logo src="/ms-icon-150x150.png"/><square310x310logo src="/ms-icon-310x310.png"/><TileColor>#eceff4</TileColor></tile></msapplication></browserconfig>
|
||||
BIN
docs/.vuepress/public/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
docs/.vuepress/public/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
docs/.vuepress/public/favicon-96x96.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
docs/.vuepress/public/favicon.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
docs/.vuepress/public/ms-icon-144x144.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
docs/.vuepress/public/ms-icon-150x150.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
docs/.vuepress/public/ms-icon-310x310.png
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
docs/.vuepress/public/ms-icon-70x70.png
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
174
docs/.vuepress/styles/index.scss
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Nord Theme:
|
||||
* - Copyright (c) 2016-present Arctic Ice Studio <development@arcticicestudio.com>
|
||||
* - Copyright (c) 2016-present Sven Greb <development@svengreb.de>
|
||||
*/
|
||||
|
||||
:root {
|
||||
--nord0: #2e3440;
|
||||
--nord1: #3b4252;
|
||||
--nord2: #434c5e;
|
||||
--nord3: #4c566a;
|
||||
--nord4: #d8dee9;
|
||||
--nord5: #e5e9f0;
|
||||
--nord6: #eceff4;
|
||||
--nord7: #8fbcbb;
|
||||
--nord8: #88c0d0;
|
||||
--nord9: #81a1c1;
|
||||
--nord10: #5e81ac;
|
||||
--nord11: #bf616a;
|
||||
--nord12: #d08770;
|
||||
--nord13: #ebcb8b;
|
||||
--nord14: #a3be8c;
|
||||
--nord15: #b48ead;
|
||||
|
||||
scroll-behavior: smooth;
|
||||
|
||||
// brand colors
|
||||
--c-brand: var(--nord9);
|
||||
--c-brand-light: var(--nord14);
|
||||
|
||||
// background colors
|
||||
--c-bg: var(--nord6);
|
||||
--c-bg-light: var(--nord6);
|
||||
--c-bg-lighter: var(--nord5);
|
||||
--c-bg-dark: var(--nord5);
|
||||
--c-bg-darker: var(--nord4);
|
||||
--c-bg-navbar: var(--c-bg);
|
||||
--c-bg-sidebar: var(--c-bg);
|
||||
--c-bg-arrow: var(--nord4);
|
||||
|
||||
// text colors
|
||||
--c-text: var(--nord1);
|
||||
--c-text-accent: var(--c-brand);
|
||||
--c-text-light: var(--nord2);
|
||||
--c-text-lighter: var(--nord3);
|
||||
--c-text-lightest: var(--nord4);
|
||||
--c-text-quote: var(--nord2);
|
||||
|
||||
// border colors
|
||||
--c-border: var(--nord4);
|
||||
--c-border-dark: var(--nord4);
|
||||
|
||||
// custom container colors
|
||||
--c-tip: var(--nord14);
|
||||
--c-tip-bg: rgba(163, 190, 140, 0.2);
|
||||
--c-tip-title: var(--c-text);
|
||||
--c-tip-text: var(--c-text);
|
||||
--c-tip-text-accent: var(--c-text-accent);
|
||||
--c-warning: var(--nord13);
|
||||
--c-warning-bg: rgba(235, 203, 139, 0.3);
|
||||
--c-warning-bg-light: rgba(235, 203, 139, 0.2);
|
||||
--c-warning-bg-lighter: rgba(235, 203, 139, 0.1);
|
||||
--c-warning-border-dark: var(--nord3);
|
||||
--c-warning-details-bg: var(--c-bg);
|
||||
--c-warning-title: var(--nord12);
|
||||
--c-warning-text: var(--nord12);
|
||||
--c-warning-text-accent: var(--nord12);
|
||||
--c-warning-text-light: var(--nord12);
|
||||
--c-warning-text-quote: var(--nord12);
|
||||
|
||||
--c-danger: var(--nord11);
|
||||
--c-danger-bg: rgba(191, 97, 106, 0.2);
|
||||
--c-danger-bg-light: rgba(191, 97, 106, 0.2);
|
||||
--c-danger-bg-lighter: rgba(191, 97, 106, 0.1);
|
||||
--c-danger-border-dark: var(--nord11);
|
||||
--c-danger-details-bg: var(--nord2);
|
||||
--c-danger-title: var(--nord11);
|
||||
--c-danger-text: var(--nord11);
|
||||
--c-danger-text-accent: var(--nord11);
|
||||
--c-danger-text-light: var(--nord11);
|
||||
--c-danger-text-quote: var(--nord11);
|
||||
|
||||
--c-details-bg: var(--c-bg-lighter);
|
||||
|
||||
// badge component colors
|
||||
--c-badge-tip: var(--c-tip);
|
||||
--c-badge-warning: var(--c-warning);
|
||||
--c-badge-warning-text: var(--c-bg);
|
||||
--c-badge-danger: var(--c-danger);
|
||||
--c-badge-danger-text: var(--c-bg);
|
||||
|
||||
// transition vars
|
||||
--t-color: 0.3s ease;
|
||||
--t-transform: 0.3s ease;
|
||||
|
||||
// code blocks vars
|
||||
--code-bg-color: var(--nord0);
|
||||
--code-hl-bg-color: var(--nord1);
|
||||
--code-ln-color: #9e9e9e;
|
||||
--code-ln-wrapper-width: 3.5rem;
|
||||
|
||||
// font vars
|
||||
--font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
|
||||
Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
|
||||
--font-family-code: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
|
||||
// layout vars
|
||||
--navbar-height: 3.6rem;
|
||||
--navbar-padding-v: 0.7rem;
|
||||
--navbar-padding-h: 1.5rem;
|
||||
--sidebar-width: 20rem;
|
||||
--sidebar-width-mobile: calc(var(--sidebar-width) * 0.82);
|
||||
--content-width: 740px;
|
||||
--homepage-width: 960px;
|
||||
}
|
||||
|
||||
html.dark {
|
||||
// brand colors
|
||||
--c-brand: var(--nord14);
|
||||
--c-brand-light: var(--nord14);
|
||||
|
||||
// background colors
|
||||
--c-bg: var(--nord1);
|
||||
--c-bg-light: var(--nord2);
|
||||
--c-bg-lighter: var(--nord2);
|
||||
--c-bg-dark: var(--nord3);
|
||||
--c-bg-darker: var(--nord3);
|
||||
|
||||
// text colors
|
||||
--c-text: var(--nord4);
|
||||
--c-text-light: var(--nord5);
|
||||
--c-text-lighter: var(--nord5);
|
||||
--c-text-lightest: var(--nord6);
|
||||
--c-text-quote: var(--c-text);
|
||||
|
||||
// border colors
|
||||
--c-border: var(--nord3);
|
||||
--c-border-dark: var(--nord3);
|
||||
|
||||
// custom container colors
|
||||
--c-tip: var(--nord14);
|
||||
--c-warning: var(--nord13);
|
||||
--c-warning-bg: rgba(235, 203, 139, 0.2);
|
||||
--c-warning-bg-light: rgba(235, 203, 139, 0.2);
|
||||
--c-warning-bg-lighter: rgba(235, 203, 139, 0.1);
|
||||
--c-warning-border-dark: var(--nord3);
|
||||
--c-warning-details-bg: var(--c-bg);
|
||||
--c-warning-title: var(--nord13);
|
||||
--c-warning-text: var(--nord13);
|
||||
--c-warning-text-accent: var(--nord13);
|
||||
--c-warning-text-light: var(--nord13);
|
||||
--c-warning-text-quote: var(--nord13);
|
||||
|
||||
--c-danger: var(--nord11);
|
||||
--c-danger-bg: rgba(191, 97, 106, 0.2);
|
||||
--c-danger-bg-light: rgba(191, 97, 106, 0.2);
|
||||
--c-danger-bg-lighter: rgba(191, 97, 106, 0.1);
|
||||
--c-danger-border-dark: var(--nord11);
|
||||
--c-danger-details-bg: var(--nord2);
|
||||
--c-danger-title: hsl(354 43% 75.7%);
|
||||
--c-danger-text: hsl(354 43% 80.7%);
|
||||
--c-danger-text-accent: var(--nord11);
|
||||
--c-danger-text-light: var(--nord11);
|
||||
--c-danger-text-quote: var(--nord11);
|
||||
|
||||
--c-details-bg: var(--c-bg-light);
|
||||
|
||||
// badge component colors
|
||||
--c-badge-warning-text: var(--nord0);
|
||||
--c-badge-danger-text: var(--nord0);
|
||||
|
||||
// code blocks vars
|
||||
--code-hl-bg-color: var(--nord2);
|
||||
}
|
||||
30
docs/README.org
Normal file
@@ -0,0 +1,30 @@
|
||||
#+title: P’undrak’s Dotfiles
|
||||
#+setupfile: headers
|
||||
|
||||
* Index
|
||||
Hi, I’m P’undrak (pronounced /PUN-DRAK/, or more exactly {{{phon(pʰynɖak̚)}}}),
|
||||
also known as Lucien Cartier-Tilet. If you want to know more about me,
|
||||
you can head to my [[https://phundrak.com/en][main website]].
|
||||
|
||||
This website is my collection of dotfiles for my daily GNU/Linux
|
||||
environment, tweaked to my liking. The sidebar will act as an index of
|
||||
the various tools I use and their configuration.
|
||||
|
||||
Additionaly, you can find my configuration for my ErgodoxEZ keyboard
|
||||
[[https://configure.ergodox-ez.com/ergodox-ez/layouts/5WrVw/latest/0][here]]. It is optimized for usage with the Bépo layout set as a software
|
||||
layout. It has also a layer set to emulate a Qwerty layout when using
|
||||
the Bépo software layout due to some games that do not offer to remap
|
||||
keys or whose remap feature is kind of buggy with some keys, such as
|
||||
the «é» placed where the «w» is on a Qwerty layout (I’m looking at
|
||||
you, HoloCure).
|
||||
|
||||
** Installation
|
||||
If you wish to install my dotfiles and you are on ArchLinux, you can
|
||||
follow the [[file:bootstrap.org][bootstrap]] page where you can find a walkthrough of how I
|
||||
configure my environment and what I install. If you have [[https://github.com/TheLocehiliosan/yadm][YADM]]
|
||||
installed, you can even execute =yadm bootstrap= to execute it after
|
||||
cloning my repo with =yadm clone
|
||||
https://labs.phundrak.com/phundrak/dotfiles.git=.
|
||||
|
||||
** License
|
||||
See [[https://labs.phundrak.com/phundrak/dotfiles/src/branch/master/LICENSE.org][the repository’s license file]].
|
||||
72
docs/about.org
Normal file
@@ -0,0 +1,72 @@
|
||||
#+title: About this website
|
||||
#+setupfile: headers
|
||||
|
||||
* About this website
|
||||
** Introduction
|
||||
This is the config website of Lucien “Phundrak” Cartier-Tilet.
|
||||
|
||||
This website is made with [[https://orgmode.org/][org-mode]] and [[https://v2.vuepress.vuejs.org/][Vuepress]] and is entirely free
|
||||
and open-source. You can find its source code on my Gitea instance
|
||||
[[https://labs.phundrak.com/phundrak/config.phundrak.com][here]].
|
||||
|
||||
** Where is the website hosted?
|
||||
This website is hosted on my private physical server, located in the
|
||||
town of Bron in France, near Lyon. All of my websites are also hosted
|
||||
on this server, except for [[https://labs.phundrak.com][=labs.phundrak.com=]] and =mail.phundrak.com=
|
||||
which are hosted on servers rented to Scaleway and OVH France
|
||||
respectively. These servers are also located in France.
|
||||
|
||||
** Cookies
|
||||
*** What are cookies?
|
||||
Cookies are small files a website saves on your computer or mobile
|
||||
phone when you visit a website. site. Although not all sites make use
|
||||
of them, they are nevertheless extremely common in order to allow
|
||||
websites to function properly or function properly or more
|
||||
efficiently.
|
||||
|
||||
This website uses some functional cookies in order to remember your
|
||||
preferences, such as your preferred language or its color theme. These
|
||||
cookies are not and cannot be used to track you.
|
||||
|
||||
However, as this site is protected by Cloudflare, they may also host
|
||||
some cookies to remember, for example, that your browser is safe or to
|
||||
record traffic to the site.
|
||||
|
||||
*** How can I control cookies on my computer?
|
||||
If you don't want Cloudflare to record your browsing activity on my
|
||||
website, a good adblocker should do the trick. I personally recommend
|
||||
[[https://ublockorigin.com/][uBlock Origin]], one of the most effective adblockers I know of if not
|
||||
the most effective one.
|
||||
|
||||
You can also manually delete cookies from your browser, but given the
|
||||
number of browsers out there, it might be quicker for you to look up
|
||||
DuckDuckGo, Qwant or Startpage to do this for your current browser (if
|
||||
you're worried about cookie usage, I guess you'll want to avoid
|
||||
Google).
|
||||
|
||||
*** What about other methods of tracking users?
|
||||
There are other more subtle methods of tracking someone on the
|
||||
internet, or even via emails or any web content rendered on the
|
||||
screen, such as web beacons (extremely small images). It is also
|
||||
possible to store Flash cookies or local shared objects.
|
||||
|
||||
This site does not use them at all.
|
||||
|
||||
** Is there targeted advertisement on this website?
|
||||
There’s no advertisement to begin with. If you see any, check your
|
||||
computer and browser for virus, that is not normal.
|
||||
|
||||
** How often is this page updated?
|
||||
It is updated from time to time to reflect any changes in how my
|
||||
website behaves, or if I notice errors on this page (such as typos). I
|
||||
might add some user tracking, however don’t worry, Matomo (the service
|
||||
I would use) would only track you on this website and this website
|
||||
only. Matomo respects the privacy of a website’s users.
|
||||
|
||||
You can see the last update of this page by looking at the last
|
||||
modification of the file =about.org= on [[https://labs.phundrak.com/phundrak/config.phundrak.com/src/branch/main/docs][this page]].
|
||||
|
||||
** I have other questions
|
||||
|
||||
And I have the answers! I’ll be more thang happy to chat with you by
|
||||
email, feel free to send me one at [[mailto:lucien@phundrak.com][lucien@phundrak.com]].
|
||||
935
docs/bootstrap.org
Normal file
@@ -0,0 +1,935 @@
|
||||
#+TITLE: Arch Linux, Phundrak-flavored
|
||||
#+setupfile: headers
|
||||
#+PROPERTY: header-args :tangle no :exports none
|
||||
#+PROPERTY: header-args:sh :tangle no :exports code
|
||||
#+PROPERTY: header-args:fish :exports code :noweb yes
|
||||
#+PROPERTY: header-args:emacs-lisp :exports none :noweb yes :tangle no :cache yes
|
||||
|
||||
* Bootstrap Script
|
||||
Here will be presented what I do to get my system up and running on a fresh Arch
|
||||
Linux install. These installation instructions were written in order to get an
|
||||
Arch Linux distribution up and running with the same configuration as my main
|
||||
computer’s and my travelling laptop’s configuration.
|
||||
|
||||
** Install Arch Linux
|
||||
I usually install Arch from the [[https://www.archlinux.org/download/][vanilla ISO]], however I began using [[https://github.com/MatMoul/archfi][archfi]] to
|
||||
install easily the distro (I’ve done it so many times, I know how it works now).
|
||||
Usually, my distros will be installed on two partitions: ~/home~ and ~/~ (root).
|
||||
|
||||
If the computer supports EFI bootloaders, the EFI partition will be mounted on
|
||||
~/boot/efi~. I generally use ~systemd-boot~ as my boot manager, but if you are
|
||||
more comfortable with another one, just install what you want. Be aware that if
|
||||
you format your ~/boot~ partition, you will delete all boot managers that
|
||||
already exist; so, if you are dual-booting, *DO NOT FORMAT IT*. Yes, I made the
|
||||
mistake of wiping the Windows boot manager when I used to dual-boot.
|
||||
|
||||
In order to use the ~suspend-then-hibernate~ systemd command, it is necessary to
|
||||
have a swap partition at least twice the size of your installed RAM. That is
|
||||
because when this command will be run, the system will try to save the current
|
||||
state of your machine, stored in your RAM, to the swap filesystem. If there is
|
||||
not enough space, the command will fail, and you won’t be able to use this
|
||||
command. For instance, my current computer has 32 GB of RAM, hence my SWAP
|
||||
partition is 16 GB large.
|
||||
|
||||
*** Get the latest, fastest mirrors
|
||||
When you boot into the live ISO, execute the following command:
|
||||
#+BEGIN_SRC sh
|
||||
pacman -Sy reflector
|
||||
reflector -c FR,DE -l 20 -p https --sort rate --save /etc/pacman.d/mirrorlist --verbose
|
||||
#+END_SRC
|
||||
|
||||
This will update the packages from your live ISO, and you will get the best
|
||||
mirrors for your installation. Of course, change the countries accordingly to
|
||||
your location. In my case, I am only interested in French, German, and Belgian
|
||||
mirrors.
|
||||
|
||||
*** Install the system
|
||||
Then you can use a custom script to ease your installation of Arch if you do not
|
||||
wish to do it manually. Personally, I’ve done it several times already, I know
|
||||
how the distro works, I just want to be able to install my distro quickly now.
|
||||
I’ll need to download the script with ~wget~, but apparently it isn’t installed
|
||||
by default on Arch ISOs anymore, so I’ll need to install it.
|
||||
#+BEGIN_SRC sh
|
||||
pacman -S wget
|
||||
#+END_SRC
|
||||
|
||||
Now, let’s grab the script. You can check it on [[https://github.com/matmoul/archfi][GitHub]].
|
||||
#+BEGIN_SRC sh
|
||||
wget archfi.sf.net/archfi
|
||||
# Or from matmoul.github.io/archfi if SourceForge is down
|
||||
sh archfi
|
||||
#+END_SRC
|
||||
|
||||
Then, follow the instructions and install Arch Linux. Take the opportunity to
|
||||
install as many packages as you need, mainly ~paru~ which I use as my package
|
||||
manager (it is just a wrapper for ~pacman~) and AUR helper, and ~pacman-contrib~
|
||||
which will help us to install some packages later.
|
||||
|
||||
Once your system is installed, reboot and remove your installation media from
|
||||
your computer.
|
||||
|
||||
** Execute bootstrap
|
||||
:PROPERTIES:
|
||||
:HEADER-ARGS:fish: :tangle ~/.config/yadm/bootstrap :shebang "#!/usr/bin/fish" :exports code :mkdirp yes
|
||||
:END:
|
||||
The first thing I will do is add the [[https://aur.chaotic.cx/][Chaotic AUR]] repository to get
|
||||
access to ~paru~ as well as some AUR packages without the need of an AUR
|
||||
helper (ironic considering ~paru~ is one). We can then install ~fish~,
|
||||
~git~, and ~paru~:
|
||||
#+BEGIN_SRC sh
|
||||
sudo pacman -S fish git paru
|
||||
#+END_SRC
|
||||
|
||||
And now that ~paru~ is available, we can install ~yadm~:
|
||||
#+BEGIN_SRC sh
|
||||
paru -S yadm
|
||||
#+END_SRC
|
||||
|
||||
~yadm~ comes with a very handy feature: its bootstrap script. It can be executed
|
||||
automatically once the dotfiles are cloned with yadm:
|
||||
#+BEGIN_SRC sh
|
||||
yadm clone https://labs.phundrak.com/phundrak/dotfiles
|
||||
# or if labs.phundrak.com is down or too slow for you
|
||||
#yadm clone https://github.com/phundrak/dotfiles
|
||||
#+END_SRC
|
||||
|
||||
Let’s take a look at what it does.
|
||||
|
||||
*** Decrypt private yadm files
|
||||
Some private files are stored encrypted in the repository of my yadm dotfiles. I
|
||||
will need them later on during the bootstrap execution.
|
||||
#+BEGIN_SRC fish
|
||||
if test "$USER" = 'phundrak'
|
||||
yadm decrypt
|
||||
else
|
||||
whiptail --yesno "Decrypt private files?" 8 40 && yadm decrypt
|
||||
end
|
||||
#+END_SRC
|
||||
|
||||
*** Get a correct keyboard layout
|
||||
I use mainly the [[https://bepo.fr/wiki/Accueil][bépo]] layout, a French keyboard layout inspired by Dvorak
|
||||
layouts, however I sometimes need to switch back to the standard French AZERTY
|
||||
or the American QWERTY layout, so I make it so the Menu key switches for me my
|
||||
layout between these three. This makes it so my xorg configuration of my
|
||||
keyboard looks like this:
|
||||
#+BEGIN_SRC fish
|
||||
set keyboardconf \
|
||||
'Section "InputClass"
|
||||
Identifier "system-keyboard"
|
||||
MatchIsKeyboard "on"
|
||||
Option "XkbLayout" "fr"
|
||||
Option "XkbModel" "pc104"
|
||||
Option "XkbVariant" "bepo_afnor"
|
||||
Option "XkbOptions" "caps:ctrl_modifier"
|
||||
EndSection'
|
||||
#+END_SRC
|
||||
|
||||
So, let’s ask the user if they want to set it as their keyboard configuration.
|
||||
#+BEGIN_SRC fish
|
||||
printf "\n# Set keyboard layout #########################################################\n\n"
|
||||
whiptail --yesno "Would you like to set your keyboard layout to the bépo layout?" 8 55
|
||||
if test $status -eq 0
|
||||
echo $keyboardconf | sudo tee /etc/X11/xorg.conf.d/00-keyboard.conf
|
||||
end
|
||||
#+END_SRC
|
||||
|
||||
*** Set our locale
|
||||
I use two main locales, the French and US UTF-8 locales, and I like to keep the
|
||||
Japanese locale activated just in case.
|
||||
#+BEGIN_SRC fish
|
||||
set mylocales "en_US.UTF-8 UTF-8" "fr_FR.UTF-8 UTF-8" "ja_JP.UTF-8 UTF-8"
|
||||
#+END_SRC
|
||||
|
||||
I’ll let the user accept them one by one.
|
||||
#+BEGIN_SRC fish
|
||||
printf "\n# Set locale ##################################################################\n\n"
|
||||
for item in $mylocales
|
||||
whiptail --yesno "Set the \"$item\" locale?" 8 40
|
||||
if test $status -eq 0 -a (grep -e "#$item" /etc/locale.gen)
|
||||
sudo sed -i "/$item/s/^#//g" /etc/locale.gen
|
||||
end
|
||||
end
|
||||
#+END_SRC
|
||||
|
||||
This is my configuration I usually use when it comes to my locale.
|
||||
#+BEGIN_SRC fish
|
||||
set localeconf "LANG=en_DK.UTF-8
|
||||
LC_COLLATE=C
|
||||
LC_NAME=fr_FR.UTF-8
|
||||
LC_IDENTIFICATION=fr_FR.UTF-8
|
||||
LC_TELEPHONE=fr_FR.UTF-8
|
||||
LC_MONETARY=fr_FR.UTF-8
|
||||
LC_PAPER=fr_FR.UTF-8
|
||||
LC_ADDRESS=fr_FR.UTF-8
|
||||
LC_MEASUREMENT=fr_FR.UTF-8"
|
||||
#+END_SRC
|
||||
|
||||
Let’s set it as our system’s locale if the user whishes to.
|
||||
#+BEGIN_SRC fish
|
||||
whiptail --yesno "Do you agree to have the following locale set?\n\n $localeconf" 20 43
|
||||
if test $status -eq 0
|
||||
echo $localeconf | sudo tee /etc/locale.conf
|
||||
end
|
||||
#+END_SRC
|
||||
|
||||
Now we can generate our locale!
|
||||
#+BEGIN_SRC fish
|
||||
printf "\n# Generate locale #############################################################\n\n"
|
||||
sudo locale-gen
|
||||
#+END_SRC
|
||||
|
||||
*** Create some folders
|
||||
Let’s create some folders we might need for mounting our drives, Android devices
|
||||
and CDs.
|
||||
#+BEGIN_SRC fish
|
||||
printf "\n# Create directories for mounting #############################################\n\n"
|
||||
sudo mkdir -p /mnt/{USB,CD,Android}
|
||||
sudo chown $USER:(id -g $USER) /mnt/{USB,CD,Android}
|
||||
#+END_SRC
|
||||
|
||||
*** Set user’s shell to fish
|
||||
First, the bootstrap shell will set the user’s shell to fish.
|
||||
#+BEGIN_SRC fish
|
||||
printf "\n# Set fish as the default shell ###############################################\n\n"
|
||||
whiptail --yesno "Set the current user’s default shell to fish?" 8 50
|
||||
if test $status -eq 0 -a ! "$SHELL" = '/usr/bin/fish'
|
||||
chsh -s /usr/bin/fish
|
||||
end
|
||||
#+END_SRC
|
||||
|
||||
*** Install basic packages
|
||||
Ok, let’s list all the packages that I need. First, let’s begin with
|
||||
system packages.
|
||||
#+name: packages-system
|
||||
| Package name | Why I need it |
|
||||
|-----------------------------+--------------------------------------------------------------|
|
||||
| acpi | Battery, power, and thermal readings |
|
||||
| acpilight | To modify the monitors’ brightness |
|
||||
| bluez-firmware | Firmware for my bluetooth device |
|
||||
| bluez-utils | To interact with bluez through custom tools |
|
||||
| bzip2 | A compression algorithm and program |
|
||||
| cpupower | Examine and tune power saving related features of the CPU |
|
||||
| exfat-utils | Utilities for exFAT filesystems |
|
||||
| ffmpegthumbnailer | Create thumbnails with ffmpeg |
|
||||
| freeglut | A small OpenGL library |
|
||||
| gcc-libs | Runtime libraries for GCC |
|
||||
| gdb | The GCC debugger |
|
||||
| gnome-disk-utility | To manage easily my disks and partitions |
|
||||
| gnome-epub-thumbnailer | Thumbnailer for Epub files |
|
||||
| i3lock-color | My screen locker |
|
||||
| corrupter-git | A script for my script using also i3lock-color |
|
||||
| inetutils | Common network programs |
|
||||
| jfsutils | JFS utilities to interact with Android |
|
||||
| jmtpfs | FUSE filesystem for the MTP protocol |
|
||||
| kitty | My current terminal emulator, works with Xorg and Wayland |
|
||||
| logrotate | Rotate system logs automatically |
|
||||
| man-pages | Linux's man pages |
|
||||
| man-db | Read the Linux man pages |
|
||||
| netctl | Profile based systemd network management |
|
||||
| network-manager-applet | System tray applet for NetworkManager |
|
||||
| networkmanager-openvpn | Connect to OpenVPN servers with NetworkManager |
|
||||
| nm-connection-editor | Manager NetworkManager connections |
|
||||
| ntfs-3g | Utilities to access NTFS filesystems |
|
||||
| openssh | SSH. Do I need to say anything more than that? |
|
||||
| pavucontrol | Graphical interface to PulseAudio settings |
|
||||
| wireplumber | Session manager for PipeWire |
|
||||
| pipewire-pulse | PipeWire replacement for ~pulseaudio~ and ~pulseaudio-bluetooth~ |
|
||||
| gst-plugin-pipewire | PipeWire plugin for GStreamer |
|
||||
| noise-suppression-for-voice | Realtime noise suppression plugin for voice |
|
||||
| raw-thumbnailer | thumbnailer for RAW images |
|
||||
| reflector | Sort pacman mirrors |
|
||||
| shadow | Password & account management tools |
|
||||
| sshfs | Mount remote filesystems through SSH |
|
||||
| usbutils | USB utilities |
|
||||
| xdg-user-dirs-gtk | Creates user dirs and asks to relocalize them |
|
||||
| xfce-polkit | XFCE’s policy kit |
|
||||
| xidlehook | xautolock with extra features |
|
||||
| xfsprogs | Access XFS filesystems |
|
||||
| xorg-xinit | xorg init program |
|
||||
| xss-lock | Use an external program as X lock screen |
|
||||
| xwallpaper | Set my Xorg session’s wallpaper |
|
||||
|
||||
For development purposes, I need the following packages:
|
||||
#+name: packages-devel
|
||||
| Package name | Why I need it |
|
||||
|----------------------------------+-----------------------------------------------------------|
|
||||
| asar | Package needed by some Electron programs |
|
||||
| base-devel | Metapackage providing lots of basic tools for development |
|
||||
| clang | LLVM’s C/C++ compiler |
|
||||
| cppcheck | Static code analysis for C/C++ |
|
||||
| cppreference | The cppreference wiki offline |
|
||||
| cppreference-devhelp | Access cppreference through devhelp |
|
||||
| docker | VMs are too heavy, get a better virtualization engine! |
|
||||
| docker-compose | Docker from the CLI? I prefer through a Yaml file. |
|
||||
| dockerfile-language-server-bin | Dockerfile LSP server |
|
||||
| doxygen | A great tool for writing code documentation for C/C++ |
|
||||
| emacs | The best +text editor+ OS, hands down |
|
||||
| farbfeld | Lossless image format |
|
||||
| flake8 | Code checker for python |
|
||||
| gnuplot | An awesome plotting tool |
|
||||
| go | The Go programming language |
|
||||
| go-tools | Go’s tooling |
|
||||
| graphviz | Graph visualization |
|
||||
| hugo | Static website generator |
|
||||
| javascript-typescript-langserver | LSP server for Javascript |
|
||||
| js-beautify | Formatter for Javascript |
|
||||
| linux-headers | Development with the Linux kernel |
|
||||
| lldb | The LLVM debugger |
|
||||
| meson | Meson build system |
|
||||
| mupdf-tools | Tools for PDF and XPS viewers |
|
||||
| npm | Javascript package manager |
|
||||
| pacman-contrib | Create and install custom ArchLinux packages |
|
||||
| pandoc-bin | Convert documents of various formats into other formats |
|
||||
| prettier | Format various web files formats |
|
||||
| python-autoflake | Remove unused imports and variables in Python |
|
||||
| python-epc | EPC (RPC stack for Emacs Lisp) for Python |
|
||||
| python-importmagic | Automatically manage imports in Python |
|
||||
| pyright | Python LSP server |
|
||||
| python-nose | A discovery-based test extension for Python |
|
||||
| python-pip | The Python package manager |
|
||||
| python-poetry | Python dependency management and packaging made easy |
|
||||
| python-ptvsd | Python debugger |
|
||||
| python-pytest | Python testing suite |
|
||||
| qemu | Machine emulator and virtualizer |
|
||||
| r | The R programming langugae |
|
||||
| rustup | The Rust toolchain installer |
|
||||
| sbcl | My favorite CommonLisp implementation |
|
||||
| typescript | Better Javascript |
|
||||
| typescript-language-server-bin | LSP server for Typescript |
|
||||
| valgrind | Our lord and saviour when writing C code |
|
||||
| vscode-css-languageserver-bin | LSP server for CSS |
|
||||
| vscode-html-languageserver-bin | LSP server for HTML |
|
||||
| yaml-language-server-bin | LSP server for Yaml |
|
||||
| zeal | Offline documentation browser |
|
||||
|
||||
A couple of packages need to be installed to make LaTeX usable.
|
||||
#+name: packages-latex
|
||||
| Package name | Why I need it |
|
||||
|----------------------+----------------------------------------------------------------------|
|
||||
| biber | A BibTex replacement, for citations in papers |
|
||||
| minted | Syntax highlight for LaTeX |
|
||||
| texlive-bibtexextra | Additional BibTeX styles and bibliography databases |
|
||||
| texlive-fontsextra | All sorts of extra fonts |
|
||||
| texlive-formatsextra | Collection of extra TeX 'formats' |
|
||||
| texlive-humanities | LaTeX packages for law, linguistics, social sciences, and humanities |
|
||||
| texlive-langjapanese | Fonts and macro packages to typeset Japanese texts |
|
||||
| texlive-pictures | Packages for drawings graphics |
|
||||
| texlive-pstricks | Additional PSTricks packages |
|
||||
| texlive-publishers | LaTeX classes and packages for specific publishers |
|
||||
| texlive-science | Typesetting for mathematics, natural and computer sciences |
|
||||
|
||||
Some visual packages:
|
||||
#+name: packages-font
|
||||
| Package name | Why I need it |
|
||||
|--------------------------------+-------------------------------------|
|
||||
| adobe-source-han-sans-jp-fonts | Japanese fonts |
|
||||
| inter-font | I’m not sure why I have these fonts |
|
||||
| nordic-theme-git | Nord theme for GTK |
|
||||
| noto-fonts-emoji | Font with emojis |
|
||||
| otf-ipafont | Japanese font |
|
||||
| picom | See [[file:picom.org]] |
|
||||
| powerline-fonts | Powerline fonts |
|
||||
| siji-git | Siji font |
|
||||
| ttf-arphic-uming | CJK font Ming style |
|
||||
| ttf-baekmuk | Korean font |
|
||||
| ttf-charis-sil | API font |
|
||||
| ttf-dejavu | DejaVu font |
|
||||
| ttf-hanazono | Japanese kanji font |
|
||||
| ttf-joypixels | Emoji font |
|
||||
| ttf-koruri | Japanese Truetype font |
|
||||
| ttf-liberation | Liberation font |
|
||||
| ttf-monapo | Japanese font |
|
||||
| ttf-sazanami | Japanese fonts |
|
||||
| ttf-unifont | The font I use in StumpWM |
|
||||
| ttf-tibetan-machine | Tibetan font |
|
||||
| unicode-emoji | Unicode emoji data files |
|
||||
|
||||
Terminal utilities
|
||||
#+name: packages-terminal
|
||||
| Package name | Why I need it |
|
||||
|-----------------+-----------------------------------------------------------------|
|
||||
| ascii | Work with ASCII |
|
||||
| aspell-en | Aspell’s dictionary for English |
|
||||
| aspell-fr | Aspell’s dictionary for French |
|
||||
| bat | A better cat with syntax highlighting |
|
||||
| bitwarden-cli | CLI application for my password manager |
|
||||
| bpytop | A very beautiful htop alternative |
|
||||
| exa | A great ~ls~ replacement |
|
||||
| fd | ~find~, but better |
|
||||
| findutils | ~find~ files on the system |
|
||||
| fzf | Command-line fuzzy finder |
|
||||
| htop | ~top~, but better |
|
||||
| isync | Gives access to ~mbsync~ so I can check my mails |
|
||||
| mpc | Dead simple MPD client |
|
||||
| mpd | Music Player Daemon |
|
||||
| mpv | The best video player in existance |
|
||||
| nano | Simple text editor |
|
||||
| ncdu | Graphical representation of disk usage |
|
||||
| ncmpcpp | TUI for MPD |
|
||||
| neofetch | System info in the terminal |
|
||||
| nordvpn-bin | Connect to NordVPN on Linux |
|
||||
| numlockx | Turn on the numpad in Xorg |
|
||||
| p7zip | 7zip on Linux |
|
||||
| pass | The standard UNIX password manager |
|
||||
| pdfpc | PDF presentation tool in the console with multi-monitor support |
|
||||
| ripgrep | ~grep~ but better |
|
||||
| rsync | ~scp~ is dead, long live ~rsync~! |
|
||||
| flameshot | To take screenshots |
|
||||
| tealdeer | ~tldr~ but faster, great cheatsheets in the terminal |
|
||||
| tmux | Terminal multiplexer |
|
||||
| tree | See files and directories as a tree |
|
||||
| unrar | Support for rar file format |
|
||||
| w3m | Terminal web browser |
|
||||
| wget | Retrieve files from the web |
|
||||
| x11-ssh-askpass | Passphrase dialog over SSH |
|
||||
| xclip | Interact with the X11 clipboard |
|
||||
| yt-dlp-drop-in | ~yt-dlp~ but it also replaces ~youtube-dl~ |
|
||||
|
||||
Let’s install some desktop applications too, shall we?
|
||||
#+name: packages-apps
|
||||
| Package name | Why I need it |
|
||||
|-----------------+---------------------------------------------------------|
|
||||
| bitwarden | Desktop application for my password manager |
|
||||
| discord | For messaging friends |
|
||||
| firefox | Because I need a good browser |
|
||||
| gimp | GIMP Is Mbetter than Photoshop |
|
||||
| helvum | Pipewire patchbay |
|
||||
| nemo | One of the best graphical file managers |
|
||||
| nemo-fileroller | Add compression options to Nemo |
|
||||
| nemo-preview | Quick file previewer for Nemo |
|
||||
| obs-studio | Simply the best screen recording and streaming software |
|
||||
| rofi | A beautiful ~dmenu~ replacement |
|
||||
|
||||
All these packages will be installed with the command ~paru -S
|
||||
--skipreview --needed~ to prevent it from nagging me about the PKGBUILD
|
||||
when I want to install something from the AUR, and if something is
|
||||
already installed it paru won’t try to reinstall it.
|
||||
|
||||
#+name: gen-package-list
|
||||
#+header: :wrap "src fish :exports none :tangle no"
|
||||
#+header: :exports none
|
||||
#+begin_src emacs-lisp :var packages=packages-apps[,0] varname="APPS"
|
||||
(format "set %s %s"
|
||||
varname
|
||||
(mapconcat #'identity packages " \\\n"))
|
||||
#+end_src
|
||||
|
||||
#+RESULTS[53aa8b22c675edad2d6d21c0095ff233bb5e26c4]: gen-package-list
|
||||
#+begin_src fish :exports none :tangle no
|
||||
set APPS bitwarden \
|
||||
discord \
|
||||
firefox \
|
||||
gimp \
|
||||
helvum \
|
||||
nemo \
|
||||
nemo-fileroller \
|
||||
nemo-preview \
|
||||
obs-studio \
|
||||
rofi
|
||||
#+end_src
|
||||
|
||||
#+name: gen-package-install
|
||||
#+header: :wrap "src fish :exports none :tangle no"
|
||||
#+header: :exports none
|
||||
#+begin_src emacs-lisp :var varname="APPS"
|
||||
(concat
|
||||
(format "%s %s %s"
|
||||
"printf \"\\n# Installing"
|
||||
varname
|
||||
"##################################################\\n\\n\"")
|
||||
"\n"
|
||||
(format "for pkg in $%s\n paru -S --skipreview --needed $pkg\nend" varname))
|
||||
#+end_src
|
||||
|
||||
#+RESULTS[8fc00f530b704dc6900087d5b91082e9fa1bb429]: gen-package-install
|
||||
#+begin_src fish :exports none :tangle no
|
||||
printf "\n# Installing APPS ##################################################\n\n"
|
||||
for pkg in $APPS
|
||||
paru -S --skipreview --needed $pkg
|
||||
end
|
||||
#+end_src
|
||||
|
||||
#+begin_src fish :noweb yes
|
||||
<<gen-package-list(packages=packages-system[,0],varname="SYSTEMPKG")>>
|
||||
|
||||
<<gen-package-install(varname="SYSTEMPKG")>>
|
||||
|
||||
|
||||
<<gen-package-list(packages=packages-devel[,0],varname="DEVELPKG")>>
|
||||
|
||||
<<gen-package-install(varname="DEVELPKG")>>
|
||||
|
||||
|
||||
<<gen-package-list(packages=packages-latex[,0],varname="LATEXPKG")>>
|
||||
|
||||
<<gen-package-install(varname="LATEXPKG")>>
|
||||
|
||||
|
||||
<<gen-package-list(packages=packages-terminal[,0],varname="TERMINALPKG")>>
|
||||
|
||||
<<gen-package-install(varname="TERMINALPKG")>>
|
||||
|
||||
|
||||
<<gen-package-list(packages=packages-apps[,0],varname="APPSPKG")>>
|
||||
|
||||
<<gen-package-install(varname="APPSPKG")>>
|
||||
#+end_src
|
||||
|
||||
Finally, I wish to install some custom packages for which I’ve written
|
||||
a ~PKGBUILD~ file myself. I store all of them in a dedicated directory
|
||||
located in ~$HOME/Documents/code/PKGBUILDs~. I want to install some of
|
||||
them immediately.
|
||||
#+name: packages-pkgbuild
|
||||
| Package Name | What it is |
|
||||
|--------------+------------------------------------------------------------------|
|
||||
| emacs | My custom Emacs build, it will replace the one already installed |
|
||||
| nsxiv | The best image viewer after Emacs |
|
||||
| pumopm-git | My very simple battery manager |
|
||||
| sent | A very simple presentation tool |
|
||||
|
||||
#+name: gen-package-pkgbuild
|
||||
#+header: :wrap "src fish :exports none"
|
||||
#+header: :exports none
|
||||
#+begin_src emacs-lisp :var packages=packages-pkgbuild[,0]
|
||||
(let ((base-dir "~/Documents/code/PKGBUILDs"))
|
||||
(mapconcat (lambda (dir)
|
||||
(format "cd %s && makepkg -si && cd"
|
||||
(expand-file-name dir base-dir)))
|
||||
packages
|
||||
"\n"))
|
||||
#+end_src
|
||||
|
||||
#+RESULTS[82db1c3f1b9c80b3c24075d1a20933be59baac47]: gen-package-pkgbuild
|
||||
#+begin_src fish :exports none
|
||||
cd /home/phundrak/Documents/code/PKGBUILDs/emacs && makepkg -si && cd
|
||||
cd /home/phundrak/Documents/code/PKGBUILDs/nsxiv && makepkg -si && cd
|
||||
cd /home/phundrak/Documents/code/PKGBUILDs/pumopm-git && makepkg -si && cd
|
||||
cd /home/phundrak/Documents/code/PKGBUILDs/sent && makepkg -si && cd
|
||||
#+end_src
|
||||
|
||||
*** Tangle configuration files from Org files
|
||||
Before tangling our configuration files, we need to create some
|
||||
directories first to make sure our files can be properly tangled.
|
||||
Here’s the list of directories we need to create:
|
||||
#+NAME: dirs-tangled-files
|
||||
| $HOME/.config/fish |
|
||||
| $HOME/.config/gtk-2.0 |
|
||||
| $HOME/.config/gtk-3.0 |
|
||||
| $HOME/.config/ncmpcpp |
|
||||
| $HOME/.config/neofetch |
|
||||
| $HOME/.config/picom |
|
||||
| $HOME/.config/yadm |
|
||||
| $HOME/.local/bin |
|
||||
| $HOME/.stumpwm.d |
|
||||
| $HOME/org/capture |
|
||||
|
||||
#+NAME: gen-dirs-tangle
|
||||
#+BEGIN_SRC emacs-lisp :var dirs=dirs-tangled-files
|
||||
(mapconcat (lambda (x) (format "mkdir -p %s" (car x)))
|
||||
dirs
|
||||
"\n")
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS[250efd14cab8a0f03e5520e0d0bd96aa311aa45f]: gen-dirs-tangle
|
||||
#+begin_example
|
||||
mkdir -p $HOME/.config/fish
|
||||
mkdir -p $HOME/.config/gtk-2.0
|
||||
mkdir -p $HOME/.config/gtk-3.0
|
||||
mkdir -p $HOME/.config/ncmpcpp
|
||||
mkdir -p $HOME/.config/neofetch
|
||||
mkdir -p $HOME/.config/picom
|
||||
mkdir -p $HOME/.config/yadm
|
||||
mkdir -p $HOME/.local/bin
|
||||
mkdir -p $HOME/.stumpwm.d
|
||||
mkdir -p $HOME/org/capture
|
||||
#+end_example
|
||||
|
||||
Our code to generate such directories looks like this:
|
||||
#+BEGIN_SRC fish :noweb yes
|
||||
<<gen-dirs-tangle()>>
|
||||
#+END_SRC
|
||||
|
||||
The next step is to tangle all the Org files. Here is the list of files that are
|
||||
to be tangled:
|
||||
#+NAME: tangled-files
|
||||
| filename |
|
||||
|--------------|
|
||||
| bin.org |
|
||||
| emacs.org |
|
||||
| fish.org |
|
||||
| index.org |
|
||||
| mpd.org |
|
||||
| neofetch.org |
|
||||
| picom.org |
|
||||
| rustfmt.org |
|
||||
| stumpwm.org |
|
||||
| tmux.org |
|
||||
|
||||
#+NAME: generate-tangle
|
||||
#+BEGIN_SRC emacs-lisp :var files=tangled-files[,0]
|
||||
(mapconcat (lambda (x) (concat
|
||||
(format "printf '\\n\\n==== Tangling %s\\n\\n' && \\\n" x)
|
||||
(concat "emacs -q --batch --eval '(require \\'ob-tangle)' \\\n"
|
||||
"--eval '(setq org-confirm-babel-evaluate nil)' \\\n"
|
||||
(format "--eval '(org-babel-tangle-file \"~/org/config/%s\")'\n" x))))
|
||||
files
|
||||
"\n")
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS[127dafd79461dab55296163e57fadb7b355a205a]: generate-tangle
|
||||
#+begin_example
|
||||
printf '\n\n==== Tangling bin.org\n\n' && \
|
||||
emacs -q --batch --eval '(require \'ob-tangle)' \
|
||||
--eval '(setq org-confirm-babel-evaluate nil)' \
|
||||
--eval '(org-babel-tangle-file "~/org/config/bin.org")'
|
||||
|
||||
printf '\n\n==== Tangling emacs.org\n\n' && \
|
||||
emacs -q --batch --eval '(require \'ob-tangle)' \
|
||||
--eval '(setq org-confirm-babel-evaluate nil)' \
|
||||
--eval '(org-babel-tangle-file "~/org/config/emacs.org")'
|
||||
|
||||
printf '\n\n==== Tangling fish.org\n\n' && \
|
||||
emacs -q --batch --eval '(require \'ob-tangle)' \
|
||||
--eval '(setq org-confirm-babel-evaluate nil)' \
|
||||
--eval '(org-babel-tangle-file "~/org/config/fish.org")'
|
||||
|
||||
printf '\n\n==== Tangling index.org\n\n' && \
|
||||
emacs -q --batch --eval '(require \'ob-tangle)' \
|
||||
--eval '(setq org-confirm-babel-evaluate nil)' \
|
||||
--eval '(org-babel-tangle-file "~/org/config/index.org")'
|
||||
|
||||
printf '\n\n==== Tangling mpd.org\n\n' && \
|
||||
emacs -q --batch --eval '(require \'ob-tangle)' \
|
||||
--eval '(setq org-confirm-babel-evaluate nil)' \
|
||||
--eval '(org-babel-tangle-file "~/org/config/mpd.org")'
|
||||
|
||||
printf '\n\n==== Tangling neofetch.org\n\n' && \
|
||||
emacs -q --batch --eval '(require \'ob-tangle)' \
|
||||
--eval '(setq org-confirm-babel-evaluate nil)' \
|
||||
--eval '(org-babel-tangle-file "~/org/config/neofetch.org")'
|
||||
|
||||
printf '\n\n==== Tangling picom.org\n\n' && \
|
||||
emacs -q --batch --eval '(require \'ob-tangle)' \
|
||||
--eval '(setq org-confirm-babel-evaluate nil)' \
|
||||
--eval '(org-babel-tangle-file "~/org/config/picom.org")'
|
||||
|
||||
printf '\n\n==== Tangling rustfmt.org\n\n' && \
|
||||
emacs -q --batch --eval '(require \'ob-tangle)' \
|
||||
--eval '(setq org-confirm-babel-evaluate nil)' \
|
||||
--eval '(org-babel-tangle-file "~/org/config/rustfmt.org")'
|
||||
|
||||
printf '\n\n==== Tangling stumpwm.org\n\n' && \
|
||||
emacs -q --batch --eval '(require \'ob-tangle)' \
|
||||
--eval '(setq org-confirm-babel-evaluate nil)' \
|
||||
--eval '(org-babel-tangle-file "~/org/config/stumpwm.org")'
|
||||
|
||||
printf '\n\n==== Tangling tmux.org\n\n' && \
|
||||
emacs -q --batch --eval '(require \'ob-tangle)' \
|
||||
--eval '(setq org-confirm-babel-evaluate nil)' \
|
||||
--eval '(org-babel-tangle-file "~/org/config/tmux.org")'
|
||||
#+end_example
|
||||
|
||||
#+BEGIN_SRC fish :noweb yes
|
||||
printf "\n# Tangling org files ##########################################################\n\n"
|
||||
<<generate-tangle()>>
|
||||
#+END_SRC
|
||||
|
||||
*** Set up dotfiles’ git repository
|
||||
**** Update our dotfiles’ remotes
|
||||
This line in the bootstrap script will test if the current user is using my
|
||||
username. If yes, it’s probably me.
|
||||
#+BEGIN_SRC fish
|
||||
if test "$USER" = 'phundrak'
|
||||
#+END_SRC
|
||||
|
||||
If it is me installing and using these dotfiles, I want the remotes of my
|
||||
dotfiles to be set to ssh remotes using my ssh keys.
|
||||
#+BEGIN_SRC fish
|
||||
printf "\n# Update yadm’s remotes #######################################################\n\n"
|
||||
yadm remote set-url origin git@labs.phundrak.com:phundrak/dotfiles.git
|
||||
#+END_SRC
|
||||
|
||||
I will also want to decrypt my encrypted files, such as said ssh keys.
|
||||
#+BEGIN_SRC fish
|
||||
printf "\n# Decrypt encrypted dotfiles ##################################################\n\n"
|
||||
yadm decrypt
|
||||
#+END_SRC
|
||||
|
||||
Finally, let’s close this ~if~ statement.
|
||||
#+BEGIN_SRC fish
|
||||
end
|
||||
#+END_SRC
|
||||
|
||||
**** Update our submodules
|
||||
Now we can download the various dependencies of our dotfiles. To do so, let’s
|
||||
run the following command:
|
||||
#+BEGIN_SRC fish
|
||||
printf "\n# Getting yadm susbmodules ####################################################\n\n"
|
||||
yadm submodule update --init --recursive
|
||||
#+END_SRC
|
||||
|
||||
*** Enable some services
|
||||
We have installed some packages which require some services to run. Let’s enable
|
||||
them.
|
||||
|
||||
**** Systemd-timesyncd
|
||||
This service enables time syncing with the NTP protocol, so I can be sure my
|
||||
computer’s time is correct. The service first needs to be enabled:
|
||||
#+BEGIN_SRC fish
|
||||
printf "\n# Enabling timesync ###########################################################\n\n"
|
||||
sudo systemctl enable --now systemd-timesyncd
|
||||
#+END_SRC
|
||||
|
||||
Now, let systemd know I want to use the NTP protocol to keep my computer’s time
|
||||
synced.
|
||||
#+BEGIN_SRC fish
|
||||
sudo timedatectl set-ntp true
|
||||
#+END_SRC
|
||||
|
||||
**** Acpilight
|
||||
~acpilight~ is our utility managing the brightness of our screen. There
|
||||
is actually no service to enable here, but we must ensure the user is
|
||||
part of the ~video~ group to enable the user modifying the brightness of
|
||||
our screen without using ~sudo~.
|
||||
#+BEGIN_SRC fish
|
||||
sudo usermod -aG video $USER
|
||||
#+END_SRC
|
||||
|
||||
**** Docker
|
||||
First, let’s activate Docker on startup.
|
||||
#+BEGIN_SRC fish
|
||||
printf "\n# Enabling and starting Docker ################################################\n\n"
|
||||
sudo systemctl enable --now docker
|
||||
#+END_SRC
|
||||
|
||||
Now, if we wish it, we can add ourselves to the =docker= group to avoid
|
||||
typing =sudo= each time we call Docker or Docker Compose.
|
||||
#+BEGIN_SRC fish
|
||||
read --prompt "echo 'Do you wish to be added to the `docker` group? (Y/n): ' " -l adddockergroup
|
||||
if test $adddockergroup = 'y' || test $adddockergroup = "Y" || test $adddockergroup = ''
|
||||
sudo usermod -aG docker $USER
|
||||
end
|
||||
#+END_SRC
|
||||
|
||||
**** Emacs
|
||||
Emacs will run as a user service, which means it won’t be launched until we log
|
||||
in. However, the service won’t be started immediately, I personally prefer to
|
||||
start a standalone instance in which installing and compiling the Emacs packages
|
||||
will happen, and then once that is done I will start the service.
|
||||
#+BEGIN_SRC fish
|
||||
printf "\n# Enabling Emacs as user service ##############################################\n\n"
|
||||
systemctl --user enable emacs
|
||||
#+END_SRC
|
||||
|
||||
I don’t want to activate it immediately however, since the first
|
||||
startup might require some interactivity with the main Emacs frame,
|
||||
not with emacsclient. When Emacs will be ready, its service can be
|
||||
started like so (command not tangled in the bootstrap):
|
||||
#+begin_src fish :tangle no
|
||||
systemctl --user start emacs
|
||||
#+end_src
|
||||
|
||||
**** Mpd
|
||||
Mpd will also use as a user service in order to get rid of some lines of code in
|
||||
my configuration.
|
||||
#+BEGIN_SRC fish
|
||||
printf "\n# Enabling Mpd as a user service ##############################################\n\n"
|
||||
mkdir -p ~/.config/mpd/playlists
|
||||
systemctl --user enable --now mpd
|
||||
#+END_SRC
|
||||
|
||||
**** NordVPN
|
||||
Thanks to the AUR package ~nordvpn-bin~, I no longer have to manually maintain
|
||||
my VPN connections with OpenVPN. However, it requires a service that we should
|
||||
activate:
|
||||
#+BEGIN_SRC fish
|
||||
sudo systemctl enable --now nordvpnd
|
||||
#+END_SRC
|
||||
|
||||
Let’s also set its default protocol to UDP. This will allow me to use
|
||||
any port while connected to any Wi-Fi as long as the 443 port is
|
||||
available. Because yes, I do connect to a Wi-Fi that blocks some
|
||||
important ports, such as the IMAP and SMTP ports. Thanks University of
|
||||
Paris 8 for being SO paranoid.
|
||||
#+BEGIN_SRC fish
|
||||
nordvpn s protocol tcp
|
||||
#+END_SRC
|
||||
|
||||
Note that this change in protocol is only valid when using the OpenVPN
|
||||
technology. If we want to use the Wireguard technology through [[https://nordvpn.com/blog/nordlynx-protocol-wireguard/][Project
|
||||
NordLynx]], this option will no longer be available. To set NordVPN to
|
||||
use WireGuard, we can run this command (not tangled in the bootstrap).
|
||||
#+begin_src fish :tangle no
|
||||
nordvpn set technology NordLynx
|
||||
#+end_src
|
||||
|
||||
Why WireGuard? Well, it can achieve better performances than OpenVPN
|
||||
with physically nearby servers, and according to [[https://restoreprivacy.com/vpn/wireguard-vs-openvpn/][this article]] the
|
||||
former can be more than half as fast as the latter. It is also much
|
||||
more auditable than OpenVPN (only a few thousands lines of code
|
||||
against some hundred of thousands). Oh, and WireGuard is part of the
|
||||
Linux kernel since its version 5.6. And Windows’ since August 2021,
|
||||
but I don’t really care about Windows.
|
||||
|
||||
*But*, WireGuard is less privacy-oriented than OpenVPN. So, if I ever
|
||||
need to use my VPN for privacy reasons, I can simply revert to the
|
||||
OpenVPN technology like shown with this command (not tangled in the
|
||||
bootstrap):
|
||||
#+begin_src fish :tangle no
|
||||
nordvpn set technology OpenVPN
|
||||
#+end_src
|
||||
|
||||
Finally, I want to be notified of NordVPN’s actions, and I want to be
|
||||
able to use IPv6.
|
||||
#+begin_src fish
|
||||
nordvpn set notify enabled
|
||||
nordvpn set ipv6 enabled
|
||||
#+end_src
|
||||
|
||||
**** PipeWire
|
||||
PipeWire is a replacement for PulseAudio, ALSA and the likes, and it
|
||||
is /*much*/ better in terms of security and performance. However, unlike
|
||||
PulseAudio, Pipewire is a user service that needs to be enabled per
|
||||
user.
|
||||
#+begin_src fish
|
||||
systemctl --user enable --now pipewire-pulse.service
|
||||
#+end_src
|
||||
|
||||
I also installed ~noise-suppression-for-voice~ which is a plugin usable
|
||||
by PipeWire to remove all noise the microphone might record save for
|
||||
the voice. It is damn effective, and it can be activated as a user
|
||||
service! In fact, I have in my dotfiles the service saved, so let’s
|
||||
activate it right away:
|
||||
#+begin_src fish
|
||||
systemctl --user enable --now pipewire-input-filter-chain.service
|
||||
#+end_src
|
||||
|
||||
Just make sure afterwards the microphone is redirected to the
|
||||
noise-canceling source. The same source should be your input device
|
||||
where you want to use your microphone. The only downside is this is
|
||||
ony a mono input, but it shouldn’t matter for most people.
|
||||
|
||||
**** SSH server
|
||||
Maybe we want to activate an SSH server on our machine. If so, we can enable it.
|
||||
Let’s ask the question.
|
||||
#+BEGIN_SRC fish
|
||||
whiptail --yesno 'Do you want to activate the ssh server?' 8 50
|
||||
if test $status -eq 0
|
||||
printf "\n# Enabling ssh server #########################################################\n\n"
|
||||
sudo systemctl enable --now sshd
|
||||
end
|
||||
#+END_SRC
|
||||
|
||||
*** Symlink some system config files
|
||||
Let’s symlink the ~plock~ script ([[file:bin.org::#Lock-635fcb38][source here]]) to ~/usr/bin~ so ~xss-lock~
|
||||
can find it.
|
||||
#+BEGIN_SRC fish
|
||||
sudo ln -s ~/.local/bin/plock /usr/bin/plock
|
||||
#+END_SRC
|
||||
|
||||
*** Install packages from git
|
||||
Now, let’s install some packages from git directly.
|
||||
#+BEGIN_SRC fish
|
||||
mkdir -p ~/fromGIT
|
||||
#+END_SRC
|
||||
|
||||
**** Reveal.JS
|
||||
I sometimes use Reveal.JS to make presentations, and I set its
|
||||
location in my [[file:emacs.org][Emacs config]] to be in =~/fromGIT=, so let’s clone it
|
||||
there.
|
||||
#+BEGIN_SRC fish
|
||||
printf "\n# Install Reveal.JS ###########################################################\n\n"
|
||||
cd ~/fromGIT
|
||||
git clone https://github.com/hakimel/reveal.js.git
|
||||
#+END_SRC
|
||||
|
||||
*** Install Rust
|
||||
**** Install the toolchains
|
||||
When using Rust, I bounce between two toolchains, the ~stable~ toolchain and the
|
||||
~nightly~ toolchain, although I try to stick with Rust Stable. To install them,
|
||||
I will use ~rustup~ which has already been installed previously.
|
||||
#+BEGIN_SRC fish
|
||||
printf "\n# Install the rust toolchains, nightly is the default one #####################\n\n"
|
||||
rustup default stable
|
||||
#+END_SRC
|
||||
|
||||
This will both download the stable toolchain and set it as the default one. Now
|
||||
to install the nightly toolchain, let’s run this:
|
||||
#+BEGIN_SRC fish
|
||||
rustup toolchain install nightly
|
||||
#+END_SRC
|
||||
|
||||
**** Install some utilities
|
||||
We’ll need some utilities when developing Rust from Emacs, namely ~rustfmt~ and
|
||||
~racer~. Let’s install them with ~cargo~.
|
||||
#+BEGIN_SRC fish
|
||||
printf "\n# Add rust utilities ##########################################################\n\n"
|
||||
cargo install rustfmt
|
||||
#+END_SRC
|
||||
|
||||
We will also need some components for development purposes.
|
||||
#+NAME: rust-components-table
|
||||
| Component | Why |
|
||||
|-----------+-------------------------------------------|
|
||||
| rust-src | Rust documentation in Emacs |
|
||||
| clippy | A better version of cargo’s ~check~ command |
|
||||
|
||||
#+NAME: rust-components-gen
|
||||
#+BEGIN_SRC emacs-lisp :var components=rust-components-table[,0]
|
||||
(mapconcat (lambda (x) (format "rustup component add %s" x))
|
||||
components
|
||||
"\n")
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS[b3935b1c09d86fe506b43670f52960306a1e9809]: rust-components-gen
|
||||
: rustup component add rust-src
|
||||
: rustup component add clippy
|
||||
|
||||
Here is the code to do so:
|
||||
#+BEGIN_SRC fish :noweb yes
|
||||
<<rust-components-gen()>>
|
||||
#+END_SRC
|
||||
|
||||
*** Set up our fish shell
|
||||
The last thing we want to do is to set up our fish shell with some extensions in
|
||||
order to improve the user experience.
|
||||
|
||||
**** Install ~fisher~
|
||||
We will be using ~fisher~ as our extension manager for Fish. Let’s install it.
|
||||
#+BEGIN_SRC fish
|
||||
printf "\n# Installing fisher ###########################################################\n\n"
|
||||
curl -sL https://git.io/fisher | source && fisher install jorgebucaran/fisher
|
||||
#+END_SRC
|
||||
|
||||
**** Install our extensions
|
||||
I generally use the following extensions in my Fish shell.
|
||||
#+NAME: fish-extensions-table
|
||||
#+CAPTION: Fish extensions managed by Fisher
|
||||
| Package name | Description |
|
||||
|---------------------------+------------------------------------------------------------------|
|
||||
| decors/fish-colored-man | Color man pages to make them more readable |
|
||||
| franciscolourenco/done | Automatically receive notifications when a long process finishes |
|
||||
| jethrokuan/fzf | Improved key bindings for [[https://github.com/junegunn/fzf][junegunn/fzf]] |
|
||||
| jorgebucaran/fish-bax | Run bash scripts, replaying environment changes in fish |
|
||||
| jorgebucaran/fish-getopts | CLI options parser; alternative to the [[https://fishshell.com/docs/current/commands.html#argparse][argparse]] fish builtin |
|
||||
| laughedelic/pisces | Autoclose parentheses, braces, quotes and other paired symbols |
|
||||
|
||||
#+NAME: fish-extensions-gen
|
||||
#+BEGIN_SRC emacs-lisp :var extensions=fish-extensions-table[,0]
|
||||
(mapconcat (lambda (x) (format "fisher install %s" x))
|
||||
extensions
|
||||
"\n")
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS[d424f363a3c11c8598a20da525de5ba9dcfbe7e7]: fish-extensions-gen
|
||||
: fisher install decors/fish-colored-man
|
||||
: fisher install franciscolourenco/done
|
||||
: fisher install jethrokuan/fzf
|
||||
: fisher install jorgebucaran/fish-bax
|
||||
: fisher install jorgebucaran/fish-getopts
|
||||
: fisher install laughedelic/pisces
|
||||
|
||||
#+BEGIN_SRC fish :noweb yes
|
||||
printf "\n# Installing Fisher Extensions ################################################\n\n"
|
||||
<<fish-extensions-gen()>>
|
||||
#+END_SRC
|
||||
1357
docs/deprecated/awesome.org
Normal file
715
docs/deprecated/i3.org
Normal file
@@ -0,0 +1,715 @@
|
||||
#+TITLE: i3
|
||||
#+setupfile: ../headers
|
||||
#+PROPERTY: header-args :noweb yes :exports code :tangle ~/.config/i3/config
|
||||
#+PROPERTY: header-args:emacs-lisp :exports none :tangle no
|
||||
|
||||
* i3
|
||||
#+begin_center
|
||||
*Before proceeding, be aware that I deprecated this i3 config on August 22nd, 2020, meaning I won’t update it anymore unless I use it again some day in the future. I will keep it on my website though.*
|
||||
#+end_center
|
||||
|
||||
=i3= is a window manager for GNU/Linux which automatically tiles windows in workspaces. This configuration was ade to automatically handle some tasks such as which software allowed where, autostart, and launching software with shortcuts.
|
||||
|
||||
It is to be noted I am using [[https://github.com/Airblader/i3][Airblader’s fork of i3]], =i3-gaps=. Some configuration will not work with =i3=.
|
||||
|
||||
#+BEGIN_SRC conf :exports none
|
||||
# -*- mode: conf -*-
|
||||
#+END_SRC
|
||||
|
||||
** Screenshots
|
||||
#+CAPTION: Desktop with Neofetch in the terminal
|
||||
[[./img/neofetch.png.webp]]
|
||||
|
||||
#+CAPTION: Desktop with Emacs opened
|
||||
[[./img/emacs.png.webp]]
|
||||
|
||||
#+CAPTION: Desktop with Rofi
|
||||
[[./img/rofi.png.webp]]
|
||||
|
||||
** Variables declaration
|
||||
*** Global
|
||||
The first I do is declaring the modifier key and the alt key —I don’t find the names =Mod1= and =Mod4= to be explicit enough. This will map =$mod= to the Super key (or as some people unfortunately call it, the /Windows/ key) and =$alt= to the Alt key.
|
||||
|
||||
Let’s also bind the =$up=, =$down=, =$left= and =$right= variables to respectively the up, down, left, and right arrows on the keyboard. Why bind them to variables? If I ever want to modify the arrow keys to some other keys, like =é=, =a=, =u=, and =i= (the equivalent of =wqsd= on the bépo layout) or =c=, =t=, =s=, and =r= (the equivalent of =hjkl= on the bépo layout), I will just have to modify these four lines.
|
||||
|
||||
I’ll also set the =$term= variable. A lot of shortcuts in my i3 config rely on the terminal emulator itself to launch commands in the terminal, and thus call the terminal itself. If I ever need to move from my current terminal, I will just have to change the name of the executable here.
|
||||
|
||||
#+NAME: variable-table
|
||||
| variable | value |
|
||||
|----------+-------|
|
||||
| $mod | Mod4 |
|
||||
| $alt | Mod1 |
|
||||
| $up | Up |
|
||||
| $down | Down |
|
||||
| $left | Left |
|
||||
| $right | Right |
|
||||
| $term | st |
|
||||
|
||||
#+NAME: variable-sh
|
||||
| variable | value |
|
||||
|-------------+--------------------------------------------------------------------------|
|
||||
| $exiti3 | i3-nagbar -t warning -m 'Leave i3?' -b 'Yes' 'i3-msg exit' |
|
||||
| $lockscreen | Lucien Cartier-Tilet\n(Phuntsok Drak-pa)\n+33 (0)6 83 90 56 89 |
|
||||
| $rofiexec | rofi -combi-modi 'window,drun' -show combi -mohh combi -m -1 -show-icons |
|
||||
| $mail | emacsclient -c -e '(mu4e)' -n |
|
||||
| $ec | emacsclient -c -n |
|
||||
| $walset | wal -i ~/Pictures/Wallpapers -o wal-set |
|
||||
|
||||
Variables will be set like so.
|
||||
#+BEGIN_SRC conf :tangle no
|
||||
set $term st
|
||||
#+END_SRC
|
||||
|
||||
#+NAME: generate-variables
|
||||
#+BEGIN_SRC emacs-lisp :var variables=variable-table :cache yes
|
||||
(mapconcat (lambda (x) (format "set %s %s" (car x) (cadr x)))
|
||||
variables
|
||||
"\n")
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS[48079cbd7e6dbf2003fe5ae87216bd38f638b6f8]: generate-variables
|
||||
: set $mod Mod4
|
||||
: set $alt Mod1
|
||||
: set $up Up
|
||||
: set $down Down
|
||||
: set $left Left
|
||||
: set $right Right
|
||||
: set $term st
|
||||
|
||||
Finally, some variables hold some long strings for commands I don’t want to have to type multiple times.
|
||||
#+NAME: generate-variables2
|
||||
#+BEGIN_SRC emacs-lisp :var variables=variable-sh :cache yes
|
||||
(mapconcat (lambda (x) (format "set %s \"%s\"" (car x) (cadr x)))
|
||||
variables
|
||||
"\n")
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS[c901e3e31c500859661650e86a6b63aef286acbe]: generate-variables2
|
||||
: set $exiti3 "i3-nagbar -t warning -m 'Leave i3?' -b 'Yes' 'i3-msg exit'"
|
||||
: set $lockscreen "Lucien Cartier-Tilet\n(Phuntsok Drak-pa)\n+33 (0)6 83 90 56 89"
|
||||
: set $rofiexec "rofi -combi-modi 'window,drun' -show combi -mohh combi -m -1 -show-icons"
|
||||
: set $mail "emacsclient -c -e '(mu4e)' -n"
|
||||
: set $ec "emacsclient -c -n"
|
||||
: set $walset "wal -i ~/Pictures/Wallpapers -o wal-set"
|
||||
|
||||
Here is the configuration:
|
||||
#+BEGIN_SRC conf :noweb yes
|
||||
<<generate-variables()>>
|
||||
<<generate-variables2()>>
|
||||
#+END_SRC
|
||||
|
||||
Now comes the font for the window tiles. Honestly, this setting is useless since we do not see it, but let’s set it anyway.
|
||||
#+BEGIN_SRC conf
|
||||
font Fira Sans Book:style=Book:pixelsize=10
|
||||
#+END_SRC
|
||||
|
||||
*** Floating windows
|
||||
Floating windows are windows that are not tiled with other windows, but rather are free to go anywhere on your screen, with any size. A bit like what you would get with any other non-tiling window manager or desktop environment (though most of them support minimal tiling features).
|
||||
|
||||
Let’s declare our floading modyfier. With floating windows, you can move them around by clicking on the window’s borders; but since we don’t have any with this config, we will have instead to press the floating modifier while clicking on the window (anywhere on the window is fine) to move them around.
|
||||
|
||||
Here is the configuration:
|
||||
#+BEGIN_SRC conf
|
||||
floating_modifier $mod
|
||||
#+END_SRC
|
||||
|
||||
** i3 global settings
|
||||
Some settings affect i3 globally, such as its aspect or how it handles the mouse. Hence, here are some settings I set in my configuration.
|
||||
|
||||
*** Mouse settings
|
||||
First of all, I do not want i3 to warp my mouse each time I change windows; my mouse stays where it is.
|
||||
#+BEGIN_SRC conf
|
||||
mouse_warping none
|
||||
#+END_SRC
|
||||
|
||||
I also to not want the window focus to follow my mouse, because sometimes I will just knock my physical mouse out of the way of my hand, and when I do that the software mouse will most likely end up in another window I do not want to focus.
|
||||
#+BEGIN_SRC conf
|
||||
focus_follows_mouse no
|
||||
#+END_SRC
|
||||
|
||||
*** Popup handling
|
||||
While in fullscreen, some software might generate a popup. In that case, I want to be aware of that, and any popup will make me leave fullscreen in order to be presented with said popup.
|
||||
#+BEGIN_SRC conf
|
||||
popup_during_fullscreen leave_fullscreen
|
||||
#+END_SRC
|
||||
|
||||
*** Behavior of workspace changes
|
||||
When changing workspace as described below, we often want to go back to the previous workspace we were working on, but we might not remember immediately which one it was, or we might still have our fingers ready to fire the shortcut which made us make the first workspace change. Hence, if we type the same workspace change shortcut, instead of doing nothing it will bring us back to the previous workspace we were on.
|
||||
#+BEGIN_SRC conf
|
||||
workspace_auto_back_and_forth yes
|
||||
#+END_SRC
|
||||
|
||||
*** Gaps and window appearance
|
||||
As mentioned in at the beginning of this document, I am using i3-gaps, which brings spacing (gaps) between windows to i3.
|
||||
|
||||
First, I want space around my windows only when there are several containers on the same screen, otherwise they will be maximized.
|
||||
#+BEGIN_SRC conf
|
||||
smart_gaps on
|
||||
#+END_SRC
|
||||
|
||||
I also do not want to see any window border, so I will be turning this setting off.
|
||||
#+BEGIN_SRC conf
|
||||
smart_borders on
|
||||
#+END_SRC
|
||||
|
||||
By the way, the default border is invisible, since it is zero pixels wide.
|
||||
#+BEGIN_SRC conf
|
||||
default_border pixel 0
|
||||
#+END_SRC
|
||||
|
||||
Then comes the size of these gaps. I made the outer gap negative so the space between my windows and the border of my screens is smaller than the gap between my containers.
|
||||
#+BEGIN_SRC conf
|
||||
gaps inner 20
|
||||
gaps outer -10
|
||||
#+END_SRC
|
||||
|
||||
Some parameters are also available when it comes to the colors i3 uses. Honestly, we won’t see these colors much, so let’s simply keep the default values.
|
||||
#+BEGIN_SRC conf
|
||||
set_from_resource $fg i3wm.color7 #f0f0f0
|
||||
set_from_resource $bg i3wm.color2 #f0f0f0
|
||||
|
||||
# class border backgr. text indicator child_border
|
||||
client.focused $bg $bg $fg $bg $bg
|
||||
client.focused_inactive $bg $bg $fg $bg $bg
|
||||
client.unfocused $bg $bg $fg $bg $bg
|
||||
client.urgent $bg $bg $fg $bg $bg
|
||||
client.placeholder $bg $bg $fg $bg $bg
|
||||
#+END_SRC
|
||||
|
||||
** Assigning windows to workspaces
|
||||
I decided to bind some windows to some workspaces in order to have a better organization of my desktop.
|
||||
#+NAME: assignment-table
|
||||
| Application | Class | Workspace |
|
||||
|-------------+-------------+-----------|
|
||||
| Emacs | Emacs | 2 |
|
||||
| Chromium | Chromium | 3 |
|
||||
| Firefox | firefox | 3 |
|
||||
| Nemo | Nemo | 4 |
|
||||
| Wonderdraft | Godot | 5 |
|
||||
| Gimp | Gimp* | 6 |
|
||||
| Gnome Boxes | gnome-boxes | 8 |
|
||||
| Steam | Steam | 9 |
|
||||
| Discord | discord | 10 |
|
||||
|
||||
The class table is used in the assignment in the i3 config file. For instance, Gimp’s assignment will look like this:
|
||||
#+BEGIN_SRC conf :tangle no
|
||||
assign [class="Gimp*"] 6
|
||||
#+END_SRC
|
||||
|
||||
#+NAME: generate-workspaces
|
||||
#+BEGIN_SRC emacs-lisp :var workspaces=assignment-table :cache yes
|
||||
(mapconcat (lambda (x) (format "assign [class=\"%s\"] %s" (cadr x) (caddr x)))
|
||||
workspaces
|
||||
"\n")
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS[0995341b013e50227edf78257ab502e46a30bc9a]: generate-workspaces
|
||||
: assign [class="Emacs"] 2
|
||||
: assign [class="Chromium"] 3
|
||||
: assign [class="firefox"] 3
|
||||
: assign [class="Nemo"] 4
|
||||
: assign [class="Godot"] 5
|
||||
: assign [class="Gimp*"] 6
|
||||
: assign [class="gnome-boxes"] 8
|
||||
: assign [class="Steam"] 9
|
||||
: assign [class="discord"] 10
|
||||
|
||||
Here is the configuration:
|
||||
#+BEGIN_SRC conf :noweb yes
|
||||
<<generate-workspaces()>>
|
||||
#+END_SRC
|
||||
|
||||
And although this is not specifically assigning a window to a workspace, I also want to have the tenth workspace assigned to a specific output in case I have two screens — and since this is the case when I am using only one computer, Marpa, I will be using some EmacsLisp in order to generate a different configuration file from this org file depending on the name of the machine.
|
||||
#+NAME: ws10-output-edp1
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(if (string= system-name "Marpa")
|
||||
"workspace 10 output eDP-1"
|
||||
"")
|
||||
#+END_SRC
|
||||
|
||||
Now I’ll call the above code as a noweb reference that should be executed.
|
||||
#+BEGIN_SRC conf
|
||||
<<ws10-output-edp1()>>
|
||||
#+END_SRC
|
||||
|
||||
** Shortcuts
|
||||
I use *A LOT* of shortcuts when it comes to my workflow. Like, all the time. So, expect this chapter to be a bit long, and I’ll try to make it readable still.
|
||||
|
||||
Shortcuts are set like so:
|
||||
#+BEGIN_SRC conf :tangle no
|
||||
bindsym shortcut command
|
||||
#+END_SRC
|
||||
|
||||
#+NAME: generate-shortcuts
|
||||
#+BEGIN_SRC emacs-lisp :exports none :var table=[] :tangle no
|
||||
(mapconcat (lambda (x) (format "bindsym %s %s" (car x) (cadr x)))
|
||||
table
|
||||
"\n")
|
||||
#+END_SRC
|
||||
|
||||
*** Terminal shortcuts
|
||||
I have a couple of shortcuts which are related to my terminal. For instance, ~$mod+Return~ opens a regular terminal instance while ~$mod+$alt+M~ opens an SSH instance on my Mila host.
|
||||
#+NAME: terminal-shortcuts
|
||||
| shortcut | command | What it does |
|
||||
|-------------------+----------------------+--------------------------------------------------|
|
||||
| $mod+Return | exec $term | Opens a regular terminal console |
|
||||
| $mod+$alt+Return | split h;; exec $term | Opens a terminal console below the current one |
|
||||
| $mod+Shift+Return | split v;; exec $term | Opens a terminal on the right of the current one |
|
||||
| $mod+$alt+m | exec $term ssh Mila | Opens an SSH instance in my Mila host |
|
||||
| $mod+$alt+n | exec $term ssh Naro | Opens an SSH instance in my Naro host |
|
||||
| $mod+Shift+h | exec $term htop | Opens a terminal with ~htop~ |
|
||||
|
||||
Here is the configuration:
|
||||
#+BEGIN_SRC conf
|
||||
<<generate-shortcuts(table=terminal-shortcuts)>>
|
||||
#+END_SRC
|
||||
|
||||
*** i3 shortcuts
|
||||
A couple of shortcuts are dedicated to i3 itself.
|
||||
#+NAME: i3-sh
|
||||
| shortcut | command | what it does |
|
||||
|--------------+---------------------------------+----------------------------------|
|
||||
| $mod+Shift+c | exec yadm alt && i3-msg reload | Reload the i3 configuration file |
|
||||
| $mod+Shift+r | exec yadm alt && i3-msg restart | Restart i3 inplace |
|
||||
| $mod+Shift+e | exec $exiti3 | Quit i3 |
|
||||
|
||||
And although this is not really an i3 shortcut per se, I add here the shortcut for launching pywal, which will set one of my wallpapers as the wallpaper and will generate my system’s color configuration from it.
|
||||
#+NAME: wal-sh
|
||||
| shortcut | command | what it does |
|
||||
|----------+--------------+--------------------------------------------------------------|
|
||||
| $mod+w | exec $walset | Set a random wallpaper and generates a color profile from it |
|
||||
|
||||
We also have some shortcuts to lock our screen, sleep, hibernate and shut down our computer.
|
||||
#+NAME: computer-sh
|
||||
| shortcut | command | what it does |
|
||||
|---------------+----------------------------+------------------------|
|
||||
| $mod+l | exec i3lock -fol | Lock the screen |
|
||||
| $mod+$alt+h | exec "systemctl suspend" | Suspend the computer |
|
||||
| $mod+Ctrl+h | exec "systemctl hibernate" | Hibernate the computer |
|
||||
| $mod+Shift+F4 | exec poweroff | Power off the computer |
|
||||
|
||||
Here is the configuration:
|
||||
#+BEGIN_SRC conf
|
||||
<<generate-shortcuts(table=i3-sh)>>
|
||||
<<generate-shortcuts(table=wal-sh)>>
|
||||
<<generate-shortcuts(table=computer-sh)>>
|
||||
#+END_SRC
|
||||
|
||||
*** Window and workspace management
|
||||
**** Managing how windows will split
|
||||
It is possible to indicate to i3 how windows interact with one another, and especially how they are organized by spawning new windows either to the right or below the current window.
|
||||
#+NAME: split-win-sh
|
||||
| shortcuts | command | what it does |
|
||||
|-----------+---------+--------------------------------------------------------|
|
||||
| $mod+h | split h | Next window to spawn will spawn below the current one |
|
||||
| $mod+v | split v | Next window to spawn will spawn beside the current one |
|
||||
|
||||
Here is the configuration:
|
||||
#+BEGIN_SRC conf
|
||||
<<generate-shortcuts(table=split-win-sh)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Focus windows
|
||||
To change window focus, you can use one of the following shortcuts:
|
||||
#+NAME: window-focus-sh
|
||||
| shortcut | command | what it does |
|
||||
|-------------+-------------+-------------------------------------------|
|
||||
| $mod+$left | focus left | Focus the window left of the current one |
|
||||
| $mod+$down | focus down | Focus the window down of the current one |
|
||||
| $mod+$up | focus up | Focus the window up of the current one |
|
||||
| $mod+$right | focus right | Focus the windof right of the current one |
|
||||
|
||||
Here is the configuration:
|
||||
#+BEGIN_SRC conf
|
||||
<<generate-shortcuts(table=window-focus-sh)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Focus workspaces
|
||||
Just like windows, it is also possible to change focus between workspaces, because let’s be honest, most people won’t have ten screens to display all ten workspaces at the same time, and frankly that would be impractical.
|
||||
#+NAME: ws-focus-sh
|
||||
| shortcut | window | what it does |
|
||||
|----------+--------------+-------------------------|
|
||||
| $mod+1 | workspace 1 | Focus first workspace |
|
||||
| $mod+2 | workspace 2 | Focus second workspace |
|
||||
| $mod+3 | workspace 3 | Focus third workspace |
|
||||
| $mod+4 | workspace 4 | Focus fourth workspace |
|
||||
| $mod+5 | workspace 5 | Focus fifth workspace |
|
||||
| $mod+6 | workspace 6 | Focus sixth workspace |
|
||||
| $mod+7 | workspace 7 | Focus seventh workspace |
|
||||
| $mod+8 | workspace 8 | Focus eighth workspace |
|
||||
| $mod+9 | workspace 9 | Focus ninth workspace |
|
||||
| $mod+0 | workspace 10 | Focus tenth workspace |
|
||||
|
||||
Here is the configuration:
|
||||
#+BEGIN_SRC conf
|
||||
<<generate-shortcuts(table=ws-focus-sh)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Moving windows
|
||||
To move windows, a couple of shortcuts are available:
|
||||
#+NAME: window-move-sh
|
||||
| shortcut | command | what it does |
|
||||
|-------------------+------------+-------------------------------|
|
||||
| $mod+Shift+$left | move left | Move the focused window left |
|
||||
| $mod+Shift+$down | move down | Move the focused window down |
|
||||
| $mod+Shift+$up | move up | Move the focused window up |
|
||||
| $mod+Shift+$right | move right | Move the focused window right |
|
||||
|
||||
Here is the configuration:
|
||||
#+BEGIN_SRC conf
|
||||
<<generate-shortcuts(table=window-move-sh)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Moving containers
|
||||
To move containers between the available screens, you have the following shortcuts:
|
||||
#+NAME: containers-move-sh
|
||||
| shortcut | command | what it does |
|
||||
|------------------+--------------------------------+------------------------------------------------------------|
|
||||
| $mod+Ctrl+$left | move container to output left | Moves the container to the screen left of the current one |
|
||||
| $mod+Ctrl+$down | move container to output down | Moves the container to the screen down of the current one |
|
||||
| $mod+Ctrl+$up | move container to output up | Moves the container to the screen above the current one |
|
||||
| $mod+Ctrl+$right | move container to output right | Moves the container to the screen right of the current one |
|
||||
|
||||
You can also send containers to other workspaces by their number.
|
||||
#+NAME: containers-ws-sh
|
||||
| shortcut | command | what it does |
|
||||
|--------------+--------------------------------+--------------------------------------------|
|
||||
| $mod+Shift+1 | move container to workspace 1 | Move current container to the workspace 1 |
|
||||
| $mod+Shift+2 | move container to workspace 2 | Move current container to the workspace 2 |
|
||||
| $mod+Shift+3 | move container to workspace 3 | Move current container to the workspace 3 |
|
||||
| $mod+Shift+4 | move container to workspace 4 | Move current container to the workspace 4 |
|
||||
| $mod+Shift+5 | move container to workspace 5 | Move current container to the workspace 5 |
|
||||
| $mod+Shift+6 | move container to workspace 6 | Move current container to the workspace 6 |
|
||||
| $mod+Shift+7 | move container to workspace 7 | Move current container to the workspace 7 |
|
||||
| $mod+Shift+8 | move container to workspace 8 | Move current container to the workspace 8 |
|
||||
| $mod+Shift+9 | move container to workspace 9 | Move current container to the workspace 9 |
|
||||
| $mod+Shift+0 | move container to workspace 10 | Move current container to the workspace 10 |
|
||||
|
||||
Here is the configuration:
|
||||
#+BEGIN_SRC conf
|
||||
<<generate-shortcuts(table=containers-move-sh)>>
|
||||
<<generate-shortcuts(table=containers-ws-sh)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Moving workspaces
|
||||
|
||||
It is also possible to move workspaces. The related shortcuts available are the following:
|
||||
|
||||
#+NAME: workspace-move-sh
|
||||
| shortcut | command | what it does |
|
||||
|------------------------+--------------------------------+------------------------------------------------------------|
|
||||
| $mod+Ctrl+Shift+$left | move workspace to output left | Moves the workspace to the screen left of the current one |
|
||||
| $mod+Ctrl+Shift+$down | move workspace to output down | Moves the workspace to the screen down of the current one |
|
||||
| $mod+Ctrl+Shift+$up | move workspace to output up | Moves the workspace to the screen above the current one |
|
||||
| $mod+Ctrl+Shift+$right | move workspace to output right | Moves the workspace to the screen right of the current one |
|
||||
|
||||
Here is the configuration:
|
||||
#+BEGIN_SRC conf
|
||||
<<generate-shortcuts(table=workspace-move-sh)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Close windows
|
||||
To close windows, we have two main shortcuts: Alt+F4 and mod+q. The first one is here due to habits, but I don’t really use it anymore due to my main keyboard which doesn’t have any easy access to the functions keys, hence mod+q.
|
||||
#+NAME: close-win-sh
|
||||
| shortcut | command | what it does |
|
||||
|----------+---------+-------------------------|
|
||||
| $mod+q | kill | kill the current window |
|
||||
| $alt+F4 | kill | kill the current window |
|
||||
|
||||
Here is the configuration:
|
||||
#+BEGIN_SRC conf
|
||||
<<generate-shortcuts(table=close-win-sh)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Manage the size of the current window
|
||||
It is possible to change the size of the current window, even if it is a floating one. The first shortcut that might interest you is $mod+f which switches your current window to fullscreen. But to resize a window, you will need to enter the ~resize~ mode.
|
||||
#+NAME: size-win-sh
|
||||
| shortcut | command | what it does |
|
||||
|----------+-------------------+---------------------------------------------------|
|
||||
| $mod+f | fullscreen toggle | Puts the current window in fullscreen or exits it |
|
||||
| $mod+r | mode "resize" | Enter resize mode |
|
||||
|
||||
When it comes to modes, they are defined as follows:
|
||||
#+BEGIN_SRC conf :tangle no
|
||||
mode "nameofyourmode" {
|
||||
here go your shortcuts
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
So, all the following shortcuts will be inserted in a mode called ~resize~. Note that not only are the resizing shortcuts bound to the arrow keys, they are also bound to ~ctsr~, which is the bépo equivalent of ~hjkl~.
|
||||
#+NAME: resize-win-sh
|
||||
| shortcut | command | what it does |
|
||||
|----------+-------------------------------------+-------------------------------------------|
|
||||
| $right | resize grow width 20 px or 10 ppt | Increase the width of the current window |
|
||||
| r | resize grow width 20 px or 10 ppt | Increase the width of the current window |
|
||||
| $left | resize shrink width 10 px or 5 ppt | Decrease the width of the current window |
|
||||
| c | resize shrink width 10 px or 5 ppt | Decrease the width of the current window |
|
||||
| $down | resize grow height 10 px or 5 ppt | Increase the height of the current window |
|
||||
| t | resize grow height 10 px or 5 ppt | Increase the height of the current window |
|
||||
| $up | resize shrink height 10 px or 5 ppt | Decrease the height of the current window |
|
||||
| s | resize shrink height 10 px or 5 ppt | Decrease the height of the current window |
|
||||
| Return | mode "default" | Return to the default mode |
|
||||
| Escape | mode "default" | Return to the default mode |
|
||||
If you prefer, you can think of these shortcuts not as increasing or decreasing the width or height of the current window, but rather as how the bottom or right limit of the windows will be moved relative to the top left corner.
|
||||
|
||||
Here is the configuration:
|
||||
#+BEGIN_SRC conf
|
||||
<<generate-shortcuts(table=size-win-sh)>>
|
||||
mode "resize" {
|
||||
<<generate-shortcuts(table=resize-win-sh)>>
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
**** Manage floating windows
|
||||
As said above, your windows can be floating windows instead of being tiled like they are by default. For this too we have a couple of shortcuts:
|
||||
#+NAME: float-win-sh
|
||||
| shortcut | command | what it does |
|
||||
|------------------+----------------------+------------------------------------------------------|
|
||||
| $mod+Shift+space | floating toggle | Toggles the window between tiled and floating mode |
|
||||
| $mod+space | focus mode_toggle | Toggles the focus between tiled and floating windows |
|
||||
| $mod+Ctrl+c | move position center | Centers the focused floating window |
|
||||
If you want to move around your floating window, you can do it with your mouse while holding down the floating modifier declared [[file:./i3.md#floating-windows][here]].
|
||||
|
||||
Here is the configuration:
|
||||
#+BEGIN_SRC conf
|
||||
<<generate-shortcuts(table=float-win-sh)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Scratchpad and window display
|
||||
You can think of i3’s scratchpad as some sort of extra workspace in which you can hide your windows you are not using, or as if you want to reduce a window to the taskbar of other window managers or desktop environments. You have basically two shortcuts for the scratchpad: one that sends the current window to the scratchpad, and one that cicles through the windows sent to the scratchpad and shows them to you sequencially. If you go through all of them, they will be hidden again. You can get a window out of the scratchpad by tiling it to the current workspace with the shortcut described above.
|
||||
|
||||
You also have the possibility of making a floating window a sticky window. This means not only will it show on all workspaces, it will also be on top of every other window. It can be useful if you have some notes you want to keep an eye on for instance.
|
||||
#+NAME: scratchpad-sh
|
||||
| shortcut | command | what it does |
|
||||
|--------------+-----------------+------------------------------------------------------|
|
||||
| $mod+Shift+s | move scratchpad | Sends the current window to the scratchpad |
|
||||
| $mod+s | scratchpad show | Shows and cycles through windows from the scratchpad |
|
||||
| $mod+Ctrl+s | sticky toggle | Toggles sticky mode on current window |
|
||||
|
||||
Here is the configuration:
|
||||
#+BEGIN_SRC conf
|
||||
<<generate-shortcuts(table=scratchpad-sh)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Gaps management
|
||||
It is possible to dynamically change the gaps between containers if we want to change a bit the appearance of i3. For that, we obviously have some shortcuts.
|
||||
#+NAME: gaps-resize-sh
|
||||
| shortcut | command | what it does |
|
||||
|-------------------+-----------------------------------------------+-----------------------------|
|
||||
| $mod+g | gaps inner current plus 5 | Increase the inner gap size |
|
||||
| $mod+Shift+g | gaps inner current minus 5 | Decrease the inner gap size |
|
||||
| $mod+Ctrl+g | gaps outer current plus 5 | Increase the outer gap size |
|
||||
| $mod+Ctrl+Shift+g | gaps outer current minus 5 | Decrease the outer gap size |
|
||||
| $mod+$alt+g | gaps inner all set 20; gaps outer all set -10 | Reset gaps |
|
||||
|
||||
Here is the corresponding configuration:
|
||||
#+BEGIN_SRC conf
|
||||
<<generate-shortcuts(table=gaps-resize-sh)>>
|
||||
#+END_SRC
|
||||
|
||||
*** Launching software
|
||||
A big part of my i3 shortcuts though are related to launching various software. I’ll try to sort them by category here, but do take a look even at categories which you might not be interested in, they might actually have something useful for you.
|
||||
|
||||
**** Software and command launcher
|
||||
These commands will allow the user to launch applications which provide ~.desktop~ files or user-defined ~.desktop~ files, as well as commands with the help of rofi.
|
||||
#+NAME: launcher-sh
|
||||
| shortcut | command | what it does |
|
||||
|--------------+---------------------------------------+-------------------------------------------------------|
|
||||
| $mod+Shift+d | exec --no-startup-id j4-dmenu-desktop | Launch a registered application |
|
||||
| $mod+d | exec --no-startup-id $rofiexec | Launch a terminal command or a registered application |
|
||||
|
||||
Here is the configuration:
|
||||
#+BEGIN_SRC conf
|
||||
<<generate-shortcuts(table=launcher-sh)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Internet software
|
||||
I have a couple of Internet-related software I can launch easily.
|
||||
#+NAME: internet-sh
|
||||
| shortcut | command | what it does |
|
||||
|--------------+---------------------+-----------------------------|
|
||||
| $mod+b | exec firefox | Launch browser |
|
||||
| $mod+m | exec $mail | Launch Gnus, my mail client |
|
||||
| Ctrl+Shift+d | exec discord-canary | Launch Discord |
|
||||
|
||||
Hence this configuration:
|
||||
#+BEGIN_SRC conf
|
||||
<<generate-shortcuts(table=internet-sh)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Screenshots
|
||||
A couple of shortcuts are available for taking screenshots.
|
||||
#+NAME: screenshot-sh
|
||||
| shortcut | command | what it does |
|
||||
|-------------+-----------------------------------+----------------------------------------------------------|
|
||||
| Print | exec --no-startup-id scrot | Takes a screenshot of the entire desktop |
|
||||
| Ctrl+Print | exec --no-startup-id "scrot -s" | Takes a screenshot of a region or the selected window |
|
||||
| Shift+Print | exec --no-startup-id "scrot -d 3" | takes a screenshot of the desktop three in three seconds |
|
||||
|
||||
This gives us this configuration:
|
||||
#+BEGIN_SRC conf
|
||||
<<generate-shortcuts(table=screenshot-sh)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Screen brightness
|
||||
Here we have four commands for managing our screen’s brightness (this is useful for laptops, not so much with desktops), and two of them are actually duplicates of the other two in case a laptop doesn’t have dedicated keys or we are using a keyboard which doesn’t provide them.
|
||||
#+NAME: brightness-sh
|
||||
| shortcut | command | what it does |
|
||||
|-----------------------+------------------------+---------------------------------------|
|
||||
| XF86MonBrightnessUp | exec xbacklight -inc 5 | Increase the brightness of the screen |
|
||||
| $mod+$alt+Next | exec xbacklight -inc 5 | Increase the brightness of the screen |
|
||||
| XF86MonBrightnessDown | exec xbacklight -dec 5 | Decrease the brightness of the screen |
|
||||
| $mod+$alt+Prev | exec xbacklight -dec 5 | Decrease the brightness of the screen |
|
||||
|
||||
This gives us this configuration:
|
||||
#+BEGIN_SRC conf
|
||||
<<generate-shortcuts(table=brightness-sh)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Media control
|
||||
Some shortcuts are dedicated to media control, especially when it comes to controlling music. All of these media control shortcuts will be calls to ~mpc~ which will in turn send commands to ~mpd~, which is the music server I use on my computers.
|
||||
#+NAME: media-sh
|
||||
| shortcut | command | what it does |
|
||||
|---------------------------+--------------------+--------------------------------|
|
||||
| XF86AudioNext | exec mpc next | Forward to the next track |
|
||||
| $alt+XF86AudioRaiseVolume | exec mpc next | Forward to the next track |
|
||||
| $mod+Next | exec mpc next | Forward to the next track |
|
||||
| XF86AudioPrev | exec mpc prev | Backward to the previous track |
|
||||
| $alt+XF86AudioLowerVolume | exec mpc prev | Backward to the previous track |
|
||||
| $mod+Prior | exec mpc prev | Backward to the previous track |
|
||||
| XF86AudioPlay | exec mpc toggle | Play or pause the music |
|
||||
| $mod+p | exec mpc toggle | Play or pause the music |
|
||||
| $mod+$alt+p | exec mpc stop | Completely stop the music |
|
||||
| XF86AudioStop | exec mpc stop | Completely stop the music |
|
||||
| $alt+XF86AudioPlay | exec mpc stop | Completely stop the music |
|
||||
| $mod+$alt+7 | exec mpc volume +5 | Increase the volume from mpd |
|
||||
| $mod+$alt+8 | exec mpc volume -5 | Decrease the volume from mpd |
|
||||
|
||||
We also have two shortcuts for launching ncmpcpp, my mpd frontend, either with the playlist open by default, or the visualizes open.
|
||||
#+NAME: ncmpcpp-sh
|
||||
| shortcut | command | what it does |
|
||||
|--------------+-----------------------------------+----------------------------------|
|
||||
| $mod+Shift+n | exec $term ncmpcpp -q | Launch ncmpcpp’s playlist editor |
|
||||
| $mod+Shift+v | exec $term ncmpcpp -qs visualizer | Launch ncmpcpp’s visualizer |
|
||||
|
||||
We also have more general shortcuts, like how to manipulate the general volume level.
|
||||
#+NAME: volume-sh
|
||||
| shortcut | command | what it does |
|
||||
|----------------------+----------------------------------------+----------------------|
|
||||
| XF86AudioMute | exec "amixer set Master 1+ toggle" | Mute or unmute audio |
|
||||
| Ctrl+$mod+Prior | exec "amixer -q set Master 2%+ unmute" | Raise volume |
|
||||
| XF86AudioRaiseVolume | exec "amixer -q set Master 2%+ unmute" | Raise volume |
|
||||
| Ctrl+$mod+Next | exec "amixer -q set Master 2%- unmute" | Reduce volume |
|
||||
| XF86AudioLowerVolume | exec "amixer -q set Master 2%- unmute" | Reduce volume |
|
||||
|
||||
This gives us this configuration:
|
||||
#+BEGIN_SRC conf
|
||||
<<generate-shortcuts(table=media-sh)>>
|
||||
<<generate-shortcuts(table=ncmpcpp-sh)>>
|
||||
<<generate-shortcuts(table=volume-sh)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Rofi utilities
|
||||
We also have some utilities I’ve written and which are interfaced with rofi. Here are said shortcuts.
|
||||
#+NAME: rofi-sh
|
||||
| shortcut | command | what it does |
|
||||
|-------------------+-----------------------+---------------------------------------------------------------------|
|
||||
| $mod+Shift+p | exec rofi-pass --type | Types the selected password available from ~pass~ where the cursor is |
|
||||
| $mod+Ctrl+Shift+p | exec rofi-pass | Copies in the clipboard the selected password from ~pass~ for 45 sec |
|
||||
| $mod+Ctrl+m | exec rofi-mount | Volume mounting helper |
|
||||
| $mod+Ctrl+u | exec rofi-umount | Volume unmounting helper |
|
||||
| $mod+$alt+e | exec rofi-emoji | Emoji picker, copies it in the clipboard |
|
||||
| $mod+Ctrl+w | exec wacom-setup | Sets my Wacom Bamboo tablet as being active on the selected screen |
|
||||
| $mod+Shift+w | exec connect-wifi | Connect to an available WiFi network |
|
||||
|
||||
This gives us the following configuration:
|
||||
#+BEGIN_SRC conf
|
||||
<<generate-shortcuts(table=rofi-sh)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Miscellaneous
|
||||
And last but not least, I have some other shortcuts for various software, some of them which I use quite a lot like the shortcut for launching Emacs.
|
||||
#+NAME: misc-sh
|
||||
| shortcut | command | what it does |
|
||||
|-------------+------------------+---------------------------------|
|
||||
| $mod+e | exec $ec | Launch Emacs client |
|
||||
| $mod+n | exec nemo | Launch Nemo (file manager) |
|
||||
| $mod+$alt+c | exec speedcrunch | Launch Speedcrunch (calculator) |
|
||||
| $mod+F3 | exec arandr | Launch arandr |
|
||||
|
||||
This gives us the following configuration:
|
||||
#+BEGIN_SRC conf
|
||||
<<generate-shortcuts(table=misc-sh)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Screen management
|
||||
Additionally, we have a shortcut for entering presentation mode on the additional screen of the computer; on my main computer, Mila, the additional screen is HDMI-1, while it is VGA1 on my travel laptop. We’ll use some Emacs Lisp to determine on the configuration file export which screens names to use.
|
||||
#+NAME: hostname-screen-management
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(cond ((string= system-name "Marpa") "bindsym $mod+Ctrl+p xrandr --output HDMI-1 --mode 1024x768 --right-of eDP-1")
|
||||
((string= system-name "gampo") "bindsym $mod+Ctrl+p xrandr --output VGA1 --mode 1024x768 --right-of LVDS1"))
|
||||
#+END_SRC
|
||||
|
||||
Now, we just have to call this Emacs Lisp code as a noweb reference and execute it.
|
||||
#+BEGIN_SRC conf :noweb yes
|
||||
<<hostname-screen-management()>>
|
||||
#+END_SRC
|
||||
|
||||
** Software autolaunch
|
||||
When i3 is launched, I want it to also launch some software automatically. Here is what we will launch:
|
||||
#+NAME: autolaunch
|
||||
| always execute it? | command | what it is |
|
||||
|--------------------+-------------------------------------------+----------------------------------------|
|
||||
| no | /usr/lib/xfce-polkit/xfce-polkit | Launch the XFCE Polkit |
|
||||
| no | picom --experimental-backends -e 1 | Launch picom |
|
||||
| no | xss-lock -- lock | Launch power management |
|
||||
| no | numlockx on | Activate NumLock |
|
||||
| no | dunst -config ~/.config/dunst/dunstrc | Launch notification manager |
|
||||
| no | nm-applet | NetworkManager system tray |
|
||||
| yes | wal -i "$(< "${HOME}/.cache/wal/wal")" | Sets the wallpaper from last session |
|
||||
| no | xrdb $HOME/.Xresources | Load Xresources files |
|
||||
| yes | polybar-launch | Launch polybar |
|
||||
| no | mpc stop | Stop music from mpd |
|
||||
| no | mpd_discord_richpresence --no-idle --fork | Launch mpd status sharing with Discord |
|
||||
|
||||
#+NAME: generate-autolaunch
|
||||
#+BEGIN_SRC emacs-lisp :exports none :cache yes :var table=autolaunch
|
||||
(mapconcat (lambda (x)
|
||||
(format (concat (if (string= (car x)
|
||||
"yes")
|
||||
"exec_always"
|
||||
"exec")
|
||||
" --no-startup-id %s")
|
||||
(cadr x)))
|
||||
table
|
||||
"\n")
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS[283577fe2e66b30c936b7fcf142713d285db8da6]: generate-autolaunch
|
||||
#+begin_example
|
||||
exec_always --no-startup-id wal -i "$(< "${HOME}/.cache/wal/wal")"
|
||||
exec --no-startup-id xss-lock -- i3lock -fol
|
||||
exec --no-startup-id dunst -config ~/.config/dunst/dunstrc
|
||||
exec --no-startup-id xrdb $HOME/.Xresources
|
||||
exec --no-startup-id compton -F --opengl --config ~/.config/compton.conf -e 1
|
||||
exec_always --no-startup-id polybar-launch
|
||||
exec_always --no-startup-id enable_touch
|
||||
exec --no-startup-id syndaemon -i 1.0 -t -k
|
||||
exec --no-startup-id mpc stop
|
||||
exec --no-startup-id mpd_discord_richpresence --no-idle --fork
|
||||
exec --no-startup-id nm-applet
|
||||
exec --no-startup-id numlockx on
|
||||
#+end_example
|
||||
|
||||
My travel laptop has a fingerprint reader which can be used as an authentification method when the root password is asked. Let’s launch our policy kit manager if that is the case:
|
||||
#+NAME: fingerprint-thinkpad
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(if (string= system-name "gampo")
|
||||
"exec --no-startup-id /usr/lib/mate-polkit/polkit-mate-authentication-agent-1"
|
||||
"")
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC conf
|
||||
<<fingerprint-thinkpad()>>
|
||||
<<generate-autolaunch()>>
|
||||
#+END_SRC
|
||||
BIN
docs/deprecated/img/emacs.png
Normal file
|
After Width: | Height: | Size: 392 KiB |
BIN
docs/deprecated/img/emacs.png.webp
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
docs/deprecated/img/neofetch.png
Normal file
|
After Width: | Height: | Size: 3.0 MiB |
BIN
docs/deprecated/img/neofetch.png.webp
Normal file
|
After Width: | Height: | Size: 179 KiB |
2540
docs/deprecated/img/org-mode.svg
Normal file
|
After Width: | Height: | Size: 415 KiB |
BIN
docs/deprecated/img/rofi.png
Normal file
|
After Width: | Height: | Size: 2.8 MiB |
BIN
docs/deprecated/img/rofi.png.webp
Normal file
|
After Width: | Height: | Size: 160 KiB |
8
docs/deprecated/index.org
Normal file
@@ -0,0 +1,8 @@
|
||||
#+title: Deprecated configs
|
||||
#+setupfile: ../headers
|
||||
|
||||
* Deprecated configs
|
||||
Here you will find configurations that I no longer use nor maintain. I
|
||||
keep them here for the sake of archiving them, but do not expect them
|
||||
to be up to date with the current state of whichever software they are
|
||||
meant to configure.
|
||||
92
docs/deprecated/nano.org
Normal file
@@ -0,0 +1,92 @@
|
||||
#+TITLE: Nano
|
||||
#+setupfile: ../headers
|
||||
#+PROPERTY: header-args :tangle ~/.config/nano/nanorc
|
||||
|
||||
* Nano
|
||||
#+begin_center
|
||||
*Before proceeding, be aware that I deprecated this nano config on August 28th, 2020, meaning I won’t update it anymore unless I use it again some day in the future. I will keep it on my website though.*
|
||||
#+end_center
|
||||
|
||||
I nowadays rarely use Nano as a text editor, since I mainly rely on Emacs for all sorts of tasks, including quick file editing. However, at times, Emacs won’t work or won’t be available, and I therefore need a lightweight, fast and reliable text editor: Nano. And despite Nano being a simple piece of software, it does offer some customization I cannot refuse. Here is how I configured it:
|
||||
|
||||
** Configuration
|
||||
When saving a file, create a backup file by adding a tilde (=~=) to the file's name. And make and keep not just one backup file, but make and keep a uniquely numbered one every time a file is saved — when backups are enabled with =set backup= or =--backup= or =-B=. The uniquely numbered files are stored in the directory =~/.cache/nano/backups/=.
|
||||
#+BEGIN_SRC conf
|
||||
set backup
|
||||
set backupdir /home/phundrak/.cache/nano/backups/
|
||||
#+END_SRC
|
||||
|
||||
Save a file by default in Unix format. This overrides nano's default behavior of saving a file in the format that it had. (This option has no effect when you also use =set noconvert=.)
|
||||
#+BEGIN_SRC conf
|
||||
set unix
|
||||
#+END_SRC
|
||||
|
||||
*** Keys behavior
|
||||
Make the Home key smarter. When Home is pressed anywhere but at the very beginning of non-whitespace characters on a line, the cursor will jump to that beginning (either forwards or backwards). If the cursor is already at that position, it will jump to the true beginning of the line.
|
||||
#+BEGIN_SRC conf
|
||||
set smarthome
|
||||
#+END_SRC
|
||||
|
||||
*** Search
|
||||
Do case-unsensitive searches by default.
|
||||
#+BEGIN_SRC conf
|
||||
unset casesensitive
|
||||
#+END_SRC
|
||||
|
||||
Do regular-expression searches by default. Regular expressions in =nano= are of the extended type (ERE).
|
||||
#+BEGIN_SRC conf
|
||||
set regexp
|
||||
#+END_SRC
|
||||
|
||||
*** Visual settings
|
||||
Use bold instead of reverse video for the title bar, status bar, key combos, function tags, line numbers, and selected text. This can be overridden by setting the options =titlecolor=, =statuscolor=, =keycolor=, =functioncolor=, =numbercolor=, and =selectedcolor=.
|
||||
#+BEGIN_SRC conf
|
||||
set boldtext
|
||||
#+END_SRC
|
||||
|
||||
Enable soft line wrapping for easier viewing of very long lines.
|
||||
#+BEGIN_SRC conf
|
||||
set softwrap
|
||||
#+END_SRC
|
||||
|
||||
When soft line wrapping is enabled, make it wrap lines at blank characters (tabs and spaces) instead of always at the edge of the screen.
|
||||
#+BEGIN_SRC conf
|
||||
set atblanks
|
||||
#+END_SRC
|
||||
|
||||
Display line numbers to the left of the text area.
|
||||
#+BEGIN_SRC conf
|
||||
set linenumbers
|
||||
#+END_SRC
|
||||
|
||||
Constantly display the cursor position in the status bar. This overrides the option =quickblank=.
|
||||
#+BEGIN_SRC conf
|
||||
set constantshow
|
||||
#+END_SRC
|
||||
|
||||
*** Whitespace settings
|
||||
Convert typed tabs to spaces. Sue me.
|
||||
#+BEGIN_SRC conf
|
||||
set tabstospaces
|
||||
#+END_SRC
|
||||
|
||||
Use a tab size of a certain amount of columns. The value of number must be greater than 0. The default value is 8.
|
||||
#+BEGIN_SRC conf
|
||||
set tabsize 2
|
||||
#+END_SRC
|
||||
|
||||
Automatically indent a newly created line to the same number of tabs and/or spaces as the previous line (or as the next line if the previous line is the beginning of a paragraph).
|
||||
#+BEGIN_SRC conf
|
||||
set autoindent
|
||||
#+END_SRC
|
||||
|
||||
Remove trailing whitespace from wrapped lines when automatic hard-wrapping occurs or when text is justified.
|
||||
#+BEGIN_SRC conf
|
||||
set trimblanks
|
||||
#+END_SRC
|
||||
|
||||
*** Included configuration file
|
||||
Nano gives the opportunity to include some files located elsewhere. This is why I added [[https://github.com/scopatz/nanorc][this repo]] as a submodule of my dotfiles so I can access a lot of them at the same time. Since the submodule is cloned in =~/.config/nanorc=, we can add only one line to include all of the =.nanorc= files.
|
||||
#+BEGIN_SRC conf
|
||||
include ~/.config/nano/nano-syntax/*.nanorc
|
||||
#+END_SRC
|
||||
743
docs/deprecated/polybar.org
Normal file
@@ -0,0 +1,743 @@
|
||||
#+TITLE: Polybar
|
||||
#+setupfile: ../headers
|
||||
#+PROPERTY: header-args :exports none
|
||||
#+PROPERTY: header-args:emacs-lisp :tangle no :exports none
|
||||
#+PROPERTY: header-args:conf-windows :tangle ~/.config/polybar/config :noweb yes :exports code :mkdirp yes
|
||||
|
||||
* Polybar
|
||||
#+begin_center
|
||||
*Before proceeding, be aware that I deprecated this polybar config on August 22nd, 2020, meaning I won’t update it anymore unless I use it again some day in the future. I will keep it on my website though.*
|
||||
#+end_center
|
||||
|
||||
Polybar is a desktop utility for displaying various information in form of bars for GNU/Linux systems. It is often used as a replacement for native bars available in window managers, such as i3. In my case, I use two instances of polybar in order to get two bars displayed on each screen. The information displayed is either related to i3 itself, or it is system information, such as CPU or disk usage. More information will be given and explained below.
|
||||
|
||||
If you want to learn more about how to configure Polybar, you can go to its [[https://github.com/jaagr/polybar][official repository on Github]].
|
||||
|
||||
#+BEGIN_EXPORT latex
|
||||
Be aware that this PDF documents suffers from a couple of issues with some characters such as emojis. If you wish to see everything correctly, I would suggest you to take a look at the online HTML version of this document.
|
||||
#+END_EXPORT
|
||||
|
||||
** General settings
|
||||
Some general settings are available for Polybar, and they are declared under
|
||||
the ~[settings]~ section.
|
||||
#+BEGIN_SRC conf-windows
|
||||
[settings]
|
||||
#+END_SRC
|
||||
Only one setting is used in this configuration though: the ability to relauch
|
||||
polybar on a configuration file rewrite.
|
||||
#+BEGIN_SRC conf-windows
|
||||
screenchange-reload = true
|
||||
#+END_SRC
|
||||
|
||||
Some global settings are also available in order to adjust the
|
||||
~_NET_WM_STRUT_PARTIAL~ top and bottom values:
|
||||
#+BEGIN_SRC conf-windows
|
||||
[global/wm]
|
||||
margin-top = 32
|
||||
margin-bottom = 22
|
||||
#+END_SRC
|
||||
|
||||
** Colors declaration for polybar
|
||||
#+BEGIN_SRC conf-windows :exports none
|
||||
; -*- mode: conf-windows -*-
|
||||
#+END_SRC
|
||||
Like most status bars available, we can declare custom colors to be used in polybar. This part of the configuration file is declared with the following header:
|
||||
#+BEGIN_SRC conf-windows
|
||||
[colors]
|
||||
#+END_SRC
|
||||
As I use pywal as a color scheme generator based on the color of my wallpaper, I need to tell polybar to fetch the colors it will use from xrdb. If such color cannot be used, other colors will be used as fallback colors. First, let’s declare our default background and foreground colors with their alternative option.
|
||||
#+BEGIN_SRC conf-windows
|
||||
background = ${xrdb:color1:#50000000}
|
||||
background-alt = ${xrdb:color2:#444}
|
||||
foreground = ${xrdb:color7:#dfdfdf}
|
||||
foreground-alt = ${xrdb:color6:#555}
|
||||
#+END_SRC
|
||||
Now, we can also declare our primary and secondary colors.
|
||||
#+BEGIN_SRC conf-windows
|
||||
primary = #ffb52a
|
||||
secondary = #e60053
|
||||
#+END_SRC
|
||||
Polybar is also aware of alerts sent by window managers such as i3 when a window opens in an unfocused workspace. For that, let’s declare an alert color.
|
||||
#+BEGIN_SRC conf-windows
|
||||
alert = #bd2c40
|
||||
#+END_SRC
|
||||
|
||||
** Declaration of the bars
|
||||
It is possible in i3 to declare as many bars as we wish, and each of these bars will be named. Naming the bar is done in its module declaration like so:
|
||||
#+BEGIN_SRC conf-windows :tangle no
|
||||
[bar/nameofthebar]
|
||||
#+END_SRC
|
||||
In my configuration, I use two of such bars, one atop of my screen, and one at the bottom.
|
||||
|
||||
*** Top bar declaration
|
||||
As unimaginative as it might seem, I went for a rather explicit name for my bars. The top one is simply named ~top~, as shown below.
|
||||
#+BEGIN_SRC conf-windows
|
||||
[bar/top]
|
||||
#+END_SRC
|
||||
|
||||
**** Positioning
|
||||
We need to set on which screen the bar is to be displayed. Indeed, it is possible to display a bar on only one specific screen if we wish to. Actually, it is even the default behavior of polybar, but as we will see later with the launching script, it is possible to launch bars on multiple outputs at the same time. Here, we simply get the value of the variable ~monitor~ from the launch environment.
|
||||
#+NAME: monitor-bar
|
||||
#+BEGIN_SRC conf-windows
|
||||
monitor = ${env:MONITOR}
|
||||
#+END_SRC
|
||||
We have a few position-related variables that need to be set. We can specify whether or not we want our bar at the bottom of the screen —which is the default behavior of polybar—, its width, its height, the radius for the rounding of its corners and whether the bar should be centered or not. In my case, my bars are rather small height-wise, and it occupies most of the width of my screens. There is some gaps between this bar and the border of the screen, but this is due to a border around the bar itself which acts not only on the width of the bar itself, but also on its height.
|
||||
#+BEGIN_SRC conf-windows
|
||||
bottom = false
|
||||
border-size = 5
|
||||
<<position-bar-top>>
|
||||
#+END_SRC
|
||||
#+NAME: position-bar-top
|
||||
#+BEGIN_SRC conf-windows :exports none :tangle no
|
||||
width = 100%
|
||||
height = 22
|
||||
radius = 10.0
|
||||
fixed-center = true
|
||||
#+END_SRC
|
||||
We also want to add some padding to our bar so our modules are not too close to its edges, especially due to the rounding of the top bar.
|
||||
#+NAME: padding-bar
|
||||
#+BEGIN_SRC conf-windows
|
||||
padding-left = 2
|
||||
padding-right = 4
|
||||
#+END_SRC
|
||||
Each module will have some padding around it, so that modules aren’t glued together and instead have some room to breathe. The padding on the left is a bit less than the padding on the right for aesthetic reasons.
|
||||
#+NAME: module-margin-bar
|
||||
#+BEGIN_SRC conf-windows
|
||||
module-margin-left = 1
|
||||
module-margin-right = 2
|
||||
#+END_SRC
|
||||
The top bar doesn’t include any system tray, so let’s disable that.
|
||||
#+BEGIN_SRC conf-windows
|
||||
tray-position = none
|
||||
#+END_SRC
|
||||
|
||||
**** Colors and display
|
||||
As explained above, we declared some global variables when it comes to colors, and this is where they will be used. The bar’s background will be of the same color as the main background color declared earlier, and the same goes for the foreground.
|
||||
#+NAME: bar-colors
|
||||
#+BEGIN_SRC conf-windows
|
||||
background = ${colors.background}
|
||||
foreground = ${colors.foreground}
|
||||
#+END_SRC
|
||||
|
||||
If we wanted, we could also declare a default color for the underlines under the various modules that will be included in the bar, but in our case this variable is unused. So we will simply add this commented line as a memento this is possible, but it won’t have any effect with this current configuration of polybar. Same goes for the border around the bar, it is a useless variable in this configuration since we want the border to be transparent.
|
||||
#+NAME: line-border-color
|
||||
#+BEGIN_SRC conf-windows
|
||||
line-color = #f00
|
||||
; border-color = #00000000
|
||||
#+END_SRC
|
||||
|
||||
Although the variable for the default line color is not used, we still have to set the default width of the underline of our modules. By default, their underline will be three pixels thick.
|
||||
#+NAME: line-size-bar
|
||||
#+BEGIN_SRC conf-windows
|
||||
line-size = 3
|
||||
#+END_SRC
|
||||
|
||||
**** Fonts and locale
|
||||
Now we can chose which font fill be used in order to display text in this bar, as well as the locale we want. The locale will be useful for displaying information such as date and time, which is a module we will have in this top bar. First, the declaration of the locale is done like so:
|
||||
#+NAME: locale-bar
|
||||
#+BEGIN_SRC conf-windows
|
||||
locale = ja_JP.UTF-8
|
||||
#+END_SRC
|
||||
Now, we can declare the fonts we want to use in Polybar. It is possible to declare several of them, the first one is the one which gets the absolute priority, and the next ones with a larger index are fallback fonts. Font declaration accepts the fontconfig format as well as possible offset[fn:1]. Five fonts are used in my polybar config:
|
||||
#+NAME: fonts-polybar
|
||||
| Font | fontconfig | Vertical offset | Why it’s used |
|
||||
|--------------+----------------------------------------------------+-----------------+-----------------------|
|
||||
| Fira Sans | Fira Sans Book:style=Book:pixelsize=10 | 1 | Text display |
|
||||
| IPA Mincho | IPAMincho:style=regular:pixelsize=6 | 0 | Japanese text display |
|
||||
| Unifont | unifont:fontformat=truetype:size=6:antialias=false | 0 | Fallback font |
|
||||
| NotoEmoji | NotoEmoji:style=Book:scale=16 | 0 | Emoji display |
|
||||
| Siji | Siji:pixelsize=8 | 0 | Symbol display |
|
||||
| Default font | fixed:pixelsize=8 | 0 | Fallback font |
|
||||
#+NAME: font-ws-config
|
||||
#+HEADER: :var text="font"
|
||||
#+BEGIN_SRC emacs-lisp :var table=fonts-polybar[,1:2] :cache yes
|
||||
(setq counter 0)
|
||||
(mapconcat (lambda (font)
|
||||
(setq counter (+ 1 counter))
|
||||
(format "%s-%d = %s;%s"
|
||||
text
|
||||
(- counter 1)
|
||||
(nth 0 font)
|
||||
(nth 1 font)))
|
||||
table
|
||||
"\n")
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS[53fd99d75f6b08e96288fd2a62b455d7ef8b1754]: font-ws-config
|
||||
: font-0 = Fira Sans Book:style=Book:pixelsize=10;1
|
||||
: font-1 = IPAMincho:style=regular:pixelsize=6;0
|
||||
: font-2 = unifont:fontformat=truetype:size=6:antialias=false;0
|
||||
: font-3 = NotoEmoji:style=Book:scale=16;0
|
||||
: font-4 = Siji:pixelsize=8;0
|
||||
: font-5 = fixed:pixelsize=8;0
|
||||
|
||||
Here’s the font configuration:
|
||||
#+BEGIN_SRC conf-windows
|
||||
<<font-ws-config(text="font",table=fonts-polybar)>>
|
||||
#+END_SRC
|
||||
Note that only Fira Sans get a small offset due to the size of the font and the height of the bar itself.
|
||||
|
||||
**** Modules
|
||||
Finally, arguably one of the most important parts of our bar configuration: the module selection. Modules can be positioned in three different parts of our bar: to the right, in middle or to the left. On the left, we want our workspace indicator for i3. In the middle, we’ll get the title of the focused window, and to the left we’ll have the date and time.
|
||||
#+NAME: modules-generate
|
||||
#+BEGIN_SRC emacs-lisp :var table=top-modules :results value :cache yes
|
||||
(setq right '()
|
||||
center '()
|
||||
left '())
|
||||
(dolist (module table)
|
||||
(let* ((module-name (nth 0 module))
|
||||
(module-layout (nth 1 module)))
|
||||
(message "%S" module-layout)
|
||||
(add-to-list (cond
|
||||
((string= "left" module-layout) 'left)
|
||||
((string= "center" module-layout) 'center)
|
||||
(t 'right))
|
||||
module-name)))
|
||||
(concat (concat "modules-left = "
|
||||
(mapconcat #'identity left " ")
|
||||
"\n")
|
||||
(concat "modules-center = "
|
||||
(mapconcat #'identity center " ")
|
||||
"\n")
|
||||
(concat "modules-right = "
|
||||
(mapconcat #'identity right " ")
|
||||
"\n"))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS[90b932dc0fd32501e1513f14059b92de09a7b59e]: modules-generate
|
||||
: modules-left = i3
|
||||
: modules-center = xwindow
|
||||
: modules-right = date
|
||||
|
||||
Here is the list of modules used:
|
||||
#+NAME: top-modules
|
||||
| Module name | Position | Brief description |
|
||||
|-------------+----------+----------------------------|
|
||||
| i3 | left | i3 workspace indicator |
|
||||
| xwindow | center | Name of the focused window |
|
||||
| date | right | Date and time |
|
||||
|
||||
#+BEGIN_SRC conf-windows :cache yes
|
||||
<<modules-generate(table=top-modules)>>
|
||||
#+END_SRC
|
||||
|
||||
Each module will be described in details later in this document.
|
||||
|
||||
*** Bottom bar declaration
|
||||
As described above, we will once again have to declare our bar with an equally unimaginative but explicit name.
|
||||
#+BEGIN_SRC conf-windows
|
||||
[bar/bottom]
|
||||
#+END_SRC
|
||||
|
||||
**** Positioning
|
||||
The variables are the same as above, but two of them will be slightly modified:
|
||||
#+BEGIN_SRC conf-windows
|
||||
bottom = true
|
||||
border-size = 0
|
||||
<<position-bar-bottom>>
|
||||
#+END_SRC
|
||||
|
||||
#+NAME: position-bar-bottom
|
||||
#+BEGIN_SRC conf-windows :exports none :tangle no
|
||||
width = 100%
|
||||
height = 22
|
||||
radius = 0.0
|
||||
fixed-center = true
|
||||
#+END_SRC
|
||||
When it comes to the bottom bar, I prefer to have it fit my outputs, without any margin around it. And of course, I have to declare it as being at the bottom of the screen, hence these modifications. As regards the padding of our modules, their own margins, and the screen output, they aren’t modified.
|
||||
#+BEGIN_SRC conf-windows
|
||||
<<padding-bar>>
|
||||
<<module-margin-bar>>
|
||||
<<monitor-bar>>
|
||||
#+END_SRC
|
||||
However, we do display the system tray on this bottom bar at its right. It has no padding and it is not detached from the bar (this allows the bar to be displayed under the icons of the system tray), and their maximum size was chosen so they are well visible without being too big.
|
||||
#+BEGIN_SRC conf-windows
|
||||
tray-position = right
|
||||
tray-padding = 0
|
||||
tray-detached = false
|
||||
tray-maxsize = 15
|
||||
#+END_SRC
|
||||
|
||||
**** Colors and display
|
||||
Nothing changes from the top bar, all the variables stay with the same values. See [[file:./polybar.md#colors-and-display][Colors and display]] of the top bar for more information.
|
||||
#+BEGIN_SRC conf-windows
|
||||
<<bar-colors>>
|
||||
<<line-border-color>>
|
||||
<<line-size-bar>>
|
||||
#+END_SRC
|
||||
|
||||
**** Fonts and locale
|
||||
Again, nothing changes from the top bar, so for more info on what’s going on, see [[file:./polybar.md#fonts-and-locale][Fonts and locale]] of the top bar.
|
||||
#+BEGIN_SRC conf-windows
|
||||
<<locale-bar>>
|
||||
<<font-ws-config(text="font",table=fonts-polybar)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Modules
|
||||
Now, we can get to something interesting again: modules. This bar has a lot more modules than the top bar. Here is the list of the modules we have on the bottom bar:
|
||||
#+NAME: table-modules-bottom
|
||||
| Module name | Position | Brief description |
|
||||
|----------------+----------+---------------------------------|
|
||||
| mpd | left | MPD status indicator |
|
||||
| filesystem | right | Free storage in our filesystem |
|
||||
| wlan | right | Name of the active WiFi network |
|
||||
| eth | right | Local address on Ethernet |
|
||||
| volume | right | System volume |
|
||||
| backlight-acpi | right | Screen backlight |
|
||||
| cpu | right | CPU usage |
|
||||
| memory | right | RAM usage |
|
||||
| temperature | right | CPU temperature |
|
||||
| custom-battery | right | Battery usage |
|
||||
Here’s the corresponding configuration:
|
||||
#+ATTR_LATEX: :options breaklines
|
||||
#+BEGIN_SRC conf-windows
|
||||
<<modules-generate(table=table-modules-bottom)>>
|
||||
#+END_SRC
|
||||
All these modules will be explained below.
|
||||
|
||||
As you may have noticed, no modules will be displayed in the middle of this bar.
|
||||
|
||||
** Modules
|
||||
Before we begin to describe the different modules, I would like to point out something that will be repeated multiple times if I don’t talk about it right now: for each module, it is possible to declare the foreground and background color of the prefix of the modules, as well as the underline color and the padding of the module. I like these parameters to be rather consistent, so the code block you will see below will often be reused. The colors refer to the colors declared earlier, and the padding is minimal.
|
||||
#+NAME: mod-prefix-col
|
||||
#+BEGIN_SRC conf-windows :tangle no
|
||||
format-prefix-foreground = ${colors.foreground-alt}
|
||||
format-prefix-underline = ${colors.secondary}
|
||||
format-underline = ${colors.secondary}
|
||||
format-padding = 1
|
||||
#+END_SRC
|
||||
|
||||
*** Hardware
|
||||
**** Battery
|
||||
This module allows the user to get a battery widget among the polybar modules that will also send a notification to the user if the battery level drops below a certain value. This module relies on ~polybar-another-battery~ ([[https://github.com/drdeimos/polybar_another_battery][link]]) and its generated binary ~polybar-ab~ which should be in the ~$PATH~.
|
||||
|
||||
The first line of the module declaration lets the user name the module however they want. In this case, the name is ~custom-battery~.
|
||||
#+BEGIN_SRC conf-windows
|
||||
[module/custom-battery]
|
||||
#+END_SRC
|
||||
Since it is not a core module, we have to declare it as a custom script so polybar knows what to do with it.
|
||||
#+BEGIN_SRC conf-windows
|
||||
type = custom/script
|
||||
#+END_SRC
|
||||
We now can specify the script execution, and whether or not the script will be continuously outputting something. In our case, the answer to this last question is yes.
|
||||
#+BEGIN_SRC conf-windows
|
||||
exec = polybar-ab -polybar -thr 10
|
||||
tail = true
|
||||
#+END_SRC
|
||||
The ~-thr 10~ specifies the threshold for polybar-ab at which it should warn the user about the battery level of the computer.
|
||||
|
||||
Of course, users on desktop computers won’t need this module which is aimed at laptop users. Feel free to remove it if you do not need it.
|
||||
|
||||
**** Filesystem
|
||||
This module allows to display information about our filesystem, including (and this is what I use this module for) displaying the used space and remaining space on different mount points. This module is an internal module to polybar, so let’s declare it as such:
|
||||
#+BEGIN_SRC conf-windows
|
||||
[module/filesystem]
|
||||
type = internal/fs
|
||||
#+END_SRC
|
||||
We can specify how often the filesystem is to be checked with the variable ~interval~. I prefer it not to check it too often in order to not ping too often my drives, but I want it to be often enough so it is somewhat responsive. This is why I settled on a 20 seconds interval.
|
||||
#+BEGIN_SRC conf-windows
|
||||
interval = 20
|
||||
#+END_SRC
|
||||
We now have to indicate where our different filesystems are mounted. In the case of my main computer /Marpa/, I have two partitions, the root partition and the home partition. But on my travel laptop, I only have the root partition, hence the usage of the below Elisp code that determines based on the computer it is running whether or not the second mount point to my home partition should be included.
|
||||
#+NAME: include-home-partition
|
||||
#+BEGIN_SRC emacs-lisp :tangle no :exports code
|
||||
(if (string= system-name "Marpa")
|
||||
"mount-1 = /home")
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC conf-windows
|
||||
mount-0 = /
|
||||
<<include-home-partition()>>
|
||||
#+END_SRC
|
||||
Now we can set the format of our module. There are two mains formats, one for mounted and one for unmounted mountpoints. For both, we’ll simply use their label.
|
||||
#+BEGIN_SRC conf-windows
|
||||
format-mounted = <label-mounted>
|
||||
format-unmounted = <label-unmounted>
|
||||
#+END_SRC
|
||||
When it comes to the mounted partition, we want to display the name of the mountpoint and how used it is, both in terms of gigabytes and percentage.
|
||||
#+BEGIN_SRC conf-windows
|
||||
label-mounted = 💽 %mountpoint%: %used%/%total% (%percentage_used%%)
|
||||
label-mounted-foreground = ${colors.foreground}
|
||||
label-mounted-underline = ${colors.secondary}
|
||||
#+END_SRC
|
||||
If the volume is unmounted (which should be worrying considering the mountpoints chosen), then we’ll simply have a message telling us about that, and the foreground color will use the alternative foreground color described earlier.
|
||||
#+BEGIN_SRC conf-windows
|
||||
label-unmounted = %mountpoint% not mounted
|
||||
label-unmounted-foreground = ${colors.foreground-alt}
|
||||
#+END_SRC
|
||||
|
||||
**** Xbacklight
|
||||
This module is used in order to display the level of brightness of a screen. It is not used by itself, but rather by other modules, such as [[file:./polybar.md#acpi-backlight][ACPI backlight]]. First of all, this module is an internal module for xbacklight. It will also display the brightness percentage, prefixed by a sun emoji. Lastly, it will be underlined by a green line.
|
||||
#+BEGIN_SRC conf-windows
|
||||
[module/xbacklight]
|
||||
type = internal/xbacklight
|
||||
format = <label>
|
||||
label = %percentage%%
|
||||
format-prefix = "🌞 "
|
||||
format-underline = #9f78e1
|
||||
#+END_SRC
|
||||
|
||||
**** ACPI backlight
|
||||
This module indicates the backlight level of a screen thanks to the ACPI Linux module. There isn’t much to tell about the module itself other than it inherits the module described above, [[file:./polybar.md#xbacklight][Xbacklight]]. It also sets which driver should be used, in this case the ~intel_backlight~ driver.
|
||||
#+BEGIN_SRC conf-windows
|
||||
[module/backlight-acpi]
|
||||
inherit = module/xbacklight
|
||||
type = internal/backlight
|
||||
card = intel_backlight
|
||||
#+END_SRC
|
||||
|
||||
**** CPU
|
||||
This module indicates how much of the CPU is being used. As shown below, I made it so we can see the load on each core. The first thing to do is to declare the module as an internal module dedicated to the CPU.
|
||||
#+BEGIN_SRC conf-windows
|
||||
[module/cpu]
|
||||
type = internal/cpu
|
||||
#+END_SRC
|
||||
|
||||
Now, we can set the refresh rate in seconds of the module. I like it at two seconds:
|
||||
#+BEGIN_SRC conf-windows
|
||||
interval = 2
|
||||
#+END_SRC
|
||||
|
||||
Now, let’s declare what will be displayed. The format will be a computer emoji followed by ramp characters.
|
||||
#+BEGIN_SRC conf-windows
|
||||
format = <label> <ramp-coreload>
|
||||
format-prefix = "💻 "
|
||||
label = %percentage%%
|
||||
ramp-coreload-0 = ▁
|
||||
ramp-coreload-1 = ▂
|
||||
ramp-coreload-2 = ▃
|
||||
ramp-coreload-3 = ▄
|
||||
ramp-coreload-4 = ▅
|
||||
ramp-coreload-5 = ▆
|
||||
ramp-coreload-6 = ▇
|
||||
ramp-coreload-7 = █
|
||||
#+END_SRC
|
||||
|
||||
Finally, this module will be underlined in red.
|
||||
#+BEGIN_SRC conf-windows
|
||||
format-underline = #f90000
|
||||
#+END_SRC
|
||||
|
||||
**** Memory
|
||||
Similarly to the CPU module, it is possible for Polybar to display the RAM load of the computer. As above, let’s declare this module as an internal module to Polybar:
|
||||
#+BEGIN_SRC conf-windows
|
||||
[module/memory]
|
||||
type = internal/memory
|
||||
#+END_SRC
|
||||
|
||||
As the CPU module still, the refresh rate will be of two seconds.
|
||||
#+BEGIN_SRC conf-windows
|
||||
interval = 2
|
||||
#+END_SRC
|
||||
|
||||
Its format will be the percentage of used RAM, prefixed by a disk emoji.
|
||||
#+BEGIN_SRC conf-windows
|
||||
format = <label>
|
||||
format-prefix = "💿 "
|
||||
label = %gb_used%
|
||||
#+END_SRC
|
||||
|
||||
Lastly, it will be underlined in green.
|
||||
#+BEGIN_SRC conf-windows
|
||||
format-underline = #4bffdc
|
||||
#+END_SRC
|
||||
|
||||
**** Wlan
|
||||
It is possible for Polybar to display the name of the current WiFi network the computer is connected to. For that, we first need to declare the Wlan module as an internal module of Polybar.
|
||||
#+BEGIN_SRC conf-windows
|
||||
[module/wlan]
|
||||
type = internal/network
|
||||
#+END_SRC
|
||||
|
||||
Now, we should set the name of the interface. As this depends on the hardware I am using, I am going to rely on the machine’s hostname and on some Elisp code to get this setting right.
|
||||
#+NAME: name-wlan-interface
|
||||
#+BEGIN_SRC emacs-lisp :exports code :tangle no
|
||||
(cond ((string= system-name "Marpa") "wlp8s0")
|
||||
((string= system-name "gampo") "wlp3s0"))
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC conf-windows
|
||||
interface = <<name-wlan-interface()>>
|
||||
#+END_SRC
|
||||
|
||||
The name of the current WiFi network will be refreshed every three seconds.
|
||||
#+BEGIN_SRC conf-windows
|
||||
interval = 3.0
|
||||
#+END_SRC
|
||||
|
||||
The format of the module when connected to a network will the the display of the antenna emoji, followed by the name of the network. When disconnected, the module will simply be empty.
|
||||
#+BEGIN_SRC conf-windows
|
||||
format-connected = <label-connected>
|
||||
format-connected-prefix = "📶 "
|
||||
label-connected = %essid%
|
||||
#+END_SRC
|
||||
|
||||
**** Ethernet
|
||||
Just like any other module, the ethernet module has to be declared as an internal module.
|
||||
#+BEGIN_SRC conf-windows
|
||||
[module/eth]
|
||||
type = internal/network
|
||||
#+END_SRC
|
||||
|
||||
And just like the Wlan module, it requires an interface which can vary depending on the machine I am using, hence this piece of Elisp:
|
||||
#+NAME: name-eth-interface
|
||||
#+BEGIN_SRC emacs-lisp :exports code :tangle no
|
||||
(cond ((string= system-name "Marpa") "enp9s0")
|
||||
((string= system-name "gampo") "enp0s25"))
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC conf-windows
|
||||
interface = <<name-eth-interface()>>
|
||||
#+END_SRC
|
||||
|
||||
The format of this module will be the local address of the computer on the network, and it will be prefixed by a desktop computer emoji. Meanwhile, when disconnected, the module won’t be visible.
|
||||
#+BEGIN_SRC conf-windows
|
||||
format-connected = <<label-connected>>
|
||||
format-connected-prefix = "🖥 "
|
||||
label-connected = %local_ip%
|
||||
format-disconnected =
|
||||
#+END_SRC
|
||||
|
||||
The module will be underlined in green.
|
||||
#+BEGIN_SRC conf-windows
|
||||
format-connected-underline = #55aa55
|
||||
#+END_SRC
|
||||
|
||||
**** Volume
|
||||
The volume module in Polybar is linked to its internal bindings to ALSA. Let’s declare it accordingly.
|
||||
#+BEGIN_SRC conf-windows
|
||||
[module/volume]
|
||||
type = internal/alsa
|
||||
#+END_SRC
|
||||
|
||||
Its format is quite simple: if the audio is not muted, it is then prefixed with a speaker emoji, followed by the volume percentage.
|
||||
#+BEGIN_SRC conf-windows
|
||||
format-volume = <label-volume>
|
||||
format-volume-prefix = "🔈 "
|
||||
label-volume = %percentage%%
|
||||
#+END_SRC
|
||||
|
||||
If the audio is muted, then the only thing the user will see is the muted speaker emoji followed by the text “muted”.
|
||||
#+BEGIN_SRC conf-windows
|
||||
format-muted-prefix = "🔇 "
|
||||
label-muted = muted
|
||||
#+END_SRC
|
||||
|
||||
In any case, it will be underlined in green.
|
||||
#+BEGIN_SRC conf-windows
|
||||
format-volume-underline = #55aa55
|
||||
#+END_SRC
|
||||
|
||||
**** Temperature
|
||||
The temperature module checks the temperature of the CPU, and warns the user above a certain threshold of heat, in my case if my CPU is above 60°C.
|
||||
#+BEGIN_SRC conf-windows
|
||||
[module/temperature]
|
||||
type = internal/temperature
|
||||
thermal-zone = 0
|
||||
warn-temperature = 60
|
||||
#+END_SRC
|
||||
|
||||
The format of the module is the thermometer emoji followed by the temperature of the CPU. If the CPU becomes too hot, the text will change color for the secondary foreground color.
|
||||
#+BEGIN_SRC conf-windows
|
||||
format = <label>
|
||||
format-underline = #f50a4d
|
||||
format-warn = <label-warn>
|
||||
format-warn-underline = ${self.format-underline}
|
||||
format-prefix = "🌡 "
|
||||
format-warn-prefix = "🌡 "
|
||||
|
||||
label = %temperature-c%
|
||||
label-warn = %temperature-c%
|
||||
label-warn-foreground = ${colors.secondary}
|
||||
#+END_SRC
|
||||
|
||||
*** Software
|
||||
**** Window title
|
||||
This module’s aim is to simply provide the name of the currently focused window given by Xorg. This module is an internal module to polybar, that is to say it is built-in, and is of the type ~xwindow~. So, let’s declare the module accordingly, including the piece of common code declared at the beginning of the chapter:
|
||||
#+BEGIN_SRC conf-windows
|
||||
[module/xwindow]
|
||||
type = internal/xwindow
|
||||
<<mod-prefix-col>>
|
||||
#+END_SRC
|
||||
|
||||
Now we can take care of the label, which is the actual text that will be displayed. In our case, we want the label to be the title of the current X window, hence the value of ~label~, and we don’t want it to be too long, though I’m not sure I’ve often seen window titles longer than 70 characters.
|
||||
#+BEGIN_SRC conf-windows
|
||||
label = %title%
|
||||
label-maxlen = 70
|
||||
#+END_SRC
|
||||
|
||||
**** i3
|
||||
Now comes the module for i3 interaction. Thanks to this module, it is possible to show which workspaces are active and focused, and it is possible to change workspaces by clicking on the ones displayed in the bar. First, let’s declare it; it is an internal module by the way.
|
||||
#+BEGIN_SRC conf-windows
|
||||
[module/i3]
|
||||
type = internal/i3
|
||||
#+END_SRC
|
||||
|
||||
Now, let’s display only the workspaces that are on the current output. This means if a workspace is either inactive or on another screen or output, it won’t be displayed.
|
||||
#+BEGIN_SRC conf-windows
|
||||
pin-workspaces = true
|
||||
#+END_SRC
|
||||
|
||||
We also want our workspaces to be sorted by number rather than by output.
|
||||
#+BEGIN_SRC conf-windows
|
||||
index-sort = true
|
||||
#+END_SRC
|
||||
|
||||
I don’t want to be able to scroll through the workspaces when my mouse is hovering the module: when it happens, most of the time it was done accidentally. So let’s deactivate that. However, I sometimes like to click on them to switch from one another, so we’ll keep that activated.
|
||||
#+BEGIN_SRC conf-windows
|
||||
enable-scroll = false
|
||||
wrapping-scroll = false
|
||||
reverse-scroll = false
|
||||
enable-click = true
|
||||
#+END_SRC
|
||||
|
||||
This parameters splits the workspaces’ name on ~:~. Let’s deactivate that.
|
||||
#+BEGIN_SRC conf-windows
|
||||
strip-wsnumbers = false
|
||||
#+END_SRC
|
||||
|
||||
An on the topic of workspaces’ name, ~fuzzy-match~ allows the user to use fuzzy search for workspaces’ name when we will be applying custom names below. Not really useful since I only use the default workspaces’ name, but it’s good to have it enabled by default.
|
||||
#+BEGIN_SRC conf-windows
|
||||
fuzzy-match = true
|
||||
#+END_SRC
|
||||
|
||||
The label format is described first by its label, but also by one of its three possible modes: focused, visible or unfocused. These will be discussed later, but for now let’s simply set our format.
|
||||
#+begin_src conf-windows
|
||||
format = <label-state> <label-mode>
|
||||
#+end_src
|
||||
|
||||
We also wand to set the label mode to be whichever mode the workspace described by polybar is in. This label will also have a padding of 2 pixels, and the text will be written in white.
|
||||
#+begin_src conf-windows
|
||||
label-mode = %mode%
|
||||
label-mode-padding = 2
|
||||
label-mode-foreground = #000
|
||||
#+end_src
|
||||
|
||||
***** Workspace icons
|
||||
Now, let’s name our workspaces. We can give them whatever name we want them to have, but I just like the aesthetics of Japanese characters, so let’s go with the kanji equivalent of the number of the workspaces.
|
||||
#+NAME: ws-names
|
||||
| workspace number | name |
|
||||
|------------------+------|
|
||||
| 1 | 一 |
|
||||
| 2 | 二 |
|
||||
| 3 | 三 |
|
||||
| 4 | 四 |
|
||||
| 5 | 五 |
|
||||
| 6 | 六 |
|
||||
| 7 | 七 |
|
||||
| 8 | 八 |
|
||||
| 9 | 九 |
|
||||
| 0 | 十 |
|
||||
|
||||
Here are the corresponding configuration lines:
|
||||
#+BEGIN_SRC conf-windows
|
||||
<<font-ws-config(text="ws",table=ws-names)>>
|
||||
#+END_SRC
|
||||
|
||||
In case we create a workspace which isn’t named from ~0~ to ~9~, I want it to appear as is.
|
||||
#+begin_src conf-windows
|
||||
ws-icon-default = %index%
|
||||
#+end_src
|
||||
|
||||
***** Focused workspaces
|
||||
Now we can define the label itself. First, we will need to define the label when the workspace is focused. We’ll simply take the alternative background for the focused label, and the underline will be defined from Xrdb’s 8th color, with yellow as the fallback color. It will also have a two pixels padding. The text itself will be the dynamic icons declared above.
|
||||
#+begin_src conf-windows
|
||||
label-focused = %icon%
|
||||
label-focused-background = ${colors.background-alt}
|
||||
label-focused-underline = ${xrdb:color8:#ffff00}
|
||||
label-focused-padding = 2
|
||||
#+end_src
|
||||
|
||||
***** Visible workspaces
|
||||
The ~visible~ label is related to the ~focused~ labels since it is describing workspaces that can be seen, but are not currently focused, i.e. a workspace that appears on another screen than the one currently used so it is visible, but it isn’t focused. The difference with the ~unfocused~ workspaces is that the latter are neither focused nor visible. As you can see, we are simply using all of the declarations from above for the focused labels so we can ensure they appear the same way the focused labels do.
|
||||
#+begin_src conf-windows
|
||||
label-visible = ${self.label-focused}
|
||||
label-visible-background = ${self.label-focused-background}
|
||||
label-visible-underline = ${self.label-focused-underline}
|
||||
label-visible-padding = ${self.label-focused-padding}
|
||||
#+end_src
|
||||
|
||||
***** Unfocused workspaces
|
||||
When it comes to the unfocused label, there won’t be any custom background or underline, so we’ll just copy the two remaining lines from the focused labels for unfocused labels.
|
||||
#+begin_src conf-windows
|
||||
label-unfocused = %icon%
|
||||
label-unfocused-padding = 2
|
||||
#+end_src
|
||||
|
||||
***** Urgent workspaces
|
||||
Lastly, we get our urgent workspaces: workspaces in which most of the time it’s just a popup that appeared or a software that finally launched itself while working on something else on another workspace. To make it a bit more unique, let’s declare its background as being the color 0 from xrdb, with some dark red as the fallback color. And as the other labels, the text will be the icon and it will have a two pixels padding.
|
||||
#+begin_src conf-windows
|
||||
label-urgent = %icon%
|
||||
label-urgent-background = ${xrdb:color0:#bd2c40}
|
||||
label-urgent-padding = 2
|
||||
#+end_src
|
||||
|
||||
**** Mpd
|
||||
Mpd is a music server for GNU/Linux systems that interfaces will several front-ends, including ncmpcpp (the main one I use), ncmpcpp and mpc. It also interfaces with polybar thanks to some built in commands.
|
||||
|
||||
First, let’s declare our module as an internal module.
|
||||
#+BEGIN_SRC conf-windows
|
||||
[module/mpd]
|
||||
type = internal/mpd
|
||||
#+END_SRC
|
||||
|
||||
The next thing we want to do is set the label for the module: we will display both the title and the name of the artist of the song playing. The maximum length will be 70 characters.
|
||||
#+BEGIN_SRC conf-windows
|
||||
label-song = %title% - %artist%
|
||||
label-song-maxlen = 70
|
||||
label-song-ellipsis = true
|
||||
#+END_SRC
|
||||
|
||||
While Mpd is online, the format of the module should be the control icons and then the song label.
|
||||
#+BEGIN_SRC conf-windows
|
||||
format-online = <icon-prev> <toggle> <icon-next> <label-song>
|
||||
icon-prev = ⏭
|
||||
icon-stop = ⏹
|
||||
icon-play = ▶
|
||||
icon-pause = ⏸
|
||||
icon-next = ⏭
|
||||
#+END_SRC
|
||||
|
||||
If Mpd is offline, then I would like to display a short messages that tells the user so.
|
||||
#+BEGIN_SRC conf-windows
|
||||
format-offline = <label-offline>
|
||||
label-offline = 🎵 mpd is offline
|
||||
#+END_SRC
|
||||
|
||||
**** Date
|
||||
This module is really simple: it gives the current date. It is an internal module, and as declared below, it updates every second:
|
||||
#+BEGIN_SRC conf-windows
|
||||
[module/date]
|
||||
type = internal/date
|
||||
interval = 1
|
||||
#+END_SRC
|
||||
|
||||
The main date and time format is the standard one, following the ISO-8601 standard.
|
||||
#+BEGIN_SRC conf-windows
|
||||
date = %Y-%m-%d
|
||||
time = %H-%M-%S
|
||||
#+END_SRC
|
||||
|
||||
It also has an alternative format which I occasionally use, which displays the date and time in the Japanese format.
|
||||
#+BEGIN_SRC conf-windows
|
||||
date-alt = %A %d, %B
|
||||
time-alt = %H:%M:%S
|
||||
#+END_SRC
|
||||
|
||||
The format is quite simple: a clock emoji preceding the date and time.
|
||||
#+BEGIN_SRC conf-windows
|
||||
format-prefix = "🕑 "
|
||||
label = %date% %time%
|
||||
#+END_SRC
|
||||
|
||||
This module is underlined in blue:
|
||||
#+BEGIN_SRC conf-windows
|
||||
format-underline = #0a6cf5
|
||||
#+END_SRC
|
||||
|
||||
** Footnotes
|
||||
|
||||
[fn:1] [[https://github.com/polybar/polybar/wiki/Fonts][https://github.com/polybar/polybar/wiki/Fonts]]
|
||||
|
||||
# LocalWords: Siji pixelsize Fira Mincho IPAMincho Unifont unifont fontformat
|
||||
# LocalWords: truetype antialias xwindow wlan eth acpi cpu
|
||||
4778
docs/deprecated/spacemacs.org
Normal file
717
docs/desktop.org
Normal file
@@ -0,0 +1,717 @@
|
||||
#+title: Desktop
|
||||
#+setupfile: headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/desktop.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
#+property: header-args:lisp :mkdirp :tangle ~/.stumpwm.d/desktop.lisp :noweb yes
|
||||
|
||||
* Desktop
|
||||
Many settings formerly present in this website’s index are related to
|
||||
my desktop settings, while some others are not.
|
||||
|
||||
# Also, since I switched to StumpWM, many of my keybinds from Emacs need
|
||||
# to be kept up to date with my StumpWM keybinds, and /vice versa/. This
|
||||
# document aims to regroup all settings related to the desktop in order
|
||||
# to have an easier time managing them.
|
||||
|
||||
** Common Emacs and StumpWM settings :noexport:
|
||||
Both Emacs and StumpWM work on the same principle of keychords
|
||||
powering a function or command. With both of them I have a prefix key,
|
||||
~SPC~ in the case of Emacs (or ~C-SPC~ when in insert-mode, see the
|
||||
relevant config) and ~s-SPC~ in the case of StumpWM. That means I can
|
||||
give them the same keychord following this, for instance ~w/~ to create
|
||||
a new vertically split frame to the right of the current one.
|
||||
|
||||
All the keybinds will be presented in the form of tables, with on the
|
||||
first column the keychord following the leader key, on the second
|
||||
column the EmacsLisp function to be called, and on the third the
|
||||
StumpWM command. If one of the ELisp or StumpWM case’s is empty, it
|
||||
means there is no equivalence. If it’s ~nil~, then it means it is a
|
||||
prefix key. The fourth column is for now reserved for Emacs’
|
||||
which-key, so I can give it a better name. If its value is ~nil~, then
|
||||
it should not show up. Hopefully this can be implemented someday in
|
||||
StumpWM.
|
||||
|
||||
*** Generating Code :noexport:
|
||||
**** Elisp
|
||||
#+name: emacs-keybinds-gen
|
||||
#+header: :var keymap=emacs-stumpwm-media-control
|
||||
#+begin_src emacs-lisp :exports none :tangle no :wrap "src emacs-lisp :tangle no"
|
||||
(mapconcat (lambda (keybind)
|
||||
(let* ((keychord (replace-regexp-in-string (rx (or (seq line-start "~")
|
||||
(seq "~" line-end)))
|
||||
""
|
||||
(car keybind)))
|
||||
(function (replace-regexp-in-string (rx (or (seq line-start "~")
|
||||
(seq "~" line-end)))
|
||||
""
|
||||
(nth 1 keybind)))
|
||||
(which (nth 3 keybind)))
|
||||
(format "\"%s\" %s"
|
||||
keychord
|
||||
(if (string= "nil" function)
|
||||
(format "%S"
|
||||
`(:ignore :which-key ,which))
|
||||
(if (string= "" which)
|
||||
(concat "#'" function)
|
||||
(format "%S"
|
||||
`'(,(intern function) :which-key ,which)))))))
|
||||
(seq-filter (lambda (elem)
|
||||
(not (string= "" (nth 1 elem))))
|
||||
keymap)
|
||||
"\n")
|
||||
#+end_src
|
||||
|
||||
#+RESULTS: emacs-keybinds-gen
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
"m" (:ignore :which-key "media")
|
||||
"m«" #'emms-player-mpd-previous
|
||||
"m»" #'emms-player-mpd-next
|
||||
"ma" '(hydra-media/body :which-key "MPD add")
|
||||
"mb" (:ignore :which-key "browse")
|
||||
"mba" #'emms-browse-by-artist
|
||||
"mbA" #'emms-browse-by-album
|
||||
"mbg" #'emms-browse-by-genre
|
||||
"mbp" #'emms-playlists-mode-go
|
||||
"mbs" #'emms-smart-browse
|
||||
"mby" #'emms-browse-by-year
|
||||
"mc" #'emms-player-mpd-clear
|
||||
"mp" #'emms-player-toggle-pause
|
||||
"ms" #'emms-player-mpd-show
|
||||
"mu" (:ignore :which-key "update")
|
||||
"mum" #'emms-player-mpd-update-all
|
||||
"muc" #'emms-cache-set-from-mpd-all
|
||||
#+end_src
|
||||
|
||||
#+name: emacs-hydra-keybinds-gen
|
||||
#+header: :var keymap=emacs-stumpwm-resize-frame
|
||||
#+begin_src emacs-lisp :exports none :tangle no :wrap "src emacs-lisp :tangle no"
|
||||
(mapconcat (lambda (keybind)
|
||||
(let ((keychord (replace-regexp-in-string "^~\\|~$"
|
||||
""
|
||||
(car keybind)))
|
||||
(function (replace-regexp-in-string "^~\\|~$"
|
||||
""
|
||||
(nth 1 keybind)))
|
||||
(which (nth 3 keybind)))
|
||||
(format "%S" (if (string= "" which)
|
||||
`(,keychord ,(intern function))
|
||||
`(,keychord ,(intern function) ,which)))))
|
||||
keymap
|
||||
"\n")
|
||||
#+end_src
|
||||
|
||||
#+RESULTS: emacs-hydra-keybinds-gen
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
("c" shrink-window-horizontally)
|
||||
("t" enlarge-window)
|
||||
("s" shrink-window)
|
||||
("r" enlarge-window-horizontally)
|
||||
#+end_src
|
||||
|
||||
**** Lisp
|
||||
#+name: stumpwm-filter-keybinds
|
||||
#+begin_src emacs-lisp :exports none :tangle no
|
||||
(let ((no-tilde (lambda (string)
|
||||
(replace-regexp-in-string "^~\\|~$" "" string))))
|
||||
(seq-filter (lambda (elem)
|
||||
(= 1 (length (car elem))))
|
||||
(mapcar (lambda (elem)
|
||||
`(,(replace-regexp-in-string (format "^%s" prefix) "" (car elem))
|
||||
.
|
||||
,(cdr elem)))
|
||||
(seq-filter (lambda (elem)
|
||||
(and (not (string= "" (cdr elem)))
|
||||
(not (string= prefix (car elem)))
|
||||
(string-prefix-p prefix (car elem))))
|
||||
(mapcar (lambda (elem)
|
||||
(let ((keychord (apply no-tilde (list (car elem))))
|
||||
(function (apply no-tilde (list (nth 2 elem)))))
|
||||
`(,keychord . ,function)))
|
||||
keymap)))))
|
||||
#+end_src
|
||||
|
||||
#+name: stumpwm-keybinds-gen
|
||||
#+header: :var keymap=emacs-stumpwm-media-control keymap-name="my-mpd-add-map" prefix="m"
|
||||
#+begin_src emacs-lisp :exports none :tangle no :wrap "src lisp :tangle no" :noweb yes
|
||||
(require 'seq)
|
||||
(format "(defvar *%s*
|
||||
(let %S
|
||||
%s
|
||||
m))"
|
||||
keymap-name
|
||||
`((m (make-sparse-keymap)))
|
||||
(mapconcat (lambda (keybind)
|
||||
(let ((keychord (replace-regexp-in-string (format "^%s" prefix)
|
||||
""
|
||||
(car keybind)))
|
||||
(function (cdr keybind)))
|
||||
(format "%S" `(define-key m (kbd ,keychord) ,function))))
|
||||
<<stumpwm-filter-keybinds>>
|
||||
"\n "))
|
||||
#+end_src
|
||||
|
||||
#+RESULTS: stumpwm-keybinds-gen
|
||||
#+begin_src lisp :tangle no
|
||||
(defvar *my-mpd-add-map*
|
||||
(let ((m (make-sparse-keymap)))
|
||||
(define-key m (kbd ".") "media-interactive")
|
||||
(define-key m (kbd "«") "mpd-prev")
|
||||
(define-key m (kbd "»") "mpd-next")
|
||||
(define-key m (kbd "a") "'*my-mpd-add-keymap*")
|
||||
(define-key m (kbd "b") "'*my-mpd-browse-keymap*")
|
||||
(define-key m (kbd "c") "mpd-clear")
|
||||
(define-key m (kbd "p") "mpd-toggle-pause")
|
||||
m))
|
||||
#+end_src
|
||||
|
||||
#+name: stumpwm-interactive-keybinds-gen
|
||||
#+header: :var keymap=emacs-stumpwm-resize-frame prefix=""
|
||||
#+header: :wrap "src lisp :exports none"
|
||||
#+begin_src emacs-lisp :noweb yes
|
||||
(format "(%s)"
|
||||
(mapconcat (lambda (keybind)
|
||||
(let ((keychord (car keybind))
|
||||
(function (cdr keybind)))
|
||||
(format "%S" `((kbd ,keychord) ,function))))
|
||||
<<stumpwm-filter-keybinds>>
|
||||
"\n "))
|
||||
#+end_src
|
||||
|
||||
#+RESULTS: stumpwm-interactive-keybinds-gen
|
||||
#+begin_src lisp :exports none
|
||||
(((kbd "c") "resize-direction left")
|
||||
((kbd "t") "resize-direction down")
|
||||
((kbd "s") "resize-direction up")
|
||||
((kbd "r") "resize-direction right"))
|
||||
#+end_src
|
||||
|
||||
#+name: stumpwm-interactive-gen
|
||||
#+header: :var keymap=emacs-stumpwm-resize-frame keymap-name="my-mpd-add-map" prefix=""
|
||||
#+begin_src emacs-lisp :exports none :tangle no :wrap "src lisp :tangle no"
|
||||
(format "%S"
|
||||
`(define-interactive-keymap ,(intern keymap-name)
|
||||
(:exit-on '((kbd "RET")
|
||||
(kbd "ESC")
|
||||
(kbd "C-g")
|
||||
(kbd "q")))
|
||||
,@
|
||||
<<stumpwm-interactive-keybinds-gen>>
|
||||
))
|
||||
#+end_src
|
||||
|
||||
#+RESULTS: stumpwm-interactive-gen
|
||||
#+begin_src lisp :tangle no
|
||||
(define-interactive-keymap my-mpd-add-map (:exit-on '((kbd "RET") (kbd "ESC") (kbd "C-g") (kbd "q"))) ((kbd "c") "resize-direction left" (kbd "t") "resize-direction down" (kbd "s") "resize-direction up" (kbd "r") "resize-direction right"))
|
||||
#+end_src
|
||||
|
||||
*** Frames Management
|
||||
In StumpWM, I’ll consider my various windows the same as Emacs’
|
||||
buffers.
|
||||
#+name: emacs-stumpwm-frames-management
|
||||
| Keychord | Emacs | StumpWM | which-key |
|
||||
|----------+---------------------------+-------------------------+-----------|
|
||||
| ~b~ | ~nil~ | ~'*my-buffers-keymap*~ | buffers |
|
||||
| ~bb~ | ~buflers-switch-buffer~ | ~windowlist~ | |
|
||||
| ~bB~ | ~bury-buffer~ | | |
|
||||
| ~bd~ | ~kill-this-buffer~ | ~delete-window~ | |
|
||||
| ~bD~ | ~kill-buffer~ | ~window-window-and-frame~ | |
|
||||
| ~bh~ | ~dashboard-refresh-buffer~ | | |
|
||||
| ~bk~ | | ~kill-window~ | |
|
||||
| ~bl~ | ~bufler~ | | |
|
||||
| ~bm~ | ~switch-to-messages-buffer~ | | |
|
||||
| ~bn~ | ~evil-next-buffer~ | ~next~ | |
|
||||
| ~bp~ | ~evil-prev-buffer~ | ~prev~ | |
|
||||
| ~br~ | ~counsel-buffer-or-recentf~ | | |
|
||||
| ~bs~ | ~switch-to-scratch-buffer~ | | |
|
||||
|
||||
EmacsLisp code:
|
||||
#+begin_src emacs-lisp
|
||||
(phundrak/leader-key
|
||||
<<emacs-keybinds-gen(keymap=emacs-stumpwm-frames-management)>>
|
||||
)
|
||||
#+end_src
|
||||
|
||||
StumpWM’s Lisp code:
|
||||
#+begin_src lisp
|
||||
<<stumpwm-keybinds-gen(keymap=emacs-stumpwm-frames-management, keymap-name="my-buffers-keymap", prefix="b")>>
|
||||
(define-key *root-map (kbd "b") '*my-buffers-keymap*)
|
||||
#+end_src
|
||||
|
||||
*** Window Management
|
||||
The following allows to have an interactive keymap for resizing the
|
||||
current frame. In Emacs, it will be translated as a hydra while in
|
||||
StumpWM it will be an interactive keymap.
|
||||
#+name: emacs-stumpwm-resize-frame
|
||||
| Keychord | Emacs | StumpWM | which-key |
|
||||
|----------+-----------------------------+------------------------+-----------|
|
||||
| ~c~ | ~shrink-window-horizontally~ | ~resize-direction left~ | |
|
||||
| ~t~ | ~enlarge-window~ | ~resize-direction down~ | |
|
||||
| ~s~ | ~shrink-window~ | ~resize-direction up~ | |
|
||||
| ~r~ | ~enlarge-window-horizontally~ | ~resize-direction right~ | |
|
||||
|
||||
This translates into the following hydra in EmacsLisp:
|
||||
#+begin_src emacs-lisp
|
||||
(defhydra windows-adjust-size ()
|
||||
"
|
||||
^Zoom^ ^Other
|
||||
^^^^^^^-----------------------------------------
|
||||
[_t_/_s_] shrink/enlarge vertically [_q_] quit
|
||||
[_c_/_r_] shrink/enlarge horizontally
|
||||
"
|
||||
<<emacs-hydra-keybinds-gen(keymap=emacs-stumpwm-resize-frame)>>
|
||||
("q" nil :exit t))
|
||||
#+end_src
|
||||
|
||||
While the following Lisp code is used with StumpWM.
|
||||
#+begin_src lisp
|
||||
(define-interactive-keymap (iresize tile-group) (:on-enter #'setup-iresize
|
||||
:on-exit #'resize-unhide
|
||||
:abort-if #'abort-resize-p
|
||||
:exit-on '((kbd "RET")
|
||||
(kbd "ESC")
|
||||
(kbd "C-g")
|
||||
(kbd "q")))
|
||||
<<stumpwm-interactive-keybinds-gen(keymap=emacs-stumpwm-resize-frame)>>
|
||||
)
|
||||
#+end_src
|
||||
|
||||
Below you will find my window management keybinds.
|
||||
#+name: emacs-stump-window-management
|
||||
| Keychord | Emacs | StumpWM | which-key |
|
||||
|----------+-------------------------------+--------------------------+------------------|
|
||||
| ~w~ | ~nil~ | ~'*my-windows-keymap*~ | windows |
|
||||
| ~w.~ | ~windows-adjust-size/body~ | ~iresize~ | resize windows |
|
||||
| ~w-~ | ~split-window-below-and-focus~ | ~vsplit-and-focus~ | |
|
||||
| ~w+~ | | ~balance-frames~ | |
|
||||
| ~wv~ | ~split-window-below~ | ~vsplit~ | |
|
||||
| ~wV~ | | ~vsplit-equally~ | |
|
||||
| ~w/~ | ~split-window-right-and-focus~ | ~hsplit-and-focus~ | |
|
||||
| ~wh~ | ~split-window-right~ | ~hsplit~ | |
|
||||
| ~wH~ | | ~hsplit-equally~ | |
|
||||
| ~wc~ | ~evil-window-left~ | ~move-focus left~ | |
|
||||
| ~wt~ | ~evil-window-down~ | ~move-focus down~ | |
|
||||
| ~ws~ | ~evil-window-up~ | ~move-focus up~ | |
|
||||
| ~wr~ | ~evil-window-right~ | ~move-focus right~ | |
|
||||
| ~wC~ | | ~move-window left~ | |
|
||||
| ~wT~ | | ~move-window down~ | |
|
||||
| ~wS~ | | ~move-window up~ | |
|
||||
| ~wR~ | | ~move-window right~ | |
|
||||
| ~w C-c~ | | ~exchange-direction right~ | |
|
||||
| ~w C-s~ | | ~exchange-direction down~ | |
|
||||
| ~w C-t~ | | ~exchange-direction up~ | |
|
||||
| ~w C-r~ | | ~exchange-direction right~ | |
|
||||
| ~wb~ | ~kill-buffer-and-delete-window~ | | |
|
||||
| ~we~ | ~winum-select-window-by-number~ | ~expose~ | |
|
||||
| ~wf~ | | ~fullscreen~ | |
|
||||
| ~wF~ | | ~'*my-floating-keymap*~ | floating windows |
|
||||
| ~wFf~ | | ~float-this~ | |
|
||||
| ~wFF~ | | ~flatten-floats~ | |
|
||||
| ~wFu~ | | ~unfloat-this~ | |
|
||||
| ~wi~ | | ~info~ | |
|
||||
| ~wd~ | ~delete-window~ | ~remove-split~ | |
|
||||
| ~wD~ | ~delete-other-windows~ | ~only~ | |
|
||||
| ~wm~ | | ~meta~ | |
|
||||
| ~wo~ | ~other-window~ | ~other-window~ | |
|
||||
| ~ws~ | | ~sibling~ | |
|
||||
| ~wu~ | | ~next-urgent~ | |
|
||||
| ~wU~ | | ~unmaximize~ | |
|
||||
| ~ww~ | ~nil~ | | writeroom |
|
||||
| ~ww.~ | ~writeroom-buffer-width/body~ | | |
|
||||
| ~www~ | ~writeroom-mode~ | | |
|
||||
|
||||
*** Media Control
|
||||
#+name: emacs-stumpwm-media-interactive
|
||||
| Keychord | Emacs | StumpWM | which-key |
|
||||
|----------+-------------------------------------------------------------+-----------------+-----------|
|
||||
| ~c~ | ~emms-player-mpd-previous~ | ~mpd-prev~ | |
|
||||
| ~t~ | ~(shell-command-and-echo "mpc volume -2" "mpc volume" "mpc")~ | ~mpd-volume-down~ | |
|
||||
| ~s~ | ~(shell-command-and-echo "mpc volume +2" "mpc volume" "mpc")~ | ~mpd-volume-up~ | |
|
||||
| ~r~ | ~emms-player-mpd-next~ | ~mpd-next~ | |
|
||||
| ~s~ | ~emms-player-mpd-stop~ | ~mpd-stop~ | |
|
||||
|
||||
#+name: emacs-stumpwm-general-media
|
||||
| Keychord | Emacs | StumpWM | which-key |
|
||||
|----------+-------+--------------------------------------+----------------|
|
||||
| ~c~ | | ~exec xbacklight -dec 2~ | backlight down |
|
||||
| ~t~ | | ~exec amixer -q set Master 2%- unmute~ | volume down |
|
||||
| ~s~ | | ~exec amixer -q set Master 2%+ unmute~ | volume up |
|
||||
| ~r~ | | ~exec xbacklight -inc 2~ | backlight up |
|
||||
| ~m~ | | ~exec amixer -q set Master 1+ toggle~ | toggle mute |
|
||||
|
||||
#+name: emacs-stumpwm-media-control
|
||||
| Keychord | Emacs | StumpWM | which-key |
|
||||
|----------+-----------------------------+---------------------------+-----------|
|
||||
| ~m~ | ~nil~ | ~'*my-media-keymap*~ | media |
|
||||
| ~m.~ | | ~media-interactive~ | |
|
||||
| ~m«~ | ~emms-player-mpd-previous~ | ~mpd-prev~ | |
|
||||
| ~m»~ | ~emms-player-mpd-next~ | ~mpd-next~ | |
|
||||
| ~ma~ | ~hydra-media/body~ | ~'*my-mpd-add-keymap*~ | MPD add |
|
||||
| ~maa~ | | ~mpd-serach-and-add-artist~ | |
|
||||
| ~maA~ | | ~mpd-serach-and-add-album~ | |
|
||||
| ~maf~ | | ~mpd-search-and-add-file~ | |
|
||||
| ~maF~ | | ~mpd-add-file~ | |
|
||||
| ~mag~ | | ~mpd-search-and-add-genre~ | |
|
||||
| ~mat~ | | ~mpd-search-and-add-title~ | |
|
||||
| ~mb~ | ~nil~ | ~'*my-mpd-browse-keymap*~ | browse |
|
||||
| ~mba~ | ~emms-browse-by-artist~ | ~mpd-browse-artists~ | |
|
||||
| ~mbA~ | ~emms-browse-by-album~ | ~mpd-browse-albums~ | |
|
||||
| ~mbg~ | ~emms-browse-by-genre~ | ~mpd-browse-genres~ | |
|
||||
| ~mbp~ | ~emms-playlists-mode-go~ | ~mpd-browse-playlist~ | |
|
||||
| ~mbs~ | ~emms-smart-browse~ | | |
|
||||
| ~mbt~ | | ~mpd-browse-tracks~ | |
|
||||
| ~mby~ | ~emms-browse-by-year~ | | |
|
||||
| ~mc~ | ~emms-player-mpd-clear~ | ~mpd-clear~ | |
|
||||
| ~mp~ | ~emms-player-toggle-pause~ | ~mpd-toggle-pause~ | |
|
||||
| ~ms~ | ~emms-player-mpd-show~ | | |
|
||||
| ~mu~ | ~nil~ | | update |
|
||||
| ~mum~ | ~emms-player-mpd-update-all~ | | |
|
||||
| ~muc~ | ~emms-cache-set-from-mpd-all~ | | |
|
||||
|
||||
** Theme and graphical tweaks
|
||||
*** GTK Settings
|
||||
**** GTK2
|
||||
***** General configuration
|
||||
:PROPERTIES:
|
||||
:HEADER-ARGS: :mkdirp yes :tangle ~/.config/gtk-2.0/gtkrc
|
||||
:END:
|
||||
This file is tangled at ~$HOME/.config/gtk-2.0/gtkrc~. This is an
|
||||
equivalent for the GTK3 configuration file you will see below, and it
|
||||
shares most of its settings. First, let’s select the Nordic theme for
|
||||
GTK2. Let’s also set the icon theme.
|
||||
#+BEGIN_SRC conf-unix
|
||||
# -*- mode: unix-config -*-
|
||||
gtk-theme-name="Nordic"
|
||||
gtk-icon-theme-name="Flat-Remix-Dark"
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC conf-unix
|
||||
gtk-xft-antialias=1
|
||||
gtk-xft-hinting=1
|
||||
gtk-xft-hintstyle="hintslight"
|
||||
#+END_SRC
|
||||
|
||||
This changes the shortcuts in menu, let’s also make the menus snappier.
|
||||
#+BEGIN_SRC conf-unix
|
||||
gtk-can-change-accels=1
|
||||
gtk-menu-bar-popup-delay=0
|
||||
gtk-menu-popdown-delay=0
|
||||
gtk-menu-popup-delay=0
|
||||
#+END_SRC
|
||||
|
||||
***** Filechooser
|
||||
:PROPERTIES:
|
||||
:HEADER-ARGS: :mkdirp yes :tangle ~/.config/gtk-2.0/gtkfilechooser.ini
|
||||
:END:
|
||||
#+BEGIN_SRC conf-unix
|
||||
[Filechooser Settings]
|
||||
#+END_SRC
|
||||
|
||||
The first option alows me to open the file chooser in the current working
|
||||
directory:
|
||||
#+BEGIN_SRC conf-unix
|
||||
StartupMode=cwd
|
||||
#+END_SRC
|
||||
|
||||
Next, setting the location mode to ~path-bar~ will show the path as buttons that
|
||||
can be clicked rather than the full path.
|
||||
#+BEGIN_SRC conf-unix
|
||||
LocationMode=path-bar
|
||||
#+END_SRC
|
||||
|
||||
With this configuration, by default we won’t see hidden files.
|
||||
#+BEGIN_SRC conf-unix
|
||||
ShowHidden=true
|
||||
#+END_SRC
|
||||
|
||||
And we'll also see the size of the visible files.
|
||||
#+BEGIN_SRC conf-unix
|
||||
ShowSizeColumn=true
|
||||
#+END_SRC
|
||||
|
||||
Now, let’s choose the geometry of our file picker. These two first lines set
|
||||
where the file picker appears:
|
||||
#+BEGIN_SRC conf-unix
|
||||
GeometryX=566
|
||||
GeometryY=202
|
||||
#+END_SRC
|
||||
|
||||
And these two describe the size of the window:
|
||||
#+BEGIN_SRC conf-unix
|
||||
GeometryWidth=800
|
||||
GeometryHeight=400
|
||||
#+END_SRC
|
||||
|
||||
With these two lines, we set how our files are sorted: by name, and in the
|
||||
ascending order.
|
||||
#+BEGIN_SRC conf-unix
|
||||
SortColumn=name
|
||||
SortOrder=ascending
|
||||
#+END_SRC
|
||||
|
||||
Our default view mode is a list of files:
|
||||
#+BEGIN_SRC conf-unix
|
||||
ViewMode=list-view
|
||||
#+END_SRC
|
||||
|
||||
And finally, setting our icon view scale to ~-1~ sets the icon view to the max
|
||||
size.
|
||||
#+BEGIN_SRC conf-unix
|
||||
IconViewScale=-1
|
||||
#+END_SRC
|
||||
|
||||
**** GTK3
|
||||
:PROPERTIES:
|
||||
:HEADER-ARGS: :mkdirp yes :tangle ~/.config/gtk-3.0/settings.ini
|
||||
:END:
|
||||
The following file helps me to choose the aspect of various GTK+ 3
|
||||
software, including their theme and icons. First, let’s declare the
|
||||
header:
|
||||
#+BEGIN_SRC conf-unix
|
||||
[Settings]
|
||||
#+END_SRC
|
||||
|
||||
Now, let’s hint to GTK that I prefer dark themes. This can have an influence
|
||||
also on some websites that can detect this preference and therefore set their
|
||||
own theme to dark by themselves.
|
||||
#+BEGIN_SRC conf-unix
|
||||
gtk-application-prefer-dark-theme = true
|
||||
#+END_SRC
|
||||
|
||||
Next, the icon theme is the Flat Remix Dark icon theme:
|
||||
#+BEGIN_SRC conf-unix
|
||||
gtk-icon-theme-name = Nordzy
|
||||
#+END_SRC
|
||||
|
||||
Now, the general theme for GTK3 is Nordic.
|
||||
#+BEGIN_SRC conf-unix
|
||||
gtk-theme-name = Nordic
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC conf-unix
|
||||
gtk-can-change-accels=1
|
||||
gtk-menu-bar-popup-delay=0
|
||||
gtk-menu-popdown-delay=0
|
||||
gtk-menu-popup-delay=0
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC conf-unix
|
||||
gtk-xft-antialias=1
|
||||
gtk-xft-hinting=1
|
||||
gtk-xft-hintstyle=hintslight
|
||||
# gtk-xft-rgba=rgb
|
||||
#+END_SRC
|
||||
|
||||
Since window decorations are handled by my WMs, I will leave this variable
|
||||
empty.
|
||||
#+BEGIN_SRC conf-unix
|
||||
gtk-decoration-layout=
|
||||
#+END_SRC
|
||||
|
||||
*** Xresources
|
||||
:PROPERTIES:
|
||||
:HEADER-ARGS: :mkdirp yes :tangle ~/.config/X11/Xresources :exports code
|
||||
:END:
|
||||
The main body in my Xresources declaration is the declaration of my
|
||||
color theme. It is based on the [[https://www.nordtheme.com/][Nord]] theme, from their [[https://github.com/arcticicestudio/nord-xresources/][Git repository]].
|
||||
#+BEGIN_SRC conf
|
||||
#define nord0 #2E3440
|
||||
#define nord1 #3B4252
|
||||
#define nord2 #434C5E
|
||||
#define nord3 #4C566A
|
||||
#define nord4 #D8DEE9
|
||||
#define nord5 #E5E9F0
|
||||
#define nord6 #ECEFF4
|
||||
#define nord7 #8FBCBB
|
||||
#define nord8 #88C0D0
|
||||
#define nord9 #81A1C1
|
||||
#define nord10 #5E81AC
|
||||
#define nord11 #BF616A
|
||||
#define nord12 #D08770
|
||||
#define nord13 #EBCB8B
|
||||
#define nord14 #A3BE8C
|
||||
#define nord15 #B48EAD
|
||||
|
||||
,*.foreground: nord4
|
||||
,*.background: nord0
|
||||
,*.cursorColor: nord4
|
||||
,*fading: 35
|
||||
,*fadeColor: nord3
|
||||
|
||||
,*.color0: nord1
|
||||
,*.color1: nord11
|
||||
,*.color2: nord14
|
||||
,*.color3: nord13
|
||||
,*.color4: nord9
|
||||
,*.color5: nord15
|
||||
,*.color6: nord8
|
||||
,*.color7: nord5
|
||||
,*.color8: nord3
|
||||
,*.color9: nord11
|
||||
,*.color10: nord14
|
||||
,*.color11: nord13
|
||||
,*.color12: nord9
|
||||
,*.color13: nord15
|
||||
,*.color14: nord7
|
||||
,*.color15: nord6
|
||||
#+END_SRC
|
||||
|
||||
** Email signature
|
||||
:PROPERTIES:
|
||||
:HEADER-ARGS: :mkdirp yes :tangle ~/.signature
|
||||
:END:
|
||||
This file gets inserted automatically at the end of my emails.
|
||||
#+BEGIN_SRC text
|
||||
Lucien “Phundrak” Cartier-Tilet
|
||||
https://phundrak.com (Français)
|
||||
https://phundrak.com/en (English)
|
||||
Sent from GNU/Emacs
|
||||
#+END_SRC
|
||||
|
||||
** ~.desktop~ files for custom applications
|
||||
Some software I use are not packaged (yet) on my system. Therefore, in
|
||||
order to make them available in ~rofi~, I need to write a ~.desktop~ file
|
||||
to launch them.
|
||||
|
||||
*** Emacs
|
||||
Emacs does have a default ~.desktop~ file, but I want to override it to
|
||||
just “open with Emacs” from other software (such as Nemo) and it will
|
||||
open with ~emacsclient~ instead of just =emacs=.
|
||||
#+begin_src conf-desktop :tangle ~/.local/share/applications/emacs.desktop
|
||||
[Desktop Entry]
|
||||
Name=Emacs
|
||||
GenericName=Text Editor
|
||||
Comment=Edit text
|
||||
MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;
|
||||
Exec=emacsclient -c %F
|
||||
Icon=emacs
|
||||
Type=Application
|
||||
Terminal=false
|
||||
Categories=Development;TextEditor;
|
||||
StartupWMClass=Emacs
|
||||
Keywords=Text;Editor;
|
||||
#+end_src
|
||||
|
||||
I also have ~mu4e.desktop~ which is used to set my default email client.
|
||||
It relies on ~emacsmail~ defined in [[file:bin.org::#Emacsmail-afffb7cd][this document]].
|
||||
#+begin_src conf-desktop :tangle ~/.local/share/applications/mu4e.desktop
|
||||
[Desktop Entry]
|
||||
Name=Mu4e
|
||||
GenericName=Mu4e
|
||||
Comment=Maildir Utils for Emacs
|
||||
MimeType=x-scheme-handler/mailto;
|
||||
Exec=/home/phundrak/.local/bin/emacsmail %U
|
||||
Icon=emacs
|
||||
Type=Application
|
||||
Terminal=false
|
||||
Categories=Network;Email;TextEditor
|
||||
StartupWMClass=Gnus
|
||||
Keywords=Text;Editor;
|
||||
#+end_src
|
||||
|
||||
Then I also have ~org-protocol.desktop~ that helps capture elements from
|
||||
other software, mainly web pages from Firefox through the [[https://github.com/sprig/org-capture-extension][org-capture
|
||||
extension]].
|
||||
#+begin_src conf-desktop :tangle ~/.local/share/applications/org-protocol.desktop
|
||||
[Desktop Entry]
|
||||
Name=org-protocol
|
||||
Exec=emacsclient %u
|
||||
Type=Application
|
||||
Terminal=false
|
||||
Categories=System;
|
||||
MimeType=x-scheme-handler/org-protocol;
|
||||
#+end_src
|
||||
|
||||
*** FlowScape
|
||||
[[https://pixelforest.itch.io/flowscape][FlowScape]] is a nice 3D compositing software I sometimes use to create
|
||||
landscapes. I always install it in =~/.local/opt/Flowscape=, so the
|
||||
~.desktop~ file is relatively straightforward.
|
||||
#+begin_src conf-desktop :tangle ~/.local/share/applications/FlowScape.desktop
|
||||
[Desktop Entry]
|
||||
Version=1.5
|
||||
Name=FlowScape
|
||||
Comment=Create gorgeous 3D landscapes with ease.
|
||||
Exec=/usr/bin/prime-run /home/phundrak/.local/opt/FlowScape/FlowScape.x86_64
|
||||
Path=/home/phundrak/.local/opt/FlowScape
|
||||
Icon=/home/phundrak/.local/opt/FlowScape/icon.jpg
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Graphics
|
||||
#+end_src
|
||||
|
||||
*** macOS
|
||||
You did not read wrong! Yes I have an entry for macOS, but this is for
|
||||
a virtual machine located in ~~/VMs/macOS~.
|
||||
#+begin_src conf-desktop :tangle ~/.local/share/applications/macos.desktop
|
||||
[Desktop Entry]
|
||||
Version=1
|
||||
Name=macOS
|
||||
Comment=macOS in a virtual machine
|
||||
Exec=/usr/bin/prime-run /home/phundrak/VMs/macOS/basic.sh
|
||||
Path=/home/phundrak/VMs/macOS
|
||||
Icon=/home/phundrak/VMs/macOS/macOS.png
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Development
|
||||
#+end_src
|
||||
|
||||
*** Minecraft
|
||||
Yup, I play Minecraft. And yes, it does have a default ~.desktop~ file,
|
||||
but this one overrides it to launch automatically Minecraft with
|
||||
[[https://wiki.archlinux.org/title/PRIME][prime-run]], using my Nvidia GPU instead of my integrated GPU.
|
||||
#+begin_src conf-desktop :tangle ~/.local/share/applications/minecraft-launcher.desktop
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Version=1.0
|
||||
Name=Minecraft Launcher (Nvidia)
|
||||
Comment=Official Minecraft Launcher
|
||||
Exec=/usr/bin/prime-run /usr/bin/minecraft-launcher
|
||||
Path=/usr/bin/
|
||||
Icon=minecraft-launcher
|
||||
Terminal=false
|
||||
Categories=Game;Application;
|
||||
#+end_src
|
||||
|
||||
*** OtherWorldMapper
|
||||
OtherWorldMapper is a map creation software. It is always installed in
|
||||
~~/.local/opt/OtherWorldMapper~.
|
||||
#+begin_src conf-desktop :tangle ~/.local/share/applications/OWM.desktop
|
||||
[Desktop Entry]
|
||||
Version=1.0.4
|
||||
Name=OtherWorldMapper
|
||||
Comment=OtherWorldMapper is a powerful yet intuitive fantasy map creation tool.
|
||||
Exec=/usr/bin/prime-run /home/phundrak/.local/opt/OtherWorldMapper/OWM
|
||||
Path=/home/phundrak/.local/opt/OtherWorldMapper
|
||||
Icon=/home/phundrak/.local/opt/OtherWorldMapper/owm.ico
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Graphics
|
||||
#+end_src
|
||||
|
||||
*** YouTube ~.desktop~ files
|
||||
The first ~.desktop~ file related to YouTube is ~ytdl.desktop~ which runs
|
||||
~ytdl~ defined in [[file:bin.org::#ytdl-a-youtube-dl-wrapper-03bd63e0][this document]].
|
||||
#+begin_src conf-desktop :tangle ~/.local/share/applications/ytdl.desktop
|
||||
[Desktop Entry]
|
||||
Version=0.3
|
||||
Name=YTDL
|
||||
Comment=YouTube (and more) video downloader
|
||||
Exec=/home/phundrak/.local/bin/rofi-ytdl
|
||||
Path=/home/phundrak/.local/bin
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Network;Video
|
||||
#+end_src
|
||||
|
||||
There is also ~ytplay.desktop~ for ~ytplay~ defined in [[file:bin.org::#Media-youtube-dl-wrappers-ytplay-z6ka39h0m9j0][this document]].
|
||||
#+begin_src conf-desktop
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Version=1.0
|
||||
Name=ytplay (YouTube in mpv)
|
||||
Comment=Play YouTube videos in mpv
|
||||
Exec=/home/phundrak/.local/bin/ytplay
|
||||
Path=/home/phundrak/.local/bin
|
||||
Terminal=false
|
||||
Categories=Media
|
||||
#+end_src
|
||||
377
docs/emacs/basic-config.org
Normal file
@@ -0,0 +1,377 @@
|
||||
#+title: Emacs — Basic Configuration
|
||||
#+setupfile: ../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/basic-config.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
* Basic Configuration
|
||||
** Early Init
|
||||
:PROPERTIES:
|
||||
:header-args:emacs-lisp: :tangle ~/.config/emacs/early-init.el :mkdirp yes
|
||||
:header-args:emacs-lisp+: :exports code :results silent :lexical t
|
||||
:END:
|
||||
The early init file is the file loaded before anything else in
|
||||
Emacs. This is where I put some options in order to disable as quickly
|
||||
as possible some built-in features of Emacs before they can be even
|
||||
loaded, speeding Emacs up a bit.
|
||||
#+begin_src emacs-lisp :mkdirp yes
|
||||
(setq package-enable-at-startup nil
|
||||
inhibit-startup-message t
|
||||
frame-resize-pixelwise t ; fine resize
|
||||
package-native-compile t) ; native compile packages
|
||||
(scroll-bar-mode -1) ; disable scrollbar
|
||||
(tool-bar-mode -1) ; disable toolbar
|
||||
(tooltip-mode -1) ; disable tooltips
|
||||
(set-fringe-mode 10) ; give some breathing room
|
||||
(menu-bar-mode -1) ; disable menubar
|
||||
(blink-cursor-mode 0) ; disable blinking cursor
|
||||
(setq gc-cons-threshold (* 1024 1024 1024))
|
||||
#+end_src
|
||||
|
||||
** Emacs Behavior
|
||||
*** Editing Text in Emacs
|
||||
I *never* want to keep trailing spaces in my files, which is why I’m
|
||||
doing this:
|
||||
#+begin_src emacs-lisp
|
||||
(add-hook 'before-save-hook #'whitespace-cleanup)
|
||||
#+end_src
|
||||
|
||||
I don’t understand why some people add two spaces behind a full stop,
|
||||
I sure don’t. Let’s tell Emacs.
|
||||
#+begin_src emacs-lisp
|
||||
(setq-default sentence-end-double-space nil)
|
||||
#+end_src
|
||||
|
||||
There is a minor mode in Emacs which allows to have a finer way of
|
||||
jumping from word to word: ~global-subword-mode~. It detects if what
|
||||
Emacs usually considers a word can be understood as several words, as
|
||||
in camelCase words, and allows us to jump words on this finer level.
|
||||
#+begin_src emacs-lisp
|
||||
(global-subword-mode 1)
|
||||
#+end_src
|
||||
|
||||
Changing half my screen each time my cursor goes too high or too low
|
||||
is not exactly ideal. Fortunately, if we set ~scroll-conservatively~
|
||||
high enough we can have the cursor stay on top or at the bottom of the
|
||||
screen while the text scrolls progressively.
|
||||
#+begin_src emacs-lisp
|
||||
(setq scroll-conservatively 1000)
|
||||
#+end_src
|
||||
|
||||
Lastly, I want the default mode for Emacs to be Emacs Lisp.
|
||||
#+begin_src emacs-lisp
|
||||
(setq-default initial-major-mode 'emacs-lisp-mode)
|
||||
#+end_src
|
||||
|
||||
**** Indentation
|
||||
I don’t like tabs. They rarely look good, and if I need it I can
|
||||
almost always tell Emacs to use them through a ~.dir-locals.el~ file or
|
||||
through the config file of my code formatter. So by default, let’s
|
||||
disable them:
|
||||
#+begin_src emacs-lisp
|
||||
(setq-default indent-tabs-mode nil)
|
||||
(add-hook 'prog-mode-hook (lambda () (setq indent-tabs-mode nil)))
|
||||
#+end_src
|
||||
|
||||
Just to go on a little tangent here: I don’t exactly /hate/ tabs, but I
|
||||
find them really annoying when your text editor knows only them. Sure,
|
||||
for indentation they work great, and they allow different people
|
||||
getting different settings in their text editor depending on their
|
||||
preferred tastes —some may prefer 2 spaces tabs, some may prefer 4
|
||||
spaces tabs, some deranged people prefer 8 spaces tabs, and some
|
||||
monsters prefer 3!
|
||||
|
||||
But the thing is, once you indented your code, and then you need
|
||||
alignment, tabs don’t work anymore! Or they may on *your* text editor
|
||||
but not on your coworker’s! (He’s the one using 3 spaces tabs by the
|
||||
way).
|
||||
|
||||
So, is the answer to use spaces instead of tabs, and screw peoples’
|
||||
preferences in terms of tabs width? No, I say the answer is more
|
||||
moderate than that, and it might frighten or anger some of you at
|
||||
first: use both spaces and tabs. Now, before you lynch me on the main
|
||||
avenue in front of everyone, let me tell you absolutely no one should
|
||||
ever be mixing spaces and tabs for indentation, that would be
|
||||
absolutely terrible and would bring the worst of both worlds. What’s
|
||||
the best of both worlds then?
|
||||
#+begin_center
|
||||
/Tabs for indentation/
|
||||
|
||||
/Spaces for alignment/
|
||||
#+end_center
|
||||
|
||||
I haven’t found a way to automate that in Emacs yet aside from
|
||||
formatters’ config file, and tabs look bat in EmacsLisp anyway, so
|
||||
I’ll stick with spaces by default and change it where needed.
|
||||
|
||||
*** Programming Modes
|
||||
First off, my definition of what makes a “programming mode” doesn’t exactly
|
||||
fit mine, so on top of ~prog-mode~, let’s add a few other modes.
|
||||
#+name: line-number-modes-table
|
||||
| Modes |
|
||||
|------------|
|
||||
| prog-mode |
|
||||
| latex-mode |
|
||||
|
||||
#+name: prog-modes-gen
|
||||
#+header: :cache yes :exports none :tangle no
|
||||
#+begin_src emacs-lisp :var modes=line-number-modes-table
|
||||
(mapconcat (lambda (mode) (format "%s-hook" (car mode)))
|
||||
modes
|
||||
" ")
|
||||
#+end_src
|
||||
|
||||
**** Line Number
|
||||
Since version 26, Emacs has a built-in capacity of displaying line
|
||||
numbers on the left-side of the buffer. This is a fantastic feature
|
||||
that should actually be the default for all programming modes.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(dolist (mode '(<<prog-modes-gen()>>))
|
||||
(add-hook mode #'display-line-numbers-mode))
|
||||
#+end_src
|
||||
|
||||
**** Folding code
|
||||
Most programming languages can usually have their code folded, be it
|
||||
code between curly braces, chunks of comments or code on another level
|
||||
of indentation (Python, why…?). The minor-mode that enables that is
|
||||
~hs-minor-mode~, let’s enable it for all of these programming modes:
|
||||
#+begin_src emacs-lisp
|
||||
(dolist (mode '(<<prog-modes-gen()>>))
|
||||
(add-hook mode #'hs-minor-mode))
|
||||
#+end_src
|
||||
|
||||
*** Stay Clean, Emacs!
|
||||
As nice as Emacs is, it isn’t very polite or clean by default: open a
|
||||
file, and it will create backup files in the same directory. But then,
|
||||
when you open your directory with your favorite file manager and see
|
||||
almost all of your files duplicated with a =~= appended to the filename,
|
||||
it looks really uncomfortable! This is why I prefer to tell Emacs to
|
||||
keep its backup files to itself in a directory it only will access.
|
||||
#+begin_src emacs-lisp
|
||||
(setq backup-directory-alist `(("." . ,(expand-file-name ".tmp/backups/"
|
||||
user-emacs-directory))))
|
||||
#+end_src
|
||||
|
||||
It also loves to litter its ~init.el~ with custom variables here and
|
||||
there, but the thing is: I regenerate my ~init.el~ each time I tangle
|
||||
this file! How can I keep Emacs from adding stuff that will be almost
|
||||
immediately lost? Did someone say /custom file/?
|
||||
#+begin_src emacs-lisp
|
||||
(setq-default custom-file (expand-file-name ".custom.el" user-emacs-directory))
|
||||
(when (file-exists-p custom-file) ; Don’t forget to load it, we still need it
|
||||
(load custom-file))
|
||||
#+end_src
|
||||
|
||||
If we delete a file, we want it moved to the trash, not simply deleted.
|
||||
#+begin_src emacs-lisp
|
||||
(setq delete-by-moving-to-trash t)
|
||||
#+end_src
|
||||
|
||||
Finally, the scatch buffer always has some message at its beginning, I
|
||||
don’t want it!
|
||||
#+begin_src emacs-lisp
|
||||
(setq-default initial-scratch-message nil)
|
||||
#+end_src
|
||||
|
||||
*** Stay Polite, Emacs!
|
||||
When asking for our opinion on something, Emacs loves asking us to
|
||||
answer by “yes” or “no”, but *in full*! That’s very rude! Fortunately,
|
||||
we can fix this.
|
||||
#+begin_src emacs-lisp
|
||||
(defalias 'yes-or-no-p 'y-or-n-p)
|
||||
#+end_src
|
||||
|
||||
This will make Emacs ask us for either hitting the ~y~ key for “yes”, or
|
||||
the ~n~ key for “no”. Much more polite!
|
||||
|
||||
It is also very impolite to keep a certain version of a file in its
|
||||
buffer when said file has changed on disk. Let’s change this behavior:
|
||||
#+begin_src emacs-lisp
|
||||
(global-auto-revert-mode 1)
|
||||
#+end_src
|
||||
|
||||
Much more polite! Note that if the buffer is modified and its changes
|
||||
haven’t been saved, it will not automatically revert the buffer and
|
||||
your unsaved changes won’t be lost. Very polite!
|
||||
|
||||
*** Misc
|
||||
Let’s raise Emacs undo memory to 10 MB, and make Emacs auto-save our
|
||||
files by default.
|
||||
#+begin_src emacs-lisp
|
||||
(setq undo-limit 100000000
|
||||
auto-save-default t)
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq window-combination-resize t) ; take new window space from all other windows
|
||||
#+end_src
|
||||
|
||||
** Personal Information
|
||||
Emacs needs to know its master! For various reasons by the way, some
|
||||
packages rely on these variables to know who it is talking to or
|
||||
dealing with, such as ~mu4e~ which will guess who you are if you haven’t
|
||||
set it up correctly.
|
||||
#+begin_src emacs-lisp
|
||||
(setq user-full-name "Lucien Cartier-Tilet"
|
||||
user-real-login-name "Lucien Cartier-Tilet"
|
||||
user-login-name "phundrak"
|
||||
user-mail-address "lucien@phundrak.com")
|
||||
#+end_src
|
||||
|
||||
** Visual Configuration
|
||||
The first visual setting in this section will activate the visible
|
||||
bell. What it does is I get a visual feedback each time I do something
|
||||
Emacs doesn’t agree with, like tring to go up a line when I’m already
|
||||
at the top of the buffer.
|
||||
#+begin_src emacs-lisp
|
||||
(setq visible-bell t)
|
||||
#+end_src
|
||||
|
||||
It is nicer to see a cursor cover the actual space of a character.
|
||||
#+begin_src emacs-lisp
|
||||
(setq x-stretch-cursor t)
|
||||
#+end_src
|
||||
|
||||
When text is ellipsed, I want the ellipsis marker to be a single
|
||||
character of three dots. Let’s make it so:
|
||||
#+begin_src emacs-lisp
|
||||
(with-eval-after-load 'mule-util
|
||||
(setq truncate-string-ellipsis "…"))
|
||||
#+end_src
|
||||
|
||||
With Emacs 29.0.50 onwards, a new frame parameter exists:
|
||||
~alpha-background~. Unlike ~alpha~, this frame parameter only makes Emacs’
|
||||
background transparent, excluding images and text.
|
||||
#+begin_src emacs-lisp
|
||||
(add-to-list 'default-frame-alist '(alpha-background . 0.9))
|
||||
#+end_src
|
||||
|
||||
*** Modeline Modules
|
||||
I sometimes use Emacs in fullscreen, meaning my usual taskbar will be
|
||||
hidden. This is why I want the current date and time to be displayed,
|
||||
in an ISO-8601 style, although not exactly ISO-8601 (this is the best
|
||||
time format, fight me).
|
||||
#+begin_src emacs-lisp
|
||||
(require 'time)
|
||||
(setq display-time-format "%Y-%m-%d %H:%M")
|
||||
(display-time-mode 1) ; display time in modeline
|
||||
#+end_src
|
||||
|
||||
Something my taskbar doesn’t have is a battery indicator. However, I
|
||||
want it enabled only if I am on a laptop or if a battery is available.
|
||||
#+begin_src emacs-lisp
|
||||
(let ((battery-str (battery)))
|
||||
(unless (or (equal "Battery status not available" battery-str)
|
||||
(string-match-p (regexp-quote "N/A") battery-str))
|
||||
(display-battery-mode 1)))
|
||||
#+end_src
|
||||
|
||||
This isn’t a modeline module per se, but we have an indicator of the
|
||||
current line in Emacs. And although it is useful, I also often wish to
|
||||
know which column I’m on. This can be activated like so:
|
||||
#+begin_src emacs-lisp
|
||||
(column-number-mode)
|
||||
#+end_src
|
||||
|
||||
The following code is, as will several chunks of code in this config,
|
||||
borrowed from [[https://tecosaur.github.io/emacs-config/#theme-modeline][TEC’s configuration]]. It hides the encoding information
|
||||
of the file if the file itself is a regular UTF-8 file with ~\n~ line
|
||||
ending. Be aware the ~doom-modeline-buffer-encoding~ variable is usabel
|
||||
here only because I use the Doom modeline as seen below.
|
||||
#+begin_src emacs-lisp
|
||||
(defun modeline-contitional-buffer-encoding ()
|
||||
"Hide \"LF UTF-8\" in modeline.
|
||||
|
||||
It is expected of files to be encoded with LF UTF-8, so only show
|
||||
the encoding in the modeline if the encoding is worth notifying
|
||||
the user."
|
||||
(setq-local doom-modeline-buffer-encoding
|
||||
(unless (and (memq (plist-get (coding-system-plist buffer-file-coding-system) :category)
|
||||
'(coding-category-undecided coding-category-utf-8))
|
||||
(not (memq (coding-system-eol-type buffer-file-coding-system) '(1 2))))
|
||||
t)))
|
||||
#+end_src
|
||||
|
||||
Now, let’s automate the call to this function in order to apply the
|
||||
modifications to the modeline each time we open a new file.
|
||||
#+begin_src emacs-lisp
|
||||
(add-hook 'after-change-major-mode-hook #'modeline-contitional-buffer-encoding)
|
||||
#+end_src
|
||||
|
||||
*** Fonts
|
||||
I don’t like the default font I usually have on my machines, I really
|
||||
don’t. I prefer [[https://github.com/microsoft/cascadia-code][Cascadia Code]], as it also somewhat supports the [[https://www.internationalphoneticassociation.org/][IPA]].
|
||||
#+begin_src emacs-lisp
|
||||
(defvar phundrak/default-font-size 90
|
||||
"Default font size.")
|
||||
|
||||
(defvar phundrak/default-font-name "Cascadia Code"
|
||||
"Default font.")
|
||||
|
||||
(defun my/set-font ()
|
||||
(when (find-font (font-spec :name phundrak/default-font-name))
|
||||
(set-face-attribute 'default nil
|
||||
:font phundrak/default-font-name
|
||||
:height phundrak/default-font-size)))
|
||||
|
||||
(my/set-font)
|
||||
(add-hook 'server-after-make-frame-hook #'my/set-font)
|
||||
#+end_src
|
||||
|
||||
*** Frame Title
|
||||
This is straight-up copied from [[https://tecosaur.github.io/emacs-config/config.html#window-title][TEC]]’s configuration. See their comment
|
||||
on the matter.
|
||||
#+begin_src emacs-lisp
|
||||
(setq frame-title-format
|
||||
'(""
|
||||
"%b"
|
||||
(:eval
|
||||
(let ((project-name (projectile-project-name)))
|
||||
(unless (string= "-" project-name)
|
||||
(format (if (buffer-modified-p) " ◉ %s" " ● %s - Emacs") project-name))))))
|
||||
#+end_src
|
||||
|
||||
** A better custom variable setter
|
||||
Something people often forget about custom variables in Elisp is they
|
||||
can have a custom setter that will run some code if we set the
|
||||
variable properly with ~customize-set-variable~, so ~setq~ shouldn’t be
|
||||
the user’s choice by default. But repeatedly writing
|
||||
~customize-set-variable~ can get tiring and boring. So why not take the
|
||||
best of both world and create ~csetq~, a ~setq~ that uses
|
||||
~customize-set-variable~ under the hood while it keeps a syntax similar
|
||||
to the one ~setq~ uses?
|
||||
#+begin_src emacs-lisp
|
||||
(defmacro csetq (&rest forms)
|
||||
"Bind each custom variable FORM to the value of its VAL.
|
||||
|
||||
FORMS is a list of pairs of values [FORM VAL].
|
||||
`customize-set-variable' is called sequentially on each pairs
|
||||
contained in FORMS. This means `csetq' has a similar behaviour as
|
||||
`setq': each VAL expression are evaluated sequentially, i.e. the
|
||||
first VAL is evaluated before the second, and so on. This means
|
||||
the value of the first FORM can be used to set the second FORM.
|
||||
|
||||
The return value of `csetq' is the value of the last VAL.
|
||||
|
||||
\(fn [FORM VAL]...)"
|
||||
(declare (debug (&rest sexp form))
|
||||
(indent 1))
|
||||
;; Check if we have an even number of arguments
|
||||
(when (= (mod (length forms) 2) 1)
|
||||
(signal 'wrong-number-of-arguments (list 'csetq (1+ (length forms)))))
|
||||
;; Transform FORMS into a list of pairs (FORM . VALUE)
|
||||
(let (sexps)
|
||||
(while forms
|
||||
(let ((form (pop forms))
|
||||
(value (pop forms)))
|
||||
(push `(customize-set-variable ',form ,value)
|
||||
sexps)))
|
||||
`(progn ,@(nreverse sexps))))
|
||||
#+end_src
|
||||
|
||||
I first got inspired by [[https://oremacs.com/2015/01/17/setting-up-ediff/][this blog article]] (archived article, just in
|
||||
case) but it seems the code snippet no longer works properly, so not
|
||||
only did I have to modify it to make it work with an arbitrary amount
|
||||
of arguments (as long as it’s pairs of variables and their value), but
|
||||
I also had to make the code simply work.
|
||||
121
docs/emacs/custom-elisp.org
Normal file
@@ -0,0 +1,121 @@
|
||||
#+title: Emacs — Custom Elisp
|
||||
#+setupfile: ../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/custom-elisp.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
* Custom Elisp
|
||||
** Dired functions
|
||||
*** ~phundrak/open-marked-files~
|
||||
This function allows the user to open all marked files from a dired
|
||||
buffer in new Emacs buffers.
|
||||
#+begin_src emacs-lisp
|
||||
(defun phundrak/open-marked-files (&optional files)
|
||||
"Open all marked FILES in Dired buffer as new Emacs buffers."
|
||||
(interactive)
|
||||
(let* ((file-list (if files
|
||||
(list files)
|
||||
(if (equal major-mode "dired-mode")
|
||||
(dired-get-marked-files)
|
||||
(list (buffer-file-name))))))
|
||||
(mapc (lambda (file-path)
|
||||
(find-file file-path))
|
||||
(file-list))))
|
||||
#+end_src
|
||||
|
||||
** Switch between buffers
|
||||
Two default shortcuts I really like from Spacemacs are ~SPC b m~ and ~SPC
|
||||
b s~, which bring the user directly to the ~*Messages*~ buffer and the
|
||||
~*scratch*~ buffer respectively. These functions do exactly this.
|
||||
#+begin_src emacs-lisp
|
||||
(defun switch-to-messages-buffer ()
|
||||
"Switch to Messages buffer."
|
||||
(interactive)
|
||||
(switch-to-buffer (messages-buffer)))
|
||||
|
||||
(defun switch-to-scratch-buffer ()
|
||||
"Switch to Messages buffer."
|
||||
(interactive)
|
||||
(switch-to-buffer "*scratch*"))
|
||||
#+end_src
|
||||
|
||||
** Screenshots
|
||||
Since Emacs27, it is possible for Emacs to take screenshots of itself
|
||||
in various formats. I’m mainly interested in the SVG and PNG format,
|
||||
so I’ll only write functions for these. It isn’t really redundant with
|
||||
the ~screenshot.el~ package used [[file:./packages/applications.md#screenshot][here]] since these functions take a
|
||||
screenshot of Emacs as a whole rather than of a code snippet.
|
||||
|
||||
First, we have a general function which is a slight modification of
|
||||
the function shared by Alphapapa in [[https://www.reddit.com/r/emacs/comments/idz35e/emacs_27_can_take_svg_screenshots_of_itself/g2c2c6y/][this Reddit comment]]. I modified it
|
||||
to make it possible to pass as an argument the format the screenshot
|
||||
will be taken as or ask the user which format they would like to save
|
||||
it as.
|
||||
#+begin_src emacs-lisp
|
||||
(defun self-screenshot (&optional type)
|
||||
"Save a screenshot of type TYPE of the current Emacs frame.
|
||||
As shown by the function `', type can weild the value `svg',
|
||||
`png', `pdf'.
|
||||
|
||||
This function will output in /tmp a file beginning with \"Emacs\"
|
||||
and ending with the extension of the requested TYPE."
|
||||
(interactive (list
|
||||
(intern (completing-read "Screenshot type: "
|
||||
'(png svg pdf postscript)))))
|
||||
(let* ((extension (pcase type
|
||||
('png ".png")
|
||||
('svg ".svg")
|
||||
('pdf ".pdf")
|
||||
('postscript ".ps")
|
||||
(otherwise (error "Cannot export screenshot of type %s" otherwise))))
|
||||
(filename (make-temp-file "Emacs-" nil extension))
|
||||
(data (x-export-frames nil type)))
|
||||
(with-temp-file filename
|
||||
(insert data))
|
||||
(kill-new filename)
|
||||
(message filename)))
|
||||
#+end_src
|
||||
|
||||
I used this function to take the screenshots you can see in this
|
||||
document.
|
||||
|
||||
** Handle new windows
|
||||
The two functions below allow the user to not only create a new window
|
||||
to the right or below the current window (respectively), but also to
|
||||
focus the new window immediately.
|
||||
#+begin_src emacs-lisp
|
||||
(defun split-window-right-and-focus ()
|
||||
"Spawn a new window right of the current one and focus it."
|
||||
(interactive)
|
||||
(split-window-right)
|
||||
(windmove-right))
|
||||
|
||||
(defun split-window-below-and-focus ()
|
||||
"Spawn a new window below the current one and focus it."
|
||||
(interactive)
|
||||
(split-window-below)
|
||||
(windmove-down))
|
||||
|
||||
(defun kill-buffer-and-delete-window ()
|
||||
"Kill the current buffer and delete its window."
|
||||
(interactive)
|
||||
(progn
|
||||
(kill-this-buffer)
|
||||
(delete-window)))
|
||||
#+end_src
|
||||
|
||||
** Extend ~add-to-list~
|
||||
One function I find missing regarding ~add-to-list~ is ~add-all-to-list~
|
||||
which enables the user to add multiple elements to a list at once.
|
||||
Instead, with vanilla Emacs, I have to repeatedly call ~add-to-list~.
|
||||
That’s not very clean. Let’s declare this missing function:
|
||||
#+begin_src emacs-lisp
|
||||
(defun add-all-to-list (list-var elements &optional append compare-fn)
|
||||
"Add ELEMENTS to the value of LIST-VAR if it isn’t there yet.
|
||||
|
||||
ELEMENTS is a list of values. For documentation on the variables
|
||||
APPEND and COMPARE-FN, see `add-to-list'."
|
||||
(let (return)
|
||||
(dolist (elt elements return)
|
||||
(setq return (add-to-list list-var elt append compare-fn)))))
|
||||
#+end_src
|
||||
1
docs/emacs/img
Symbolic link
@@ -0,0 +1 @@
|
||||
../img/emacs
|
||||
125
docs/emacs/index.org
Normal file
@@ -0,0 +1,125 @@
|
||||
#+title: Emacs Configuration
|
||||
#+setupfile: ../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/init.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
* Emacs Configuration
|
||||
|
||||
[[file:./img/emacs.svg]]
|
||||
|
||||
** Introduction
|
||||
After a couple of years using Spacemacs and a failed attempt at
|
||||
switching to DoomEmacs, I’m finally switching back to a vanilla
|
||||
configuration! Why? Because I got tired of the framework getting in my
|
||||
way when I wanted to do stuff. I’m sure this is more applicable to
|
||||
Spacemacs than DoomEmacs since the latter has nice macros written to
|
||||
easily add new packages and configure them, such as ~package!~, ~after!~,
|
||||
and others. But ultimately, I wanted to have a system I designed
|
||||
entirely, with the keybinds I want, the packages I want.
|
||||
|
||||
Aso, why Emacs? You know this famous quote:
|
||||
#+begin_quote
|
||||
Emacs is a great operating system, it just lacks a good text editor.
|
||||
#+end_quote
|
||||
|
||||
It’s actually pretty true in my opinion. Emacs is basically a Lisp
|
||||
machine with a default text editor, programmed with EmacsLisp, a
|
||||
general-purpose programming language. Therefore, if you want to do
|
||||
something in Emacs, with enough Elisp you can do it --- if it’s not in
|
||||
Emacs already, that is.
|
||||
|
||||
#+attr_html: :alt Dammit Emacs… :loading lazy
|
||||
#+caption: [[https://xkcd.com/378/][XKCD n°378]]: Real Programmers
|
||||
[[file:./img/real_programmers.png]]
|
||||
|
||||
** A Warning Before You Proceed
|
||||
:PROPERTIES:
|
||||
:header-args:emacs-lisp: :tangle no
|
||||
:END:
|
||||
This configuration makes heavy use of the [[https://orgmode.org/manual/Noweb-Reference-Syntax.html][noweb]] syntax. This means if
|
||||
you encounter some code that looks ~<<like-this>>~, org-mode will
|
||||
replace this snippet with another code snippet declared elsewhere in
|
||||
my configuration. If you see some code that looks ~<<like-this()>>~,
|
||||
some generating code will run and replace this piece of text with the
|
||||
text generated. A quick example:
|
||||
#+begin_src elisp
|
||||
(defun hello ()
|
||||
<<generate-docstring()>>
|
||||
<<print-hello>>)
|
||||
#+end_src
|
||||
|
||||
Will instead appear as
|
||||
#+begin_src emacs-lisp :noweb yes
|
||||
(defun hello ()
|
||||
<<generate-docstring()>>
|
||||
<<print-hello>>)
|
||||
#+end_src
|
||||
|
||||
This is because I have the block of code below named
|
||||
~generate-docstring~ which generates an output, which replaces its noweb
|
||||
tag. You can recognize noweb snippets generating code with the
|
||||
parenthesis. Often, such blocks aren’t visible in my HTML exports, but
|
||||
you can still see them if you open the actual org source file.
|
||||
#+name: generate-docstring
|
||||
#+begin_src emacs-lisp
|
||||
(concat "\""
|
||||
"Print \\\"Hello World!\\\" in the minibuffer."
|
||||
"\"")
|
||||
#+end_src
|
||||
|
||||
On the other hand, noweb snippets without parenthesis simply replace
|
||||
the snippet with the equivalent named code block. For instance the one
|
||||
below is named ~print-hello~ and is placed as-is in the target source
|
||||
block.
|
||||
#+name: print-hello
|
||||
#+begin_src emacs-lisp
|
||||
(message "Hello World!")
|
||||
#+end_src
|
||||
|
||||
** Loading All Configuration Modules
|
||||
|
||||
#+name: emacs-modules
|
||||
| Module Name | Config Page |
|
||||
|--------------------------+----------------------------------|
|
||||
| =basic-config.el= | [[file:./basic-config.org][Basic Configuration]] |
|
||||
| =custom-elisp.el= | [[file:./custom-elisp.org][Custom Elisp]] |
|
||||
| =package-manager.el= | [[file:./package-manager.org][Package Manager]] |
|
||||
| =keybinding-managemers.el= | [[file:./keybinding-managemers.org][Keybinding Managers]] |
|
||||
| =applications.el= | [[file:./packages/applications.org][Packages — Applications]] |
|
||||
| =autocompletion.el= | [[file:./packages/autocompletion.org][Packages — Autocompletion]] |
|
||||
| =editing.el= | [[file:./packages/editing.org][Packages — Editing]] |
|
||||
| =emacs-builtin.el= | [[file:./packages/emacs-builtin.org][Packages — Emacs Built-ins]] |
|
||||
| =exwm.el= | [[file:./packages/exwm.org][Packages — EXWM]] |
|
||||
| =helpful.el= | [[file:./packages/helpful.org][Packages — Making My Life Easier]] |
|
||||
| =latex.el= | [[file:./packages/latex.org][Packages — LaTeX]] |
|
||||
| =misc.el= | [[file:./packages/misc.org][Packages — Misc]] |
|
||||
| =org.el= | [[file:./packages/org.org][Packages — Org Mode]] |
|
||||
| =programming.el= | [[file:./packages/programming.org][Packages — Programming]] |
|
||||
| =visual-config.el= | [[file:./packages/visual-config.org][Packages — Visual Configuration]] |
|
||||
| =keybindings.el= | [[file:./keybindings.org][Keybindings]] |
|
||||
|
||||
#+name: generate-modules
|
||||
#+begin_src emacs-lisp :tangle no :cache yes :var modules=emacs-modules :exports none
|
||||
(mapconcat (lambda (line)
|
||||
(concat "\"" (string-trim (car line) "=" "=") "\""))
|
||||
modules
|
||||
" ")
|
||||
#+end_src
|
||||
|
||||
#+RESULTS[f76449860408293997e174ff94c743d46951835b]: generate-modules
|
||||
: "basic-config.el" "custom-elisp.el" "package-manager.el" "keybinding-managemers.el" "applications.el" "autocompletion.el" "editing.el" "emacs-builtin.el" "exwm.el" "helpful.el" "latex.el" "misc.el" "org.el" "programming.el" "visual-config.el" "keybindings.el"
|
||||
|
||||
#+begin_src emacs-lisp :noweb yes
|
||||
(dolist (module '(<<generate-modules()>>))
|
||||
(load (expand-file-name module
|
||||
(expand-file-name "lisp" user-emacs-directory))))
|
||||
#+end_src
|
||||
|
||||
* TODOs :noexport:
|
||||
** TODO advise ~evil-insert~ in eshell
|
||||
Advise ~evil-insert~ to go to the end of the buffer while in
|
||||
~eshell-mode~.
|
||||
|
||||
** DONE Get started with org-roam
|
||||
CLOSED: [2023-06-17 Sat 13:38]
|
||||
211
docs/emacs/keybinding-managers.org
Normal file
@@ -0,0 +1,211 @@
|
||||
#+title: Emacs — Keybinding Managers
|
||||
#+setupfile: ../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/keybinding-managemers.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
* Keybinding Managers
|
||||
** Which-key
|
||||
Which key is, I think, one of my favorite quality of life package.
|
||||
When you begin a keybind, Emacs will show you all keybinds you can
|
||||
follow the first one with in order to form a full keychord. Very
|
||||
useful when you have a lot of keybinds and don’t remember exactly what
|
||||
is what.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package which-key
|
||||
:straight (:build t)
|
||||
:defer t
|
||||
:init (which-key-mode)
|
||||
:diminish which-key-mode
|
||||
:config
|
||||
(setq which-key-idle-delay 1))
|
||||
#+end_src
|
||||
|
||||
** General
|
||||
General is an awesome package for managing keybindings. Not only is it
|
||||
oriented towards keychords by default (which I love), but it also
|
||||
provides some integration with evil so that we can declare keybindings
|
||||
for certain states only! This is a perfect replacement for ~define-key~,
|
||||
~evil-define-key~, and any other function for defining keychords. And it
|
||||
is also possible to declare a prefix for my keybindings! By default,
|
||||
all keybinds will be prefixed with ~SPC~ and keybinds related to a
|
||||
specific mode (often major modes) will be prefixed by a comma ~,~ (and
|
||||
by ~C-SPC~ and ~M-m~ respectively when in ~insert-mode~ or ~emacs-mode~). You
|
||||
can still feel some influence from my Spacemacs years here.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package general
|
||||
:straight (:build t)
|
||||
:init
|
||||
(general-auto-unbind-keys)
|
||||
:config
|
||||
(general-create-definer phundrak/undefine
|
||||
:keymaps 'override
|
||||
:states '(normal emacs))
|
||||
(general-create-definer phundrak/evil
|
||||
:states '(normal))
|
||||
(general-create-definer phundrak/leader-key
|
||||
:states '(normal insert visual emacs)
|
||||
:keymaps 'override
|
||||
:prefix "SPC"
|
||||
:global-prefix "C-SPC")
|
||||
(general-create-definer phundrak/major-leader-key
|
||||
:states '(normal insert visual emacs)
|
||||
:keymaps 'override
|
||||
:prefix ","
|
||||
:global-prefix "M-m"))
|
||||
#+end_src
|
||||
|
||||
** Evil
|
||||
Evil emulates most of vim’s keybinds, because let’s be honest here,
|
||||
they are much more comfortable than Emacs’.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package evil
|
||||
:straight (:build t)
|
||||
:after (general)
|
||||
:init
|
||||
(setq evil-want-integration t
|
||||
evil-want-keybinding nil
|
||||
evil-want-C-u-scroll t
|
||||
evil-want-C-i-jump nil)
|
||||
(require 'evil-vars)
|
||||
(evil-set-undo-system 'undo-tree)
|
||||
:config
|
||||
<<evil-undefine-keys>>
|
||||
<<evil-bepo>>
|
||||
(evil-mode 1)
|
||||
(setq evil-want-fine-undo t) ; more granular undo with evil
|
||||
(evil-set-initial-state 'messages-buffer-mode 'normal)
|
||||
(evil-set-initial-state 'dashboard-mode 'normal))
|
||||
#+end_src
|
||||
|
||||
I want to undefine some default keybinds of Evil because it does not
|
||||
match my workflow. Namely, I use the space key and the comma as
|
||||
leaders for my keybinds, and I’m way too used to Emacs’ ~C-t~, ~C-a~, ~C-e~,
|
||||
and ~C-y~.
|
||||
#+name: evil-undefine-keys
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(evil-global-set-key 'motion "t" 'evil-next-visual-line)
|
||||
(evil-global-set-key 'motion "s" 'evil-previous-visual-line)
|
||||
|
||||
(general-define-key
|
||||
:keymaps 'evil-motion-state-map
|
||||
"SPC" nil
|
||||
"," nil)
|
||||
(general-define-key
|
||||
:keymaps 'evil-insert-state-map
|
||||
"C-t" nil)
|
||||
(general-define-key
|
||||
:keymaps 'evil-insert-state-map
|
||||
"U" nil
|
||||
"C-a" nil
|
||||
"C-y" nil
|
||||
"C-e" nil)
|
||||
#+end_src
|
||||
|
||||
Something else that really bugs me is I use the bépo layout, which is
|
||||
not at all like the qwerty layout. For instance, ~hjkl~ becomes ~ctsr~.
|
||||
Thus, I need some bépo-specific changes.
|
||||
#+name: evil-bepo
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(dolist (key '("c" "C" "t" "T" "s" "S" "r" "R" "h" "H" "j" "J" "k" "K" "l" "L"))
|
||||
(general-define-key :states 'normal key nil))
|
||||
|
||||
(general-define-key
|
||||
:states 'motion
|
||||
"h" 'evil-replace
|
||||
"H" 'evil-replace-state
|
||||
"j" 'evil-find-char-to
|
||||
"J" 'evil-find-char-to-backward
|
||||
"k" 'evil-substitute
|
||||
"K" 'evil-smart-doc-lookup
|
||||
"l" 'evil-change
|
||||
"L" 'evil-change-line
|
||||
|
||||
"c" 'evil-backward-char
|
||||
"C" 'evil-window-top
|
||||
"t" 'evil-next-visual-line
|
||||
"T" 'evil-join
|
||||
"s" 'evil-previous-visual-line
|
||||
"S" 'evil-lookup
|
||||
"r" 'evil-forward-char
|
||||
"R" 'evil-window-bottom)
|
||||
#+end_src
|
||||
|
||||
This package enables and integrates Evil into a lot of different
|
||||
modes, such as org-mode, dired, mu4e, etc. Again, I need some
|
||||
additional code compared to most people due to the bépo layout.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package evil-collection
|
||||
:after evil
|
||||
:straight (:build t)
|
||||
:config
|
||||
;; bépo conversion
|
||||
(defun my/bépo-rotate-evil-collection (_mode mode-keymaps &rest _rest)
|
||||
(evil-collection-translate-key 'normal mode-keymaps
|
||||
;; bépo ctsr is qwerty hjkl
|
||||
"c" "h"
|
||||
"t" "j"
|
||||
"s" "k"
|
||||
"r" "l"
|
||||
;; add back ctsr
|
||||
"h" "c"
|
||||
"j" "t"
|
||||
"k" "s"
|
||||
"l" "r"))
|
||||
(add-hook 'evil-collection-setup-hook #'my/bépo-rotate-evil-collection)
|
||||
(evil-collection-init))
|
||||
#+end_src
|
||||
|
||||
~undo-tree~ is my preferred way of undoing and redoing stuff. The main
|
||||
reason is it doesn’t create a linear undo/redo history, but rather a
|
||||
complete tree you can navigate to see your complete editing history.
|
||||
One of the two obvious things to do are to tell Emacs to save all its
|
||||
undo history fies in a dedicated directory, otherwise we’d risk
|
||||
littering all of our directories. The second thing is to simply
|
||||
globally enable its mode.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package undo-tree
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:custom
|
||||
(undo-tree-history-directory-alist
|
||||
`(("." . ,(expand-file-name (file-name-as-directory "undo-tree-hist")
|
||||
user-emacs-directory))))
|
||||
:init
|
||||
(global-undo-tree-mode)
|
||||
:config
|
||||
<<undo-tree-ignore-text-properties>>
|
||||
<<undo-tree-compress-files>>
|
||||
(setq undo-tree-visualizer-diff t
|
||||
undo-tree-visualizer-timestamps t
|
||||
undo-tree-auto-save-history t
|
||||
undo-tree-enable-undo-in-region t
|
||||
undo-limit (* 800 1024)
|
||||
undo-strong-limit (* 12 1024 1024)
|
||||
undo-outer-limit (* 128 1024 1024)))
|
||||
#+end_src
|
||||
|
||||
An interesting behavior from DoomEmacs is to compress the history
|
||||
files with ~zstd~ when it is present on the system. Not only do we enjoy
|
||||
much smaller files (according to DoomEmacs, we get something like 80%
|
||||
file savings), Emacs can load them much faster than the regular files.
|
||||
Sure, it uses more CPU time uncompressing these files, but it’s
|
||||
insignificant, and it’s still faster than loading a heavier file.
|
||||
#+name: undo-tree-compress-files
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(when (executable-find "zstd")
|
||||
(defun my/undo-tree-append-zst-to-filename (filename)
|
||||
"Append .zst to the FILENAME in order to compress it."
|
||||
(concat filename ".zst"))
|
||||
(advice-add 'undo-tree-make-history-save-file-name
|
||||
:filter-return
|
||||
#'my/undo-tree-append-zst-to-filename))
|
||||
#+end_src
|
||||
|
||||
** Hydra
|
||||
[[https://github.com/abo-abo/hydra][Hydra]] is a simple menu creator for keybindings.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package hydra
|
||||
:straight (:build t)
|
||||
:defer t)
|
||||
#+end_src
|
||||
391
docs/emacs/keybindings.org
Normal file
@@ -0,0 +1,391 @@
|
||||
#+title: Emacs — Keybindings
|
||||
#+setupfile: ../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/keybindings.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
* Keybindings
|
||||
Undefining some stuff to make keybind prefixes work correctly.
|
||||
|
||||
#+name: general-keybindings-gen
|
||||
#+header: :tangle no :exports none :results value :cache yes
|
||||
#+begin_src emacs-lisp :var table=keybinds-windows prefix=""
|
||||
(mapconcat (lambda (line)
|
||||
(let* ((key (nth 0 line))
|
||||
(function (nth 1 line))
|
||||
(comment (or (nth 2 line) ""))
|
||||
(package (or (nth 3 line) "")))
|
||||
(format "\"%s%s\" %s"
|
||||
prefix
|
||||
key
|
||||
(if (string= "" comment)
|
||||
(if (member function '("" "nil")) "nil" (concat "#'" function))
|
||||
(format "'(%s :wk %s%s)"
|
||||
(if (member function '("" "nil")) ":ignore t" function)
|
||||
(if (member function '("none" "nil")) "t" (concat "\"" comment "\""))
|
||||
(if (string-blank-p package) "" (concat ":package " package)))))))
|
||||
table
|
||||
"\n")
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(general-define-key
|
||||
:keymaps 'global-map
|
||||
"<mouse-2>" nil
|
||||
"<mouse-3>" nil)
|
||||
|
||||
(phundrak/evil
|
||||
:packages '(counsel)
|
||||
"U" #'evil-redo
|
||||
"C-a" #'beginning-of-line
|
||||
"C-e" #'end-of-line
|
||||
"C-y" #'yank
|
||||
"M-y" #'counsel-yank-pop)
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(general-define-key
|
||||
"<f5>" #'compile
|
||||
"<f6>" #'recompile)
|
||||
|
||||
(phundrak/leader-key
|
||||
"SPC" '(counsel-M-x :wk "M-x")
|
||||
"'" #'shell-pop
|
||||
|
||||
<<general-keybindings-gen(table=keybinds-tabs, prefix="TAB ")>>
|
||||
|
||||
<<general-keybindings-gen(table=keybinds-apps, prefix="a")>>
|
||||
<<general-keybindings-gen(table=keybinds-apps-shell, prefix="as")>>
|
||||
<<general-keybindings-gen(table=treemacs-keybinds, prefix="at")>>
|
||||
|
||||
<<general-keybindings-gen(table=keybinds-buffers, prefix="b")>>
|
||||
|
||||
"c" '(:ignore t :wk "code")
|
||||
"cl" #'evilnc-comment-or-uncomment-lines
|
||||
|
||||
<<keybindings-flycheck>>
|
||||
|
||||
<<general-keybindings-gen(table=keybinds-files, prefix="f")>>
|
||||
<<keybinds-specific-files>>
|
||||
|
||||
<<general-keybindings-gen(table=keybinds-help, prefix="h")>>
|
||||
|
||||
"i" '(:ignore t :wk "insert")
|
||||
"iu" #'counsel-unicode-char
|
||||
|
||||
<<general-keybindings-gen(table=keybinds-jump, prefix="j")>>
|
||||
|
||||
<<general-keybindings-gen(table=keybinds-toggle, prefix="t ")>>
|
||||
|
||||
<<general-keybindings-gen(table=keybinds-text, prefix="T")>>
|
||||
|
||||
<<general-keybindings-gen(table=keybinds-windows, prefix="w")>>
|
||||
|
||||
<<general-keybindings-gen(table=keybinds-quit, prefix="q")>>
|
||||
|
||||
"u" #'universal-argument
|
||||
"U" #'undo-tree-visualize)
|
||||
#+end_src
|
||||
|
||||
** Apps
|
||||
Here are my apps keybinds. Each one of them is prefixed by ~a~.
|
||||
#+name: keybinds-apps
|
||||
| Key | Function | Description | Package |
|
||||
|-----+----------------------------+-------------+------------|
|
||||
| | | apps | |
|
||||
| c | calc | | |
|
||||
| C | | calendar | |
|
||||
| CC | calendar | | |
|
||||
| Co | org-agenda | | org |
|
||||
| Cs | org-caldav-sync | | org-caldav |
|
||||
| d | docker | | |
|
||||
| E | elfeed | | |
|
||||
| e | | email | |
|
||||
| ec | mu4e-compose-new | | |
|
||||
| em | mu4e | | |
|
||||
| k | keycast-mode | | |
|
||||
| K | keycast-log-mode | | |
|
||||
| m | | mastodon | |
|
||||
| mm | mastodon | | mastodon |
|
||||
| mn | mastodon-notifications-get | | mastodon |
|
||||
| mt | mastodon-toot | | mastodon |
|
||||
| T | tetris | | |
|
||||
| w | wttrin | | wttrin |
|
||||
|
||||
I also have two main shell-related functions, prefixed with ~as~.
|
||||
#+name: keybinds-apps-shell
|
||||
| Key | Function | Description | Package |
|
||||
|-----+-------------+-------------+-------------|
|
||||
| | | shells | |
|
||||
| e | eshell-new | | |
|
||||
| v | vterm | | vterm |
|
||||
| V | multi-vterm | | multi-vterm |
|
||||
|
||||
** Buffers
|
||||
My buffer-related keybinds are all prefixed by ~b~.
|
||||
#+name: keybinds-buffers
|
||||
| Key | Function | Description |
|
||||
|-----+------------------------------------+-------------|
|
||||
| | | buffers |
|
||||
| b | bufler-switch-buffer | |
|
||||
| B | bury-buffer | |
|
||||
| c | clone-indirect-buffer | |
|
||||
| C | clone-indirect-buffer-other-window | |
|
||||
| l | bufler | |
|
||||
| d | kill-this-buffer | |
|
||||
| D | kill-buffer | |
|
||||
| h | dashboard-refresh-buffer | |
|
||||
| m | switch-to-messages-buffer | |
|
||||
| n | next-buffer | |
|
||||
| p | previous-buffer | |
|
||||
| r | counsel-buffer-or-recentf | |
|
||||
| s | switch-to-scratch-buffer | |
|
||||
|
||||
** Errors
|
||||
#+begin_src emacs-lisp
|
||||
(defhydra hydra-flycheck
|
||||
(:pre (flycheck-list-errors)
|
||||
:post (quit-windows-on "*Flycheck errors*")
|
||||
:hint nil)
|
||||
("f" flycheck-error-list-set-filter "Filter")
|
||||
("t" flycheck-next-error "Next")
|
||||
("s" flycheck-previous-error "Previous")
|
||||
("gg" flycheck-first-error "First")
|
||||
("G" (progn (goto-char (point-max)) (flycheck-previous-error)) "Last")
|
||||
("q" nil))
|
||||
#+end_src
|
||||
|
||||
#+name: keybindings-flycheck
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
"e" '(:ignore t :which-key "errors")
|
||||
"e." '(hydra-flycheck/body :wk "hydra")
|
||||
"el" #'counsel-flycheck
|
||||
"ee" '(:keymap flycheck-command-map :package 'flycheck :wk "flycheck")
|
||||
"ef" '(:keymap flyspell-mode-map :package 'flyspell :wk "flyspell")
|
||||
"eF" #'flyspell-hydra/body
|
||||
#+end_src
|
||||
|
||||
** Files
|
||||
My keybinds for file manipulation are prefixed by ~f~.
|
||||
#+name: keybinds-files
|
||||
| Key | Function | Description |
|
||||
|-----+----------------------+-------------|
|
||||
| | | files |
|
||||
| f | counsel-find-file | |
|
||||
| F | ivy-quick-find-files | |
|
||||
| h | hexl-find-file | |
|
||||
| r | counsel-recentf | |
|
||||
| s | save-buffer | |
|
||||
|
||||
I also have some keybinds dedicated to opening specific files.
|
||||
#+name: keybinds-specific-files
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
"fc" '((lambda ()
|
||||
(interactive)
|
||||
(find-file "~/org/config/emacs.org"))
|
||||
:wk "emacs.org")
|
||||
"fi" '((lambda ()
|
||||
(interactive)
|
||||
(find-file (concat user-emacs-directory "init.el")))
|
||||
:which-key "init.el")
|
||||
"fR" '((lambda ()
|
||||
(interactive)
|
||||
(counsel-find-file ""
|
||||
(concat user-emacs-directory
|
||||
(file-name-as-directory "straight")
|
||||
(file-name-as-directory "repos"))))
|
||||
:which-key "straight package")
|
||||
"fS" '((lambda ()
|
||||
(interactive)
|
||||
(find-file "~/org/config/stumpwm.org"))
|
||||
:which-key "stumpwm.org")
|
||||
#+end_src
|
||||
|
||||
** Help
|
||||
My keybinds for help are prefixed by ~h~.
|
||||
#+name: keybinds-help
|
||||
| Key | Function | Description |
|
||||
|-----+--------------------------+-------------|
|
||||
| | | help |
|
||||
| k | which-key-show-top-level | |
|
||||
| i | info | |
|
||||
| I | info-display-manual | |
|
||||
| d | | describe |
|
||||
| dc | describe-char | |
|
||||
| dC | helpful-command | |
|
||||
| df | helpful-callable | |
|
||||
| di | describe-input-method | |
|
||||
| dk | helpful-key | |
|
||||
| dm | helpful-macro | |
|
||||
| dM | helpful-mode | |
|
||||
| dp | describe-package | |
|
||||
| ds | helpful-symbol | |
|
||||
| dv | helpful-variable | |
|
||||
|
||||
** Jump
|
||||
My keybinds for jumping around are prefixed by ~j~.
|
||||
#+name: keybinds-jump
|
||||
| Key | Function | Description |
|
||||
|-----+-------------------------+-------------|
|
||||
| | | jump |
|
||||
| f | counsel-file-jump | |
|
||||
| d | dirvish-dwim | |
|
||||
| D | dired-jump-other-window | |
|
||||
|
||||
** Project
|
||||
My keybinds for my projects are prefixed by ~p~.
|
||||
#+name: keybinds-project
|
||||
| Key | Function | Description |
|
||||
|-----+--------------------------------------------+-------------|
|
||||
| | | project |
|
||||
| ! | projectile-run-shell-command-in-root | |
|
||||
| & | projectile-run-async-shell-command-in-root | |
|
||||
| b | counsel-projectile-switch-to-buffer | |
|
||||
| c | counsel-projectile | |
|
||||
| d | counsel-projectile-find-dir | |
|
||||
| e | projectile-edit-dir-locals | |
|
||||
| f | counsel-projectile-find-file | |
|
||||
| g | projectile-find-tag | |
|
||||
| k | project-kill-buffers | |
|
||||
| p | counsel-projectile-switch-project | |
|
||||
| t | ivy-magit-todos | |
|
||||
| v | projectile-vc | |
|
||||
|
||||
*** Treemacs
|
||||
|
||||
#+name: treemacs-keybinds
|
||||
| Key | Function | Description |
|
||||
|-----+----------------------------------------+-------------|
|
||||
| | | treemacs |
|
||||
| c | | create |
|
||||
| cd | treemacs-create-dir | |
|
||||
| cf | treemacs-create-file | |
|
||||
| ci | treemacs-create-icon | |
|
||||
| ct | treemacs-create-theme | |
|
||||
| cw | treemacs-create-workspace | |
|
||||
| d | treemacs-delete-file | |
|
||||
| f | | files |
|
||||
| ff | treemacs-find-file | |
|
||||
| ft | treemacs-find-tag | |
|
||||
| l | | lsp |
|
||||
| ls | treemacs-expand-lsp-symbol | |
|
||||
| ld | treemacs-expand-lsp-treemacs-deps | |
|
||||
| lD | treemacs-collapse-lsp-treemacs-deps | |
|
||||
| lS | treemacs-collapse-lsp-symbol | |
|
||||
| p | | projects |
|
||||
| pa | treemacs-add-project-to-workspace | |
|
||||
| pf | treemacs-project-follow-mode | |
|
||||
| pn | treemacs-project-of-node | |
|
||||
| pp | treemacs-project-at-point | |
|
||||
| pr | treemacs-remove-project-from-workspace | |
|
||||
| pt | treemacs-move-project-down | |
|
||||
| ps | treemacs-move-project-up | |
|
||||
| r | | rename |
|
||||
| rf | treemacs-rename-file | |
|
||||
| rp | treemacs-rename-project | |
|
||||
| rr | treemacs-rename | |
|
||||
| rw | treemacs-rename-workspace | |
|
||||
| t | treemacs | |
|
||||
| T | | toggles |
|
||||
| Td | treemacs-toggle-show-dotfiles | |
|
||||
| Tn | treemacs-toggle-node | |
|
||||
| v | | visit node |
|
||||
| va | treemacs-visit-node-ace | |
|
||||
| vc | treemacs-visit-node-close-treemacs | |
|
||||
| vn | treemacs-visit-node-default | |
|
||||
| y | | yank |
|
||||
| ya | treemacs-copy-absolute-path-at-point | |
|
||||
| yp | treemacs-copy-project-path-at-point | |
|
||||
| yr | treemacs-copy-relative-path-at-point | |
|
||||
| yf | treemacs-copy-file | |
|
||||
|
||||
** Tabs
|
||||
Emacs has native tabs available, which can be interesting when working
|
||||
on multiple projects at once between which we may want to switch. Tabs
|
||||
allow the user not to have multiple frames while keeping the
|
||||
advantages of having multiple frames.
|
||||
|
||||
My keybinds are prefixed by ~SPC TAB~.
|
||||
#+name: keybinds-tabs
|
||||
| Key | Function | Description |
|
||||
|-----+--------------+-------------|
|
||||
| | | tabs |
|
||||
| TAB | tab-switch | |
|
||||
| » | tab-next | |
|
||||
| « | tab-previous | |
|
||||
| c | tab-new | |
|
||||
| C | tab-new-to | |
|
||||
| d | tab-close | |
|
||||
| n | tab-next | |
|
||||
| p | tab-previous | |
|
||||
| r | tab-rename | |
|
||||
|
||||
** Text
|
||||
The prefix here is ~T~.
|
||||
#+name: keybinds-text
|
||||
| Key | Function | Description |
|
||||
|-----+----------------------+-------------|
|
||||
| | | text |
|
||||
| e | string-edit-at-point | |
|
||||
| u | downcase-region | |
|
||||
| U | upcase-region | |
|
||||
| z | hydra-zoom/body | |
|
||||
|
||||
** Toggles
|
||||
My toggle keybinds are prefixed by ~t~.
|
||||
#+name: keybinds-toggle
|
||||
| Key | Function | Description |
|
||||
|-----+---------------------------------------+--------------|
|
||||
| | | toggles |
|
||||
| TAB | tab-bar-mode | |
|
||||
| t | my/modify-frame-alpha-background/body | |
|
||||
| T | counsel-load-theme | |
|
||||
| d | | debug |
|
||||
| de | toggle-debug-on-error | |
|
||||
| dq | toggle-debug-on-quit | |
|
||||
| i | | input method |
|
||||
| it | toggle-input-method | |
|
||||
| is | set-input-method | |
|
||||
|
||||
** Windows
|
||||
A couple of keybinds are hidden from which-key, otherwise there’s not
|
||||
much to say. The prefix here is ~w~.
|
||||
#+name: keybinds-windows
|
||||
| Key | Function | Description |
|
||||
|-----+-------------------------------+-------------|
|
||||
| | | windows |
|
||||
| c | evil-window-left | |
|
||||
| t | evil-window-down | |
|
||||
| s | evil-window-up | |
|
||||
| r | evil-window-right | |
|
||||
| . | windows-adjust-size/body | |
|
||||
| - | split-window-below-and-focus | |
|
||||
| / | split-window-right-and-focus | |
|
||||
| $ | winum-select-window-by-number | |
|
||||
| 0 | winum-select-window-0-or-10 | none |
|
||||
| 1 | winum-select-window-1 | none |
|
||||
| 2 | winum-select-window-2 | none |
|
||||
| 3 | winum-select-window-3 | none |
|
||||
| 4 | winum-select-window-4 | none |
|
||||
| 5 | winum-select-window-5 | none |
|
||||
| 6 | winum-select-window-6 | none |
|
||||
| 7 | winum-select-window-7 | none |
|
||||
| 8 | winum-select-window-8 | none |
|
||||
| 9 | winum-select-window-9 | none |
|
||||
| b | kill-buffer-and-delete-window | |
|
||||
| d | delete-window | |
|
||||
| o | other-window | |
|
||||
| D | delete-other-windows | |
|
||||
| w | | writeroom |
|
||||
| w. | writeroom-buffer-width/body | |
|
||||
| ww | writeroom-mode | |
|
||||
|
||||
** Quit
|
||||
Why would I ever use any of these keybinds? They are prefixed with ~q~.
|
||||
#+name: keybinds-quit
|
||||
| Key | Function | Description |
|
||||
|-----+----------------------------+-------------|
|
||||
| | | quit |
|
||||
| f | delete-frame | |
|
||||
| q | save-buffers-kill-terminal | |
|
||||
| Q | kill-emacs | |
|
||||
85
docs/emacs/package-manager.org
Normal file
@@ -0,0 +1,85 @@
|
||||
#+title: Emacs — Package Manager
|
||||
#+setupfile: ../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/package-manager.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
* Package Manager
|
||||
** Repositories
|
||||
By default, only GNU’s repositories are available to the package
|
||||
managers of Emacs. I also want to use Melpa and org-mode’s repository,
|
||||
so let’s add them! Note that the stock /elpa/ repository is renamed to
|
||||
/gnu/ due to the addition of another Elpa repository, /nongnu/, which will
|
||||
hosts packages that do not conform to the FSF’s copyright assignment.
|
||||
Both the /gnu/ and the /nonfree/ repositories are Elpa repositories now,
|
||||
and they are renamed here in order to avoid any confusion between the
|
||||
two of them. Melpa is a community-maintained repository which contains
|
||||
an absurd amount of Emacs packages.
|
||||
#+begin_src emacs-lisp
|
||||
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
|
||||
("gnu" . "https://elpa.gnu.org/packages/")
|
||||
("nongnu" . "https://elpa.nongnu.org/nongnu/")))
|
||||
#+end_src
|
||||
|
||||
** Straight
|
||||
For my package management, I prefer to use ~straight~ ([[https://github.com/raxod502/straight.el][GitHub]]). This is
|
||||
due to its capacity of integrating nicely with ~use-package~, which also
|
||||
supports ~general~ which I use for my keybindings (see below), but also
|
||||
because with it, I can specify where to retrieve packages that are not
|
||||
on MELPA or ELPA but on GitHub and other online Git repositories too.
|
||||
First, let’s bootstrap straight.
|
||||
#+begin_src emacs-lisp
|
||||
(defvar bootstrap-version)
|
||||
(defvar comp-deferred-compilation-deny-list ()) ; workaround, otherwise straight shits itself
|
||||
(let ((bootstrap-file
|
||||
(expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
|
||||
(bootstrap-version 5))
|
||||
(unless (file-exists-p bootstrap-file)
|
||||
(with-current-buffer
|
||||
(url-retrieve-synchronously
|
||||
"https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
|
||||
'silent 'inhibit-cookies)
|
||||
(goto-char (point-max))
|
||||
(eval-print-last-sexp)))
|
||||
(load bootstrap-file nil 'nomessage))
|
||||
#+end_src
|
||||
|
||||
Now, we can refresh our package list in order to be able to install
|
||||
stuff.
|
||||
#+begin_src emacs-lisp
|
||||
(package-initialize)
|
||||
(unless package-archive-contents
|
||||
(package-refresh-contents))
|
||||
|
||||
#+end_src
|
||||
|
||||
From time to time, I fork some packages either because I’m trying to
|
||||
implement something new in said package, or because the package is
|
||||
unmaintained, and I want to continue developing it a bit more. Straight
|
||||
provides a nice feature for using forks of a package with its ~:fork~
|
||||
option. If set to ~t~, then straight will attempt to retrieve the
|
||||
package with the same name but with a different username on the same
|
||||
host. This username is retrieved through the following variable:
|
||||
#+begin_src emacs-lisp
|
||||
(setq straight-host-usernames
|
||||
'((github . "Phundrak")
|
||||
(gitlab . "Phundrak")))
|
||||
#+end_src
|
||||
|
||||
The huge advantage of straight is it clones through git the packages
|
||||
it installs. This means development can be done directly on the
|
||||
downloaded package. However, Forge (a Magit extension for interacting
|
||||
with websites such as GitHub, Gitlab, and such) interacts by default
|
||||
with the forge described by the =origin= remote, which isn’t necessarily
|
||||
the one I want Forge to interact with by default. Therefore,
|
||||
=straight.el= will name all default remotes =straight= to avoid any name
|
||||
collision with my regular development flow.
|
||||
#+begin_src emacs-lisp
|
||||
(setq straight-vc-git-default-remote-name "straight")
|
||||
#+end_src
|
||||
|
||||
We finally come to the ~use-package~ installation. This is done like so:
|
||||
#+begin_src emacs-lisp
|
||||
(straight-use-package '(use-package :build t))
|
||||
(setq use-package-always-ensure t)
|
||||
#+end_src
|
||||
1703
docs/emacs/packages/applications.org
Normal file
310
docs/emacs/packages/autocompletion.org
Normal file
@@ -0,0 +1,310 @@
|
||||
#+title: Emacs — Packages — Autocompletion
|
||||
#+setupfile: ../../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/autocompletion.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
* Autocompletion
|
||||
** Code Autocompletion
|
||||
Company is, in my opinion, the best autocompleting engine for Emacs,
|
||||
and it is one of the most popular if not /the/ most popular.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package company
|
||||
:straight (:build t)
|
||||
:defer t
|
||||
:hook (company-mode . evil-normalize-keymaps)
|
||||
:init (global-company-mode)
|
||||
:config
|
||||
(setq company-minimum-prefix-length 2
|
||||
company-toolsip-limit 14
|
||||
company-tooltip-align-annotations t
|
||||
company-require-match 'never
|
||||
company-global-modes '(not erc-mode message-mode help-mode gud-mode)
|
||||
company-frontends
|
||||
'(company-pseudo-tooltip-frontend ; always show candidates in overlay tooltip
|
||||
company-echo-metadata-frontend) ; show selected candidate docs in echo area
|
||||
company-backends '(company-capf)
|
||||
company-auto-commit nil
|
||||
company-auto-complete-chars nil
|
||||
company-dabbrev-other-buffers nil
|
||||
company-dabbrev-ignore-case nil
|
||||
company-dabbrev-downcase nil))
|
||||
#+end_src
|
||||
|
||||
This package is a backend for company. It emulates
|
||||
~ac-source-dictionary~ by proposing text related to the current
|
||||
major-mode.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package company-dict
|
||||
:after company
|
||||
:straight (:build t)
|
||||
:config
|
||||
(setq company-dict-dir (expand-file-name "dicts" user-emacs-directory)))
|
||||
#+end_src
|
||||
|
||||
On the other hand, ~company-box~ is a Company front-end which offers
|
||||
colors, icons, documentation and so on. Very nice.
|
||||
|
||||
Declaring all the icons for the variable
|
||||
~company-box-icons-all-the-icons~ is quite verbose in Elisp, so I do it
|
||||
with an org-table.
|
||||
#+name: company-box-icons
|
||||
| Type | Icon | Color |
|
||||
|---------------+--------------------------+--------|
|
||||
| Unknown | find_in_page | purple |
|
||||
| Text | text_fields | green |
|
||||
| Method | functions | red |
|
||||
| Function | functions | red |
|
||||
| Constructor | functions | red |
|
||||
| Field | functions | red |
|
||||
| Variable | adjust | blue |
|
||||
| Class | class | red |
|
||||
| Interface | settings_input_component | red |
|
||||
| Module | view_module | red |
|
||||
| Property | settings | red |
|
||||
| Unit | straighten | red |
|
||||
| Value | filter_1 | red |
|
||||
| Enum | plus_one | red |
|
||||
| Keyword | filter_center_focus | red |
|
||||
| Snippet | short_text | red |
|
||||
| Color | color_lens | red |
|
||||
| File | insert_drive_file | red |
|
||||
| Reference | collections_bookmark | red |
|
||||
| Folder | folder | red |
|
||||
| EnumMember | people | red |
|
||||
| Constant | pause_circle_filled | red |
|
||||
| Struct | streetview | red |
|
||||
| Event | event | red |
|
||||
| Operator | control_point | red |
|
||||
| TypeParameter | class | red |
|
||||
| Template | short_text | green |
|
||||
| ElispFunction | functions | red |
|
||||
| ElispVariable | check_circle | blue |
|
||||
| ElispFeature | stars | orange |
|
||||
| ElispFace | format_paint | pink |
|
||||
|
||||
#+name: gen-company-box-icons
|
||||
#+headers: :tangle no :noweb yes :exports none :cache yes
|
||||
#+header: :wrap "src emacs-lisp :exports none :tangle no"
|
||||
#+begin_src emacs-lisp :var table=company-box-icons
|
||||
(mapconcat (lambda (row)
|
||||
(format "(%s . ,(all-the-icons-material \"%s\" :face 'all-the-icons-%s))"
|
||||
(car row)
|
||||
(cadr row)
|
||||
(caddr row)))
|
||||
table
|
||||
"\n")
|
||||
#+end_src
|
||||
|
||||
#+RESULTS[8ebf4bb3f7f354571a5d42cf58f8b9ba847ba028]: gen-company-box-icons
|
||||
#+begin_src emacs-lisp :exports none :tangle no
|
||||
(Unknown . ,(all-the-icons-material "find_in_page" :face 'all-the-icons-purple))
|
||||
(Text . ,(all-the-icons-material "text_fields" :face 'all-the-icons-green))
|
||||
(Method . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
||||
(Function . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
||||
(Constructor . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
||||
(Field . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
||||
(Variable . ,(all-the-icons-material "adjust" :face 'all-the-icons-blue))
|
||||
(Class . ,(all-the-icons-material "class" :face 'all-the-icons-red))
|
||||
(Interface . ,(all-the-icons-material "settings_input_component" :face 'all-the-icons-red))
|
||||
(Module . ,(all-the-icons-material "view_module" :face 'all-the-icons-red))
|
||||
(Property . ,(all-the-icons-material "settings" :face 'all-the-icons-red))
|
||||
(Unit . ,(all-the-icons-material "straighten" :face 'all-the-icons-red))
|
||||
(Value . ,(all-the-icons-material "filter_1" :face 'all-the-icons-red))
|
||||
(Enum . ,(all-the-icons-material "plus_one" :face 'all-the-icons-red))
|
||||
(Keyword . ,(all-the-icons-material "filter_center_focus" :face 'all-the-icons-red))
|
||||
(Snippet . ,(all-the-icons-material "short_text" :face 'all-the-icons-red))
|
||||
(Color . ,(all-the-icons-material "color_lens" :face 'all-the-icons-red))
|
||||
(File . ,(all-the-icons-material "insert_drive_file" :face 'all-the-icons-red))
|
||||
(Reference . ,(all-the-icons-material "collections_bookmark" :face 'all-the-icons-red))
|
||||
(Folder . ,(all-the-icons-material "folder" :face 'all-the-icons-red))
|
||||
(EnumMember . ,(all-the-icons-material "people" :face 'all-the-icons-red))
|
||||
(Constant . ,(all-the-icons-material "pause_circle_filled" :face 'all-the-icons-red))
|
||||
(Struct . ,(all-the-icons-material "streetview" :face 'all-the-icons-red))
|
||||
(Event . ,(all-the-icons-material "event" :face 'all-the-icons-red))
|
||||
(Operator . ,(all-the-icons-material "control_point" :face 'all-the-icons-red))
|
||||
(TypeParameter . ,(all-the-icons-material "class" :face 'all-the-icons-red))
|
||||
(Template . ,(all-the-icons-material "short_text" :face 'all-the-icons-green))
|
||||
(ElispFunction . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
||||
(ElispVariable . ,(all-the-icons-material "check_circle" :face 'all-the-icons-blue))
|
||||
(ElispFeature . ,(all-the-icons-material "stars" :face 'all-the-icons-orange))
|
||||
(ElispFace . ,(all-the-icons-material "format_paint" :face 'all-the-icons-pink))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package company-box
|
||||
:straight (:build t)
|
||||
:after (company all-the-icons)
|
||||
:config
|
||||
(setq company-box-show-single-candidate t
|
||||
company-box-backends-colors nil
|
||||
company-box-max-candidates 50
|
||||
company-box-icons-alist 'company-box-icons-all-the-icons
|
||||
company-box-icons-all-the-icons
|
||||
(let ((all-the-icons-scale-factor 0.8))
|
||||
`(
|
||||
<<gen-company-box-icons()>>))))
|
||||
#+end_src
|
||||
|
||||
** Ivy
|
||||
My main menu package is =ivy= which I use as much as possible –I’ve
|
||||
noticed =helm= can be slow, very slow in comparison to =ivy=, so I’ll use
|
||||
the latter as much as possible. Actually, only =ivy= is installed for
|
||||
now. I could have used =ido= too, but I find it to be a bit too
|
||||
restricted in terms of features compared to =ivy=.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ivy
|
||||
:straight t
|
||||
:defer t
|
||||
:diminish
|
||||
:bind (("C-s" . swiper)
|
||||
:map ivy-minibuffer-map
|
||||
("TAB" . ivy-alt-done)
|
||||
("C-l" . ivy-alt-done)
|
||||
("C-t" . ivy-next-line)
|
||||
("C-s" . ivy-previous-line)
|
||||
("C-u" . ivy-scroll-up-command)
|
||||
("C-d" . ivy-scroll-down-command)
|
||||
:map ivy-switch-buffer-map
|
||||
("C-t" . ivy-next-line)
|
||||
("C-s" . ivy-previous-line)
|
||||
("C-l" . ivy-done)
|
||||
("C-d" . ivy-switch-buffer-kill)
|
||||
:map ivy-reverse-i-search-map
|
||||
("C-t" . ivy-next-line)
|
||||
("C-s" . ivy-previous-line)
|
||||
("C-d" . ivy-reverse-i-search-kill))
|
||||
:config
|
||||
(ivy-mode 1)
|
||||
(setq ivy-wrap t
|
||||
ivy-height 17
|
||||
ivy-sort-max-size 50000
|
||||
ivy-fixed-height-minibuffer t
|
||||
ivy-read-action-functions #'ivy-hydra-read-action
|
||||
ivy-read-action-format-function #'ivy-read-action-format-columns
|
||||
projectile-completion-system 'ivy
|
||||
ivy-on-del-error-function #'ignore
|
||||
ivy-use-selectable-prompt t))
|
||||
#+end_src
|
||||
|
||||
There is also [[https://github.com/raxod502/prescient.el][~prescient.el~]] that offers some nice features when
|
||||
coupled with ~ivy~, guess what was born out of it? ~ivy-prescient~, of
|
||||
course!
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ivy-prescient
|
||||
:after ivy
|
||||
:straight (:build t))
|
||||
#+end_src
|
||||
|
||||
I warned you I’d use too much ~all-the-icons~, I did!
|
||||
#+begin_src emacs-lisp
|
||||
(use-package all-the-icons-ivy
|
||||
:straight (:build t)
|
||||
:after (ivy all-the-icons)
|
||||
:init (all-the-icons-ivy-setup)
|
||||
:hook (after-init . all-the-icons-ivy-setup))
|
||||
(all-the-icons-ivy-setup)
|
||||
#+end_src
|
||||
|
||||
A buffer popping at the bottom of the screen is nice and all, but have
|
||||
you considered a floating buffer in the center of your frame?
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ivy-posframe
|
||||
:defer t
|
||||
:after (:any ivy helpful)
|
||||
:hook (ivy-mode . ivy-posframe-mode)
|
||||
:straight (:build t)
|
||||
:init
|
||||
(ivy-posframe-mode 1)
|
||||
:config
|
||||
(setq ivy-fixed-height-minibuffer nil
|
||||
ivy-posframe-border-width 10
|
||||
ivy-posframe-parameters
|
||||
`((min-width . 90)
|
||||
(min-height . ,ivy-height))))
|
||||
#+end_src
|
||||
|
||||
Something that can be missing sometimes in Ivy is the ability to
|
||||
select multiple entries at once. For instance, when programming in
|
||||
Java, LPS can offer you to automatically generate the methods ~equals~
|
||||
and ~hashCode~ based on selected members, but with vanilla Ivy, you can
|
||||
only select one. Not really useful. ~ivy-hydra~ is a package that offers
|
||||
a Hydra interface when in Ivy which allows you to select multiple
|
||||
choices among other things.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ivy-hydra
|
||||
:requires (ivy hydra)
|
||||
:after ivy
|
||||
:straight (:build t))
|
||||
#+end_src
|
||||
|
||||
Finally, let’s make ~ivy~ richer:
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ivy-rich
|
||||
:straight (:build t)
|
||||
:after ivy
|
||||
:init
|
||||
(ivy-rich-mode 1))
|
||||
#+end_src
|
||||
|
||||
** Counsel
|
||||
I could almost merge this chapter with the previous one since counsel
|
||||
is a package that provides loads of completion functions for ivy. The
|
||||
ones I find most useful are ~counsel-M-x~ and ~counsel-find-file~.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package counsel
|
||||
:straight t
|
||||
:after recentf
|
||||
:after ivy
|
||||
:bind (("M-x" . counsel-M-x)
|
||||
("C-x b" . counsel-ibuffer)
|
||||
("C-x C-f" . counsel-find-file)
|
||||
:map minibuffer-local-map
|
||||
("C-r" . 'counsel-minibuffer-history)))
|
||||
#+end_src
|
||||
|
||||
** Yasnippet
|
||||
Yasnippet allows you to insert some pre-made code by just typing a few
|
||||
characters. It can even generate some string with Elisp expressions
|
||||
and ask the user for some input in some precise places.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package yasnippet
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:init
|
||||
(yas-global-mode)
|
||||
:hook ((prog-mode . yas-minor-mode)
|
||||
(text-mode . yas-minor-mode)))
|
||||
#+end_src
|
||||
|
||||
Of course, yasnippet wouldn’t be as awesome as it is without pre-made
|
||||
snippets.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package yasnippet-snippets
|
||||
:defer t
|
||||
:after yasnippet
|
||||
:straight (:build t))
|
||||
#+end_src
|
||||
|
||||
Similarly, yatemplate offers pre-made files rather than just strings.
|
||||
That’s still yasnippet by the way.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package yatemplate
|
||||
:defer t
|
||||
:after yasnippet
|
||||
:straight (:build t))
|
||||
#+end_src
|
||||
|
||||
And finally, with ivy you can choose your snippets from a menu if
|
||||
you’re not sure or if you don’t remember what your snippet is.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ivy-yasnippet
|
||||
:defer t
|
||||
:after (ivy yasnippet)
|
||||
:straight (:build t)
|
||||
:general
|
||||
(phundrak/leader-key
|
||||
:infix "i"
|
||||
:packages 'ivy-yasnippet
|
||||
"y" #'ivy-yasnippet))
|
||||
#+end_src
|
||||
174
docs/emacs/packages/editing.org
Normal file
@@ -0,0 +1,174 @@
|
||||
#+title: Emacs — Packages — Editing
|
||||
#+setupfile: ../../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/editing.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
|
||||
* Editing
|
||||
First, I’ll define some keybindings for easily inserting pairs when
|
||||
editing text.
|
||||
#+begin_src emacs-lisp
|
||||
(general-define-key
|
||||
:states 'visual
|
||||
"M-[" #'insert-pair
|
||||
"M-{" #'insert-pair
|
||||
"M-<" #'insert-pair
|
||||
"M-'" #'insert-pair
|
||||
"M-`" #'insert-pair
|
||||
"M-\"" #'insert-pair)
|
||||
#+end_src
|
||||
|
||||
** Atomic Chrome
|
||||
Why write in your browser when you could write with Emacs? Despite its
|
||||
name, this package isn’t only geared towards Chrome/Chromium-based
|
||||
browsers but also towards Firefox since its 2.0 version. I find it a
|
||||
bit unfortunate Chrome’s name stuck in the package’s name though.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package atomic-chrome
|
||||
:straight (:build t)
|
||||
:init
|
||||
(atomic-chrome-start-server)
|
||||
:config
|
||||
(setq atomic-chrome-default-major-mode 'markdown-mode
|
||||
atomic-chrome-url-major-mode-alist `(("github\\.com" . gfm-mode)
|
||||
("gitlab\\.com" . gfm-mode)
|
||||
("labs\\.phundrak\\.com" . markdown-mode)
|
||||
("reddit\\.com" . markdown-mode))))
|
||||
#+end_src
|
||||
|
||||
** Editorconfig
|
||||
Editorconfig is a unified way of passing to your text editor settings
|
||||
everyone working in a repo need to follow. ~.editorconfig~ files work
|
||||
for VSCode users, vim users, Atom users, Sublime users, and of course
|
||||
Emacs users.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package editorconfig
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:diminish editorconfig-mode
|
||||
:init
|
||||
(editorconfig-mode t))
|
||||
#+end_src
|
||||
|
||||
** Evil Nerd Commenter
|
||||
Emacs’ default commenting system is nice, but I don’t find it smart
|
||||
enough for me.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package evil-nerd-commenter
|
||||
:after evil
|
||||
:straight (:build t))
|
||||
#+end_src
|
||||
|
||||
** Iedit
|
||||
Iedit is a powerful text editing tool that can be used to refactor
|
||||
code through the edition of multiple regions at once, be it in a
|
||||
region or in a whole buffer. Since I’m using evil, I’ll also use a
|
||||
compatibility package that adds states for iedit.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package evil-iedit-state
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:commands (evil-iedit-state evil-iedit-state/iedit-mode)
|
||||
:init
|
||||
(setq iedit-curent-symbol-default t
|
||||
iedit-only-at-symbol-boundaries t
|
||||
iedit-toggle-key-default nil)
|
||||
:general
|
||||
(phundrak/leader-key
|
||||
:infix "r"
|
||||
:packages '(iedit evil-iedit-state)
|
||||
"" '(:ignore t :which-key "refactor")
|
||||
"i" #'evil-iedit-state/iedit-mode)
|
||||
(general-define-key
|
||||
:keymaps 'evil-iedit-state-map
|
||||
"c" nil
|
||||
"s" nil
|
||||
"J" nil
|
||||
"S" #'iedit-expand-down-a-line
|
||||
"T" #'iedit-expand-up-a-line
|
||||
"h" #'evil-iedit-state/evil-change
|
||||
"k" #'evil-iedit-state/evil-substitute
|
||||
"K" #'evil-iedit-state/substitute
|
||||
"q" #'evil-iedit-state/quit-iedit-mode))
|
||||
#+end_src
|
||||
|
||||
** Smartparens
|
||||
#+begin_src emacs-lisp
|
||||
(use-package smartparens
|
||||
:straight (:build t)
|
||||
:defer t)
|
||||
#+end_src
|
||||
|
||||
** Parinfer
|
||||
Don’t let the name of the package fool you! ~parinfer-rust-mode~ is not
|
||||
a ~parinfer~ mode for ~rust-mode~, but a mode for ~parinfer-rust~. ~parinfer~
|
||||
was a project for handling parenthesis and other double markers in a
|
||||
much more intuitive way when writing Lisp code. However, it is now out
|
||||
of date (last commit was on January 2nd, 2019) and the repository has
|
||||
since been archived. New implementations then appeared, one of them is
|
||||
[[https://github.com/eraserhd/parinfer-rust][~parinfer-rust~]], obviously written in Rust, around which
|
||||
~parinfer-rust-mode~ is built. Enabling ~parinfer-rust-mode~ should also
|
||||
automatically disable ~smartparens-mode~ in order to avoid conflicting
|
||||
behavior.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package parinfer-rust-mode
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:diminish parinfer-rust-mode
|
||||
:hook emacs-lisp-mode common-lisp-mode scheme-mode
|
||||
:init
|
||||
(setq parinfer-rust-auto-download t
|
||||
parinfer-rust-library-directory (concat user-emacs-directory
|
||||
"parinfer-rust/"))
|
||||
(add-hook 'parinfer-rust-mode-hook
|
||||
(lambda () (smartparens-mode -1)))
|
||||
:general
|
||||
(phundrak/major-leader-key
|
||||
:keymaps 'parinfer-rust-mode-map
|
||||
"m" #'parinfer-rust-switch-mode
|
||||
"M" #'parinfer-rust-toggle-disable))
|
||||
#+end_src
|
||||
|
||||
** Smartparens
|
||||
~smartparens~ is a package similar to ~parinfer~, but while the latter is
|
||||
more specialized for Lisp dialects, ~smartparens~ works better with
|
||||
other programming languages that still uses parenthesis, but not as
|
||||
much as Lisp dialects; think for example C, C++, Rust, Javascript, and
|
||||
so on.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package smartparens
|
||||
:defer t
|
||||
:straight (smartparens :build t
|
||||
:type git
|
||||
:host github
|
||||
:repo "Fuco1/smartparens")
|
||||
:hook (prog-mode . smartparens-mode))
|
||||
#+end_src
|
||||
|
||||
** ~string-edit~
|
||||
~string-edit~ is a cool package that allows the user to write naturally
|
||||
a string and get it automatically escaped for you. No more manually
|
||||
escaping your strings!
|
||||
#+begin_src emacs-lisp
|
||||
(use-package string-edit-at-point
|
||||
:defer t
|
||||
:straight (:build t))
|
||||
#+end_src
|
||||
|
||||
** Writeroom
|
||||
On the other hand, ~writeroom~ allows the user to enter a
|
||||
distraction-free mode of Emacs, and I like that! But the default width
|
||||
is a bit too small for me, and I prefer not to go fullscren.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package writeroom-mode
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:init (global-writeroom-mode 1)
|
||||
:config
|
||||
(setq writeroom-width 100
|
||||
writeroom-fullscreen-effect nil
|
||||
writeroom-maximize-window nil
|
||||
writeroom-mode-line t
|
||||
writeroom-major-modes '(text-mode org-mode markdown-mode nov-mode Info-mode)))
|
||||
#+end_src
|
||||
496
docs/emacs/packages/emacs-builtin.org
Normal file
@@ -0,0 +1,496 @@
|
||||
#+title: Emacs — Packages — Emacs Built-ins
|
||||
#+setupfile: ../../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/emacs-builtin.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
|
||||
* Emacs built-ins
|
||||
** Dired
|
||||
Dired is Emacs’ built-in file manager. It’s really great, and replaces
|
||||
any graphical file manager for me most of the time because:
|
||||
- I am not limited to /x/ tabs or panes
|
||||
- All actions can be done with keybindings
|
||||
- I get a consistent behavior between Dired and Emacs, since it’s the
|
||||
same thing.
|
||||
I used to have an extensive configuration for Dired with a couple of
|
||||
additional packages to make it more usable. Dirvish rendered that
|
||||
obsolete!
|
||||
#+begin_src emacs-lisp
|
||||
(use-package dirvish
|
||||
:straight (:build t)
|
||||
:defer t
|
||||
:init (dirvish-override-dired-mode)
|
||||
:custom
|
||||
(dirvish-quick-access-entries
|
||||
'(("h" "~/" "Home")
|
||||
("d" "~/Downloads/" "Downloads")
|
||||
("c" "~/org/config" "Config")
|
||||
("C" "~/Documents/conlanging/content" "Conlanging")))
|
||||
(dirvish-mode-line-format
|
||||
'(:left (sort file-time "" file-size symlink) :right (omit yank index)))
|
||||
(dirvish-attributes '(all-the-icons file-size collapse subtree-state vc-state git-msg))
|
||||
:config
|
||||
(dirvish-peek-mode)
|
||||
<<dired-drag-and-drop>>
|
||||
<<dired-listing-flags>>
|
||||
<<dired-files-and-dirs>>
|
||||
<<dirvish-exa-offload>>
|
||||
(setq dired-dwim-target t
|
||||
dired-recursive-copies 'always
|
||||
dired-recursive-deletes 'top
|
||||
delete-by-moving-to-trash t
|
||||
dirvish-preview-dispatchers (cl-substitute 'pdf-preface 'pdf dirvish-preview-dispatchers))
|
||||
:general
|
||||
(phundrak/evil
|
||||
:keymaps 'dirvish-mode-map
|
||||
:packages '(dired dirvish)
|
||||
"q" #'dirvish-quit
|
||||
"TAB" #'dirvish-subtree-toggle)
|
||||
(phundrak/major-leader-key
|
||||
:keymaps 'dirvish-mode-map
|
||||
:packages '(dired dirvish)
|
||||
"A" #'gnus-dired-attach
|
||||
"a" #'dirvish-quick-access
|
||||
"d" #'dirvish-dispatch
|
||||
"e" #'dirvish-emerge-menu
|
||||
"f" #'dirvish-fd-jump
|
||||
"F" #'dirvish-file-info-menu
|
||||
"h" '(:ignore t :which-key "history")
|
||||
"hp" #'dirvish-history-go-backward
|
||||
"hn" #'dirvish-history-go-forward
|
||||
"hj" #'dirvish-history-jump
|
||||
"hl" #'dirvish-history-last
|
||||
"l" '(:ignore t :which-key "layout")
|
||||
"ls" #'dirvish-layout-switch
|
||||
"lt" #'dirvish-layout-toggle
|
||||
"m" #'dirvish-mark-menu
|
||||
"s" #'dirvish-quicksort
|
||||
"S" #'dirvish-setup-menu
|
||||
"y" #'dirvish-yank-menu
|
||||
"n" #'dirvish-narrow))
|
||||
#+end_src
|
||||
|
||||
It requires some programs which can be installed like so:
|
||||
#+begin_src sh :dir /sudo::~/ :exports code :tangle no :results verbatim
|
||||
pacman -S --needed --noprogressbar --noconfirm --color=never \
|
||||
fd poppler ffmpegthumbnailer mediainfo imagemagick tar unzip
|
||||
#+end_src
|
||||
|
||||
Since Emacs 29, it is possible to enable drag-and-drop between Emacs
|
||||
and other applications.
|
||||
#+name: dired-drag-and-drop
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(csetq dired-mouse-drag-files t
|
||||
mouse-drag-and-drop-region-cross-program t)
|
||||
#+end_src
|
||||
|
||||
In Dirvish, it’s best to use the long name of flags whenever possible,
|
||||
otherwise some commands won’t work.
|
||||
#+name: dired-listing-flags
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(csetq dired-listing-switches (string-join '("--all"
|
||||
"--human-readable"
|
||||
"--time-style=long-iso"
|
||||
"--group-directories-first"
|
||||
"-lv1")
|
||||
" "))
|
||||
#+end_src
|
||||
|
||||
However, it is possible to instead use ~exa~ when it is available.
|
||||
Instead of making Emacs’ main thread to the file listing in a
|
||||
directory, we offload it to an external thread.
|
||||
#+name: dirvish-exa-offload
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(dirvish-define-preview exa (file)
|
||||
"Use `exa' to generate directory preview."
|
||||
:require ("exa")
|
||||
(when (file-directory-p file)
|
||||
`(shell . ("exa" "--color=always" "-al" ,file))))
|
||||
|
||||
(add-to-list 'dirvish-preview-dispatchers 'exa)
|
||||
#+end_src
|
||||
|
||||
Finally, some directories need to be set for Dired to store various
|
||||
files and images.
|
||||
#+name: dired-files-and-dirs
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(let ((my/file (lambda (path &optional dir)
|
||||
(expand-file-name path (or dir user-emacs-directory))))
|
||||
(my/dir (lambda (path &optional dir)
|
||||
(expand-file-name (file-name-as-directory path)
|
||||
(or dir user-emacs-directory)))))
|
||||
(csetq image-dired-thumb-size 150
|
||||
image-dired-dir (funcall my/dir "dired-img")
|
||||
image-dired-db-file (funcall my/file "dired-db.el")
|
||||
image-dired-gallery-dir (funcall my/dir "gallery")
|
||||
image-dired-temp-image-file (funcall my/file "temp-image" image-dired-dir)
|
||||
image-dired-temp-rotate-image-file (funcall my/file "temp-rotate-image" image-dired-dir)))
|
||||
#+end_src
|
||||
|
||||
Copying files with Dired is a blocking process. It’s usually fine when
|
||||
there’s not a lot to copy, but it becomes annoying when moving larger
|
||||
files. The package ~dired-rsync~ allows copying files with ~rsync~ in the
|
||||
background; we can then carry on with our tasks while the copy is
|
||||
happening.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package dired-rsync
|
||||
:if (executable-find "rsync")
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:general
|
||||
(phundrak/evil
|
||||
:keymaps 'dired-mode-map
|
||||
:packages 'dired-rsync
|
||||
"C-r" #'dired-rsync))
|
||||
#+end_src
|
||||
|
||||
** Compilation mode
|
||||
After reading about a blog article, I found out it is possible to run
|
||||
quite a few things through ~compilation-mode~, so why not? First, let’s
|
||||
redefine some keybinds for this mode. I’ll also define a general
|
||||
keybind in order to re-run my programs from other buffers than the
|
||||
~compilation-mode~ buffer. I also want to follow the output of the
|
||||
compilation buffer, as well as enable some syntax highlighting.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package compile
|
||||
:defer t
|
||||
:straight (compile :type built-in)
|
||||
:hook (compilation-filter . colorize-compilation-buffer)
|
||||
:init
|
||||
(require 'ansi-color)
|
||||
(defun colorize-compilation-buffer ()
|
||||
(let ((inhibit-read-only t))
|
||||
(ansi-color-apply-on-region (point-min) (point-max))))
|
||||
:general
|
||||
(phundrak/evil
|
||||
:keymaps 'compilation-mode-map
|
||||
"g" nil
|
||||
"r" nil
|
||||
"R" #'recompile
|
||||
"h" nil)
|
||||
(phundrak/leader-key
|
||||
"R" #'recompile)
|
||||
:config
|
||||
(setq compilation-scroll-output t))
|
||||
#+end_src
|
||||
|
||||
** Eshell
|
||||
[[file:../img/emacs-eshell.svg]]
|
||||
|
||||
Eshell is a built-in shell available from Emacs which I use almost as
|
||||
often as fish. Some adjustments are necessary to make it fit my taste
|
||||
though.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package eshell
|
||||
:defer t
|
||||
:straight (:type built-in :build t)
|
||||
:config
|
||||
(setq eshell-prompt-function
|
||||
(lambda ()
|
||||
(concat (abbreviate-file-name (eshell/pwd))
|
||||
(if (= (user-uid) 0) " # " " λ ")))
|
||||
eshell-prompt-regexp "^[^#λ\n]* [#λ] ")
|
||||
<<eshell-alias-file>>
|
||||
<<eshell-concat-shell-command>>
|
||||
<<eshell-alias-open>>
|
||||
<<eshell-alias-clear>>
|
||||
<<eshell-alias-buffers>>
|
||||
<<eshell-alias-emacs>>
|
||||
<<eshell-alias-mkcd>>
|
||||
:general
|
||||
(phundrak/evil
|
||||
:keymaps 'eshell-mode-map
|
||||
[remap evil-collection-eshell-evil-change] #'evil-backward-char
|
||||
"c" #'evil-backward-char
|
||||
"t" #'evil-next-visual-line
|
||||
"s" #'evil-previous-visual-line
|
||||
"r" #'evil-forward-char
|
||||
"h" #'evil-collection-eshell-evil-change)
|
||||
(general-define-key
|
||||
:keymaps 'eshell-mode-map
|
||||
:states 'insert
|
||||
"C-a" #'eshell-bol
|
||||
"C-e" #'end-of-line))
|
||||
#+end_src
|
||||
|
||||
*** Aliases
|
||||
First, let’s declare our list of “dumb” aliases we’ll use in
|
||||
Eshell. You can find them here.
|
||||
#+name: eshell-alias-file
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(setq eshell-aliases-file (expand-file-name "eshell-alias" user-emacs-directory))
|
||||
#+end_src
|
||||
|
||||
A couple of other aliases will be defined through custom Elisp
|
||||
functions, but first I’ll need a function for concatenating a shell
|
||||
command into a single string:
|
||||
#+name: eshell-concat-shell-command
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(defun phundrak/concatenate-shell-command (&rest command)
|
||||
"Concatenate an eshell COMMAND into a single string.
|
||||
All elements of COMMAND will be joined in a single
|
||||
space-separated string."
|
||||
(mapconcat #'identity command " "))
|
||||
#+end_src
|
||||
|
||||
I’ll also declare some aliases here, such as ~open~ and ~openo~ that
|
||||
respectively allow me to open a file in Emacs, and same but in another
|
||||
window.
|
||||
#+name: eshell-alias-open
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(defalias 'open #'find-file)
|
||||
(defalias 'openo #'find-file-other-window)
|
||||
#+end_src
|
||||
|
||||
The default behavior of ~eshell/clear~ is not great at all, although it
|
||||
clears the screen it also scrolls all the way down. Therefore, let’s
|
||||
alias it to ~eshell/clear-scrollback~ which has the correct behavior.
|
||||
#+name: eshell-alias-clear
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(defalias 'eshell/clear #'eshell/clear-scrollback)
|
||||
#+end_src
|
||||
|
||||
As you see, these were not declared in my dedicated aliases file but
|
||||
rather were declared programmatically. This is because I like to keep
|
||||
my aliases file for stuff that could work too with other shells were
|
||||
the syntax a bit different, and aliases related to Elisp are kept
|
||||
programmatically. I’ll also declare ~list-buffers~ an alias of ~ibuffer~
|
||||
because naming it that way kind of makes more sense to me.
|
||||
#+name: eshell-alias-buffers
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(defalias 'list-buffers 'ibuffer)
|
||||
#+end_src
|
||||
|
||||
I still have some stupid muscle memory telling me to open ~emacs~, ~vim~
|
||||
or ~nano~ in Eshell, which is stupid: I’m already inside Emacs and I
|
||||
have all its power available instantly. So, let’s open each file
|
||||
passed to these commands.
|
||||
#+name: eshell-alias-emacs
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(defun eshell/emacs (&rest file)
|
||||
"Open each FILE and kill eshell.
|
||||
Old habits die hard."
|
||||
(when file
|
||||
(dolist (f (reverse file))
|
||||
(find-file f t))))
|
||||
#+end_src
|
||||
|
||||
Finally, I’ll declare ~mkcd~ which allows the simultaneous creation of a
|
||||
directory and moving into this newly created directory. And of course,
|
||||
it will also work if the directory also exists or if parent
|
||||
directories don’t, similarly to the ~-p~ option passed to ~mkdir~.
|
||||
#+name: eshell-alias-mkcd
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(defun eshell/mkcd (dir)
|
||||
"Create the directory DIR and move there.
|
||||
If the directory DIR doesn’t exist, create it and its parents
|
||||
if needed, then move there."
|
||||
(mkdir dir t)
|
||||
(cd dir))
|
||||
#+end_src
|
||||
|
||||
*** Commands
|
||||
When I’m in Eshell, sometimes I wish to open multiple files at once in
|
||||
Emacs. For this, when I have several arguments for ~find-file~, I want
|
||||
to be able to open them all at once. Let’s modify ~find-file~ like so:
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defadvice find-file (around find-files activate)
|
||||
"Also find all files within a list of files. This even works recursively."
|
||||
(if (listp filename)
|
||||
(cl-loop for f in filename do (find-file f wildcards))
|
||||
ad-do-it))
|
||||
#+END_SRC
|
||||
|
||||
I also want to be able to have multiple instances of Eshell opened at
|
||||
once. For that, I declared the function ~eshell-new~ that does exactly
|
||||
that.
|
||||
#+begin_src emacs-lisp
|
||||
(defun eshell-new ()
|
||||
"Open a new instance of eshell."
|
||||
(interactive)
|
||||
(eshell 'N))
|
||||
#+end_src
|
||||
|
||||
A very useful command I often use in fish is ~z~, a port from bash’s and
|
||||
zsh’s command that allows to jump around directories based on how
|
||||
often we go in various directories.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package eshell-z
|
||||
:defer t
|
||||
:after eshell
|
||||
:straight (:build t)
|
||||
:hook (eshell-mode . (lambda () (require 'eshell-z))))
|
||||
#+end_src
|
||||
|
||||
*** Environment Variables
|
||||
Some environment variables need to be correctly set so Eshell can
|
||||
correctly work. I would like to set two environment variables related
|
||||
to Dart development: the ~DART_SDK~ and ~ANDROID_HOME~ variables.
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setenv "DART_SDK" "/opt/dart-sdk/bin")
|
||||
(setenv "ANDROID_HOME" (concat (getenv "HOME") "/Android/Sdk/"))
|
||||
#+END_SRC
|
||||
|
||||
The ~EDITOR~ variable also needs to be set for git commands, especially the
|
||||
~yadm~ commands.
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setenv "EDITOR" "emacsclient -c -a emacs")
|
||||
#+END_SRC
|
||||
|
||||
Finally, for some specific situations I need ~SHELL~ to be set to
|
||||
something more standard than fish:
|
||||
#+begin_src emacs-lisp
|
||||
(setenv "SHELL" "/bin/sh")
|
||||
#+end_src
|
||||
|
||||
*** Visual configuration
|
||||
I like to have at quick glance some information about my machine when
|
||||
I fire up a terminal. I haven’t found anything that does that the way
|
||||
I like it, so [[https://github.com/Phundrak/eshell-info-banner.el][I’ve written a package]]! It’s actually available on
|
||||
MELPA, but since I’m the main dev of this package, I’ll keep track of
|
||||
the git repository.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package eshell-info-banner
|
||||
:after (eshell)
|
||||
:defer t
|
||||
:straight (eshell-info-banner :build t
|
||||
:type git
|
||||
:host github
|
||||
:protocol ssh
|
||||
:repo "phundrak/eshell-info-banner.el")
|
||||
:hook (eshell-banner-load . eshell-info-banner-update-banner)
|
||||
:custom-face
|
||||
(eshell-info-banner-normal-face ((t :foreground "#A3BE8C")))
|
||||
(eshell-info-banner-background-face ((t :foreground "#E5E9F0")))
|
||||
(eshell-info-banner-warning-face ((t :foreround "#D08770")))
|
||||
(eshell-info-banner-critical-face ((t :foreground "#BF616A")))
|
||||
:custom
|
||||
(eshell-info-banner-partition-prefixes (list "/dev" "zroot" "tank")))
|
||||
#+end_src
|
||||
|
||||
Another feature I like is fish-like syntax highlight, which brings
|
||||
some more colors to Eshell.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package eshell-syntax-highlighting
|
||||
:after (esh-mode eshell)
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:config
|
||||
(eshell-syntax-highlighting-global-mode +1))
|
||||
#+end_src
|
||||
|
||||
Powerline prompts are nice, git-aware prompts are even better!
|
||||
~eshell-git-prompt~ is nice, but I prefer to write my own package for
|
||||
that.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package powerline-eshell
|
||||
:if (string= (string-trim (shell-command-to-string "uname -n")) "leon")
|
||||
:load-path "~/fromGIT/emacs-packages/powerline-eshell.el/"
|
||||
:after eshell)
|
||||
#+end_src
|
||||
|
||||
** Eww
|
||||
Since Emacs 29, it is possible to automatically rename ~eww~ buffers to
|
||||
a more human-readable name, see [[https://protesilaos.com/codelog/2021-10-15-emacs-29-eww-rename-buffers/][Prot’s blog]] post on the matter.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package eww
|
||||
:defer t
|
||||
:straight (:type built-in)
|
||||
:config
|
||||
(setq eww-auto-rename-buffer 'title))
|
||||
#+end_src
|
||||
|
||||
** Image-mode
|
||||
I won’t modify much for ~image-mode~ (the mode used to display images)
|
||||
aside from Emacs’ ability to use external converters to display some
|
||||
images it wouldn’t be able to handle otherwise.
|
||||
#+begin_src emacs-lisp
|
||||
(setq image-use-external-converter t)
|
||||
#+end_src
|
||||
|
||||
** Info
|
||||
Let’s define some more intuitive keybinds for ~info-mode~.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package info
|
||||
:defer t
|
||||
:straight (info :type built-in :build t)
|
||||
:general
|
||||
(phundrak/evil
|
||||
:keymaps 'Info-mode-map
|
||||
"c" #'Info-prev
|
||||
"t" #'evil-scroll-down
|
||||
"s" #'evil-scroll-up
|
||||
"r" #'Info-next)
|
||||
(phundrak/major-leader-key
|
||||
:keymaps 'Info-mode-map
|
||||
"?" #'Info-toc
|
||||
"b" #'Info-history-back
|
||||
"f" #'Info-history-forward
|
||||
"m" #'Info-menu
|
||||
"t" #'Info-top-node
|
||||
"u" #'Info-up))
|
||||
#+end_src
|
||||
|
||||
** Tab Bar
|
||||
#+begin_src emacs-lisp
|
||||
(use-package tab-bar
|
||||
:defer t
|
||||
:straight (:type built-in)
|
||||
:custom
|
||||
(tab-bar-close-button-show nil)
|
||||
(tab-bar-new-button-show nil)
|
||||
(tab-bar-new-tab-choice "*dashboard*")
|
||||
:custom-face
|
||||
(tab-bar ((t (:background "#272C36"
|
||||
:foreground "#272C36"
|
||||
:box (:line-width (8 . 5) :style flat-button)))))
|
||||
:init
|
||||
(advice-add #'tab-new
|
||||
:after
|
||||
(lambda (&rest _) (when (y-or-n-p "Rename tab? ")
|
||||
(call-interactively #'tab-rename)))))
|
||||
#+end_src
|
||||
|
||||
** Tramp
|
||||
Tramp is an Emacs built-in package that allows the user to connect to
|
||||
various hosts using various protocols, such as ~ssh~ and
|
||||
~rsync~. However, I have some use-case for Tramp which are not
|
||||
supported natively. I will describe them here.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package tramp
|
||||
:straight (tramp :type built-in :build t)
|
||||
:config
|
||||
<<tramp-add-yadm>>
|
||||
(csetq tramp-ssh-controlmaster-options nil
|
||||
tramp-verbose 0
|
||||
tramp-auto-save-directory (locate-user-emacs-file "tramp/")
|
||||
tramp-chunksize 2000)
|
||||
(add-to-list 'backup-directory-alist ; deactivate auto-save with TRAMP
|
||||
(cons tramp-file-name-regexp nil)))
|
||||
#+end_src
|
||||
|
||||
*** Yadm
|
||||
[[https://yadm.io/][~yadm~]] is a git wrapper made to easily manage your dotfiles. It has
|
||||
loads of features I don’t use (the main one I like but don’t use is
|
||||
its [[https://yadm.io/docs/templates][Jinja-like host and OS-aware syntax]]), but unfortunately Magit
|
||||
doesn’t play nice with it. Tramp to the rescue, and this page explains
|
||||
how! Let’s just insert in my config this code snippet:
|
||||
#+name: tramp-add-yadm
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(add-to-list 'tramp-methods
|
||||
'("yadm"
|
||||
(tramp-login-program "yadm")
|
||||
(tramp-login-args (("enter")))
|
||||
(tramp-login-env (("SHELL") ("/bin/sh")))
|
||||
(tramp-remote-shell "/bin/sh")
|
||||
(tramp-remote-shell-args ("-c"))))
|
||||
#+end_src
|
||||
|
||||
I’ll also create a fuction for connecting to this new Tramp protocol:
|
||||
#+begin_src emacs-lisp
|
||||
(defun my/yadm ()
|
||||
"Manage my dotfiles through TRAMP."
|
||||
(interactive)
|
||||
(magit-status "/yadm::"))
|
||||
#+end_src
|
||||
401
docs/emacs/packages/exwm.org
Normal file
@@ -0,0 +1,401 @@
|
||||
#+title: Emacs — Packages — EXWM
|
||||
#+setupfile: ../../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/exwm.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
* EXWM
|
||||
So, I’m finally slowly getting back to EXWM. I tried it a couple of
|
||||
years ago, but that was with the SpacemacsOS layer on Spacemacs, on a
|
||||
laptop which got accidentaly formatted before I could save my config
|
||||
and all… So it got me some time to come back. I’m still a bit worried
|
||||
about Emacs being single threaded, so if I get one blocking function
|
||||
blocking Emacs, my whole desktop will hang, but for now I haven’t had
|
||||
this issue.
|
||||
|
||||
All my EXWM config is enabled only if I launch Emacs with the argument
|
||||
~--with-exwm~, otherwise none of the related packages get installed, let
|
||||
alone activated and made available.
|
||||
|
||||
First, I need to install the /X protocol Emacs Lisp Bindings/. It
|
||||
doesn’t seem to be available in any repo, so I’ll install it directly
|
||||
from Git.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package xelb
|
||||
:if (seq-contains-p command-line-args "--with-exwm")
|
||||
:straight (xelb :build t
|
||||
:type git
|
||||
:host github
|
||||
:repo "emacs-straight/xelb"
|
||||
:fork "ch11ng/xelb"))
|
||||
#+end_src
|
||||
|
||||
Next is a function I’ve +stolen+ copied from Daviwil’s [[https://config.daviwil.com/desktop][desktop
|
||||
configuration]]. This allows to launch software in the background
|
||||
easily.
|
||||
#+begin_src emacs-lisp
|
||||
(defun exwm/run-in-background (command &optional once)
|
||||
(let ((command-parts (split-string command " +")))
|
||||
(apply #'call-process `(,(car command-parts) nil 0 nil ,@(cdr command-parts)))))
|
||||
#+end_src
|
||||
|
||||
In order to launch Emacs with EXWM with ~startx~, I need a ~xinit~ file.
|
||||
This one is exported to ~$HOME/.xinitrc.emacs~.
|
||||
#+begin_src sh :tangle ~/.xinitrc.emacs :shebang "#!/bin/sh"
|
||||
xhost +SI:localuser:$USER
|
||||
|
||||
# Set fallback cursor
|
||||
xsetroot -cursor_name left_ptr
|
||||
|
||||
# If Emacs is started in server mode, `emacsclient` is a convenient
|
||||
# way to edit files in place (used by e.g. `git commit`)
|
||||
export VISUAL=emacsclient
|
||||
export EDITOR="$VISUAL"
|
||||
|
||||
# in case Java applications display /nothing/
|
||||
# wmname LG3D
|
||||
# export _JAVA_AWT_WM_NONREPARENTING=1
|
||||
|
||||
autorandr -l home
|
||||
|
||||
exec emacs --with-exwm
|
||||
#+end_src
|
||||
|
||||
** EXWM itself
|
||||
Now we come to the plat de résistance. Like with ~xelb~, I’m using its
|
||||
Git source to install it to make sure I get the right version --- the
|
||||
version available on the GNU ELPA is from the same source, true, but I
|
||||
don’t know at which rate it is updated. And more packages down the
|
||||
line will depend on this Git repository, so I might as well just clone
|
||||
it right now.
|
||||
|
||||
As you can see, I added in the ~:config~ secion to two hooks functions
|
||||
that rename buffers accurately. While the average X window will simply
|
||||
get the name of the current X window, I want Firefox and Qutebrowser
|
||||
to be prefixed with the name of the browser. Actually, all these will
|
||||
be renamed this way:
|
||||
#+name: exwm-renamed-buffers-list
|
||||
- Kitty
|
||||
- Qutebrowser
|
||||
|
||||
#+name: exwm-gen-buffers-rename
|
||||
#+header: :exports none :tangle no
|
||||
#+begin_src emacs-lisp :var buffers=exwm-renamed-buffers-list :cache yes
|
||||
(format "%s\n%S"
|
||||
(mapconcat (lambda (buffer)
|
||||
(let ((buffer-name (if (stringp buffer)
|
||||
buffer
|
||||
(car buffer))))
|
||||
(format "(\"%s\" %S)"
|
||||
(downcase buffer-name)
|
||||
`(exwm-workspace-rename-buffer
|
||||
(concat ,(concat "EXWM: " buffer-name " - ")
|
||||
exwm-title)))))
|
||||
buffers
|
||||
"\n")
|
||||
'(_otherwise (exwm-workspace-rename-buffer exwm-title)))
|
||||
#+end_src
|
||||
|
||||
#+RESULTS[64fdbf1e8957b82aad801ec57f2155a0a8f5be54]: exwm-gen-buffers-rename
|
||||
: ("kitty" (exwm-workspace-rename-buffer (concat "EXWM: Kitty - " exwm-title)))
|
||||
: ("qutebrowser" (exwm-workspace-rename-buffer (concat "EXWM: Qutebrowser - " exwm-title)))
|
||||
: (_otherwise (exwm-workspace-rename-buffer exwm-title))
|
||||
|
||||
#+name: exwm-buffers-name
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(add-hook 'exwm-update-class-hook
|
||||
(lambda () (exwm-workspace-rename-buffer exwm-class-name)))
|
||||
|
||||
(add-hook 'exwm-update-title-hook
|
||||
(lambda ()
|
||||
(pcase exwm-class-name
|
||||
<<exwm-gen-buffers-rename()>>)))
|
||||
#+end_src
|
||||
|
||||
As you can see below, in the ~:config~ section I added two advices and
|
||||
one hook in order to correctly integrate evil with EXWM. When I’m in
|
||||
an X window, I want to be in insert-mode in order to type however I
|
||||
want. However, when I exit one, I want to default back to normal-mode.
|
||||
#+name: exwm-advices-evil
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(add-hook 'exwm-manage-finish-hook (lambda () (call-interactively #'exwm-input-release-keyboard)))
|
||||
(advice-add #'exwm-input-grab-keyboard :after (lambda (&optional id) (evil-normal-state)))
|
||||
(advice-add #'exwm-input-release-keyboard :after (lambda (&optional id) (evil-insert-state)))
|
||||
#+end_src
|
||||
|
||||
Secondly, I add ~i~, ~C-SPC~, and ~M-m~ as exwm prefix keys so they aren’t
|
||||
sent directly to the X windows but caught by Emacs (and EXWM). I’ll
|
||||
use the ~i~ key in normal-mode to enter ~insert-mode~ and have Emacs
|
||||
release the keyboard so the X window can grab it. Initially, I had
|
||||
~s-<escape>~ as a keybind for grabbing back the keyboard from an X
|
||||
window, as if I were in insert mode and wanted to go back to normal
|
||||
mode, and I had ~s-I~ to toggle keyboard grabbing. But I found myself
|
||||
more than once trying to use ~s-<escape>~ to toggle this state, ~s-I~
|
||||
completely forgotten. So I removed ~s-I~ and made ~s-<escape>~ behave like
|
||||
~s-I~ once did.
|
||||
#+name: exwm-prefix-keys
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(general-define-key
|
||||
:keymaps 'exwm-mode-map
|
||||
:states 'normal
|
||||
"i" #'exwm-input-release-keyboard)
|
||||
|
||||
(exwm-input-set-key (kbd "s-<escape>") #'exwm-input-toggle-keyboard)
|
||||
|
||||
(push ?\i exwm-input-prefix-keys)
|
||||
(push (kbd "C-SPC") exwm-input-prefix-keys)
|
||||
(push (kbd "M-m") exwm-input-prefix-keys)
|
||||
#+end_src
|
||||
|
||||
As stated a couple of times in my different configuration files, I’m
|
||||
using the bépo layout, which means the default keys in the number row
|
||||
are laid as follows:
|
||||
#+name: exwm-bepo-number-row
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(defconst exwm-workspace-keys '("\"" "«" "»" "(" ")" "@" "+" "-" "/" "*"))
|
||||
#+end_src
|
||||
|
||||
With this, we can create keybinds for going or sending X windows to
|
||||
workspaces 0 to 9.
|
||||
#+name: exwm-workspace-keybinds
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(setq exwm-input-global-keys
|
||||
`(,@exwm-input-global-keys
|
||||
,@(mapcar (lambda (i)
|
||||
`(,(kbd (format "s-%s" (nth i exwm-workspace-keys))) .
|
||||
(lambda ()
|
||||
(interactive)
|
||||
(exwm-workspace-switch-create ,i))))
|
||||
(number-sequence 0 9))
|
||||
,@(mapcar (lambda (i)
|
||||
`(,(kbd (format "s-%d" i)) .
|
||||
(lambda ()
|
||||
(interactive)
|
||||
(exwm-workspace-move-window ,(let ((index (1- i)))
|
||||
(if (< index 0)
|
||||
(- 10 index)
|
||||
;; FIXME: does not work with s-0
|
||||
index))))))
|
||||
(number-sequence 0 9))))
|
||||
#+end_src
|
||||
|
||||
You can then see the list of the keybinds I have set for EXWM, which
|
||||
are all prefixed with ~SPC x~ in normal mode (and ~C-SPC x~ in insert
|
||||
mode), except for ~s-RET~ which opens an eshell terminal.
|
||||
#+name: exwm-keybinds
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(exwm-input-set-key (kbd "s-<return>") (lambda ()
|
||||
(interactive)
|
||||
(eshell)))
|
||||
|
||||
(phundrak/leader-key
|
||||
:infix "x"
|
||||
"" '(:ignore t :which-key "EXWM")
|
||||
"d" #'exwm-debug
|
||||
"k" #'exwm-input-send-next-key
|
||||
"l" '((lambda ()
|
||||
(interactive)
|
||||
(start-process "" nil "plock"))
|
||||
:which-key "lock")
|
||||
"r" '(:ignore t :wk "rofi")
|
||||
"rr" '((lambda () (interactive)
|
||||
(shell-command "rofi -show drun" (current-buffer) (current-buffer)))
|
||||
:wk "drun")
|
||||
"rw" '((lambda () (interactive)
|
||||
(shell-command "rofi -show window" (current-buffer) (current-buffer)))
|
||||
:wk "windows")
|
||||
"R" '(:ignore t :wk "restart")
|
||||
"Rr" #'exwm-reset
|
||||
"RR" #'exwm-restart
|
||||
"t" '(:ignore t :which-key "toggle")
|
||||
"tf" #'exwm-layout-toggle-fullscreen
|
||||
"tF" #'exwm-floating-toggle-floating
|
||||
"tm" #'exwm-layout-toggle-mode-line
|
||||
"w" '(:ignore t :which-key "workspaces")
|
||||
"wa" #'exwm-workspace-add
|
||||
"wd" #'exwm-workspace-delete
|
||||
"ws" #'exwm-workspace-switch
|
||||
"x" '((lambda ()
|
||||
(interactive)
|
||||
(let ((command (string-trim (read-shell-command "RUN: "))))
|
||||
(start-process command nil command)))
|
||||
:which-key "run")
|
||||
"RET" #'eshell-new)
|
||||
#+end_src
|
||||
|
||||
A couple of commands are also automatically executed through my
|
||||
~autostart~ script written [[file:bin.org::#Autostart-a99e99e7][here]].
|
||||
#+name: exwm-autostart
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(exwm/run-in-background "autostart")
|
||||
#+end_src
|
||||
|
||||
Finally, let’s only initialize and start EXWM once functions from
|
||||
exwm-randr ran, because otherwise having multiple monitors don’t work.
|
||||
#+name: exwm-init
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(with-eval-after-load 'exwm-randr
|
||||
(exwm-init))
|
||||
#+end_src
|
||||
|
||||
The complete configuration for the ~exwm~ package can be found below.
|
||||
#+begin_src emacs-lisp :noweb yes
|
||||
(use-package exwm
|
||||
:if (seq-contains-p command-line-args "--with-exwm")
|
||||
:straight (exwm :build t
|
||||
:type git
|
||||
:host github
|
||||
:repo "ch11ng/exwm")
|
||||
:custom
|
||||
(use-dialog-box nil "Disable dialog boxes since they are unusable in EXWM")
|
||||
(exwm-input-line-mode-passthrough t "Pass all keypresses to emacs in line mode.")
|
||||
:init
|
||||
(require 'exwm-config)
|
||||
(setq exwm-workspace-number 6)
|
||||
:config
|
||||
(set-frame-parameter (selected-frame) 'alpha-background 0.7)
|
||||
<<exwm-randr>>
|
||||
|
||||
<<exwm-buffers-name>>
|
||||
|
||||
<<exwm-advices-evil>>
|
||||
<<exwm-prefix-keys>>
|
||||
|
||||
<<exwm-bepo-number-row>>
|
||||
<<exwm-workspace-keybinds>>
|
||||
|
||||
<<exwm-keybinds>>
|
||||
|
||||
<<exwm-autostart>>
|
||||
|
||||
<<exwm-init>>)
|
||||
#+end_src
|
||||
|
||||
** EXWM-Evil integration
|
||||
#+begin_src emacs-lisp
|
||||
(use-package evil-exwm-state
|
||||
:if (seq-contains-p command-line-args "--with-exwm")
|
||||
:defer t
|
||||
:after exwm
|
||||
:straight (evil-exwm-state :build t
|
||||
:type git
|
||||
:host github
|
||||
:repo "domenzain/evil-exwm-state"))
|
||||
#+end_src
|
||||
|
||||
** Multimonitor support
|
||||
#+name: exwm-randr
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(require 'exwm-randr)
|
||||
(exwm/run-in-background "xwallpaper --zoom \"${cat $HOME/.cache/wallpaper}\"")
|
||||
(start-process-shell-command
|
||||
"xrandr" nil "xrandr --output eDP1 --mode 1920x1080 --pos 2560x0 --rotate normal --output HDMI1 --primary --mode 2560x1080 --pos 0x0 --rotate normal --output VIRTUAL1 --off --output DP-1-0 --off --output DP-1-1 --off")
|
||||
(exwm-randr-enable)
|
||||
(setq exwm-randr-workspace-monitor-plist '(3 "eDP1"))
|
||||
#+end_src
|
||||
|
||||
** Keybinds for a desktop environment
|
||||
#+begin_src emacs-lisp
|
||||
(use-package desktop-environment
|
||||
:defer t
|
||||
:straight (desktop-environment :build t
|
||||
:type git
|
||||
:host github
|
||||
:repo "DamienCassou/desktop-environment")
|
||||
:after exwm
|
||||
:diminish t
|
||||
:config
|
||||
(add-hook 'exwm-init-hook #'desktop-environment-mode)
|
||||
(setq desktop-environment-update-exwm-global-keys :prefix
|
||||
exwm-layout-show-al-buffers t)
|
||||
|
||||
(setq desktop-environment-bluetooth-command "bluetoothctl"
|
||||
|
||||
desktop-environment-brightness-get-command "xbacklight -get"
|
||||
desktop-environment-brightness-get-regexp (rx line-start (group (+ digit)))
|
||||
desktop-environment-brightness-set-command "xbacklight %s"
|
||||
desktop-environment-brightness-normal-increment "-inc 5"
|
||||
desktop-environment-brightness-normal-decrement "-dec 5"
|
||||
desktop-environment-brightness-small-increment "-inc 2"
|
||||
desktop-environment-brightness-small-decrement "-dec 2"
|
||||
|
||||
desktop-environment-volume-normal-decrement "-d 5"
|
||||
desktop-environment-volume-normal-increment "-i 5"
|
||||
desktop-environment-volume-small-decrement "-d 2"
|
||||
desktop-environment-volume-small-increment "-i 2"
|
||||
desktop-environment-volume-set-command "pamixer -u %s"
|
||||
|
||||
desktop-environment-screenshot-directory "~/Pictures/Screenshots"
|
||||
desktop-environment-screenlock-command "plock"
|
||||
|
||||
desktop-environment-music-toggle-command "mpc toggle"
|
||||
desktop-environment-music-previous-command "mpc prev"
|
||||
desktop-environment-music-next-command "mpc next"
|
||||
desktop-environment-music-stop-command "mpc stop")
|
||||
|
||||
(general-define-key
|
||||
"<XF86AudioPause>" (lambda () (interactive)
|
||||
(with-temp-buffer
|
||||
(shell-command "mpc pause" (current-buffer) (current-buffer)))))
|
||||
|
||||
(desktop-environment-mode))
|
||||
#+end_src
|
||||
|
||||
** Bluetooth
|
||||
#+begin_src emacs-lisp
|
||||
(defvar bluetooth-command "bluetoothctl")
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun bluetooth-turn-on ()
|
||||
(interactive)
|
||||
(let ((process-connection-type nil))
|
||||
(start-process "" nil bluetooth-command "power" "on")))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun bluetooth-turn-off ()
|
||||
(interactive)
|
||||
(let ((process-connection-type nil))
|
||||
(start-process "" nil bluetooth-command "power" "off")))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun create-bluetooth-device (raw-name)
|
||||
"Create a bluetooth device cons from RAW NAME.
|
||||
The cons will hold first the MAC address of the device, then its
|
||||
human-friendly name."
|
||||
(let ((split-name (split-string raw-name " " t)))
|
||||
`(,(mapconcat #'identity (cddr split-name) " ") . ,(cadr split-name))))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(require 'dbus)
|
||||
(defun bluetooth-get-devices ()
|
||||
(let ((bus-list (dbus-introspect-get-node-names :system "org.bluez" "/org/bluez/hci0")))
|
||||
(mapcar (lambda (device)
|
||||
`(,(dbus-get-property :system
|
||||
"org.bluez"
|
||||
(concat "/org/bluez/hci0/" device)
|
||||
"org.bluez.Device1"
|
||||
"Alias")
|
||||
. ,device))
|
||||
bus-list)))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun bluetooth-connect-device ()
|
||||
(interactive)
|
||||
(progn
|
||||
(bluetooth-turn-on)
|
||||
(let* ((devices (bluetooth-get-devices))
|
||||
(device (alist-get (completing-read "Device: " devices)
|
||||
devices nil nil #'string=)))
|
||||
(dbus-call-method-asynchronously
|
||||
:system "org.bluez"
|
||||
(concat "/org/bluez/hci0" device)
|
||||
"org.bluez.Device1"
|
||||
"Connect"
|
||||
(lambda (&optional msg)
|
||||
(when msg (message "%s" msg)))))))
|
||||
#+end_src
|
||||
59
docs/emacs/packages/helpful.org
Normal file
@@ -0,0 +1,59 @@
|
||||
#+title: Emacs — Packages — Making My Life Easier
|
||||
#+setupfile: ../../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/helpful.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
* Making my life easier
|
||||
** Bufler
|
||||
Bufler is a package that organises and lists buffers in a much better
|
||||
way than how they are usually sorted. You can easily and quickly find
|
||||
buffers by their group, not only by their name, and THIS is great
|
||||
news! Also, no ~helm~ please! And for some reasons the keybindings are
|
||||
borked by default, so let’s redefine them, and let’s also rebind ~SPC~
|
||||
to ~p~ since it would conflict with my main ~general~ prefix.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package bufler
|
||||
:straight (bufler :build t
|
||||
:files (:defaults (:exclude "helm-bufler.el")))
|
||||
:defer t
|
||||
:general
|
||||
(phundrak/evil
|
||||
:keymaps 'bufler-list-mode-map
|
||||
:packages 'bufler
|
||||
"?" #'hydra:bufler/body
|
||||
"g" #'bufler
|
||||
"f" #'bufler-list-group-frame
|
||||
"F" #'bufler-list-group-make-frame
|
||||
"N" #'bufler-list-buffer-name-workspace
|
||||
"k" #'bufler-list-buffer-kill
|
||||
"p" #'bufler-list-buffer-peek
|
||||
"s" #'bufler-list-buffer-save
|
||||
"RET" #'bufler-list-buffer-switch))
|
||||
#+end_src
|
||||
|
||||
** Helpful
|
||||
As the name tells, ~helpful~ is a really helpful package which greatly
|
||||
enhances a couple of built-in functions from Emacs, namely:
|
||||
| Vanilla Emacs Function | Helpful Function | Comment |
|
||||
|------------------------+------------------+-----------------------------------------------|
|
||||
| ~describe-function~ | ~helpful-callable~ | Only interactive functions |
|
||||
| ~describe-function~ | ~helpful-function~ | Only actual functions (including interactive) |
|
||||
| ~describe-function~ | ~helpful-macro~ | |
|
||||
| ~describe-command~ | ~helpful-command~ | |
|
||||
| ~describe-key~ | ~helpful-key~ | |
|
||||
| ~describe-variable~ | ~helpful-variable~ | |
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package helpful
|
||||
:straight (:build t)
|
||||
:after (counsel ivy)
|
||||
:custom
|
||||
(counsel-describe-function-function #'helpful-callable)
|
||||
(counsel-describe-variable-function #'helpful-variable)
|
||||
:bind
|
||||
([remap describe-function] . counsel-describe-function)
|
||||
([remap describe-command] . helpful-command)
|
||||
([remap describe-variable] . counsel-describe-variable)
|
||||
([remap describe-key] . helpful-key))
|
||||
#+end_src
|
||||
207
docs/emacs/packages/latex.org
Normal file
@@ -0,0 +1,207 @@
|
||||
#+title: Emacs — Packages — LaTeX
|
||||
#+setupfile: ../../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/latex.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
* LaTeX
|
||||
#+begin_src emacs-lisp :noweb yes
|
||||
(use-package auctex
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:hook (tex-mode . lsp-deferred)
|
||||
:hook (latex-mode . lsp-deferred)
|
||||
:init
|
||||
(setq TeX-command-default (if (executable-find "latexmk") "LatexMk" "LaTeX")
|
||||
TeX-engine (if (executable-find "xetex") 'xetex 'default)
|
||||
TeX-auto-save t
|
||||
TeX-parse-self t
|
||||
TeX-syntactic-comment t
|
||||
TeX-auto-local ".auctex-auto"
|
||||
TeX-style-local ".auctex-style"
|
||||
TeX-source-correlate-mode t
|
||||
TeX-source-correlate-method 'synctex
|
||||
TeX-source-correlate-start-server nil
|
||||
TeX-electric-sub-and-superscript t
|
||||
TeX-fill-break-at-separators nil
|
||||
TeX-save-query t)
|
||||
:config
|
||||
<<latex-fontification>>
|
||||
(setq TeX-master t)
|
||||
(setcar (cdr (assoc "Check" TeX-command-list)) "chktex -v6 -H %s")
|
||||
(add-hook 'TeX-mode-hook (lambda ()
|
||||
(setq ispell-parser 'tex
|
||||
fill-nobreak-predicate (cons #'texmathp fill-nobreak-predicate))))
|
||||
(add-hook 'TeX-mode-hook #'visual-line-mode)
|
||||
(add-hook 'TeX-update-style-hook #'rainbow-delimiters-mode)
|
||||
:general
|
||||
(phundrak/major-leader-key
|
||||
:packages 'lsp-mode
|
||||
:keymaps '(latex-mode-map LaTeX-mode-map)
|
||||
"l" '(:keymap lsp-command-map :which-key "lsp"))
|
||||
(phundrak/major-leader-key
|
||||
:packages 'auctex
|
||||
:keymaps '(latex-mode-map LaTeX-mode-map)
|
||||
"v" '(TeX-view :which-key "View")
|
||||
"c" '(TeX-command-run-all :which-key "Compile")
|
||||
"m" '(TeX-command-master :which-key "Run a command")))
|
||||
#+end_src
|
||||
|
||||
From Doom Emacs’ configuration:
|
||||
#+name: latex-fontification
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(setq font-latex-match-reference-keywords
|
||||
'(;; BibLaTeX.
|
||||
("printbibliography" "[{") ("addbibresource" "[{")
|
||||
;; Standard commands.
|
||||
("cite" "[{") ("citep" "[{")
|
||||
("citet" "[{") ("Cite" "[{")
|
||||
("parencite" "[{") ("Parencite" "[{")
|
||||
("footcite" "[{") ("footcitetext" "[{")
|
||||
;; Style-specific commands.
|
||||
("textcite" "[{") ("Textcite" "[{")
|
||||
("smartcite" "[{") ("Smartcite" "[{")
|
||||
("cite*" "[{") ("parencite*" "[{")
|
||||
("supercite" "[{")
|
||||
;; Qualified citation lists.
|
||||
("cites" "[{") ("Cites" "[{")
|
||||
("parencites" "[{") ("Parencites" "[{")
|
||||
("footcites" "[{") ("footcitetexts" "[{")
|
||||
("smartcites" "[{") ("Smartcites" "[{")
|
||||
("textcites" "[{") ("Textcites" "[{")
|
||||
("supercites" "[{")
|
||||
;; Style-independent commands.
|
||||
("autocite" "[{") ("Autocite" "[{")
|
||||
("autocite*" "[{") ("Autocite*" "[{")
|
||||
("autocites" "[{") ("Autocites" "[{")
|
||||
;; Text commands.
|
||||
("citeauthor" "[{") ("Citeauthor" "[{")
|
||||
("citetitle" "[{") ("citetitle*" "[{")
|
||||
("citeyear" "[{") ("citedate" "[{")
|
||||
("citeurl" "[{")
|
||||
;; Special commands.
|
||||
("fullcite" "[{")
|
||||
;; Cleveref.
|
||||
("cref" "{") ("Cref" "{")
|
||||
("cpageref" "{") ("Cpageref" "{")
|
||||
("cpagerefrange" "{") ("Cpagerefrange" "{")
|
||||
("crefrange" "{") ("Crefrange" "{")
|
||||
("labelcref" "{")))
|
||||
|
||||
(setq font-latex-match-textual-keywords
|
||||
'(;; BibLaTeX brackets.
|
||||
("parentext" "{") ("brackettext" "{")
|
||||
("hybridblockquote" "[{")
|
||||
;; Auxiliary commands.
|
||||
("textelp" "{") ("textelp*" "{")
|
||||
("textins" "{") ("textins*" "{")
|
||||
;; Subcaption.
|
||||
("subcaption" "[{")))
|
||||
|
||||
(setq font-latex-match-variable-keywords
|
||||
'(;; Amsmath.
|
||||
("numberwithin" "{")
|
||||
;; Enumitem.
|
||||
("setlist" "[{") ("setlist*" "[{")
|
||||
("newlist" "{") ("renewlist" "{")
|
||||
("setlistdepth" "{") ("restartlist" "{")
|
||||
("crefname" "{")))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package tex-mode
|
||||
:defer t
|
||||
:straight (:type built-in)
|
||||
:config
|
||||
(setq LaTeX-section-hook '(LaTeX-section-heading
|
||||
LaTeX-section-title
|
||||
LaTeX-section-toc
|
||||
LaTeX-section-section
|
||||
LaTeX-section-label)
|
||||
LaTeX-fill-break-at-separators nil
|
||||
LaTeX-item-indent 0))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package preview
|
||||
:defer t
|
||||
:straight (:type built-in)
|
||||
:config
|
||||
(add-hook 'LaTeX-mode-hook #'LaTeX-preview-setup)
|
||||
(setq-default preview-scale 1.4
|
||||
preview-scale-function
|
||||
(lambda () (* (/ 10.0 (preview-document-pt)) preview-scale)))
|
||||
(setq preview-auto-cache-preamble nil)
|
||||
(phundrak/major-leader-key
|
||||
:packages 'auctex
|
||||
:keymaps '(latex-mode-map LaTeX-mode-map)
|
||||
"p" #'preview-at-point
|
||||
"P" #'preview-clearout-at-point))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package cdlatex
|
||||
:defer t
|
||||
:after auctex
|
||||
:straight (:build t)
|
||||
:hook (LaTeX-mode . cdlatex-mode)
|
||||
:hook (org-mode . org-cdlatex-mode)
|
||||
:config
|
||||
(setq cdlatex-use-dollar-to-ensure-math nil)
|
||||
:general
|
||||
(phundrak/major-leader-key
|
||||
:packages 'cdlatex
|
||||
:keymaps 'cdlatex-mode-map
|
||||
"$" nil
|
||||
"(" nil
|
||||
"{" nil
|
||||
"[" nil
|
||||
"|" nil
|
||||
"<" nil
|
||||
"^" nil
|
||||
"_" nil
|
||||
[(control return)] nil))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package adaptive-wrap
|
||||
:defer t
|
||||
:after auctex
|
||||
:straight (:build t)
|
||||
:hook (LaTeX-mode . adaptative-wrap-prefix-mode)
|
||||
:init (setq-default adaptative-wrap-extra-indent 0))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package auctex-latexmk
|
||||
:after auctex
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:init
|
||||
(setq auctex-latexmk-inherit-TeX-PDF-mode t)
|
||||
(add-hook 'LaTeX-mode (lambda () (setq TeX-command-default "LatexMk")))
|
||||
:config
|
||||
(auctex-latexmk-setup))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package company-auctex
|
||||
:defer t
|
||||
:after (company auctex)
|
||||
:straight (:build t)
|
||||
:config
|
||||
(company-auctex-init))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package company-math
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:after (company auctex)
|
||||
:config
|
||||
(defun my-latex-mode-setup ()
|
||||
(setq-local company-backends
|
||||
(append '((company-math-symbols-latex company-latex-commands))
|
||||
company-backends)))
|
||||
(add-hook 'TeX-mode-hook #'my-latex-mode-setup))
|
||||
#+end_src
|
||||
276
docs/emacs/packages/misc.org
Normal file
@@ -0,0 +1,276 @@
|
||||
#+title: Emacs — Packages — Misc
|
||||
#+setupfile: ../../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/misc.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
* Misc
|
||||
** ArchWiki pages
|
||||
A small package I’ve written allows the user to view ArchLinux pages
|
||||
either in Emacs or in an external web browser. I prefer the defaults.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package archwiki
|
||||
:defer t
|
||||
:straight (archwiki :build t
|
||||
:type git
|
||||
:repo "https://labs.phundrak.com/phundrak/archwiki.el"))
|
||||
#+end_src
|
||||
|
||||
** ~avy~
|
||||
~avy~ is a really convenient way of jumping around and performing
|
||||
actions on these selections, but I’ll need some configuration to make
|
||||
it bépo-compatible.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package avy
|
||||
:defer t
|
||||
:straight t
|
||||
:config
|
||||
(csetq avy-keys '(?a ?u ?i ?e ?c ?t ?s ?r ?n)
|
||||
avy-dispatch-alist '((?x . avy-action-kill-move)
|
||||
(?X . avy-action-kill-stay)
|
||||
(?T . avy-action-teleport)
|
||||
(?m . avy-action-mark)
|
||||
(?C . avy-action-copy)
|
||||
(?y . avy-action-yank)
|
||||
(?Y . avy-action-yank-line)
|
||||
(?I . avy-action-ispell)
|
||||
(?z . avy-action-zap-to-char)))
|
||||
(defun my/avy-goto-url ()
|
||||
"Jump to url with avy."
|
||||
(interactive)
|
||||
(avy-jump "https?://"))
|
||||
(defun my/avy-open-url ()
|
||||
"Open url selected with avy."
|
||||
(interactive)
|
||||
(my/avy-goto-url)
|
||||
(browse-url-at-point))
|
||||
:general
|
||||
(phundrak/evil
|
||||
:pakages 'avy
|
||||
"gc" #'evil-avy-goto-char-timer
|
||||
"gl" #'evil-avy-goto-line)
|
||||
(phundrak/leader-key
|
||||
:packages 'avy
|
||||
:infix "j"
|
||||
"b" #'avy-pop-mark
|
||||
"c" #'evil-avy-goto-char-timer
|
||||
"l" #'avy-goto-line)
|
||||
(phundrak/leader-key
|
||||
:packages 'avy
|
||||
:infix "A"
|
||||
"c" '(:ignore t :which-key "copy")
|
||||
"cl" #'avy-copy-line
|
||||
"cr" #'avy-copy-region
|
||||
"k" '(:ignore t :which-key "kill")
|
||||
"kl" #'avy-kill-whole-line
|
||||
"kL" #'avy-kill-ring-save-whole-line
|
||||
"kr" #'avy-kill-region
|
||||
"kR" #'avy-kill-ring-save-region
|
||||
"m" '(:ignore t :which-key "move")
|
||||
"ml" #'avy-move-line
|
||||
"mr" #'avy-move-region
|
||||
"mt" #'avy-transpose-lines-in-region
|
||||
"n" #'avy-next
|
||||
"p" #'avy-prev
|
||||
"u" #'my/avy-goto-url
|
||||
"U" #'my/avy-open-url)
|
||||
(phundrak/major-leader-key
|
||||
:packages '(avy org)
|
||||
:keymaps 'org-mode-map
|
||||
"A" '(:ignore t :which-key "avy")
|
||||
"Ar" #'avy-org-refile-as-child
|
||||
"Ah" #'avy-org-goto-heading-timer))
|
||||
#+end_src
|
||||
|
||||
** Calc
|
||||
Let’s give ~calc-mode~ some better defaults.
|
||||
#+begin_src emacs-lisp
|
||||
(setq calc-angle-mode 'rad
|
||||
calc-symbolic-mode t)
|
||||
#+end_src
|
||||
|
||||
** Elcord
|
||||
What’s the point of using Emacs if you can’t tell everyone?
|
||||
#+begin_src emacs-lisp
|
||||
(use-package elcord
|
||||
:straight (:built t)
|
||||
:defer t
|
||||
:config
|
||||
(csetq elcord-use-major-mode-as-main-icon t
|
||||
elcord-refresh-rate 5
|
||||
elcord-boring-buffers-regexp-list `("^ "
|
||||
,(rx "*" (+ any) "*")
|
||||
,(rx bol (or "Re: "
|
||||
"Fwd: ")))))
|
||||
#+end_src
|
||||
|
||||
** ~ivy-quick-find-files.el~
|
||||
This package is a small utility package I’ve written in order to
|
||||
quickly find files across my filesystem.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ivy-quick-find-files
|
||||
:defer t
|
||||
:straight (ivy-quick-find-files :type git
|
||||
:host github
|
||||
:repo "phundrak/ivy-quick-find-files.el"
|
||||
:build t)
|
||||
:config
|
||||
(setq ivy-quick-find-files-program 'fd
|
||||
ivy-quick-find-files-dirs-and-exts '(("~/org" . "org")
|
||||
("~/Documents/university" . "org"))
|
||||
ivy-quick-find-files-fd-additional-options "-L"))
|
||||
#+end_src
|
||||
|
||||
** Keycast
|
||||
In case I am sharing my screen with people and I want to show which
|
||||
functions are called on my keystrokes since I don’t exactly use
|
||||
standard keybindings.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package keycast
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:config
|
||||
(define-minor-mode keycast-mode
|
||||
"Show current command and its key binding in the mode line."
|
||||
:global t
|
||||
(if keycast-mode
|
||||
(add-hook 'pre-command-hook 'keycast--update t)
|
||||
(remove-hook 'pre-command-hook 'keycast--update)))
|
||||
(add-to-list 'global-mode-string '("" mode-line-keycast " ")))
|
||||
#+end_src
|
||||
|
||||
** Keyfreq
|
||||
Keyfreq is a package that records all the commands I call from Emacs
|
||||
and builds a heatmap out of it.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package keyfreq
|
||||
:straight (:build t)
|
||||
:init
|
||||
(keyfreq-mode 1)
|
||||
(keyfreq-autosave-mode 1)
|
||||
:config
|
||||
(setq keyfreq-excluded-commands '(self-insert-command org-self-insert-command
|
||||
evil-previous-visual-line evil-next-visual-line
|
||||
ivy-next-line evil-backward-char evil-forward-char
|
||||
evil-next-line evil-previous-line evil-normal-state
|
||||
text-scale-pinch)))
|
||||
#+end_src
|
||||
|
||||
** Mastodon
|
||||
#+begin_src emacs-lisp
|
||||
(use-package mastodon
|
||||
:defer t
|
||||
:ensure t
|
||||
:straight (mastodon :type git
|
||||
:host codeberg
|
||||
:repo "martianh/mastodon.el")
|
||||
:config
|
||||
(setq mastodon-instance-url "https://emacs.ch"
|
||||
mastodon-active-user "phundrak")
|
||||
|
||||
(defun me/mastodon-toot--send-language-if-none ()
|
||||
(unless mastodon-toot--language
|
||||
(mastodon-toot--set-toot-language)))
|
||||
(advice-add #'me/mastodon-toot--send-language-if-none :before #'mastodon-toot--send)
|
||||
:general
|
||||
(phundrak/evil
|
||||
:packages '(mastodon)
|
||||
:keymaps 'mastodon-mode-map
|
||||
"]]" '(mastodon-tl--goto-next-toot :wk "Next status")
|
||||
"[[" '(mastodon-tl--goto-prev-toot :wk "Previous status")
|
||||
"gt" '(mastodon-tl--next-tab-item :wk "Next tab item")
|
||||
"gs" '(mastodon-tl--previous-tab-item :wk "Previous tab item")
|
||||
"»" '(mastodon-tl--goto-next-toot :wk "Next status")
|
||||
"«" '(mastodon-tl--goto-prev-toot :wk "Previous status")
|
||||
"q" #'kill-current-buffer)
|
||||
(phundrak/major-leader-key
|
||||
:package 'mastodon
|
||||
:keymaps 'mastodon-mode-map
|
||||
"#" '(mastodon-tl--get-tag-timeline :wk "Tag timeline")
|
||||
"f" '(mastodon-tl--get-federated-timeline :wk "Federated timeline")
|
||||
"F" '(mastoton-tl--view-filters :wk "Filters")
|
||||
"H" '(mastodon-tl--get-local-timeline :wk "Home timeline")
|
||||
"L" '(mastodon-tl--get-local-timeline :wk "Local timeline")
|
||||
"N" '(mastodon-notifications-get :wk "Notifications")
|
||||
"T" '(mastodon-tl--thread :wk "Thread")
|
||||
"O" '(mastodon-profile--my-profile :wk "My profile")
|
||||
"S" '(mastodon-tl--get-follow-suggestions :wk "Follow suggestions")
|
||||
"a" '(mastodon-profile--get-toot-author :wk "Toot author")
|
||||
"b" '(mastodon-profile--view-bookmarks :wk "Bookmarks")
|
||||
"s" '(mastodon-search--search-query :wk "Search query")
|
||||
"U" '(mastodon-tl--update :wk "Update")
|
||||
|
||||
"t" '(nil :wk "Toots")
|
||||
"tt" '(mastodon-toot :wk "Toot")
|
||||
"tb" '(mastodon-toot--toggle-boost :wk "Boost")
|
||||
"tB" '(mastodon-toot--bookmark-toot-toggle :wk "Bookmark")
|
||||
"td" '(mastodon-toot--delete-toot :wk "Delete")
|
||||
"tD" '(mastodon-toot--delete-and-redraft-toot :wk "Redraft")
|
||||
"tf" '(mastodon-toot--toggle-favourite :wk "Favourite")
|
||||
"tF" '(mastodon-profile--view-favourites :wk "View favourites")
|
||||
"tr" '(mastodon-toot--reply :wk "Reply")
|
||||
"tp" '(mastodon-toot--pin-toot-toggle :wk "Pin")
|
||||
"ts" '(mastodon-tl--toggle-spoiler-text-in-toot :wk "Spoiler")
|
||||
"tu" '(mastodon-toot--copy-toot-url :wk "Copy url")
|
||||
"tv" '(mastodon-tl--poll-vote :wk "Vote on poll")
|
||||
|
||||
"f" '(nil :wk "Follow requests")
|
||||
"fa" '(mastodon-notifications--follow-request-accept :wk "Accept")
|
||||
"fr" '(mastodon-notifications--follow-request-reject :wk "Reject")
|
||||
"fv" '(mastodon-profile--view-follow-requests :wk "View follow requests")
|
||||
|
||||
"u" '(nil :wk "User")
|
||||
"uf" '(mastodon-tl--follow-user :wk "Follow")
|
||||
"uF" '(mastodon-tl--unfollow-user :wk "Unfollow")
|
||||
"ub" '(mastodon-tl--block-user :wk "Block")
|
||||
"uB" '(mastodon-tl--unblock-user :wk "Unblock")
|
||||
"um" '(mastodon-tl--mute-user :wk "Mute")
|
||||
"uM" '(mastodon-tl--unmute-user :wk "Unmute")
|
||||
"un" '(mastodon-profile--update-user-profile-note :wk "Update user profile note")
|
||||
"uu" '(mastodon-profile--show-user :wk "Show user")))
|
||||
#+end_src
|
||||
|
||||
** Mediawiki
|
||||
#+begin_src emacs-lisp
|
||||
(use-package mediawiki
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:custom
|
||||
(mediawiki-site-alist '(("PhundrakWiki" ; Title
|
||||
"https://wiki.phundrak.com/" ; URL
|
||||
"phundrak" ; username
|
||||
nil ; password
|
||||
nil ; LDAP
|
||||
"Main Page")))) ; Default page
|
||||
#+end_src
|
||||
|
||||
** SICP
|
||||
Who would get interested in Emacs and not want to read the SICP?
|
||||
Moreover, inside Emacs?
|
||||
#+begin_src emacs-lisp
|
||||
(use-package sicp
|
||||
:straight (:build t)
|
||||
:defer t)
|
||||
#+end_src
|
||||
|
||||
** Winum
|
||||
Winum allows Emacs to associate windows with a specific number and
|
||||
navigate through these windows by directly refering to their
|
||||
associated number! This allows for faster window configuration than
|
||||
just going to the frame above, then left, left, and up.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package winum
|
||||
:straight (:build t)
|
||||
:init (winum-mode))
|
||||
#+end_src
|
||||
|
||||
** Ytplay
|
||||
~ytplay~ is a small package I’ve written with which you can choose at
|
||||
which resolution to play a YouTube video in an external video player.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ytplay
|
||||
:defer t
|
||||
:straight (ytplay :build t
|
||||
:type git
|
||||
:repo "https://labs.phundrak.com/phundrak/ytplay.el"))
|
||||
#+end_src
|
||||
1399
docs/emacs/packages/org.org
Normal file
1782
docs/emacs/packages/programming.org
Normal file
260
docs/emacs/packages/visual-config.org
Normal file
@@ -0,0 +1,260 @@
|
||||
#+title: Emacs — Packages — Visual Configuration
|
||||
#+setupfile: ../../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/visual-config.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
* Visual Configuration
|
||||
** Dashboard
|
||||
#+begin_src emacs-lisp
|
||||
(use-package dashboard
|
||||
:straight (:build t)
|
||||
:ensure t
|
||||
:after all-the-icons
|
||||
:config
|
||||
(setq dashboard-banner-logo-title "Phundrak’s Vanilla Emacs"
|
||||
dashboard-startup-banner 'logo
|
||||
dashboard-center-content t
|
||||
dashboard-show-shortcuts t
|
||||
dashboard-set-navigator t
|
||||
dashboard-set-heading-icons t
|
||||
dashboard-set-file-icons t
|
||||
initial-buffer-choice (lambda () (get-buffer "*dashboard*"))
|
||||
dashboard-projects-switch-function 'counsel-projectile-switch-project-by-name)
|
||||
(setq dashboard-navigator-buttons
|
||||
`(((,(all-the-icons-faicon "language" :height 1.1 :v-adjust 0.0)
|
||||
"Linguistics Website"
|
||||
""
|
||||
(lambda (&rest _) (browse-url "https://langue.phundrak.com")))
|
||||
|
||||
(,(all-the-icons-faicon "firefox" :height 1.1 :v-adjust 0.0)
|
||||
"Config Website"
|
||||
""
|
||||
(lambda (&rest _) (browse-url "https://config.phundrak.com"))))
|
||||
|
||||
((,(all-the-icons-octicon "git-branch" :height 1.1 :v-adjust 0.0)
|
||||
"Dotfiles Sources"
|
||||
""
|
||||
(lambda (&rest _) (browse-url "https://labs.phundrak.com/phundrak/dotfiles")))
|
||||
("!" "Issues" "Show issues" (lambda (&rest _)
|
||||
(browse-url "https://labs.phundrak.com/phundrak/dotfiles/issues"))
|
||||
warning))
|
||||
((,(all-the-icons-faicon "level-up" :height 1.1 :v-adjust 0.0)
|
||||
"Update Packages"
|
||||
""
|
||||
(lambda (&rest _) (progn
|
||||
(require 'straight)
|
||||
(straight-pull-all)
|
||||
(straight-rebuild-all)))))))
|
||||
|
||||
(setq dashboard-items '((recents . 15)
|
||||
(agenda . 10)
|
||||
(projects . 10)))
|
||||
(dashboard-setup-startup-hook)
|
||||
:init
|
||||
(add-hook 'after-init-hook 'dashboard-refresh-buffer))
|
||||
#+end_src
|
||||
|
||||
** Fringe
|
||||
It’s nice to know which lines were modified since the last commit in a
|
||||
file.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package git-gutter-fringe
|
||||
:straight (:build t)
|
||||
:hook ((prog-mode . git-gutter-mode)
|
||||
(org-mode . git-gutter-mode)
|
||||
(markdown-mode . git-gutter-mode)
|
||||
(latex-mode . git-gutter-mode)))
|
||||
#+end_src
|
||||
|
||||
** Icons? Did someone say icons?
|
||||
/*YES! ALL OF THEM!*/
|
||||
|
||||
Ahem…
|
||||
|
||||
The package ~all-the-icons~ allows us to use a wide variety of icons in
|
||||
Emacs for various purposes, wherever we want, and /THAT/ is *GREAT*! I’ll
|
||||
(ab)use this feature in my config, be warned! *NOTE*: The first time a
|
||||
configuration with ~all-the-icons~ loads on a machine, the needed fonts
|
||||
might not be available, so you’ll need to install them with the
|
||||
command ~M-x all-the-icons-install-fonts~.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package all-the-icons
|
||||
:defer t
|
||||
:straight t)
|
||||
#+end_src
|
||||
|
||||
~prettify-symbols-mode~ is also a nifty feature of Emacs, and it is
|
||||
built-in! With that, I can replace strings of my choice by another
|
||||
character of my choice! First, let’s declare the general symbols that
|
||||
will be used everywhere.
|
||||
#+begin_src emacs-lisp
|
||||
(defun prog-mode-set-symbols-alist ()
|
||||
(setq prettify-symbols-alist '(("lambda" . ?λ)))
|
||||
(prettify-symbols-mode 1))
|
||||
|
||||
(add-hook 'prog-mode-hook #'prog-mode-set-symbols-alist)
|
||||
#+end_src
|
||||
|
||||
We can now take care of the language-specific symbols. First, let’s
|
||||
declare some symbols for the Lisp languages.
|
||||
#+begin_src emacs-lisp
|
||||
(setq-default lisp-prettify-symbols-alist '(("lambda" . ?λ)
|
||||
("defun" . ?𝑓)
|
||||
("defvar" . ?𝑣)
|
||||
("defcustom" . ?𝑐)
|
||||
("defconst" . ?𝐶)))
|
||||
|
||||
(defun lisp-mode-prettify ()
|
||||
(setq prettify-symbols-alist lisp-prettify-symbols-alist)
|
||||
(prettify-symbols-mode -1)
|
||||
(prettify-symbols-mode 1))
|
||||
|
||||
(dolist (lang '(emacs-lisp lisp common-lisp scheme))
|
||||
(add-hook (intern (format "%S-mode-hook" lang))
|
||||
#'lisp-mode-prettify))
|
||||
#+end_src
|
||||
|
||||
Finally, similar to how ~org-appear~ behaves, let’s show the real string
|
||||
of our symbols when the cursor is on it.
|
||||
#+begin_src emacs-lisp
|
||||
(setq prettify-symbols-unprettify-at-point t)
|
||||
#+end_src
|
||||
|
||||
** Ligatures
|
||||
The font I’m using (see *here*) supports ligatures, but Emacs in GUI
|
||||
mode does not. And of course, there’s a package for that.
|
||||
|
||||
# Insert equivalent of #Basic-configuration-Visual-Configuration-Fontsxfkjel6184j0 in *here*
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ligature
|
||||
:straight (ligature :type git
|
||||
:host github
|
||||
:repo "mickeynp/ligature.el"
|
||||
:build t)
|
||||
:config
|
||||
(ligature-set-ligatures 't
|
||||
'("www"))
|
||||
;; Enable traditional ligature support in eww-mode, if the
|
||||
;; `variable-pitch' face supports it
|
||||
(ligature-set-ligatures '(eww-mode org-mode elfeed-show-mode)
|
||||
'("ff" "fi" "ffi"))
|
||||
;; Enable all Cascadia Code ligatures in programming modes
|
||||
(ligature-set-ligatures 'prog-mode
|
||||
'("|||>" "<|||" "<==>" "<!--" "####" "~~>" "***" "||=" "||>"
|
||||
":::" "::=" "=:=" "===" "==>" "=!=" "=>>" "=<<" "=/=" "!=="
|
||||
"!!." ">=>" ">>=" ">>>" ">>-" ">->" "->>" "-->" "---" "-<<"
|
||||
"<~~" "<~>" "<*>" "<||" "<|>" "<$>" "<==" "<=>" "<=<" "<->"
|
||||
"<--" "<-<" "<<=" "<<-" "<<<" "<+>" "</>" "###" "#_(" "..<"
|
||||
"..." "+++" "/==" "///" "_|_" "www" "&&" "^=" "~~" "~@" "~="
|
||||
"~>" "~-" "**" "*>" "*/" "||" "|}" "|]" "|=" "|>" "|-" "{|"
|
||||
"[|" "]#" "::" ":=" ":>" ":<" "$>" "==" "=>" "!=" "!!" ">:"
|
||||
">=" ">>" ">-" "-~" "-|" "->" "--" "-<" "<~" "<*" "<|" "<:"
|
||||
"<$" "<=" "<>" "<-" "<<" "<+" "</" "#{" "#[" "#:" "#=" "#!"
|
||||
"##" "#(" "#?" "#_" "%%" ".=" ".-" ".." ".?" "+>" "++" "?:"
|
||||
"?=" "?." "??" ";;" "/*" "/=" "/>" "//" "__" "~~" "(*" "*)"
|
||||
"\\\\" "://"))
|
||||
(global-ligature-mode t))
|
||||
#+end_src
|
||||
|
||||
** Modeline
|
||||
The DoomEmacs modeline looks nice in my opinion, let’s use it.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package doom-modeline
|
||||
:straight (:build t)
|
||||
:defer t
|
||||
:init (doom-modeline-mode 1)
|
||||
:config
|
||||
(csetq doom-modeline-height 15
|
||||
doom-modeline-enable-word-count t
|
||||
doom-modeline-continuous-word-count-modes '(markdown-mode gfm-mode org-mode)
|
||||
doom-modeline-mu4e t
|
||||
doom-modeline-env-version t)
|
||||
(mu4e-alert-enable-mode-line-display))
|
||||
#+end_src
|
||||
|
||||
** Pixel-perfect alignment of Markdown and org-mode tables
|
||||
:END:
|
||||
Usually, I have no issue with the alignment of the tables I write in
|
||||
org-mode and (more rarely) Markdown. However, there are occurences
|
||||
where I’ll use a character that does not exactly respect my monospace
|
||||
font, which messes with the alignment of the table (often when I do
|
||||
linguistics stuff). A solution to this is the package ~valign~. A little
|
||||
caveat though, as its name implies ~valign~ helps with vertical
|
||||
alignment. If some lines are too high, they won’t exactly fit. Unless?
|
||||
Unless ~valign-fancy-bar~ is set to ~t~.
|
||||
|
||||
For now, I disabled the hook with org-mode and markdown-mode because
|
||||
it slows down opening these files quite a lot. I’ll re-enable the hook
|
||||
once it is fixed.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package valign
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:after (org markdown-mode)
|
||||
;; :hook ((org-mode markdown-mode) . valign-mode)
|
||||
:custom ((valign-fancy-bar t)))
|
||||
#+end_src
|
||||
|
||||
** Secret mode
|
||||
Sometimes, I want to hide the text displayed by Emacs but not lock
|
||||
altogether my computer. In this case, ~secret-mode~ comes in handy.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package secret-mode
|
||||
:defer t
|
||||
:straight (secret-mode :build t
|
||||
:type git
|
||||
:host github
|
||||
:repo "bkaestner/secret-mode.el"))
|
||||
#+end_src
|
||||
|
||||
** Solaire: Incandescent Emacs
|
||||
A common issue when you have a lot of windows opened in Emacs is
|
||||
sometimes there’s just too much. Is the first window source code? Is
|
||||
the other one just an open email? Oh, let’s not forget the ~*Messages*~
|
||||
buffer open next to another source buffer.
|
||||
|
||||
Solaire-mode applies a subtle but useful tweak to your current color
|
||||
scheme: the background of programming buffers is slightly lighter than
|
||||
the background of other buffers. (Or is it other buffers that have a
|
||||
slightly darker background? I’m not sure.)
|
||||
#+begin_src emacs-lisp
|
||||
(use-package solaire-mode
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:init (solaire-global-mode +1))
|
||||
#+end_src
|
||||
|
||||
** Theme
|
||||
You may have noticed I use the Nord theme pretty much everywhere on my
|
||||
computer, why not Emacs? In my opinion, its aurora variant is nicer
|
||||
than the default Nord theme since it is richer in colors --- just a
|
||||
personal preference.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package doom-themes
|
||||
:straight (:build t)
|
||||
:defer t
|
||||
:init (load-theme 'doom-nord-aurora t))
|
||||
#+end_src
|
||||
|
||||
** Rainbow Delimiters
|
||||
This makes Lisp especially more readable, but it’s also nice to have
|
||||
for any language that has delimiters like brackets too.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package rainbow-delimiters
|
||||
:straight (:build t)
|
||||
:defer t
|
||||
:hook (prog-mode . rainbow-delimiters-mode))
|
||||
#+end_src
|
||||
|
||||
** Y’all want some more /COLORS/?
|
||||
It is possible to make info buffers much more colorful (and imo easier
|
||||
to read) with this simple package:
|
||||
#+begin_src emacs-lisp
|
||||
(use-package info-colors
|
||||
:straight (:build t)
|
||||
:commands info-colors-fnontify-node
|
||||
:hook (Info-selection . info-colors-fontify-node)
|
||||
:hook (Info-mode . mixed-pitch-mode))
|
||||
#+end_src
|
||||
590
docs/fish.org
Normal file
@@ -0,0 +1,590 @@
|
||||
#+TITLE: Fish
|
||||
#+setupfile: headers
|
||||
#+PROPERTY: header-args:fish :mkdirp yes :tangle ~/.config/fish/config.fish :exports code :noweb yes
|
||||
#+PROPERTY: header-args :exports code :tangle no
|
||||
|
||||
* Fish
|
||||
The file present in =~/.config/fish/config.fish= is the configuration file for
|
||||
the [[https://fishshell.com/][fish shell]]. It contains custom functions, environment variables and
|
||||
abbreviations.
|
||||
|
||||
Just in case, we might sometimes need to declare the fish function =fish_title=
|
||||
as =true=, so let’s do so.
|
||||
#+BEGIN_SRC fish
|
||||
function fish_title
|
||||
true
|
||||
end
|
||||
#+END_SRC
|
||||
|
||||
** Fish from within Emacs
|
||||
I sometimes call fish from within emacs, with =M-x ansi-term=. In this case, the
|
||||
variable =TERM= needs to have the value =eterm-color=.
|
||||
#+BEGIN_SRC fish
|
||||
if test -n "$EMACS"
|
||||
set -x TERM eterm-color
|
||||
end
|
||||
#+END_SRC
|
||||
|
||||
** Global variables
|
||||
An important thing to do is to load all variables from my =~/.profile=
|
||||
file (which you can find [[https://labs.phundrak.com/phundrak/dotfiles/src/branch/master/.profile][here]]). The [[https://github.com/oh-my-fish/plugin-foreign-env][foreign-env]] plugin comes in handy:
|
||||
#+begin_src fish
|
||||
fenv source ~/.profile
|
||||
#+end_src
|
||||
|
||||
*** Development
|
||||
Finally, some development packages require the =PKG_CONFIG_PATH= to be set, so
|
||||
let’s do so.
|
||||
#+BEGIN_SRC fish
|
||||
set -gx PKG_CONFIG_PATH /usr/local/lib/pkgconfig/ $PKG_CONFIG_PATH
|
||||
#+END_SRC
|
||||
|
||||
** Tramp remote access
|
||||
When accessing from a remote machine our computer from Emacs, tramp
|
||||
needs a precise shell appearance: a simple =$= followed by a space after
|
||||
which to put the commands it needs to execute, and nothing else. Due
|
||||
to this, let’s deactivate and redefine some functions defining the
|
||||
appearance of fish.
|
||||
#+BEGIN_SRC fish
|
||||
if test "$TERM" = "dumb"
|
||||
function fish_prompt
|
||||
echo "\$ "
|
||||
end
|
||||
function fish_right_prompt; end
|
||||
function fish_greeting; end
|
||||
function fish_title; end
|
||||
end
|
||||
#+END_SRC
|
||||
|
||||
** Regular fish shell appearance
|
||||
Now, there is only one function I modify when it comes to the
|
||||
appearance of fish when I’m the one using it: the ~fish_greeting~
|
||||
function. I just want it empty.
|
||||
#+BEGIN_SRC fish
|
||||
function fish_greeting; end
|
||||
#+END_SRC
|
||||
|
||||
For my fish prompt, I use [[https://starship.rs][starship]], a shell-agnostic prompt. Let’s load it:
|
||||
#+begin_src fish
|
||||
starship init fish | source
|
||||
#+end_src
|
||||
|
||||
** Setting up external tools
|
||||
*** Starship configuration
|
||||
:PROPERTIES:
|
||||
:header-args:toml: :tangle ~/.config/starship.toml
|
||||
:END:
|
||||
As mentioned above, starship is a shell-agnostic prompt, written in Rust and which can be configured separately from the shell. I decided to configure it here though, since fish is the only shell I use which is compatible with starship.
|
||||
|
||||
First I’ll modify the default format variable, removing the modules I don’t need.
|
||||
#+begin_src toml
|
||||
format = """
|
||||
$username\
|
||||
$hostname\
|
||||
$shlvl\
|
||||
$singularity\
|
||||
$kubernetes\
|
||||
$directory\
|
||||
$vcsh\
|
||||
$git_branch\
|
||||
$git_commit\
|
||||
$git_state\
|
||||
$git_metrics\
|
||||
$git_status\
|
||||
$hg_branch\
|
||||
$docker_context\
|
||||
$package\
|
||||
$cmake\
|
||||
$dart\
|
||||
$deno\
|
||||
$lua\
|
||||
$nodejs\
|
||||
$python\
|
||||
$rlang\
|
||||
$rust\
|
||||
$scala\
|
||||
$zig\
|
||||
$memory_usage\
|
||||
$env_var\
|
||||
$custom\
|
||||
$cmd_duration\
|
||||
$line_break\
|
||||
$jobs\
|
||||
$battery\
|
||||
$time\
|
||||
$status\
|
||||
$shell\
|
||||
$character"""
|
||||
#+end_src
|
||||
|
||||
I want starship to be able to detect Lisp files, be it CommonLisp or EmacsLisp. Unfortunately, it seems nerd-font doesn’t have any symbol for either language, so I’m just using a lambda character.
|
||||
#+begin_src toml
|
||||
[custom.lisp]
|
||||
extensions = ["lisp", "el"]
|
||||
symbol = "λ "
|
||||
style = "bold green"
|
||||
#+end_src
|
||||
|
||||
Finally, let’s disable all modules I don’t need.
|
||||
#+begin_src toml
|
||||
[cobol]
|
||||
disable = true
|
||||
[dotnet]
|
||||
disable = true
|
||||
[elixir]
|
||||
disable = true
|
||||
[elm]
|
||||
disable = true
|
||||
[erlang]
|
||||
disable = true
|
||||
[golang]
|
||||
disable = true
|
||||
[helm]
|
||||
disable = true
|
||||
[java]
|
||||
disable = true
|
||||
[julia]
|
||||
disable = true
|
||||
[kotlin]
|
||||
disable = true
|
||||
[nim]
|
||||
disable = true
|
||||
[ocaml]
|
||||
disable = true
|
||||
[perl]
|
||||
disable = true
|
||||
[php]
|
||||
disable = true
|
||||
[pulumi]
|
||||
disable = true
|
||||
[purescript]
|
||||
disable = true
|
||||
[red]
|
||||
disable = true
|
||||
[ruby]
|
||||
disable = true
|
||||
[swift]
|
||||
disable = true
|
||||
[terraform]
|
||||
disable = true
|
||||
[vlang]
|
||||
disable = true
|
||||
[vagrant]
|
||||
disable = true
|
||||
[nix_shell]
|
||||
disable = true
|
||||
[conda]
|
||||
disable = true
|
||||
[aws]
|
||||
disable = true
|
||||
[gcloud]
|
||||
disable = true
|
||||
[openstack]
|
||||
disable = true
|
||||
[crystal]
|
||||
disable = true
|
||||
#+end_src
|
||||
|
||||
*** Loading ~zoxide~
|
||||
~zoxide~ is a smarter ~cd~ command, accessible through ~z~. It can be loaded like so:
|
||||
#+begin_src fish
|
||||
zoxide init fish | source
|
||||
#+end_src
|
||||
|
||||
** Abbreviations
|
||||
#+NAME: generate-abbr
|
||||
#+BEGIN_SRC emacs-lisp :var table=[] :exports none :tangle no
|
||||
(replace-regexp-in-string "\\\\vert[{}]*"
|
||||
"|"
|
||||
(mapconcat (lambda (x) (format "abbr %s '%s'" (car x) (cadr x)))
|
||||
table
|
||||
"\n")
|
||||
t t)
|
||||
#+END_SRC
|
||||
|
||||
Abbreviations are a great way to keep correctly track of which commands are run
|
||||
in the shell without polluting the history of the shell with obscure commands.
|
||||
When typing an abbreviation, fish will replace it with replace it with its
|
||||
expanded equivalent. Below are some of the abbreviations I use. Be aware some of
|
||||
them that invoke GUI programs can be invoked through ~devour~ which will make
|
||||
the terminal disappear while the program runs, and once the GUI program exists
|
||||
the terminal window will come back.
|
||||
|
||||
*** System monitoring
|
||||
Here I have some abbreviations which are quite useful when performing
|
||||
some system monitoring. With =df=, we can get an overview of our
|
||||
filesystem usage, while with =diskspace= we get some more precise
|
||||
information. =meminfo= is a call to =free= with sane defaults, and similar
|
||||
to =meminfo=, we also have =gpumeminfo= to get a quick look at the
|
||||
memory-related logs of our X session. I also declared =cpuinfo= an alias
|
||||
of =lscpu= in order to keep consistent with =meminfo=. =pscpu= gives us
|
||||
information on what the CPU is running right now, and =pscpu10= limits
|
||||
that to the top 10 threads. Similarly, =psmem= gives us information on
|
||||
the memory usage of the current threads, and =psmem10= only the ten most
|
||||
important threads in terms of memory usage.
|
||||
#+NAME: mgmt-abbr
|
||||
| abbreviation | command |
|
||||
|--------------+--------------------------------------------|
|
||||
| df | df -H |
|
||||
| diskspace | sudo df -h \vert grep -E "sd\vert{}lv\vert{}Size" |
|
||||
| du | du -ch |
|
||||
| meminfo | free -m -l -t |
|
||||
| gpumeminfo | grep -i --color memory /var/log/Xorg.0.log |
|
||||
| cpuinfo | lscpu |
|
||||
| pscpu | ps auxf \vert sort -nr -k 3 |
|
||||
| pscpu10 | ps auxf \vert sort -nr -k 3 \vert head -10 |
|
||||
| psmem | ps auxf \vert sort -nr -k 4 |
|
||||
| psmem10 | ps auxf \vert sort -nr -k 4 \vert head -10 |
|
||||
|
||||
#+begin_SRC fish
|
||||
<<generate-abbr(table=mgmt-abbr)>>
|
||||
#+END_SRC
|
||||
|
||||
*** System management (packages and services)
|
||||
I added some of these abbreviations due to how often I have to write the whole
|
||||
thing.
|
||||
|
||||
**** Package management
|
||||
The first command is =remove= which removes a package from my system, as well as
|
||||
its dependencies no longer needed. =p=. =pacman='s or =paru='s. This is why I
|
||||
simply type =purge=. And if I want to simply seach among the =pacman= repos, I
|
||||
can type =search=. Otherwise, if I want to include AUR results, I’ll use =paru=.
|
||||
|
||||
#+NAME: pm-abbr
|
||||
| abbreviation | command |
|
||||
|--------------+------------------|
|
||||
| remove | sudo pacman -Rsc |
|
||||
| purge | paru -Sc |
|
||||
|
||||
#+BEGIN_SRC fish
|
||||
<<generate-abbr(table=pm-abbr)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Service management
|
||||
I don’t have the muscle memory of =systemctl=. So instead, I simply type =c=
|
||||
when I want to do something user service related. And if I want to manipulate
|
||||
system services, I can instead type a simple capital =S=.
|
||||
#+NAME: service-abbr
|
||||
| abbreviation | command |
|
||||
|--------------+------------------|
|
||||
| s | systemctl |
|
||||
| suser | systemctl --user |
|
||||
|
||||
#+BEGIN_SRC fish
|
||||
<<generate-abbr(table=service-abbr)>>
|
||||
#+END_SRC
|
||||
|
||||
*** Development
|
||||
A good amount of these commands are development related, especially when it
|
||||
comes to compilation or Docker.
|
||||
|
||||
**** CMake
|
||||
I have the following abbreviations to quickly run CMake and create a
|
||||
configuration for debug or release profiles.
|
||||
#+NAME: abbr-cmake
|
||||
| abbreviation | command |
|
||||
|--------------+----------------------------------|
|
||||
| cdebug | cmake -DCMAKE_BUILD_TYPE=Debug |
|
||||
| crelease | cmake -DCMAKE_BUILD_TYPE=Release |
|
||||
|
||||
Here is the corresponding fish configuration:
|
||||
#+BEGIN_SRC fish
|
||||
<<generate-abbr(table=abbr-cmake)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Docker
|
||||
And of course, when it comes to Docker Compose, I don't have time to write the
|
||||
full command, so I use these instead.
|
||||
#+NAME: abbr-docker
|
||||
| abbreviation | command |
|
||||
|--------------+------------------------------|
|
||||
| dc | docker-compose |
|
||||
| dcb | docker-compose build |
|
||||
| dcd | docker-compose down |
|
||||
| dcl | docker-compose logs |
|
||||
| dclf | docker-compose logs -f |
|
||||
| dcp | docker-compose pull |
|
||||
| dcr | docker-compose run --rm |
|
||||
| dcu | docker-compose up |
|
||||
| dcub | docker-compose up --build |
|
||||
| dcud | docker-compose up -d |
|
||||
| dcudb | docker-compose up -d --build |
|
||||
|
||||
Here is the corresponding fish configuration:
|
||||
#+BEGIN_SRC fish
|
||||
<<generate-abbr(table=abbr-docker)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Text editors
|
||||
I greatly prefer to use Emacsclient as my main text editor; Emacs has basically
|
||||
all I need. So, it's only normal I have an abbreviation to launch a new instance
|
||||
of it. If launched in the terminal, I’ll usually want Emacs to be displayed in
|
||||
CLI mode and not in GUI mode, otherwise I would invoke it with my WM’s shortcut.
|
||||
In case we want to launch Emacs in GUI mode anyway, ~egui~ is available too.
|
||||
|
||||
#+NAME: abbr-text-ed
|
||||
| abbreviation | command |
|
||||
|--------------+-----------------------|
|
||||
| e | emacsclient -c -n |
|
||||
| egui | devour emacsclient -c |
|
||||
|
||||
Here is the corresponding fish configuration:
|
||||
#+BEGIN_SRC fish :noweb yes
|
||||
<<generate-abbr(table=abbr-text-ed)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Compilation
|
||||
By default, I set ~clang~, ~clang++~, ~gcc~ and ~g++~ to the latest standard and
|
||||
with the ~-Wall~ flag activated.
|
||||
#+NAME: abbr-comp
|
||||
| abbreviation | command |
|
||||
|--------------+----------------------|
|
||||
| clang | clang -Wall |
|
||||
| clang++ | clang++ -Wall |
|
||||
| g++ | g++ -Wall -std=c++20 |
|
||||
| gcc | gcc -Wall -std=c18 |
|
||||
|
||||
Here is the corresponding fish configuration:
|
||||
#+BEGIN_SRC fish
|
||||
<<generate-abbr(table=abbr-comp)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Git
|
||||
And let's face it: we all at one point just wanted to commit our code without
|
||||
thinking about the message, to just get over with it. Don't worry, I got you
|
||||
covered.
|
||||
#+NAME: abbr-git
|
||||
| abbreviation | command |
|
||||
|--------------+-----------------------------------------------------|
|
||||
| randcommit | git commit -m (curl -s whatthecommit.com/index.txt) |
|
||||
|
||||
Here is the corresponding fish configuration:
|
||||
#+BEGIN_SRC fish
|
||||
<<generate-abbr(table=abbr-git)>>
|
||||
#+END_SRC
|
||||
|
||||
*** LaTeX
|
||||
Yes, although I use org-mode, I still have some use for LaTeX, especially when
|
||||
it comes to PDF exports of my org files. Hence, why I use the LaTeX package
|
||||
manager. It is recommended to use ~tllocalmgr~ instead of ~tlmgr~, but I can
|
||||
never remember the command, and the latter is faster to type, so time for an
|
||||
abbreviation. Same goes for ~texhash~ which must be run as sudo.
|
||||
#+NAME: latex-abbr
|
||||
| abbreviation | command |
|
||||
|--------------+--------------|
|
||||
| tlmgr | tllocalmgr |
|
||||
| texhash | sudo texhash |
|
||||
|
||||
Here is the corresponding fish configuration:
|
||||
#+BEGIN_SRC fish
|
||||
<<generate-abbr(table=latex-abbr)>>
|
||||
#+END_SRC
|
||||
|
||||
*** Some security measures
|
||||
Some commands can be quite dangerous when not used properly, which is
|
||||
why I added default flags and options in order to get warnings before
|
||||
things get ugly. The =-i= and =-I= add prompts in case we might not want
|
||||
to do what we asked the shell to do. Notice =lns= which creates
|
||||
symlinks, =rmd= which removes directories, =rmf= which forces deletion,
|
||||
and =rmdf= which forces the delition of a directory. Notice also the
|
||||
=--preserve-root= which will prevent me from accidentally removing the
|
||||
root folder. I added the same option to =chgrp=, =chmod=, and =chown=.
|
||||
#+NAME: sec-abbr
|
||||
| abbreviation | command |
|
||||
|--------------+--------------------------|
|
||||
| cp | cp -i |
|
||||
| rsync | rsync -Pa --progress |
|
||||
| ln | ln -i |
|
||||
| lns | ln -si |
|
||||
| mv | mv -i |
|
||||
| rm | rm -Iv |
|
||||
| rmd | rm --preserve-root -Irv |
|
||||
| rmdf | rm --preserve-root -Irfv |
|
||||
| rmf | rm --preserve-root -Ifv |
|
||||
| chgrp | chgrp --preserve-root -v |
|
||||
| chmod | chmod --preserve-root -v |
|
||||
| chown | chown --preserve-root -v |
|
||||
|
||||
Here is the corresponding fish configuration:
|
||||
#+BEGIN_SRC fish
|
||||
<<generate-abbr(table=sec-abbr)>>
|
||||
#+END_SRC
|
||||
|
||||
*** Typos
|
||||
Let's admit it, we all make typos from time to time in the shell, and some are
|
||||
recurrent enough we make abbreviations or aliases of the correct command. Well,
|
||||
I have some of my abbreviations which were make exactly because of this.
|
||||
Sometimes for some reasons, my brain makes me write ~clean~ instead of ~clear~.
|
||||
So, let's just replace the former by the latter. I'm also very bad at typing
|
||||
~exit~. And sometimes I suck at typing ~htop~.
|
||||
#+NAME: typo-abbr
|
||||
| abbreviation | command |
|
||||
|--------------+---------|
|
||||
| clean | clear |
|
||||
| exi | exit |
|
||||
| exti | exit |
|
||||
| hotp | htop |
|
||||
|
||||
Here is the corresponding fish configuration:
|
||||
#+BEGIN_SRC fish
|
||||
<<generate-abbr(table=typo-abbr)>>
|
||||
#+END_SRC
|
||||
|
||||
*** Misc
|
||||
Finally, some miscellaneous abbreviations that don't really fit into any of the
|
||||
above categories.
|
||||
|
||||
**** Screens setup
|
||||
I have an automatic screen setup for when I am at home, but it
|
||||
unfortunately doesn’t match my setup at work. =autorandr horizontal=
|
||||
does not work because my third screen is vertical, the wallpaper is
|
||||
misaligned, and picom becomes too taxing on my system. I ended up
|
||||
writing the following command each morning, but now a simple abbrev
|
||||
does the work for me.
|
||||
#+begin_src fish
|
||||
abbr work 'autorandr -l work; xwallpaper --zoom (cat $HOME/.cache/wallpaper); pkill picom'
|
||||
#+end_src
|
||||
|
||||
**** Media
|
||||
Here you will find various commands related to media in general. The
|
||||
first one is a command to play some chillhop from the [[https://www.youtube.com/@LofiGirl][Lofi Girl
|
||||
YouTube channel]]'s livestream.
|
||||
#+BEGIN_SRC fish
|
||||
abbr chill 'mpv --force-window=no --no-video "https://www.youtube.com/watch?v=jfKfPfyJRdk" &'
|
||||
#+END_SRC
|
||||
|
||||
When it comes to mpv, I do not want to force it to open a graphical window if
|
||||
for example I want to listen to an audio file. I also do not want any border on
|
||||
that window. So, I declared this abbreviation.
|
||||
#+BEGIN_SRC fish
|
||||
abbr mpv 'mpv --no-border --force-window=no'
|
||||
#+END_SRC
|
||||
|
||||
When I want to download a song from YouTube, I'll just use the command ~flac
|
||||
videoIdentifier~ to get it through ~youtube-dl~.
|
||||
#+BEGIN_SRC fish
|
||||
abbr flac 'youtube-dl -x --audio-format flac --audio-quality 0 -o "~/Music/%(uploader)s/%(title)s.%(ext)s"'
|
||||
#+END_SRC
|
||||
|
||||
Some sane default options for [[https://github.com/nsxiv/nsxiv][~nsxiv~]]. This includes playing GIFs and
|
||||
not displaying the filename below. Nsxiv will also open in fullscreen
|
||||
and will fit the displayed image to the frame. It will also output to
|
||||
stdout the selected files in case I want to pipe them to another
|
||||
program.
|
||||
#+BEGIN_SRC fish
|
||||
abbr nsxiv 'nsxiv -abfos f'
|
||||
#+END_SRC
|
||||
|
||||
The following abbreviation is here to launch software with my Nvidia
|
||||
GPU.
|
||||
#+begin_src fish
|
||||
abbr nv 'env __NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia'
|
||||
#+end_src
|
||||
|
||||
Finally, let's declare the following abbreviation that will launch a MPV
|
||||
instance displaying my webcam:
|
||||
#+BEGIN_SRC fish
|
||||
abbr webcam 'devour mpv --demuxer-lavf-format=video4linux2 --demuxer-lavf-o-set=input_format=mjpeg av://v4l2:/dev/video0 --profile=low-latency --untimed'
|
||||
#+END_SRC
|
||||
|
||||
**** Sudo
|
||||
First, I make it so that ~sudo~ comes with the ~-A~ switch in order to call my
|
||||
custom graphical script for getting my password (see [[file:bin.org::#Askpass-d0d7a8c0][askpass]]). I also made it so
|
||||
~please~ is an equivalent to ~sudo -A~ as a joke.
|
||||
#+BEGIN_SRC fish
|
||||
abbr please 'sudo -A'
|
||||
#+END_SRC
|
||||
|
||||
**** History
|
||||
I find it more intuitive and faster to just write ~hist~ instead of ~history~,
|
||||
so let's declare that.
|
||||
#+BEGIN_SRC fish
|
||||
abbr hist history
|
||||
#+END_SRC
|
||||
|
||||
**** Compression
|
||||
It seems it's just like many other people, but I cannot for the life
|
||||
of me remember the syntax of ~tar~. So, I made the following
|
||||
abbreviations, and one day hopefully, after seeing the abbreviations'
|
||||
expansion over and over I'll remember the command like I did for the
|
||||
abbreviation of ~remove~ (see [[file:./fish.md#package-management][Package management]]).
|
||||
#+NAME: tar-abbr
|
||||
| abbreviation | command |
|
||||
|--------------+-----------|
|
||||
| compress | tar -czf |
|
||||
| untar | tar -xvzf |
|
||||
|
||||
#+BEGIN_SRC fish
|
||||
<<generate-abbr(table=tar-abbr)>>
|
||||
#+END_SRC
|
||||
|
||||
**** exa
|
||||
#+NAME: exa-abbr
|
||||
| abbreviation | command |
|
||||
|--------------+--------------------------------------------|
|
||||
| exa | exa -halg@ --group-directories-first --git |
|
||||
| lsl | exa -halg@ --group-directories-first --git |
|
||||
|
||||
#+BEGIN_SRC fish
|
||||
<<generate-abbr(table=exa-abbr)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Network Management
|
||||
First, we have just =nmcli= with sane default options, that is a pretty output
|
||||
with colors.
|
||||
#+BEGIN_SRC fish
|
||||
abbr nmcli 'nmcli -p -c auto'
|
||||
#+END_SRC
|
||||
|
||||
**** NordVPN
|
||||
Next, we have some NordVPN-related shortcuts. The first one is a simple
|
||||
abbreviation to =nordvpn=. The second one is a shortcut to connect to a server,
|
||||
and to disconnect from the current server. I also have a couple of shortcuts to
|
||||
quickly connect to some preselected countries, mainly France, Germany, Japan and
|
||||
the US.
|
||||
#+NAME: nordvpn-abbr
|
||||
| abbreviation | command |
|
||||
|--------------+-------------------------|
|
||||
| n | nordvpn |
|
||||
| nc | nordvpn c |
|
||||
| nd | nordvpn d |
|
||||
| ncf | nordvpn c France |
|
||||
| ncg | nordvpn c Germany |
|
||||
| ncj | nordvpn c Japan |
|
||||
| ncu | nordvpn c United_States |
|
||||
|
||||
#+BEGIN_SRC fish
|
||||
<<generate-abbr(table=nordvpn-abbr)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Wget
|
||||
By default, continue a download that was interupted.
|
||||
#+BEGIN_SRC fish
|
||||
abbr wget 'wget --hsts-file="$XDG_DATA_HOME/wget-hsts" -c'
|
||||
#+END_SRC
|
||||
|
||||
** Last thing before we’re done
|
||||
For some reason, Fish began searching for packages when I enter a command name
|
||||
wrong. For instance, if I type ~vim~, I get something like this:
|
||||
#+BEGIN_SRC text :tangle no
|
||||
$ vim
|
||||
fish: Unknown command: vim
|
||||
usr/bin/vim is owned by extra/gvim 8.2.2653-1
|
||||
usr/bin/vim is owned by extra/vim 8.2.2653-1
|
||||
#+END_SRC
|
||||
|
||||
But I don’t want that, it slows down my shell. So, in order to fix that, we need
|
||||
the following lines:
|
||||
#+BEGIN_SRC fish
|
||||
function fish_command_not_found
|
||||
__fish_default_command_not_found_handler $argv
|
||||
end
|
||||
#+END_SRC
|
||||
|
||||
Tadah! No more package suggestions from fish!
|
||||
|
||||
I also have some private abbreviations I don’t want people to know
|
||||
about that I store in a separate configuration file.
|
||||
#+begin_src fish
|
||||
source $HOME/.config/fish/private.fish
|
||||
#+end_src
|
||||
295
docs/git.org
Normal file
@@ -0,0 +1,295 @@
|
||||
# -*- indent-tabs-mode: t; -*-
|
||||
#+title: Git
|
||||
#+setupfile: headers
|
||||
#+PROPERTY: header-args :exports code :tangle no
|
||||
#+PROPERTY: header-args:conf-unix :mkdirp yes :tangle ~/.config/git/config :exports code :noweb yes
|
||||
|
||||
* Git
|
||||
** Basic configuration
|
||||
#+begin_src conf-unix
|
||||
# -*- indent-tabs-mode: t; -*-
|
||||
#+end_src
|
||||
|
||||
#+begin_src conf-unix
|
||||
[user]
|
||||
email = lucien@phundrak.com
|
||||
name = Lucien Cartier-Tilet
|
||||
signingkey = BD7789E705CB8DCA
|
||||
#+end_src
|
||||
|
||||
#+begin_src conf-unix
|
||||
[core]
|
||||
editor = emacsclient -c -a emacs
|
||||
whitespace = fix,-indent-with-non-tab,trailing-space
|
||||
excludesfile = /home/phundrak/.gitignore_global
|
||||
#+end_src
|
||||
|
||||
#+begin_src conf-unix
|
||||
[pull]
|
||||
rebase = true
|
||||
#+end_src
|
||||
|
||||
#+begin_src conf-unix
|
||||
[init]
|
||||
defaultBranch = main
|
||||
#+end_src
|
||||
|
||||
#+begin_src conf-unix
|
||||
[color]
|
||||
ui = auto
|
||||
#+end_src
|
||||
|
||||
#+begin_src conf-unix
|
||||
[web]
|
||||
browser = firefox
|
||||
#+end_src
|
||||
|
||||
** Aliases
|
||||
#+name: git-add-abbrev
|
||||
| abbreviation | equivalent |
|
||||
|--------------+------------------------------------------------|
|
||||
| =a= | =add --all= |
|
||||
| =aca= | =!git add --all && git commit --amend= |
|
||||
| =acan= | =!git add --all && git commit --amend --no-edit= |
|
||||
|
||||
#+name: abbrev-gen
|
||||
#+begin_src emacs-lisp :tangle no :exports none :var abbrevs=git-push-abbrev :wrap "src conf-unix :tangle no"
|
||||
(mapconcat (lambda (abbreviation)
|
||||
(replace-regexp-in-string
|
||||
(concat (regexp-quote "\\vert") (rx (? "{}")))
|
||||
"|"
|
||||
(concat "\t"
|
||||
(string-replace "=" "" (car abbreviation))
|
||||
" = "
|
||||
(string-replace "=" "" (cadr abbreviation)))))
|
||||
abbrevs
|
||||
"\n")
|
||||
#+end_src
|
||||
|
||||
#+RESULTS: abbrev-gen
|
||||
#+begin_src conf-unix :tangle no
|
||||
ps = push
|
||||
psf = push --force-with-lease
|
||||
pso = push origin
|
||||
psfo = push --force-with-lease origin
|
||||
pushall = !git remote | xargs -L1 git push
|
||||
psl = !git remote | xargs -L1 git push
|
||||
pullall = !git remote | xargs -L1 git pull
|
||||
pll = !git remote | xargs -L1 git pull
|
||||
#+end_src
|
||||
|
||||
#+name: git-branch-abbrev
|
||||
| abbreviation | equivalent |
|
||||
|--------------+------------|
|
||||
| =b= | =branch= |
|
||||
| =bd= | =branch -d= |
|
||||
| =bdd= | =branch -D= |
|
||||
|
||||
#+name: git-commit-abbrev
|
||||
| abbreviation | equivalent |
|
||||
|--------------+----------------------|
|
||||
| =c= | =commit -S= |
|
||||
| =ca= | =commit -Sa= |
|
||||
| =can= | =commit -Sa --no-edit= |
|
||||
| =cm= | =commit -Sm= |
|
||||
| =cam= | =commit -Sam= |
|
||||
|
||||
#+name: git-checkout-abbrev
|
||||
| abbreviation | equivalent |
|
||||
|--------------+------------------|
|
||||
| =co= | =checkout= |
|
||||
| =cob= | =checkout -b= |
|
||||
| =cod= | =checkout develop= |
|
||||
|
||||
#+name: git-clone-abbrev
|
||||
| abbreviation | equivalent |
|
||||
|--------------+-----------------|
|
||||
| =cl= | =clone= |
|
||||
| =cl1= | =clone --depth 1= |
|
||||
|
||||
#+name: git-fetch-abbrev
|
||||
| abbreviation | equivalent |
|
||||
|--------------+---------------|
|
||||
| =f= | =fetch= |
|
||||
| =fp= | =fetch --prune= |
|
||||
|
||||
#+name: git-push-abbrev
|
||||
| abbreviation | equivalent |
|
||||
|--------------+----------------------------------|
|
||||
| =ps= | =push= |
|
||||
| =psf= | =push --force-with-lease= |
|
||||
| =pso= | =push origin= |
|
||||
| =psfo= | =push --force-with-lease origin= |
|
||||
| =pushall= | =!git remote \vert{} xargs -L1 git push= |
|
||||
| =psl= | =!git remote \vert{} xargs -L1 git push= |
|
||||
| =pullall= | =!git remote \vert{} xargs -L1 git pull= |
|
||||
| =pll= | =!git remote \vert{} xargs -L1 git pull= |
|
||||
|
||||
#+name: git-pull-abbrev
|
||||
| abbreviation | equivalent |
|
||||
|--------------+---------------|
|
||||
| =pl= | =pull= |
|
||||
| =pb= | =pull --rebase= |
|
||||
|
||||
#+name: git-rebase-abbrev
|
||||
| abbreviation | equivalent |
|
||||
|--------------+-------------------|
|
||||
| =r= | =rebase= |
|
||||
| =ra= | =rebase --abort= |
|
||||
| =rc= | =rebase --continue= |
|
||||
| =rd= | =rebase develop= |
|
||||
| =ri= | =rebase -i= |
|
||||
|
||||
#+name: git-rm-abbrev
|
||||
| abbreviation | equivalent |
|
||||
|--------------+------------|
|
||||
| =rmf= | =rm -f= |
|
||||
| =rmd= | =rm -r= |
|
||||
| =rmdf= | =rm -rf= |
|
||||
|
||||
#+name: git-submodule-abbrev
|
||||
| abbreviation | equivalent |
|
||||
|--------------+-------------------------------------|
|
||||
| =sm= | =submodule= |
|
||||
| =sms= | =submodule status= |
|
||||
| =sma= | =submodule add= |
|
||||
| =smu= | =submodule update= |
|
||||
| =smui= | =submodule update --init= |
|
||||
| =smuir= | =submodule update --init --recursive= |
|
||||
|
||||
#+name: git-stash-abbrev
|
||||
| abbreviation | equivalent |
|
||||
|--------------+-------------|
|
||||
| =st= | =stash= |
|
||||
| =stc= | =stash clear= |
|
||||
| =stp= | =stash pop= |
|
||||
| =stw= | =stash show= |
|
||||
|
||||
#+name: git-unstage-abbrev
|
||||
| abbreviation | equivalent |
|
||||
|--------------+------------|
|
||||
| =u= | =reset --= |
|
||||
| =unstage= | =reset --= |
|
||||
|
||||
#+name: git-single-abbrev
|
||||
| abbreviation | equivalent |
|
||||
|--------------+----------------------------------|
|
||||
| =d= | =diff -w= |
|
||||
| =l= | =log --oneline --graph --decorate= |
|
||||
| =s= | =status= |
|
||||
| =staged= | =diff --cached= |
|
||||
| =upstream= | =!git push -u origin HEAD= |
|
||||
|
||||
#+RESULTS:
|
||||
: a = add --all
|
||||
: aca = !git add --all && git commit --amend
|
||||
: acan = !git add --all && git commit --amend --no-edit
|
||||
|
||||
#+begin_src conf-unix
|
||||
[alias]
|
||||
<<abbrev-gen(abbrevs=git-add-abbrev)>>
|
||||
<<abbrev-gen(abbrevs=git-branch-abbrev)>>
|
||||
<<abbrev-gen(abbrevs=git-commit-abbrev)>>
|
||||
<<abbrev-gen(abbrevs=git-checkout-abbrev)>>
|
||||
<<abbrev-gen(abbrevs=git-clone-abbrev)>>
|
||||
<<abbrev-gen(abbrevs=git-fetch-abbrev)>>
|
||||
<<abbrev-gen(abbrevs=git-push-abbrev)>>
|
||||
<<abbrev-gen(abbrevs=git-pull-abbrev)>>
|
||||
<<abbrev-gen(abbrevs=git-rebase-abbrev)>>
|
||||
<<abbrev-gen(abbrevs=git-rm-abbrev)>>
|
||||
<<abbrev-gen(abbrevs=git-submodule-abbrev)>>
|
||||
<<abbrev-gen(abbrevs=git-stash-abbrev)>>
|
||||
<<abbrev-gen(abbrevs=git-unstage-abbrev)>>
|
||||
<<abbrev-gen(abbrevs=git-single-abbrev)>>
|
||||
#+end_src
|
||||
|
||||
** Tools
|
||||
*** Sendemail
|
||||
#+begin_src conf-unix
|
||||
[sendemail]
|
||||
smtpserver = mail.phundrak.com
|
||||
smtpuser = lucien@phundrak.com
|
||||
smtpencryption = tls
|
||||
smtpserverport = 587
|
||||
#+end_src
|
||||
|
||||
#+begin_src conf-unix
|
||||
[credentials "smtp://lucien@phundrak.com@mail.phundrak.com:587"]
|
||||
helper = "secret-tool lookup password email_lucien-phundrak-com"
|
||||
#+end_src
|
||||
|
||||
*** Magit
|
||||
#+begin_src conf-unix
|
||||
[magithub]
|
||||
online = true
|
||||
[magithub "status"]
|
||||
includeStatusHeader = true
|
||||
includePullRequestsSection = true
|
||||
includeIssuesSection = true
|
||||
#+end_src
|
||||
|
||||
*** GPG
|
||||
#+begin_src conf-unix
|
||||
[gpg]
|
||||
program = gpg2
|
||||
[commit]
|
||||
gpgsign = true
|
||||
#+end_src
|
||||
|
||||
*** Merge
|
||||
#+begin_src conf-unix
|
||||
[merge]
|
||||
tool = ediff
|
||||
#+end_src
|
||||
|
||||
#+begin_src conf-unix
|
||||
[mergetool.ediff]
|
||||
cmd = emacs --eval \" (progn (defun ediff-write-merge-buffer () (let ((file ediff-merge-store-file)) (set-buffer ediff-buffer-C) (write-region (point-min) (point-max) file) (message \\\"Merge buffer saved in: %s\\\" file) (set-buffer-modified-p nil) (sit-for 1))) (setq ediff-quit-hook 'kill-emacs ediff-quit-merge-hook 'ediff-write-merge-buffer) (ediff-merge-files-with-ancestor \\\"$LOCAL\\\" \\\"$REMOTE\\\" \\\"$BASE\\\" nil \\\"$MERGED\\\"))\"
|
||||
#+end_src
|
||||
|
||||
*** Pager
|
||||
#+begin_src conf-unix
|
||||
[pager]
|
||||
diff = delta
|
||||
log = delta
|
||||
reflog = delta
|
||||
show = delta
|
||||
#+end_src
|
||||
|
||||
*** Delta
|
||||
#+begin_src conf-unix
|
||||
[delta]
|
||||
features = side-by-side line-numbers decorations
|
||||
whitespace-error-style = 22 reverse
|
||||
|
||||
[delta "decorations"]
|
||||
commit-decoration-style = bold yellow box ul
|
||||
file-style = bold yellow ul
|
||||
file-decoration-style = none
|
||||
|
||||
[interactive]
|
||||
diffFilter = delta --color-only
|
||||
#+end_src
|
||||
|
||||
*** Git forges
|
||||
#+begin_src conf-unix
|
||||
[github]
|
||||
user = phundrak
|
||||
#+end_src
|
||||
|
||||
#+begin_src conf-unix
|
||||
[url "https://phundrak@github.com"]
|
||||
insteadOf = https://github.com
|
||||
|
||||
[url "https://phundrak@labs.phundrak.com"]
|
||||
insteadOf = https://labs.phundrak.com
|
||||
#+end_src
|
||||
|
||||
*** LFS
|
||||
#+begin_src conf-unix
|
||||
[filter "lfs"]
|
||||
required = true
|
||||
clean = git-lfs clean -- %f
|
||||
smudge = git-lfs smudge -- %f
|
||||
process = git-lfs filter-process
|
||||
#+end_src
|
||||
21
docs/headers
Normal file
@@ -0,0 +1,21 @@
|
||||
# -*- mode: org -*-
|
||||
#+AUTHOR: Lucien Cartier-Tilet
|
||||
#+EMAIL: lucien@phundrak.com
|
||||
#+CREATOR: Lucien Cartier-Tilet
|
||||
#+LANGUAGE: en
|
||||
|
||||
# ### ORG OPTIONS ##############################################################
|
||||
|
||||
#+options: H:4 broken_links:mark email:t ^:{} tex:dvisvgm toc:nil
|
||||
#+KEYWORDS: dotfiles, linux, emacs, configuration, phundrak, drakpa
|
||||
#+startup: content align hideblocks
|
||||
#+property: header-args:emacs-lisp :noweb yes :exports none :eval yes :cache yes
|
||||
#+property: header-args:dot :dir img :exports results :eval yes :cache yes :class gentree
|
||||
|
||||
# ### MACROS ###################################################################
|
||||
#+macro: phon @@html:/$1/@@
|
||||
#+macro: newline @@html:<br>@@
|
||||
#+macro: latex-html @@latex:$1@@@@html:$2@@
|
||||
#+macro: v @@html:<span class=vertical>$1</span>@@
|
||||
#+macro: begin-largetable @@html:<div class="largetable">@@
|
||||
#+macro: end-largetable @@html:</div>@@
|
||||
9
docs/img/emacs/emacs-eshell.svg
Normal file
|
After Width: | Height: | Size: 323 KiB |
BIN
docs/img/emacs/emacs.png
Normal file
|
After Width: | Height: | Size: 592 KiB |
9
docs/img/emacs/emacs.svg
Normal file
|
After Width: | Height: | Size: 4.3 MiB |
1493
docs/img/emacs/eshell.svg
Normal file
|
After Width: | Height: | Size: 114 KiB |
2540
docs/img/emacs/org-mode.svg
Normal file
|
After Width: | Height: | Size: 415 KiB |
BIN
docs/img/emacs/real_programmers.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
docs/img/icon.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
docs/img/icon.webp
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
docs/img/stumpwm.png
Normal file
|
After Width: | Height: | Size: 395 KiB |
88
docs/mpd.org
Normal file
@@ -0,0 +1,88 @@
|
||||
#+title: MPD Configuration
|
||||
#+setupfile: headers
|
||||
#+property: header-args:emacs-lisp :lexical t :exports none :tangle no
|
||||
#+property: header-args:emacs-lisp+ :noweb yes :wrap src conf-space
|
||||
#+property: header-args:conf-space :tangle ~/.config/mpd/mpd.conf :noweb yes :exports code
|
||||
|
||||
* MPD
|
||||
As its name indicates, the [[https://www.musicpd.org/][Music Player Daemon]] --- or MPD for short
|
||||
--- is a daemon that manages music files on a computer and plays them.
|
||||
It can be manipulated by various front-end applications, such as the
|
||||
command-line utility ~mpc~, TUI ~ncmpcpp~, or GUI ~cantata~. In my case, I
|
||||
use mainly ~ncmpcpp~ and Emacs’ EMMS.
|
||||
|
||||
On my computer, MPD runs as a user daemon, as seen in [[file:bootstrap.org::#Execute_bootstrap-Enable_some_services-Mpd-f0f5b9b7][my bootstrap
|
||||
file here]].
|
||||
|
||||
** Required Parameters
|
||||
MPD requires a few compulsory parameters that we will see below.
|
||||
#+name: mpd-required-parameters
|
||||
| Parameter name | Value | Comment |
|
||||
|-------------------------+---------------------------+--------------------------------------------------------------------------|
|
||||
| =follow_outside_symlinks= | =yes= | Whether to follow symlinks pointing outside the music directory |
|
||||
| =follow_inside_symlinks= | =yes= | Whether to follow symlinks pointing inside the music directory |
|
||||
| =db_file= | =~/.config/mpd/database= | Location of MPD’s database |
|
||||
| =sticker_file= | =~/.config/mpd/sticker.sql= | Location of the sticker database (dynamic information attached to songs) |
|
||||
| =log_file= | =~/.config/mpd/log= | Location of MPD’s log file |
|
||||
|
||||
#+name: mpd-gen-values
|
||||
#+begin_src emacs-lisp :var table=mpd-required-parameters :exports results
|
||||
(mapconcat (lambda (parameter)
|
||||
(let* ((trim-name (lambda (parameter)
|
||||
(replace-regexp-in-string (regexp-quote "=")
|
||||
""
|
||||
parameter)))
|
||||
(name (apply trim-name `(,(car parameter))))
|
||||
(value (apply trim-name `(,(cadr parameter)))))
|
||||
(format "%s \"%s\"" name value)))
|
||||
table
|
||||
"\n")
|
||||
#+end_src
|
||||
|
||||
#+RESULTS: mpd-gen-values
|
||||
#+begin_src conf-space
|
||||
follow_outside_symlinks "yes"
|
||||
follow_inside_symlinks "yes"
|
||||
db_file "~/.config/mpd/database"
|
||||
sticker_file "~/.config/mpd/sticker.sql"
|
||||
log_file "~/.config/mpd/log"
|
||||
#+end_src
|
||||
|
||||
** Optional Parameters
|
||||
While these values are not strictly necessary, some are still useful
|
||||
such as ~music_directory~: we don’t have to manually add our music to
|
||||
MPD each time we run it.
|
||||
#+name: mpd-optional-parameters
|
||||
| Parameter | Value | Comment |
|
||||
|--------------------+---------------------+-----------------------------------------------------------|
|
||||
| =music_directory= | =~/Music= | Location of the music directory |
|
||||
| =playlist_directory= | =~/Music/playlists= | Location of MPD playlists |
|
||||
| =pid_file= | =~/.config/mpd/pid= | Location of MPD’s PID |
|
||||
| =state_file= | =~/.config/mpd/state= | File where the state of MPD is saved when killed |
|
||||
| =bind_to_address= | =localhost= | Limit MPD to the localhost address |
|
||||
| =auto_update= | =yes= | No need to manually update MPD’s database with ~mpc update~ |
|
||||
|
||||
#+begin_src conf-space
|
||||
<<mpd-gen-values(table=mpd-optional-parameters)>>
|
||||
#+end_src
|
||||
|
||||
** Audio outputs
|
||||
Two audio outputs will be defined. The first one sets Pulseaudio up so
|
||||
I can actually hear my music. Its configuration is simple, really.
|
||||
#+begin_src conf-space
|
||||
audio_output {
|
||||
type "pulse"
|
||||
name "pulse audio"
|
||||
}
|
||||
#+end_src
|
||||
|
||||
Another one sets up the visualizer of ~ncmpcpp~. It is not necessary to
|
||||
create this one if you don’t plan on using this feature.
|
||||
#+begin_src conf-space
|
||||
audio_output {
|
||||
type "fifo"
|
||||
name "my_fifo"
|
||||
path "/tmp/mpd.fifo"
|
||||
format "44100:16:2"
|
||||
}
|
||||
#+end_src
|
||||
491
docs/neofetch.org
Normal file
@@ -0,0 +1,491 @@
|
||||
#+title: Neofetch
|
||||
#+setupfile: headers
|
||||
#+PROPERTY: header-args :noweb yes :exports code :tangle no :exports none
|
||||
#+PROPERTY: header-args:sh :tangle ~/.config/neofetch/config.conf :exports code
|
||||
#+PROPERTY: header-args:sh+ :noweb yes :padline no :mkdirp yes
|
||||
|
||||
* Neofetch
|
||||
[[https://github.com/dylanaraps/neofetch][Neofetch]] is a CLI utility used to display system information. It was written in
|
||||
Bash, and thus its configuration file is written as a Bash script too. This
|
||||
document was written with org-mode, and my configuration file is tangled from
|
||||
the source blocks you will see below to ~~/.config/neofetch/config.conf~. This
|
||||
configuration will only contain what I need. For any further information, please
|
||||
refer to the [[https://github.com/dylanaraps/neofetch][original repository]] and [[https://github.com/dylanaraps/neofetch/wiki/Customizing-Info][its documentation]].
|
||||
|
||||
** The ~print_info~ functions
|
||||
The ~print_info~ function is the function called by Neofetch in order to print
|
||||
the system information it could fetch. In this function, we’ll choose what to
|
||||
display, and how. This function looks like this:
|
||||
#+BEGIN_SRC sh :tangle no
|
||||
print_info() {
|
||||
# Print information here…
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
Generally, what we will display will be shown through the ~info~ function,
|
||||
redefined inside Neofetch (this is not ~info(1)~). This ~info~ function accepts
|
||||
one or two arguments. With one argument, such as with ~info memory~, we can get
|
||||
a result that looks like ~5136MiB / 15873MiB~, while calling it with two
|
||||
arguments will treat the first one as a prefix and the second one as the
|
||||
interesting information; ~info "Memory" memory~ will look like
|
||||
~Memory: 5136MiB / 15873MiB~. Here is what we want to display:
|
||||
#+NAME: info-elements-table
|
||||
| Prefix | Information | What it does |
|
||||
|----------+-------------+------------------------------|
|
||||
| | title | Username and hostname |
|
||||
| | line_break | Insert a blank line |
|
||||
| | cols | System theme |
|
||||
| | line_break | Insert a blank line |
|
||||
| Distro | distro | Distribution name |
|
||||
| Kernel | kernel | Kernel version |
|
||||
| Uptime | uptime | Machine uptime |
|
||||
| Packages | packages | Number of installed packages |
|
||||
| Shell | shell | User’s default shell |
|
||||
| WM | wm | User’s Window Manager |
|
||||
| Terminal | term | Default terminal |
|
||||
| CPU | cpu | CPU information |
|
||||
| GPU | gpu | GPU information |
|
||||
| Memory | memory | RAM information |
|
||||
|
||||
#+NAME: info-elements-gen
|
||||
#+BEGIN_SRC emacs-lisp :var table=info-elements-table :cache yes
|
||||
(mapconcat (lambda (x)
|
||||
(let ((prefix (car x))
|
||||
(information (cadr x)))
|
||||
(format "info %s%s"
|
||||
(if (not (string= prefix ""))
|
||||
(format "\"%s\" " prefix)
|
||||
"")
|
||||
information)))
|
||||
table
|
||||
"\n")
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS[83eb4aaa554df955ad996157d911eec3a9251628]: info-elements-gen
|
||||
#+begin_example
|
||||
info title
|
||||
info line_break
|
||||
info cols
|
||||
info line_break
|
||||
info "Distro" distro
|
||||
info "Kernel" kernel
|
||||
info "Uptime" uptime
|
||||
info "Packages" packages
|
||||
info "Shell" shell
|
||||
info "WM" wm
|
||||
info "Terminal" term
|
||||
info "CPU" cpu
|
||||
info "GPU" gpu
|
||||
info "Memory" memory
|
||||
#+end_example
|
||||
|
||||
Hence, the function looks like so:
|
||||
#+BEGIN_SRC sh
|
||||
print_info() {
|
||||
<<info-elements-gen()>>
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
Each of these modules can be tuned with the variables presented below.
|
||||
|
||||
** Information settings
|
||||
Each of the following variable tunes a function that can be called in
|
||||
~print_info~ described above. It is possible to tune them by modifying this
|
||||
document or the configuration file itself, and they can be overridden by the
|
||||
command line with flags passed to ~neofetch~. I will divide these variables in
|
||||
two main categories: hardware and software-related properties.
|
||||
|
||||
*** Software
|
||||
**** OS
|
||||
***** Distro
|
||||
This variable can shorten the output of the ~distro~ function.
|
||||
- Default value :: ~"on"~
|
||||
- Values ::
|
||||
- ~"on"~
|
||||
- ~"off"~
|
||||
- Flag :: ~--distro_shorthand~
|
||||
- Supports :: Everything except Windows and Haiku
|
||||
- Examples ::
|
||||
- on :: ~Arch Linux~
|
||||
- off :: ~Arch~
|
||||
#+begin_src sh
|
||||
distro_shorthand="off"
|
||||
#+end_src
|
||||
|
||||
It is possible to display when the distro has been installed on the computer.
|
||||
|
||||
****** Distro art or image
|
||||
By default, Neofetch will display ascii art next to our system information
|
||||
representing our distro’s logo. We’ll customize it a bit. First, let’s change
|
||||
the ~backend~ value. Note that most of them (except ~off~ of course) support
|
||||
shorthands such as ~--kitty~ when passed as arguments from the command line. In
|
||||
my case, I will use the Kitty backend since it is the native backend of the
|
||||
terminal emulator I use.
|
||||
- Default value :: ~"ascii"~
|
||||
- Values ::
|
||||
- ~ascii~
|
||||
- ~caca~
|
||||
- ~catimg~
|
||||
- ~chafa~
|
||||
- ~jp2a~
|
||||
- ~iterm2~
|
||||
- ~off~
|
||||
- ~pot~
|
||||
- ~termpix~
|
||||
- ~pixterm~
|
||||
- ~tycat~
|
||||
- ~w3m~
|
||||
- ~kitty~
|
||||
- ~ueberzug~
|
||||
- ~viu~
|
||||
- flag :: ~--backend~
|
||||
#+BEGIN_SRC sh
|
||||
image_backend="kitty"
|
||||
#+END_SRC
|
||||
|
||||
Now, since I indicated I wanted an image engine, I’ll indicate neofetch which
|
||||
image to find. Note that ~auto~ will pick the best image source for whatever
|
||||
image backend is used. In ascii mode, distro ascii art will be used and in an
|
||||
image mode, your wallpaper will be used.
|
||||
- Default value :: ~auto~
|
||||
- Values ::
|
||||
- ~auto~
|
||||
- ~ascii~
|
||||
- ~wallpaper~
|
||||
- ~/path/to/img~
|
||||
- ~/path/to/ascii~
|
||||
- ~/path/to/dir/~
|
||||
- ~command output (neofetch --ascii "$(fortune | cowsay -W 30)")~
|
||||
- Flag :: ~--source~
|
||||
#+BEGIN_SRC sh
|
||||
image_source="$HOME/org/config/img/leon.png"
|
||||
#+END_SRC
|
||||
|
||||
The default image size will probably not be correct since it is half the
|
||||
terminal width and I have an ultrawide monitor, so I’ll need to set it manually.
|
||||
- Default value :: ~auto~
|
||||
- Values ::
|
||||
- ~auto~
|
||||
- ~00px~
|
||||
- ~00%~
|
||||
- ~none~
|
||||
- Flag :: ~--image-size~ or ~--size~
|
||||
#+BEGIN_SRC sh
|
||||
image_size="224px"
|
||||
#+END_SRC
|
||||
|
||||
***** Kernel
|
||||
The variable below can shorten the output ofh the ~kernel~ function.
|
||||
- Default value :: ~"on"~
|
||||
- Values ::
|
||||
- ~"on"~
|
||||
- ~"off"~
|
||||
- Flag :: ~--kernel_shorthand~
|
||||
- Supports :: Everything except *BSDs (except PacBSD and PC-BSD)
|
||||
- Examples ::
|
||||
- on :: ~4.8.9-1-ARCH~
|
||||
- off :: ~Linux 4.8.9-1-ARCH~
|
||||
#+begin_src sh
|
||||
kernel_shorthand="off"
|
||||
#+end_src
|
||||
|
||||
***** OS Architecture
|
||||
This variable can show or hide the OS architecture in the ~distro~ output.
|
||||
- Default value :: ~"off"~
|
||||
- Values ::
|
||||
- ~"on"~
|
||||
- ~"off"~
|
||||
- Flag :: ~--os_arch~
|
||||
- Examples ::
|
||||
- on :: ~Arch Linux x86_64~
|
||||
- off :: ~Arch Linux~
|
||||
#+begin_src sh
|
||||
os_arch="off"
|
||||
#+end_src
|
||||
|
||||
***** Packages
|
||||
It is possible to show or hide Package Manager names.
|
||||
- Default :: ~'tiny'~
|
||||
- Values :: ~'on'~ / ~'tiny'~ / ~'off'~
|
||||
- Flag :: ~--package_managers~
|
||||
- Example ::
|
||||
- on :: ~'998 (pacman), 8 (flatpak), 4 (snap)'~
|
||||
- tiny :: ~'908 (pacman, flatpak, snap)'~
|
||||
- off :: ~'908'~
|
||||
#+BEGIN_SRC sh
|
||||
package_managers="on"
|
||||
#+END_SRC
|
||||
|
||||
***** Shell
|
||||
****** Shell path
|
||||
This allows to show either the path of the user’s shell, or simply its name.
|
||||
- Default value :: ~"off"~
|
||||
- Values ::
|
||||
- ~"on"~
|
||||
- ~"off"~
|
||||
- Flag :: ~--shell_path~
|
||||
- Examples ::
|
||||
- on :: ~/bin/bash~
|
||||
- off :: ~bash~
|
||||
#+begin_src sh
|
||||
shell_path="off"
|
||||
#+end_src
|
||||
|
||||
****** Shell version
|
||||
This allows to show the shell’s version in the output of ~shell~.
|
||||
- Default value :: ~"on"~
|
||||
- Values ::
|
||||
- ~"on"~
|
||||
- ~"off"~
|
||||
- Flag :: ~--shell_version~
|
||||
- Examples ::
|
||||
- on :: ~bash 4.4.5~
|
||||
- off :: ~bash~
|
||||
#+begin_src sh
|
||||
shell_version="off"
|
||||
#+end_src
|
||||
|
||||
**** Uptime
|
||||
This variable can shorten the output of the ~uptime~ function. ~on~ shortens
|
||||
it a bit, while ~tiny~ shortens it greatly.
|
||||
- Default value :: ~"on"~
|
||||
- Values ::
|
||||
- ~"on"~
|
||||
- ~"tiny"~
|
||||
- ~"off"~
|
||||
- Flag :: ~--uptime_shorthand~
|
||||
- Examples ::
|
||||
- on :: ~2 days, 10 hours, 3 mins~
|
||||
- off :: ~2 days, 10 hours, 3 minutes~
|
||||
- tiny :: ~2d 10h 3m~
|
||||
#+begin_src sh
|
||||
uptime_shorthand="on"
|
||||
#+end_src
|
||||
|
||||
**** IP address
|
||||
It is possible to display the machine’s public IP address with the function
|
||||
~ip~. The value below allows the user to change the website used to fetch it.
|
||||
- Default value :: ~"http://ident.me"~
|
||||
- Value :: ~"url"~
|
||||
- Flag :: ~--ip_host~
|
||||
#+begin_src sh
|
||||
public_ip_host="http://ident.me"
|
||||
#+end_src
|
||||
|
||||
# - Default value :: ~""~
|
||||
# - Values ::
|
||||
# - ~""~
|
||||
# - ~""~
|
||||
# - Flag :: ~""~
|
||||
# - Supports ::
|
||||
# - Examples ::
|
||||
# - on :: ~~
|
||||
# - off :: ~~
|
||||
# #+begin_src sh
|
||||
# #+end_src
|
||||
|
||||
**** Theming
|
||||
This section will allow the user to modify what Neofetch can and cannot display
|
||||
about the machine’s theming —by this, I mean its GTK theme, its icons and its
|
||||
default font.
|
||||
|
||||
***** Shorten output
|
||||
With this value, it is possible to shorten the output of the computer’s theming.
|
||||
- Default value :: ~"off"~
|
||||
- Values ::
|
||||
- ~"on"~
|
||||
- ~"off"~
|
||||
- Flag :: ~--gtk_shorthand~
|
||||
- Examples ::
|
||||
- on :: ~Numix, Adwaita~
|
||||
- off :: ~Numix [GTK2], Adwaita [GTK3]~
|
||||
#+begin_src sh
|
||||
gtk_shorthand="on"
|
||||
#+end_src
|
||||
|
||||
***** Enable or disable theming display for GTK2
|
||||
It is possible to explicitely show or hide the computer’s theming with GTK2 with
|
||||
this variable.
|
||||
- Default value :: ~"on"~
|
||||
- Values ::
|
||||
- ~"on"~
|
||||
- ~"off"~
|
||||
- Flag :: ~--gtk2~
|
||||
- Examples ::
|
||||
- on :: ~Numix [GTK2], Adwaita [GTK3]~
|
||||
- off :: ~Adwaita [GTK3]~
|
||||
#+begin_src sh
|
||||
gtk2="off"
|
||||
#+end_src
|
||||
|
||||
***** Enable or disable theming display for GTK3
|
||||
The same variable as above is also available for GTK3.
|
||||
- Default value :: ~"on"~
|
||||
- Values ::
|
||||
- ~"on"~
|
||||
- ~"off"~
|
||||
- Flag :: ~--gtk3~
|
||||
- Examples ::
|
||||
- on :: ~Numix [GTK2], Adwaita [GTK3]~
|
||||
- off :: ~Numix [GTK2]~
|
||||
#+begin_src sh
|
||||
gtk3="off"
|
||||
#+end_src
|
||||
|
||||
*** Hardware
|
||||
**** CPU
|
||||
***** CPU brand
|
||||
With these variables, it is possible to show or hide the brand of a CPU in the
|
||||
~cpu~ output.
|
||||
- Default value :: ~"on"~
|
||||
- Values ::
|
||||
- ~"on"~
|
||||
- ~"off"~
|
||||
- Flag :: ~--cpu_brand~
|
||||
- Examples ::
|
||||
- on :: ~Intel i7-6500U~
|
||||
- off :: ~i7-6500U~
|
||||
#+begin_src sh
|
||||
cpu_brand="off"
|
||||
#+end_src
|
||||
|
||||
***** CPU speed
|
||||
With this variable, it is possible to show or hide the speed of the CPU.
|
||||
- Default value :: ~"on"~
|
||||
- Values ::
|
||||
- ~"on"~
|
||||
- ~"off"~
|
||||
- Flag :: ~--cpu_speed~
|
||||
- Examples ::
|
||||
- on :: ~Intel i7-6500U (4) @ 3.1GHz~
|
||||
- off :: ~Intel i7-6500U (4)~
|
||||
#+begin_src sh
|
||||
cpu_speed="off"
|
||||
#+end_src
|
||||
|
||||
***** CPU speed type
|
||||
This allows Neofetch to know what type of speed it has to fetch regarding the
|
||||
machine’s CPU. Any file in ~/sys/devices/system/cpu/cpu0/cpufreq~ can be used as
|
||||
a value.
|
||||
- Default value :: ~"bios_limit"~
|
||||
- Values ::
|
||||
- ~"scaling_cur_freq"~
|
||||
- ~"scaling_min_freq"~
|
||||
- ~"scaling_max_freq"~
|
||||
- ~"bios_limit"~
|
||||
- Flag :: ~--speed_type~
|
||||
- Supports :: Linux with ~cpufreq~
|
||||
#+begin_src sh
|
||||
speed_type="bios_limit"
|
||||
#+end_src
|
||||
|
||||
***** CPU speed shorthand
|
||||
This value allows showing sorter CPU speed with fewer digits. This flag
|
||||
is not supported in systems with CPU speed below 1GHz.
|
||||
- Default value :: ~"off"~
|
||||
- Values ::
|
||||
- ~"on"~
|
||||
- ~"on"~
|
||||
- Flag :: ~--speed_shorthand~
|
||||
- Examples ::
|
||||
- on :: ~i7-6500U (4) @ 3.1GHz~
|
||||
- off :: ~i7-6500U (4) @ 3.100GHz~
|
||||
#+begin_src sh
|
||||
speed_shorthand="on"
|
||||
#+end_src
|
||||
|
||||
***** CPU cores
|
||||
With this variable, it is possible to display the number of cores that are
|
||||
available in the CPU.
|
||||
- Default value :: ~"logical"~
|
||||
- Values ::
|
||||
- ~"logical"~
|
||||
- ~"physical"~
|
||||
- ~"off"~
|
||||
- Flag :: ~--cpu_cores~
|
||||
- Supports :: ~physical~ does not work on BSD.
|
||||
- Examples ::
|
||||
- logical :: ~Intel i7-6500U (4) @ 3.1GHz~ (All virtual cores)
|
||||
- physical :: ~Intel i7-6500U (2) @ 3.1GHz~ (All physical cores)
|
||||
- off :: ~Intel i7-6500U @ 3.1GHz~
|
||||
#+begin_src sh
|
||||
cpu_cores="off"
|
||||
#+end_src
|
||||
|
||||
***** CPU temperature
|
||||
This variable allows the user to hide or show the CPU’s temperature, and if
|
||||
shown, the user can display it in Celcius or Farenheit degrees. For FreeBSD and
|
||||
NetBSD-based systems, you’ll need to enable the ~coretemp~ kernel module. This
|
||||
only supports newer Intel processors.
|
||||
- Default value :: ~"off"~
|
||||
- Values ::
|
||||
- ~"C"~
|
||||
- ~"F"~
|
||||
- ~"off"~
|
||||
- Flag :: ~--cpu_temp~
|
||||
- Supports :: Linux, BSD
|
||||
- Examples ::
|
||||
- C :: ~Intel i7-6500U (4) @ 3.1GHz [27.2°C]~
|
||||
- F :: ~Intel i7-6500U (4) @ 3.1GHz [82.0°F]~
|
||||
- off :: ~Intel i7-6500U (4) @ 3.1GHz~
|
||||
#+begin_src sh
|
||||
cpu_temp="off"
|
||||
#+end_src
|
||||
|
||||
**** GPU
|
||||
The function responsible for displaying information regarding the GPUs is ~gpu~.
|
||||
It will try to list all available GPUs and display what it knows about them.
|
||||
|
||||
***** GPU brand
|
||||
This value allows the user to hide or show the brand of their GPU in the output
|
||||
of ~gpu~.
|
||||
- Default value :: ~"on"~
|
||||
- Values ::
|
||||
- ~"on"~
|
||||
- ~"off"~
|
||||
- Flag :: ~--gpu_brand~
|
||||
- Supports ::
|
||||
- Examples ::
|
||||
- on :: ~AMD HD 7950~
|
||||
- off :: ~HD 7950~
|
||||
#+begin_src sh
|
||||
gpu_brand="off"
|
||||
#+end_src
|
||||
|
||||
***** Which GPU to display
|
||||
This allows the user to choose which GPU appears in the output of the function
|
||||
~gpu~.
|
||||
- Default value :: ~"all"~
|
||||
- Values ::
|
||||
- ~"all"~
|
||||
- ~"dedicated"~
|
||||
- ~"integrated"~
|
||||
- Flag :: ~--gpu_type~
|
||||
- Supports :: Linux
|
||||
- Examples ::
|
||||
- all ::
|
||||
#+BEGIN_SRC text
|
||||
GPU1: AMD HD 7950
|
||||
GPU2: Intel Integrated Graphics
|
||||
#+END_SRC
|
||||
- dedicated :: ~GPU1: AMD HD 7950~
|
||||
- integrated :: ~GPU1: Intel Integrated Graphics~
|
||||
#+begin_src sh
|
||||
gpu_type="all"
|
||||
#+end_src
|
||||
|
||||
**** Resolution
|
||||
This will try to list all the connected screens and display their resolution
|
||||
individually. It is possible to display the refresh rate or to hide it.
|
||||
- Default value :: ~"off"~
|
||||
- Values ::
|
||||
- ~"on"~
|
||||
- ~"off"~
|
||||
- Flag :: ~--refresh_rate~
|
||||
- Supports :: Does not work on Windows
|
||||
- Examples ::
|
||||
- on :: ~1920x1080 @ 60Hz~
|
||||
- off :: ~1920x1080~
|
||||
#+begin_src sh
|
||||
refresh_rate="off"
|
||||
#+end_src
|
||||
592
docs/picom.org
Normal file
@@ -0,0 +1,592 @@
|
||||
#+title: Picom (Compton) Configuration
|
||||
#+setupfile: headers
|
||||
#+PROPERTY: header-args:conf :exports code :mkdirp yes :tangle ~/.config/picom/picom.conf
|
||||
|
||||
* Picom
|
||||
Picom is the successor to Compton, a standalone compositor for Xorg. It provides
|
||||
compositing for WM that do not provide any, such as i3. I am currently using
|
||||
[[https://github.com/ibhagwan/picom][ibhagwan’s fork of compton]] which provides the ~dual-kawase~ blur from [[https://github.com/tryone144/compton][tryone’s
|
||||
compton]] and rounded corners from [[https://github.com/sdhand/picom][sdhand’s compton]].
|
||||
|
||||
** Shadows
|
||||
The following enables client-side shadows on windows. Note desktop windows
|
||||
(windows with ~_NET_WM_WINDOW_TYPE_DESKTOP~) never get shadow, unless explicitly
|
||||
requested using the wintypes option.
|
||||
#+BEGIN_SRC conf
|
||||
shadow = true;
|
||||
#+END_SRC
|
||||
|
||||
The blur radius for shadows is measured in pixels, and it defaults to
|
||||
12px.
|
||||
#+BEGIN_SRC conf
|
||||
shadow-radius = 17;
|
||||
#+END_SRC
|
||||
|
||||
Picom can also apply some level of opacity on shadows.
|
||||
| Default value | ~0.75~ |
|
||||
| Min value | ~0.0~ |
|
||||
| Max value | ~1.0~ |
|
||||
#+BEGIN_SRC conf
|
||||
shadow-opacity = 0.75
|
||||
#+END_SRC
|
||||
|
||||
The left and top offsets for shadows are expressed in pixels.
|
||||
| Default value | ~-15~ |
|
||||
#+BEGIN_SRC conf
|
||||
shadow-offset-x = -16;
|
||||
shadow-offset-y = -16;
|
||||
#+END_SRC
|
||||
|
||||
It is possible to set the color of the shadow with the string contained in
|
||||
~shadow-color~ with a hexadecimal value. I haven’t included these values in my
|
||||
config, but this value will override any value in ~shadow-red~, ~shadow-green~,
|
||||
or ~shadow-blue~.
|
||||
#+BEGIN_SRC conf
|
||||
shadow-color = "#171A20"
|
||||
#+END_SRC
|
||||
|
||||
It is possible to specify a list of conditions of windows that should
|
||||
have no shadow.
|
||||
| Default value | ~[]~ |
|
||||
#+BEGIN_SRC conf
|
||||
shadow-exclude = [
|
||||
"name = 'Notification'",
|
||||
"class_g = 'Conky'",
|
||||
"class_g ?= 'Notify-osd'",
|
||||
"class_g = 'Cairo-clock'",
|
||||
"_GTK_FRAME_EXTENTS@:c"
|
||||
];
|
||||
#+END_SRC
|
||||
|
||||
It is also possible to specify an X geometry that describes the region in which
|
||||
shadows should not be painted in, such as a dock window region. For example,
|
||||
#+BEGIN_SRC conf :tangle no
|
||||
# shadow-exclude-reg = "x10+0+0"
|
||||
#+END_SRC
|
||||
would make the 10 pixels at the bottom of the screen not have any shadow painted
|
||||
on.
|
||||
| Default value | ~""~ |
|
||||
#+BEGIN_SRC conf :tangle no
|
||||
shadow-exclude-reg = ""
|
||||
#+END_SRC
|
||||
|
||||
Finally, it is also possible to crop the shadow of a window fully on a
|
||||
particular Xinerama screen to the screen.
|
||||
- Default value :: ~false~
|
||||
#+BEGIN_SRC conf
|
||||
xinerama-shadow-crop = false
|
||||
#+END_SRC
|
||||
|
||||
*** Deprecated options
|
||||
:PROPERTIES:
|
||||
:HEADER-ARGS:conf: :tangle no
|
||||
:END:
|
||||
Options in this subheader *will not* be exported to my configuration file.
|
||||
|
||||
Thanks to this value, Picom can avoid drawing shadows on dock or panel windows.
|
||||
This option is deprecated, and users should use the ~wintypes~ option in their
|
||||
config file instead.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
no-dock-shadow = false;
|
||||
#+END_SRC
|
||||
|
||||
This option allows Picom not to draw on drag-and-drop windows. It is
|
||||
deprecated, and users should use the ~wintypes~ option in their config
|
||||
file instead.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
no-dnd-shadow = false;
|
||||
#+END_SRC
|
||||
|
||||
~shadow-ignore-shaped~ is also deprecated. It used to indicate Picom not to
|
||||
paint shadows on shaped windows. Note shaped windows here means windows setting
|
||||
their shape through X Shape extension. Those using ARGB background are beyond
|
||||
Picom’s control. Since it is deprecated, you could instead use
|
||||
#+BEGIN_SRC conf :tangle no
|
||||
shadow-exclude = 'bounding_shaped'
|
||||
#+END_SRC
|
||||
or
|
||||
#+BEGIN_SRC conf :tangle no
|
||||
shadow-exclude = 'bounding_shaped && !rounded_corners'
|
||||
#+END_SRC
|
||||
| Default value | ~""~ |
|
||||
#+BEGIN_SRC conf :tangle no
|
||||
shadow-ignore-shaped = ""
|
||||
#+END_SRC
|
||||
|
||||
** Rounded corners
|
||||
Here we can see the declaration of the corners’ radius:
|
||||
#+BEGIN_SRC conf
|
||||
corner-radius = 10;
|
||||
#+END_SRC
|
||||
|
||||
It is also possible to exclude some windows from getting their corners rounded.
|
||||
I personally excluded any window generated by AwesomeWM.
|
||||
#+BEGIN_SRC conf
|
||||
rounded-corners-exclude = [
|
||||
"_NET_WM_WINDOW_TYPE@[0]:a = '_NET_WM_WINDOW_TYPE_DOCK'"
|
||||
];
|
||||
#+END_SRC
|
||||
|
||||
** Fading
|
||||
Picom has the ability to create some fading effects on windows when opening or
|
||||
closing or when the opacity changes. The following parameter toggles this
|
||||
feature on or off. However, its behavior can be changed with
|
||||
~no-fading-openclose~.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
fading = true
|
||||
#+END_SRC
|
||||
|
||||
These values control the opacity change between steps while fading in
|
||||
and out.
|
||||
| Default value | ~0.028~ (fade-in), ~0.03~ (fade-out) |
|
||||
| Min value | ~0.01~ |
|
||||
| Max value | ~1.0~ |
|
||||
#+BEGIN_SRC conf
|
||||
fade-in-step = 0.25;
|
||||
fade-out-step = 0.23;
|
||||
#+END_SRC
|
||||
|
||||
This value represents the time between steps in fade steps, in milliseconds.
|
||||
| Default value | ~10~ |
|
||||
| Min value | ~1~ |
|
||||
#+BEGIN_SRC conf
|
||||
fade-delta = 20;
|
||||
#+END_SRC
|
||||
|
||||
It is possible to exclude some windows that should not be faded with a specified
|
||||
list of conditions.
|
||||
| Default value | ~[]~ |
|
||||
#+BEGIN_SRC conf
|
||||
fade-exclude = [ "class_g = 'mpv'" ];
|
||||
#+END_SRC
|
||||
|
||||
This option allows Picom not to create any fade on windows opening or closing.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
no-fading-openclose = true;
|
||||
#+END_SRC
|
||||
|
||||
Finally, this option is a workaround for Openbox, Fluxbox and others by not
|
||||
fading destroyed ARGB windows with WM frame.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
no-fading-destroyed-argb = false
|
||||
#+END_SRC
|
||||
|
||||
** Transparency and opacity
|
||||
Picom is also able to create some opacity or transparency for windows, depending
|
||||
on their state or on some user-defined rules. For instance, the following value
|
||||
describes the opacity of inactive windows.
|
||||
| Default value | ~1.0~ |
|
||||
| Min value | ~0.1~ |
|
||||
| Max value | ~1.0~ |
|
||||
#+BEGIN_SRC conf
|
||||
inactive-opacity = 0.8;
|
||||
#+END_SRC
|
||||
|
||||
On the other hand, it is possible to declare a default opacity for active
|
||||
windows.
|
||||
| Default value | ~1.0~ |
|
||||
| Min value | ~0.1~ |
|
||||
| Max value | ~1.0~ |
|
||||
#+BEGIN_SRC conf
|
||||
active-opacity = 1;
|
||||
#+END_SRC
|
||||
|
||||
This however describes the opacity of window titlebars and borders.
|
||||
| Default value | ~1.0~ |
|
||||
| Min value | ~0.1~ |
|
||||
| Max value | ~1.0~ |
|
||||
#+BEGIN_SRC conf
|
||||
frame-opacity = 1.0;
|
||||
#+END_SRC
|
||||
|
||||
~menu-opacity~ describes the opacity for dropdown menus and popup menus.
|
||||
| Default value | ~1.0~ |
|
||||
| Min value | ~0.1~ |
|
||||
| Max value | ~1.0~ |
|
||||
#+BEGIN_SRC conf
|
||||
# menu-opacity = 0.9;
|
||||
#+END_SRC
|
||||
|
||||
~inactive-opacity-override~ allows the user to let inactive opacity set by ~-i~
|
||||
override the ~_NET_WM_OPACITY_ values of windows.
|
||||
| Default value | ~true~ |
|
||||
#+BEGIN_SRC conf
|
||||
inactive-opacity-override = true;
|
||||
#+END_SRC
|
||||
|
||||
While it is possible to alter opacity on inactive windows, it is also possible
|
||||
to dim them.
|
||||
| Default value | ~1.0~ |
|
||||
| Min value | ~0.1~ |
|
||||
| Max value | ~1.0~ |
|
||||
#+BEGIN_SRC conf
|
||||
# inactive-dim = 1.0
|
||||
#+END_SRC
|
||||
|
||||
It is also possible to use a fixed inactive dim value, instead of adjusting
|
||||
according to window opacity.
|
||||
| Default value | ~1.0~ |
|
||||
| Min value | ~0.1~ |
|
||||
| Max value | ~1.0~ |
|
||||
#+BEGIN_SRC conf
|
||||
# inactive-dim-fixed = 1.0
|
||||
#+END_SRC
|
||||
|
||||
It is also possible to specify a list of conditions of windows that should
|
||||
always be considered focused.
|
||||
| Default value | ~[]~ |
|
||||
#+BEGIN_SRC conf
|
||||
focus-exclude = [
|
||||
"class_g = 'mpv'",
|
||||
"class_g = 'qemu'",
|
||||
"class_g = 'Qemu-system-x86_64'"
|
||||
];
|
||||
#+END_SRC
|
||||
|
||||
The user can also specify a list of opacity rules, in the format
|
||||
~PERCENT:PATTERN~, like ~50:name *= "Firefox"~ . ~picom-trans~ is recommended
|
||||
over this. Note we don't make any guarantee about possible conflicts with other
|
||||
programs that set ~_NET_WM_WINDOW_OPACITY~ on frame or client windows.
|
||||
| Default value | ~[]~ |
|
||||
#+BEGIN_SRC conf
|
||||
opacity-rule = [];
|
||||
#+END_SRC
|
||||
|
||||
** Background blurring
|
||||
The following are the parameters for background blurring, see the \*BLUR\*
|
||||
section for more information.
|
||||
#+BEGIN_SRC conf
|
||||
blur: {
|
||||
method = "dual_kawase";
|
||||
strength = 7;
|
||||
background = false;
|
||||
background-frame = false;
|
||||
background-fixed = false;
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
This value enables or disables the blur for the background of semi-transparent
|
||||
or ARGB windows. It has bad performances though, with driver-dependent behavior.
|
||||
The name of the switch may change without prior notifications.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
blur-background = true;
|
||||
#+END_SRC
|
||||
|
||||
Blur background of windows when the window frame is not opaque. If true, this
|
||||
implies the value ~true~ for ~blur-background~.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
blur-background-frame = true;
|
||||
#+END_SRC
|
||||
|
||||
The following determines whether to use fixed blur strength rather than
|
||||
adjusting according to window opacity.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
blur-background-fixed = false;
|
||||
#+END_SRC
|
||||
|
||||
Specify the blur convolution kernel, with the format
|
||||
~"5,5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1"~.
|
||||
| Default value | ~""~ |
|
||||
#+BEGIN_SRC conf
|
||||
# blur-kern = "3x3box";
|
||||
#+END_SRC
|
||||
|
||||
It is possible to write exclude conditions for background blur.
|
||||
| Default value | ~[]~ |
|
||||
#+BEGIN_SRC conf
|
||||
blur-background-exclude = [
|
||||
"window_type = 'desktop'",
|
||||
"class_g = 'Polybar'",
|
||||
"class_g = 'discord-overlay'",
|
||||
"_GTK_FRAME_EXTENTS@:c"
|
||||
];
|
||||
#+END_SRC
|
||||
|
||||
** General settings
|
||||
Daemonize process. Fork to background after initialization. Can cause
|
||||
issues with certain (badly-written) drivers.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
daemon = true;
|
||||
#+END_SRC
|
||||
|
||||
Picom has three backends it can use: ~xrender~, ~glx~, and ~xr_glx_hybrid~. GLX
|
||||
backend is typically much faster but depends on a sane driver.
|
||||
| Default value | ~xrender~ |
|
||||
#+BEGIN_SRC conf
|
||||
backend = "glx";
|
||||
#+END_SRC
|
||||
|
||||
This enables or disables VSync.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
vsync = true;
|
||||
#+END_SRC
|
||||
|
||||
Enable remote control via D-Bus. See the *D-BUS API* section below for more
|
||||
details.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
dbus = false;
|
||||
#+END_SRC
|
||||
|
||||
Try to detect WM windows (a non-override-redirect window with no child that has
|
||||
~WM_STATE~) and markz them as active.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
mark-wmwin-focused = true;
|
||||
#+END_SRC
|
||||
|
||||
Mark override-redirect windows that doesn't have a child window with ~WM_STATE~
|
||||
focused.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
mark-ovredir-focused = true;
|
||||
#+END_SRC
|
||||
|
||||
Try to detect windows with rounded corners and don't consider them shaped
|
||||
windows. The accuracy is not very high, unfortunately.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
detect-rounded-corners = true;
|
||||
#+END_SRC
|
||||
|
||||
Detect ~_NET_WM_OPACITY~ on client windows, useful for window managers not
|
||||
passing ~_NET_WM_OPACITY~ of client windows to frame windows.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
detect-client-opacity = true;
|
||||
#+END_SRC
|
||||
|
||||
Limit picom to repaint at most once every 1 / ~refresh_rate~ second to
|
||||
boost performance. This should not be used with ~vsync
|
||||
drm/opengl/opengl-oml~ as they essentially do sw-opti's job already,
|
||||
unless you wish to specify a lower refresh rate than the actual value.
|
||||
| Default value | ~""~ |
|
||||
#+BEGIN_SRC conf
|
||||
# sw-opti =;
|
||||
#+END_SRC
|
||||
|
||||
Use EWMH ~_NET_ACTIVE_WINDOW~ to determine currently focused window, rather than
|
||||
listening to ~FocusIn~/~FocusOut~ event. Might have more accuracy, provided that
|
||||
the WM supports it.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
# use-ewmh-active-win = false;
|
||||
#+END_SRC
|
||||
|
||||
Unredirect all windows if a full-screen opaque window is detected, to
|
||||
maximize performance for full-screen windows. Known to cause
|
||||
flickering when redirecting/unredirecting windows. =paint-on-overlay=
|
||||
may make the flickering less obvious.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
unredir-if-possible = false;
|
||||
#+END_SRC
|
||||
|
||||
Delay before unredirecting the window, in milliseconds.
|
||||
| Default value | ~0~ |
|
||||
#+BEGIN_SRC conf
|
||||
unredir-if-possible-delay = 0;
|
||||
#+END_SRC
|
||||
|
||||
Conditions of windows that shouldn't be considered full-screen for unredirecting
|
||||
screen.
|
||||
| Default value | ~[]~ |
|
||||
#+BEGIN_SRC conf
|
||||
unredir-if-possible-exclude = [];
|
||||
#+END_SRC
|
||||
|
||||
Use ~WM_TRANSIENT_FOR~ to group windows, and consider windows in the same group
|
||||
focused at the same time.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
detect-transient = true;
|
||||
#+END_SRC
|
||||
|
||||
Use ~WM_CLIENT_LEADER~ to group windows, and consider windows in the same group
|
||||
focused at the same time. ~WM_TRANSIENT_FOR~ has higher priority if
|
||||
detect-transient is enabled, too.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
detect-client-leader = true;
|
||||
#+END_SRC
|
||||
|
||||
Resize damaged region by a specific number of pixels. A positive value enlarges
|
||||
it while a negative one shrinks it. If the value is positive, those additional
|
||||
pixels will not be actually painted to screen, only used in blur calculation,
|
||||
and such. (Due to technical limitations, with use-damage, those pixels will
|
||||
still be incorrectly painted to screen.) Primarily used to fix the line
|
||||
corruption issues of blur, in which case you should use the blur radius value
|
||||
here (e.g. with a 3x3 kernel, you should use ~--resize-damage 1~, with a 5x5 one
|
||||
you use ~--resize-damage 2~, and so on). May or may not work with
|
||||
~--glx-no-stencil~. Shrinking doesn't function correctly.
|
||||
| Default value | ~1~ |
|
||||
#+BEGIN_SRC conf
|
||||
resize-damage = 1;
|
||||
#+END_SRC
|
||||
|
||||
Specify a list of conditions of windows that should be painted with inverted
|
||||
color. Resource-hogging, and is not well tested.
|
||||
| Default value | ~[]~ |
|
||||
#+BEGIN_SRC conf
|
||||
invert-color-include = [];
|
||||
#+END_SRC
|
||||
|
||||
Disable the use of damage information. This cause the whole screen to be redrawn
|
||||
everytime, instead of the part of the screen has actually changed. Potentially
|
||||
degrades the performance, but might fix some artifacts. The opposing option is
|
||||
use-damage
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
use-damage = false;
|
||||
#+END_SRC
|
||||
|
||||
Use X Sync fence to sync clients' draw calls, to make sure all draw calls are
|
||||
finished before picom starts drawing. Needed on nvidia-drivers with GLX backend
|
||||
for some users.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
xrender-sync-fence = false;
|
||||
#+END_SRC
|
||||
|
||||
Force all windows to be painted with blending. Useful if you have a
|
||||
glx-fshader-win that could turn opaque pixels transparent.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
force-win-blend = false;
|
||||
#+END_SRC
|
||||
|
||||
Do not use EWMH to detect fullscreen windows. Reverts to checking if a window is
|
||||
fullscreen based only on its size and coordinates.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
no-ewmh-fullscreen = false;
|
||||
#+END_SRC
|
||||
|
||||
Dimming bright windows so their brightness doesn't exceed this set
|
||||
value. Brightness of a window is estimated by averaging all pixels in
|
||||
the window, so this could come with a performance hit. Setting this to
|
||||
1.0 disables this behaviour. Requires ~--use-damage~ to be disabled.
|
||||
| Default value | ~1.0~ |
|
||||
#+BEGIN_SRC conf
|
||||
max-brightness = 1.0;
|
||||
#+END_SRC
|
||||
|
||||
Make transparent windows clip other windows like non-transparent windows do,
|
||||
instead of blending on top of them.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
transparent-clipping = false;
|
||||
#+END_SRC
|
||||
|
||||
Set the log level. Possible values in increasing level of importance are:
|
||||
- ~trace~
|
||||
- ~debug~
|
||||
- ~info~
|
||||
- ~warn~
|
||||
- ~error~
|
||||
Case doesn't matter. If using the "TRACE" log level, it's better to
|
||||
log into a file using ~--log-file~, since it can generate a huge stream
|
||||
of logs.
|
||||
| Default value | ~"debug"~ |
|
||||
#+BEGIN_SRC conf
|
||||
log-level = "warn";
|
||||
#+END_SRC
|
||||
|
||||
Set the log file. If ~--log-file~ is never specified, logs will be
|
||||
written to stderr. Otherwise, logs will to written to the given file,
|
||||
though some early logs might still be written to the stderr. When
|
||||
setting this option from the config file, it is recommended to use an
|
||||
absolute path.
|
||||
| Default value | ~''~ |
|
||||
#+BEGIN_SRC conf
|
||||
# log-file = '/path/to/your/log/file';
|
||||
#+END_SRC
|
||||
|
||||
Show all X errors (for debugging)
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
# show-all-xerrors = false;
|
||||
#+END_SRC
|
||||
|
||||
Write process ID to a file.
|
||||
| Default value | ~''~ |
|
||||
#+BEGIN_SRC conf
|
||||
# write-pid-path = '/path/to/your/log/file';
|
||||
#+END_SRC
|
||||
|
||||
Window type settings. ~WINDOW_TYPE~ is one of the 15 window types defined in
|
||||
EWMH standard:
|
||||
- ~"unknown"~
|
||||
- ~"desktop"~
|
||||
- ~"dock"~
|
||||
- ~"toolbar"~
|
||||
- ~"menu"~
|
||||
- ~"utility"~
|
||||
- ~"splash"~
|
||||
- ~"dialog"~
|
||||
- ~"normal"~
|
||||
- ~"dropdown_menu"~
|
||||
- ~"popup_menu"~
|
||||
- ~"tooltip"~
|
||||
- ~"notification"~
|
||||
- ~"combo"~
|
||||
- ~"dnd"~
|
||||
Following per window-type options are available:
|
||||
- fade, shadow :: Controls window-type-specific shadow and fade settings.
|
||||
- opacity :: Controls default opacity of the window type.
|
||||
- focus :: Controls whether the window of this type is to be always considered
|
||||
focused. (By default, all window types except "normal" and "dialog" has this
|
||||
on.)
|
||||
- full-shadow :: Controls whether shadow is drawn under the parts of the window
|
||||
that you normally won't be able to see. Useful when the window has parts of it
|
||||
transparent, and you want shadows in those areas.
|
||||
- redir-ignore :: Controls whether this type of windows should cause
|
||||
screen to become redirected again after being unredirected. If you
|
||||
have =unredir-if-possible= set, and doesn't want certain window to
|
||||
cause unnecessary screen redirection, you can set this to =true=.
|
||||
#+BEGIN_SRC conf
|
||||
wintypes:
|
||||
{
|
||||
tooltip = { fade = true; shadow = true; opacity = 0.75; focus = true; full-shadow = false; };
|
||||
dock = { shadow = false; }
|
||||
dnd = { shadow = false; }
|
||||
popup_menu = { opacity = 0.8; }
|
||||
dropdown_menu = { opacity = 0.8; }
|
||||
};
|
||||
#+END_SRC
|
||||
|
||||
*** GLX backend-specific options
|
||||
Avoid using stencil buffer, useful if you don't have a stencil buffer. Might
|
||||
cause incorrect opacity when rendering transparent content (but never
|
||||
practically happened) and may not work with blur-background. Tests show a 15%
|
||||
performance boost. Recommended.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
glx-no-stencil = true;
|
||||
#+END_SRC
|
||||
|
||||
Avoid rebinding pixmap on window damage. Probably could improve performance on
|
||||
rapid window content changes, but is known to break things on some drivers
|
||||
(LLVMpipe, xf86-video-intel, etc.). Recommended if it works.
|
||||
| Default value | ~false~ |
|
||||
#+BEGIN_SRC conf
|
||||
glx-no-rebind-pixmap = false;
|
||||
#+END_SRC
|
||||
|
||||
Use specified GLSL fragment shader for rendering window contents. See
|
||||
~compton-default-fshader-win.glsl~ and
|
||||
~compton-fake-transparency-fshader-win.glsl~ in the source tree for examples.
|
||||
| Default value | ~''~ |
|
||||
#+BEGIN_SRC conf :tangle no
|
||||
glx-fshader-win = '';
|
||||
#+END_SRC
|
||||
91
docs/rustfmt.org
Normal file
@@ -0,0 +1,91 @@
|
||||
#+TITLE: Rust Formatter
|
||||
#+setupfile: headers
|
||||
#+PROPERTY: header-args:toml :mkdirp yes :tangle ~/.rustfmt.toml
|
||||
|
||||
* Rust Formatter
|
||||
The ~.rustfmt.toml~ file located in the ~$HOME~ directory is a global
|
||||
configuration file for Rust’s code formatters, such as ~rustfmt~. In this file,
|
||||
you can find how my Rust code is always formatted.
|
||||
|
||||
** General settings
|
||||
First, we are using the 2018 edition of Rust.
|
||||
#+BEGIN_SRC toml
|
||||
edition = "2018"
|
||||
#+END_SRC
|
||||
Put single-expression functions on a single line.
|
||||
#+BEGIN_SRC toml
|
||||
fn_single_line = true
|
||||
#+END_SRC
|
||||
Format string literals where necessary.
|
||||
#+BEGIN_SRC toml
|
||||
format_strings = true
|
||||
#+END_SRC
|
||||
Maximum width of each line
|
||||
#+BEGIN_SRC toml
|
||||
max_width = 80
|
||||
#+END_SRC
|
||||
Merge multiple imports into a single nested import.
|
||||
#+BEGIN_SRC toml
|
||||
merge_imports = true
|
||||
#+END_SRC
|
||||
|
||||
** Structs and Enums
|
||||
The maximum length of enum variant having discriminant, that gets vertically
|
||||
aligned with others. Variants without discriminants would be ignored for the
|
||||
purpose of alignment.
|
||||
|
||||
Note that this is not how much whitespace is inserted, but instead the longest
|
||||
variant name that doesn't get ignored when aligning.
|
||||
#+BEGIN_SRC toml
|
||||
enum_discrim_align_threshold = 20
|
||||
#+END_SRC
|
||||
The maximum diff of width between struct fields to be aligned with each other.
|
||||
#+BEGIN_SRC toml
|
||||
struct_field_align_threshold = 20
|
||||
#+END_SRC
|
||||
Reorder impl items. ~type~ and ~const~ are put first, then macros and methods.
|
||||
#+BEGIN_SRC toml
|
||||
reorder_impl_items = true
|
||||
#+END_SRC
|
||||
|
||||
** Comments
|
||||
Convert ~/* */~ comments to ~//~ comments where possible.
|
||||
#+BEGIN_SRC toml
|
||||
normalize_comments = true
|
||||
#+END_SRC
|
||||
Break comments to fit on the line.
|
||||
#+BEGIN_SRC toml
|
||||
wrap_comments = true
|
||||
#+END_SRC
|
||||
Report ~FIXME~ items in comments.
|
||||
#+BEGIN_SRC toml
|
||||
report_fixme = "Always"
|
||||
#+END_SRC
|
||||
Report ~TODO~ items in comments.
|
||||
#+BEGIN_SRC toml
|
||||
todo = "Always"
|
||||
#+END_SRC
|
||||
|
||||
** Documentation
|
||||
Format code snippet included in doc comments.
|
||||
#+BEGIN_SRC toml
|
||||
format_code_in_doc_comments = true
|
||||
#+END_SRC
|
||||
Convert ~#![doc]~ and ~#[doc]~ attributes to ~//!~ and ~///~ doc comments.
|
||||
#+BEGIN_SRC toml
|
||||
normalize_doc_attributes = true
|
||||
#+END_SRC
|
||||
|
||||
** Whitespace
|
||||
Use tab characters for indentation, spaces for alignment.
|
||||
#+BEGIN_SRC toml
|
||||
hard_tabs = false
|
||||
#+END_SRC
|
||||
Number of spaces per tab.
|
||||
#+BEGIN_SRC toml
|
||||
tab_spaces = 4
|
||||
#+END_SRC
|
||||
I want newlines to always be Unix style.
|
||||
#+BEGIN_SRC toml
|
||||
newline_style = "Unix"
|
||||
#+END_SRC
|
||||
2092
docs/scripts.org
Normal file
1969
docs/stumpwm.org
Normal file
285
docs/tmux.org
Normal file
@@ -0,0 +1,285 @@
|
||||
#+title: Tmux
|
||||
#+setupfile: headers
|
||||
#+property: header-args:tmux :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:tmux+ :tangle ~/.config/tmux/tmux.conf
|
||||
#+property: header-args:tmux+ :mkdirp yes :noweb yes
|
||||
|
||||
* Tmux
|
||||
Tmux is one of the widest known terminal multiplexers along with
|
||||
=screen=. I find it useful when I don’t want to bother with panes in my
|
||||
[[https://sw.kovidgoyal.net/kitty/][kitty]] terminal.
|
||||
|
||||
Be aware this configuration is mostly keybinds.
|
||||
|
||||
** Setting sane configurations
|
||||
By default, Tmux does not support all the colours your terminal may
|
||||
support, so we need to tell it to set true colours..
|
||||
#+begin_src tmux
|
||||
set-option -sa terminal-overrides ",xterm*:Tc"
|
||||
#+end_src
|
||||
|
||||
We can also tell it to enable mouse support. That way, we will be able
|
||||
to click on Tmux elements and scroll in its panes!
|
||||
#+begin_src tmux
|
||||
set -g mouse on
|
||||
#+end_src
|
||||
|
||||
Finally, I’ll set ~vi-mode~ for some sane movements.
|
||||
#+begin_src tmux
|
||||
set-window-option -g mode-keys vi
|
||||
#+end_src
|
||||
|
||||
** Windows and panes configuration
|
||||
Although I agree in computer science most things should begin with
|
||||
zero, I find it quite weird to see my first window and my first pane
|
||||
to be labeled with it rather than one. So, let’s pull a Lua on Tmux
|
||||
and force it to begin with 1 instead of 0.
|
||||
#+begin_src tmux
|
||||
set -g base-index 1
|
||||
set -g pane-base-index 1
|
||||
set-window-option -g pane-base-index 1
|
||||
set-option -g renumber-windows on
|
||||
#+end_src
|
||||
|
||||
** Plugins!
|
||||
Using [[https://github.com/tmux-plugins/tpm][TPM]], we can use plugins in Tmux! The way I installed it is very simple:
|
||||
#+begin_src bash
|
||||
mkdir -p ~/.config/tmux/
|
||||
git clone https://github.com/tmux-plugins/tpm.git ~/.config/tmux/tpm
|
||||
#+end_src
|
||||
|
||||
Here’s a list of the plugins that I use.
|
||||
#+name: plugins
|
||||
| Plugin | Why |
|
||||
|-----------------------+------------------------------------------------------|
|
||||
| tpm | TPM itself |
|
||||
| tmux-sensible | Better defaults I can’t be bothered to change myself |
|
||||
| tmux-yank | Better copy/pasting |
|
||||
| tmux-prefix-highlight | Tell me which prefix I’m using |
|
||||
| tmux-resurrect | Persist tmux sessions across system restarts |
|
||||
| nordtheme/tmux | Nord theme for Tmux! |
|
||||
|
||||
#+begin_src emacs-lisp :var plugins=plugins[,0] :exports code :wrap src tmux
|
||||
(mapconcat (lambda (plugin)
|
||||
(format "set -g @plugin '%s'"
|
||||
(if (string-match-p (quote "/") plugin)
|
||||
plugin
|
||||
(concat "tmux-plugins/" plugin))))
|
||||
plugins
|
||||
"\n")
|
||||
#+end_src
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_src tmux
|
||||
set -g @plugin 'tmux-plugins/tpm'
|
||||
set -g @plugin 'tmux-plugins/tmux-sensible'
|
||||
set -g @plugin 'tmux-plugins/tmux-yank'
|
||||
set -g @plugin 'tmux-plugins/tmux-prefix-highlight'
|
||||
set -g @plugin 'tmux-plugins/tmux-resurrect'
|
||||
set -g @plugin 'nordtheme/tmux'
|
||||
#+end_src
|
||||
|
||||
Let’s run TPM right after that.
|
||||
#+begin_src tmux
|
||||
run '~/.config/tmux/tpm/tpm'
|
||||
#+end_src
|
||||
|
||||
For restoring processes with =tmux-resurrect=, we must add additional
|
||||
programs in the =@resurrect-processes= variable. These are:
|
||||
#+name: resurrect-processes-list
|
||||
- ="~ncmpcpp -q"=
|
||||
- =btop=
|
||||
- =ssh=
|
||||
|
||||
#+name: resurrect-processes
|
||||
#+begin_src emacs-lisp :var processes=resurrect-processes-list :exports none :cache yes
|
||||
(mapconcat (lambda (process) (string-replace "=" "" process))
|
||||
processes
|
||||
" ")
|
||||
#+end_src
|
||||
|
||||
#+RESULTS[4f72312f2da98c81eff2b092779a59c993fa19e2]: resurrect-processes
|
||||
: "~ncmpcpp -q" btop ssh
|
||||
|
||||
#+begin_src tmux :noweb yes
|
||||
set -g @resurrect-processes '<<resurrect-processes()>>'
|
||||
#+end_src
|
||||
|
||||
** Keybindings
|
||||
First of all, I don’t like prefixing all of my keybindings with ~C-b~,
|
||||
that’s what I use in ~insert-mode~ in Emacs to make the cursor go back.
|
||||
So instead, let’s set meta with space as my prefix.
|
||||
#+begin_src tmux
|
||||
unbind C-b
|
||||
set -g prefix M-Space
|
||||
bind M-Space send-prefix
|
||||
#+end_src
|
||||
|
||||
Now, I will only add few keybindings on the root prefix that actually
|
||||
do something immediately, I will mostly add keybindings that will lead
|
||||
to other prefixes; I prefer by far to have keychords that are a bit
|
||||
lengthy and mnemonic than some obscure “ ~C-M-&~ is for doing this and
|
||||
that”.
|
||||
|
||||
#+name: std-prefix
|
||||
| Keybinding | Command | Prefix to go to |
|
||||
|------------+------------------+-----------------|
|
||||
| =«= | select-window -p | |
|
||||
| =»= | select-window -n | |
|
||||
| =Tab= | | windows |
|
||||
| =w= | | pane |
|
||||
| =y= | | copy-mode |
|
||||
|
||||
Note I am using the key =w= to access the pane prefix because of how
|
||||
used to Emacs I am, and in Emacs terminology panes are windows while
|
||||
tmux windows would be tabs.
|
||||
|
||||
#+name: gen-keybinds
|
||||
#+begin_src emacs-lisp :var keybinds=std-prefix :var prefix="prefix" :exports none
|
||||
(mapconcat (lambda (keybind)
|
||||
(format "bind-key -T %s %s %s"
|
||||
prefix
|
||||
(string-replace "=" "" (car keybind))
|
||||
(let* ((command (nth 1 keybind))
|
||||
(command (if (string= "" command) nil command))
|
||||
(goto-prefix (nth 2 keybind))
|
||||
(goto-prefix (if (string= "" goto-prefix) nil (concat "switch-client -T " goto-prefix))))
|
||||
(if (and command goto-prefix)
|
||||
(concat command "\\; " goto-prefix)
|
||||
(or command goto-prefix)))))
|
||||
keybinds
|
||||
"\n")
|
||||
#+end_src
|
||||
|
||||
#+RESULTS: gen-keybinds
|
||||
: bind-key -T prefix « select-window -p
|
||||
: bind-key -T prefix » select-window -n
|
||||
: bind-key -T prefix Tab switch-client -T windows
|
||||
: bind-key -T prefix w switch-client -T pane
|
||||
: bind-key -T prefix y switch-client -T copy-mode
|
||||
|
||||
#+begin_src tmux
|
||||
<<gen-keybinds()>>
|
||||
#+end_src
|
||||
|
||||
*** Panes
|
||||
As you will see not only here but also lower, I am not using the usual
|
||||
=hjkl= to navigate around since I am using the [[https://bepo.fr][bépo]] layout. I use
|
||||
instead the =ctsr= keys.
|
||||
|
||||
Below are the keybindings living in the =pane= prefix. Note that calls to
|
||||
=split-window= have a =-c "#{pane_current_path}"= argument so new panes
|
||||
open in the same directory as the directory I am currently in.
|
||||
#+name: pane-prefix
|
||||
| Keybinding | Command | Prefix to go to |
|
||||
|------------+-------------------------------------------+-----------------|
|
||||
| =/= | split-window -h -c "#{pane-current_path}" | |
|
||||
| =-= | split-window -v -c "#{pane-current_path}" | |
|
||||
| =c= | select-pane -L | |
|
||||
| =t= | select-pane -D | |
|
||||
| =s= | select-pane -U | |
|
||||
| =r= | select-pane -R | |
|
||||
| =f= | resize-pane -Z | |
|
||||
| =.= | | pane-resize |
|
||||
|
||||
#+begin_src tmux
|
||||
<<gen-keybinds(keybinds=pane-prefix, prefix="pane")>>
|
||||
#+end_src
|
||||
|
||||
When it comes to resizing the panes, the keybindings are in their own
|
||||
prefix referenced above: =pane-resize=. All keybindings will lead to the
|
||||
same prefix again, which enables the user to type for instance =M-Space
|
||||
w . r r r r r= in order to call repetitively =resize-pane -R 5=. Hitting
|
||||
any key that is not part of the current prefix will get us out of it.
|
||||
#+name: pane-resize-prefix
|
||||
| Keybinding | Command | Prefix to go to |
|
||||
|------------+------------------+-----------------|
|
||||
| c | resize-pane -L 5 | pane-resize |
|
||||
| t | resize-pane -D 5 | pane-resize |
|
||||
| s | resize-pane -U 5 | pane-resize |
|
||||
| r | resize-pane -R 5 | pane-resize |
|
||||
| C | resize-pane -L | pane-resize |
|
||||
| T | resize-pane -D | pane-resize |
|
||||
| S | resize-pane -U | pane-resize |
|
||||
| R | resize-pane -R | pane-resize |
|
||||
|
||||
#+begin_src tmux
|
||||
<<gen-keybinds(keybinds=pane-resize-prefix, prefix="pane-resize")>>
|
||||
#+end_src
|
||||
|
||||
*** Windows
|
||||
Since windows are more akin to tabs in Emacs, and I am way more used
|
||||
to it than Tmux, all keybinds are prefixed with a =Tab=, itself prefixed
|
||||
with the main prefix.
|
||||
#+name: windows-prefix
|
||||
| Keybinding | Command |
|
||||
|------------+-----------------|
|
||||
| c | new-window |
|
||||
| n | next-window |
|
||||
| p | previous-window |
|
||||
|
||||
#+begin_src tmux
|
||||
<<gen-keybinds(keybinds=windows-prefix, prefix="windows")>>
|
||||
#+end_src
|
||||
|
||||
In order to access more easily the different windows, I want to be able to type =<prefix> TAB <window number>=. However, I’m using the bépo layout, numbers are available only when pressing shift. Otherwise, the characters typed are ="«»()@+-/*= (from 1 to 0).
|
||||
#+begin_src emacs-lisp :wrap src tmux :exports code
|
||||
(let ((keybinds "")
|
||||
(keys '("\\\"" "«" "»" "(" ")" "@" "+" "-" "/" "*")))
|
||||
(dotimes (i (length keys) keybinds)
|
||||
(setq keybinds (string-trim
|
||||
(concat keybinds
|
||||
"\n"
|
||||
(format "bind-key -T windows %s select-window -t :=%d"
|
||||
(nth i keys)
|
||||
(1+ i)))))))
|
||||
#+end_src
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_src tmux
|
||||
bind-key -T windows \" select-window -t :=1
|
||||
bind-key -T windows « select-window -t :=2
|
||||
bind-key -T windows » select-window -t :=3
|
||||
bind-key -T windows ( select-window -t :=4
|
||||
bind-key -T windows ) select-window -t :=5
|
||||
bind-key -T windows @ select-window -t :=6
|
||||
bind-key -T windows + select-window -t :=7
|
||||
bind-key -T windows - select-window -t :=8
|
||||
bind-key -T windows / select-window -t :=9
|
||||
bind-key -T windows * select-window -t :=10
|
||||
#+end_src
|
||||
|
||||
*** Copy in vi mode
|
||||
Tmux has a nice mode for vim keybindings users: =copy-mode-vi= which
|
||||
allows to move the cursor around in the pane, select some stuff, and
|
||||
copy it. But first, I need to unbind some keys:
|
||||
#+begin_src tmux
|
||||
unbind -T copy-mode-vi H
|
||||
unbind -T copy-mode-vi J
|
||||
unbind -T copy-mode-vi K
|
||||
unbind -T copy-mode-vi L
|
||||
unbind -T copy-mode-vi h
|
||||
unbind -T copy-mode-vi j
|
||||
unbind -T copy-mode-vi k
|
||||
unbind -T copy-mode-vi l
|
||||
#+end_src
|
||||
|
||||
#+name: copy-mode-vi-prefix
|
||||
| Keybinding | Command |
|
||||
|------------+----------------------------------------|
|
||||
| v | send-keys -X begin-selection |
|
||||
| C-v | send-keys -X rectangle-toggle |
|
||||
| y | send-keys -X copy-selection-and-cancel |
|
||||
| C | send-keys -X top-line |
|
||||
| J | send-keys -X jump-to-backward |
|
||||
| S | send-keys -X scroll-up |
|
||||
| R | send-keys -X bottom-line |
|
||||
| T | send-keys -X scroll-down |
|
||||
| c | send-keys -X cursor-left |
|
||||
| t | send-keys -X cursor-down |
|
||||
| s | send-keys -X cursor-up |
|
||||
| r | send-keys -X cursor-right |
|
||||
|
||||
#+begin_src tmux
|
||||
<<gen-keybinds(keybinds=copy-mode-vi-prefix, prefix="copy-mode-vi")>>
|
||||
#+end_src
|
||||