This is a comprehensive configuration file for my system.
I still need to implement package installing using GNU Guix. wob
and
pywal
are two that I am looking at. I also want to migrate more
packages to use Guix to improve migratability of my configuration to
new machines.
When using noweb, be very careful to be consistent with function
names. If I make a mistake (i.e. using src/
for the name and src-
in the call), my/tangle-init
will fail silently for the rest of the session.
I also have a daemon.sh
file that creates any necessary background
daemons.
setup.sh
and any daemons I create should log to this file. Note that
this returns " "
around the object if you use noweb. As such, I use
${HOME}/
instead of ~~/~ as bash
will complain otherwise if you
try to use it during redirection.
"${HOME}/.log.txt"
An incomplete .bashrc
file. I plan on breaking it up across the
config file.
I also need to fix ssh-agent environment variables. They aren’t passed to Emacs or other subprocesses when launched through dmenu.
# /etc/skel/.bashrc
#
# This file is sourced by all *interactive* bash shells on startup,
# including some apparently interactive shells such as scp and rcp
# that can't tolerate any output. So make sure this doesn't display
# anything or bad things will happen !
export PATH=~/bin:$PATH
# Test for an interactive shell. There is no need to set anything
# past this point for scp and rcp, and it's important to refrain from
# outputting anything in those cases.
if [[ $- != *i* ]] ; then
# Shell is non-interactive. Be done now!
return
fi
# Put your fun stuff here.
alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'
# Color output from less
export LESS_TERMCAP_mb=$'\e[1;32m'
export LESS_TERMCAP_md=$'\e[1;32m'
export LESS_TERMCAP_me=$'\e[0m'
export LESS_TERMCAP_se=$'\e[0m'
export LESS_TERMCAP_so=$'\e[01;33m'
export LESS_TERMCAP_ue=$'\e[0m'
export LESS_TERMCAP_us=$'\e[1;4;31m'
# Rbenv setup, trying new method to only run if rbenv is installed
# "$(rbenv init -)"
if type rbenv >/dev/null 2>&1
then
$(rbenv init -)
fi
# Use ssh-agent to temporarily store passphrases in RAM
if ! pgrep -u "$USER" ssh-agent > /dev/null; then
ssh-agent -t 1h > "$XDG_RUNTIME_DIR/ssh-agent.env"
fi
if [[ ! "$SSH_AUTH_SOCK" ]]; then
source "$XDG_RUNTIME_DIR/ssh-agent.env" >/dev/null
fi
# Colored diffs and colored cats (meow)
alias cdiff=colordiff
alias ccat=bat
# /etc/skel/.bash_profile
# This file is sourced by bash for login shells. The following line
# runs your .bashrc and is recommended by the bash info pages.
if [[ -f ~/.bashrc ]] ; then
. ~/.bashrc
fi
# See https://askubuntu.com/a/121075 for what should go
# in .bashrc, .bash_profile, and .profile
[[ -r ~/.profile ]] && . ~/.profile
# Use ssh-agent to temporarily store passphrases in RAM
if ! pgrep -u "$USER" ssh-agent > /dev/null; then
ssh-agent -t 1h > "$XDG_RUNTIME_DIR/ssh-agent.env"
fi
if [[ ! "$SSH_AUTH_SOCK" ]]; then
source "$XDG_RUNTIME_DIR/ssh-agent.env" >/dev/null
fi
# Enable Wayland support for Firefox
export MOZ_ENABLE_WAYLAND=1
# Used by fish shell. Do I need full path?
export BROWSER=/usr/bin/firefox
# TODO: move to emacs -nw, need to test config
export EDITOR=jove
if status is-interactive
alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'
end
I can use tools like fc-list
to view what fonts I have installed and
available. Similarly, fc-match
will tell me what names are valid for
those fonts..
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
<fontconfig>
<alias>
<family>sans-serif</family>
<prefer>
<family>Fira Sans</family>
<family>Liberation Sans</family>
<family>Noto Sans</family>
</prefer>
</alias>
<alias>
<family>monospace</family>
<prefer>
<family>Fira Code</family>
<family>Liberation Mono</family>
<family>Noto Sans Mono</family>
</prefer>
</alias>
<alias>
<family>serif</family>
<prefer>
<family>Liberation Serif</family>
<family>Noto Serif</family>
</prefer>
</alias>
</fontconfig>
### Variables
#
# Logo key. Use Mod1 for Alt.
set $mod Mod4
# Home row direction keys, like vim
set $left h
set $down j
set $up k
set $right l
# Your preferred terminal emulator
set $term alacritty
# Your preferred application launcher
# Note: pass the final command to swaymsg so that the resulting window can be opened
# on the original workspace that the command was run on.
set $menu dmenu_path | dmenu | xargs swaymsg exec --
XWayland applications (e.g. Emacs) do not handle Sway-native scaling
well, see #2966 and #2064. Emacs supports being built with pure gtk
(--pgtk
), where, if it’s also build with --without-x
it should be
a Wayland native application, avoiding blurry text problems.
However, Gentoo does not have the USE flags for this yet (and it may not be supported upstream, not sure), so instead I am going to set the scale to 1 and adjust the font sizes in all my other applications. Reddit has a nice description of the problem that is current as of July 2021.
See #2064 on GitLab for any progress on the proposed solution.
### Output configuration
#
# Default wallpaper (more resolutions are available in /usr/share/backgrounds/sway/)
output * bg /usr/share/backgrounds/sway/Sway_Wallpaper_Blue_1920x1080.png fill
#
output eDP-1 resolution 2560x1600 pos 0 0 scale 1
Adjust the font of sway-bar
and window titles to a reasonable size.
font pango:monospace Medium 18
Scale all X applications with this one easy trick! (Wayland developers
hate him!) As an extra bonus, this also scales dmenu
.
Xft.dpi: 190
And load the application on Sway startup.
exec xrdb -merge ~/.Xresources
While we’re at at, let’s also scale all Wayland-native QT applications.
export QT_SCALE_FACTOR=2.0
### Idle configuration
#
# Example configuration:
#
# exec swayidle -w \
# timeout 300 'swaylock -f -c 000000' \
# timeout 600 'swaymsg "output * dpms off"' resume 'swaymsg "output * dpms on"' \
# before-sleep 'swaylock -f -c 000000'
#
# This will lock your screen after 300 seconds of inactivity, then turn off
# your displays after another 300 seconds, and turn your screens back on when
# resumed. It will also lock your screen before your computer goes to sleep.
### Input configuration
#
# Example configuration:
#
# input "2:14:SynPS/2_Synaptics_TouchPad" {
# dwt enabled
# tap enabled
# natural_scroll enabled
# middle_emulation enabled
# }
#
input "type:keyboard" {
xkb_options ctrl:nocaps
}
input 2:10:TPPS/2_Elan_TrackPoint {
# Lower trackpoint sensitivity, -1 <= pointer_accel <= 1
# Numbers closer to 1 mean a large acceleration, while -1 is vice versa
pointer_accel -0.5
# Lower trackpoint scrolling sensitivity, 0 <= scroll_factor < inf
# https://github.com/swaywm/sway/issues/3004
# Thanks SpencerMichaels
scroll_factor 0.3
}
input "type:touchpad" {
pointer_accel 0.4
}
# You can get the names of your inputs by running: swaymsg -t get_inputs
# Read `man 5 sway-input` for more information about this section.
### Key bindings
#
# Basics:
#
# Start a terminal
bindsym $mod+Return exec $term
# Kill focused window
bindsym $mod+Shift+q kill
# Start your launcher
bindsym $mod+d exec $menu
# Drag floating windows by holding down $mod and left mouse button.
# Resize them with right mouse button + $mod.
# Despite the name, also works for non-floating windows.
# Change normal to inverse to use left mouse button for resizing and right
# mouse button for dragging.
floating_modifier $mod normal
# Reload the configuration file
bindsym $mod+Shift+c reload
# Exit sway (logs you out of your Wayland session)
bindsym $mod+Shift+e exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit'
#
# Moving around:
#
# Move your focus around
bindsym $mod+$left focus left
bindsym $mod+$down focus down
bindsym $mod+$up focus up
bindsym $mod+$right focus right
# Or use $mod+[up|down|left|right]
bindsym $mod+Left focus left
bindsym $mod+Down focus down
bindsym $mod+Up focus up
bindsym $mod+Right focus right
# Move the focused window with the same, but add Shift
bindsym $mod+Shift+$left move left
bindsym $mod+Shift+$down move down
bindsym $mod+Shift+$up move up
bindsym $mod+Shift+$right move right
# Ditto, with arrow keys
bindsym $mod+Shift+Left move left
bindsym $mod+Shift+Down move down
bindsym $mod+Shift+Up move up
bindsym $mod+Shift+Right move right
#
# Workspaces:
#
# Switch to workspace
bindsym $mod+1 workspace number 1
bindsym $mod+2 workspace number 2
bindsym $mod+3 workspace number 3
bindsym $mod+4 workspace number 4
bindsym $mod+5 workspace number 5
bindsym $mod+6 workspace number 6
bindsym $mod+7 workspace number 7
bindsym $mod+8 workspace number 8
bindsym $mod+9 workspace number 9
bindsym $mod+0 workspace number 10
# Move focused container to workspace
bindsym $mod+Shift+1 move container to workspace number 1
bindsym $mod+Shift+2 move container to workspace number 2
bindsym $mod+Shift+3 move container to workspace number 3
bindsym $mod+Shift+4 move container to workspace number 4
bindsym $mod+Shift+5 move container to workspace number 5
bindsym $mod+Shift+6 move container to workspace number 6
bindsym $mod+Shift+7 move container to workspace number 7
bindsym $mod+Shift+8 move container to workspace number 8
bindsym $mod+Shift+9 move container to workspace number 9
bindsym $mod+Shift+0 move container to workspace number 10
# Note: workspaces can have any name you want, not just numbers.
# We just use 1-10 as the default.
# move focused workspace between monitors
bindsym $mod+greater move workspace to output right
bindsym $mod+less move workspace to output left
#
# Layout stuff:
#
# You can "split" the current object of your focus with
# $mod+b or $mod+v, for horizontal and vertical splits
# respectively.
bindsym $mod+b splith
bindsym $mod+v splitv
# Switch the current container between different layout styles
bindsym $mod+s layout stacking
bindsym $mod+w layout tabbed
bindsym $mod+e layout toggle split
# Make the current focus fullscreen
bindsym $mod+f fullscreen
# Toggle the current focus between tiling and floating mode
bindsym $mod+Shift+space floating toggle
# Swap focus between the tiling area and the floating area
bindsym $mod+space focus mode_toggle
# Move focus to the parent container
bindsym $mod+a focus parent
#
# Scratchpad:
#
# Sway has a "scratchpad", which is a bag of holding for windows.
# You can send windows there and get them back later.
# Move the currently focused window to the scratchpad
bindsym $mod+Shift+minus move scratchpad
# Show the next scratchpad window or hide the focused scratchpad window.
# If there are multiple scratchpad windows, this command cycles through them.
bindsym $mod+minus scratchpad show
#
# Resizing containers:
#
mode "resize" {
# left will shrink the containers width
# right will grow the containers width
# up will shrink the containers height
# down will grow the containers height
bindsym $left resize shrink width 10px
bindsym $down resize grow height 10px
bindsym $up resize shrink height 10px
bindsym $right resize grow width 10px
# Ditto, with arrow keys
bindsym Left resize shrink width 10px
bindsym Down resize grow height 10px
bindsym Up resize shrink height 10px
bindsym Right resize grow width 10px
# Return to default mode
bindsym Return mode "default"
bindsym Escape mode "default"
}
bindsym $mod+r mode "resize"
#
# Status Bar:
#
# Read `man 5 sway-bar` for more information about this section.
bar {
position top
# When the status_command prints a new line to stdout, swaybar updates.
# The default just shows the current date and time.
# status_command while date +'%Y-%m-%d %l:%M:%S %p'; do sleep 1; done
status_command i3blocks
colors {
statusline #ffffff
background #323232
inactive_workspace #32323200 #32323200 #5c5c5c
}
}
# i3blocks configuration file
#
# The i3blocks man page describes the usage of the binary,
# and its website describes the configuration:
#
# https://vivien.github.io/i3blocks
# Global properties
separator=true
separator_block_width=25
[emerge]
color=#a5ef19
# No (xx of yy). Seems TOML messes with regex slightly.
# I found a solution that worked in the shell but not here.
# command=qlop -qrM | awk -F'/|[.]|( ETA: )' '{printf "emerging %s %4ds %s\n", $2, $NF, substr($5, index($5, " ")+1, length($5))}'
command=qlop -qrM | awk -F'[ /.]' '{printf "emerging %s %4ds\n", $4, $NF}'
interval=1
# FIXME run on headphones plug-in/remove
# FIXME literate config signal number as variable
[volume]
command=~/bin/volume.sh
interval=once
signal=10
[battery]
command=~/bin/battery.sh
interval=10
[time]
command=date '+%Y-%m-%d %H:%M:%S'
interval=1
VOL=$(pactl get-sink-volume @DEFAULT_SINK@ | awk '$1=="Volume:" {printf "%4s", $5}')
# Full and short texts
echo "Volume: $VOL"
echo "VOL: $VOL"
# Set urgent if we can't get volume
[ -z ${VOL} ] && exit 33
exit 0
BAT=$(acpi -b | awk -F ',| ' '{print $5}')
# Full and short texts
echo "Battery: $BAT"
echo "BAT: $BAT"
# Set urgent flag below 5% or use orange below 20%
[ ${BAT%?} -le 5 ] && exit 33
# [ ${BAT%?} == 100 ] && echo "$00FF00"
[ ${BAT%?} -le 20 ] && echo "#FF8000"
exit 0
include /etc/sway/config.d/*
# Use dev-libs/light for monitor brightness
# FIXME better way to save brightness?
bindsym XF86MonBrightnessDown exec light -U 10 && light -O
bindsym XF86MonBrightnessUp exec light -A 10 && light -O
# Restore previous brightness on startup
exec light -I
# Use pulseaudio for sound control
# FIXME literate config signal number as variable
bindsym XF86AudioRaiseVolume exec pactl set-sink-volume @DEFAULT_SINK@ +5% && pkill -SIGRTMIN+10 i3blocks
bindsym XF86AudioLowerVolume exec pactl set-sink-volume @DEFAULT_SINK@ -5% && pkill -SIGRTMIN+10 i3blocks
bindsym XF86AudioMute exec pactl set-sink-mute @DEFAULT_SINK@ toggle && pkill -SIGRTMIN+10 i3blocks
bindsym XF86AudioMicMute exec pactl set-source-mute @DEFAULT_SOURCE@ toggle
# Import additional configuration files
#
# Imports are loaded in order, skipping all missing files, with the importing
# file being loaded last. If a field is already present in a previous import, it
# will be replaced.
#
# All imports must either be absolute paths starting with `/`, or paths relative
# to the user's home directory starting with `~/`.
#import:
# - /path/to/alacritty.yml
# Any items in the `env` entry below will be added as
# environment variables. Some entries may override variables
# set by alacritty itself.
#env:
# TERM variable
#
# This value is used to set the `$TERM` environment variable for
# each instance of Alacritty. If it is not present, alacritty will
# check the local terminfo database and use `alacritty` if it is
# available, otherwise `xterm-256color` is used.
#TERM: alacritty
#window:
# Window dimensions (changes require restart)
#
# Number of lines/columns (not pixels) in the terminal. The number of columns
# must be at least `2`, while using a value of `0` for columns and lines will
# fall back to the window manager's recommended size.
#dimensions:
# columns: 0
# lines: 0
# Window position (changes require restart)
#
# Specified in number of pixels.
# If the position is not set, the window manager will handle the placement.
#position:
# x: 0
# y: 0
# Window padding (changes require restart)
#
# Blank space added around the window in pixels. This padding is scaled
# by DPI and the specified value is always added at both opposing sides.
#padding:
# x: 0
# y: 0
# Spread additional padding evenly around the terminal content.
#dynamic_padding: false
# Window decorations
#
# Values for `decorations`:
# - full: Borders and title bar
# - none: Neither borders nor title bar
#
# Values for `decorations` (macOS only):
# - transparent: Title bar, transparent background and title bar buttons
# - buttonless: Title bar, transparent background and no title bar buttons
#decorations: full
# Startup Mode (changes require restart)
#
# Values for `startup_mode`:
# - Windowed
# - Maximized
# - Fullscreen
#
# Values for `startup_mode` (macOS only):
# - SimpleFullscreen
#startup_mode: Windowed
# Window title
#title: Alacritty
# Allow terminal applications to change Alacritty's window title.
#dynamic_title: true
# Window class (Linux/BSD only):
#class:
# Application instance name
#instance: Alacritty
# General application class
#general: Alacritty
# GTK theme variant (Linux/BSD only)
#
# Override the variant of the GTK theme. Commonly supported values are `dark`
# and `light`. Set this to `None` to use the default theme variant.
#gtk_theme_variant: None
#scrolling:
# Maximum number of lines in the scrollback buffer.
# Specifying '0' will disable scrolling.
#history: 10000
# Scrolling distance multiplier.
#multiplier: 3
# Font configuration
font:
# Normal (roman) font face
#normal:
# Font family
#
# Default:
# - (macOS) Menlo
# - (Linux/BSD) monospace
# - (Windows) Consolas
#family: monospace
# The `style` can be specified to pick a specific face.
#style: Regular
# Bold font face
#bold:
# Font family
#
# If the bold family is not specified, it will fall back to the
# value specified for the normal font.
#family: monospace
# The `style` can be specified to pick a specific face.
#style: Bold
# Italic font face
#italic:
# Font family
#
# If the italic family is not specified, it will fall back to the
# value specified for the normal font.
#family: monospace
# The `style` can be specified to pick a specific face.
#style: Italic
# Bold italic font face
#bold_italic:
# Font family
#
# If the bold italic family is not specified, it will fall back to the
# value specified for the normal font.
#family: monospace
# The `style` can be specified to pick a specific face.
#style: Bold Italic
# Point size
size: 18.0
# Offset is the extra space around each character. `offset.y` can be thought
# of as modifying the line spacing, and `offset.x` as modifying the letter
# spacing.
#offset:
# x: 0
# y: 0
# Glyph offset determines the locations of the glyphs within their cells with
# the default being at the bottom. Increasing `x` moves the glyph to the
# right, increasing `y` moves the glyph upward.
#glyph_offset:
# x: 0
# y: 0
# Thin stroke font rendering (macOS only)
#
# Thin strokes are suitable for retina displays, but for non-retina screens
# it is recommended to set `use_thin_strokes` to `false`.
#use_thin_strokes: true
# If `true`, bold text is drawn using the bright color variants.
#draw_bold_text_with_bright_colors: false
# Colors (Tomorrow Night)
#colors:
# Default colors
#primary:
# background: '#1d1f21'
# foreground: '#c5c8c6'
# Bright and dim foreground colors
#
# The dimmed foreground color is calculated automatically if it is not
# present. If the bright foreground color is not set, or
# `draw_bold_text_with_bright_colors` is `false`, the normal foreground
# color will be used.
#dim_foreground: '#828482'
#bright_foreground: '#eaeaea'
# Cursor colors
#
# Colors which should be used to draw the terminal cursor.
#
# Allowed values are CellForeground/CellBackground, which reference the
# affected cell, or hexadecimal colors like #ff00ff.
#cursor:
# text: CellBackground
# cursor: CellForeground
# Vi mode cursor colors
#
# Colors for the cursor when the vi mode is active.
#
# Allowed values are CellForeground/CellBackground, which reference the
# affected cell, or hexadecimal colors like #ff00ff.
#vi_mode_cursor:
# text: CellBackground
# cursor: CellForeground
# Search colors
#
# Colors used for the search bar and match highlighting.
#search:
# Allowed values are CellForeground/CellBackground, which reference the
# affected cell, or hexadecimal colors like #ff00ff.
#matches:
# foreground: '#000000'
# background: '#ffffff'
#focused_match:
# foreground: '#ffffff'
# background: '#000000'
#bar:
# background: '#c5c8c6'
# foreground: '#1d1f21'
# Keyboard regex hints
#hints:
# Fist character in the hint label
#
# Allowed values are CellForeground/CellBackground, which reference the
# affected cell, or hexadecimal colors like #ff00ff.
#start:
# foreground: '#1d1f21'
# background: '#e9ff5e'
# All characters after the first one in the hint label
#
# Allowed values are CellForeground/CellBackground, which reference the
# affected cell, or hexadecimal colors like #ff00ff.
#end:
# foreground: '#e9ff5e'
# background: '#1d1f21'
# Line indicator
#
# Color used for the indicator displaying the position in history during
# search and vi mode.
#
# By default, these will use the opposing primary color.
#line_indicator:
# foreground: None
# background: None
# Selection colors
#
# Colors which should be used to draw the selection area.
#
# Allowed values are CellForeground/CellBackground, which reference the
# affected cell, or hexadecimal colors like #ff00ff.
#selection:
# text: CellBackground
# background: CellForeground
# Normal colors
#normal:
# black: '#1d1f21'
# red: '#cc6666'
# green: '#b5bd68'
# yellow: '#f0c674'
# blue: '#81a2be'
# magenta: '#b294bb'
# cyan: '#8abeb7'
# white: '#c5c8c6'
# Bright colors
#bright:
# black: '#666666'
# red: '#d54e53'
# green: '#b9ca4a'
# yellow: '#e7c547'
# blue: '#7aa6da'
# magenta: '#c397d8'
# cyan: '#70c0b1'
# white: '#eaeaea'
# Dim colors
#
# If the dim colors are not set, they will be calculated automatically based
# on the `normal` colors.
#dim:
# black: '#131415'
# red: '#864343'
# green: '#777c44'
# yellow: '#9e824c'
# blue: '#556a7d'
# magenta: '#75617b'
# cyan: '#5b7d78'
# white: '#828482'
# Indexed Colors
#
# The indexed colors include all colors from 16 to 256.
# When these are not set, they're filled with sensible defaults.
#
# Example:
# `- { index: 16, color: '#ff00ff' }`
#
#indexed_colors: []
# Bell
#
# The bell is rung every time the BEL control character is received.
#bell:
# Visual Bell Animation
#
# Animation effect for flashing the screen when the visual bell is rung.
#
# Values for `animation`:
# - Ease
# - EaseOut
# - EaseOutSine
# - EaseOutQuad
# - EaseOutCubic
# - EaseOutQuart
# - EaseOutQuint
# - EaseOutExpo
# - EaseOutCirc
# - Linear
#animation: EaseOutExpo
# Duration of the visual bell flash in milliseconds. A `duration` of `0` will
# disable the visual bell animation.
#duration: 0
# Visual bell animation color.
#color: '#ffffff'
# Bell Command
#
# This program is executed whenever the bell is rung.
#
# When set to `command: None`, no command will be executed.
#
# Example:
# command:
# program: notify-send
# args: ["Hello, World!"]
#
#command: None
# Background opacity
#
# Window opacity as a floating point number from `0.0` to `1.0`.
# The value `0.0` is completely transparent and `1.0` is opaque.
#background_opacity: 1.0
#selection:
# This string contains all characters that are used as separators for
# "semantic words" in Alacritty.
#semantic_escape_chars: ",│`|:\"' ()[]{}<>\t"
# When set to `true`, selected text will be copied to the primary clipboard.
#save_to_clipboard: false
#cursor:
# Cursor style
#style:
# Cursor shape
#
# Values for `shape`:
# - ▇ Block
# - _ Underline
# - | Beam
#shape: Block
# Cursor blinking state
#
# Values for `blinking`:
# - Never: Prevent the cursor from ever blinking
# - Off: Disable blinking by default
# - On: Enable blinking by default
# - Always: Force the cursor to always blink
#blinking: Off
# Vi mode cursor style
#
# If the vi mode cursor style is `None` or not specified, it will fall back to
# the style of the active value of the normal cursor.
#
# See `cursor.style` for available options.
#vi_mode_style: None
# Cursor blinking interval in milliseconds.
#blink_interval: 750
# If this is `true`, the cursor will be rendered as a hollow box when the
# window is not focused.
#unfocused_hollow: true
# Thickness of the cursor relative to the cell width as floating point number
# from `0.0` to `1.0`.
#thickness: 0.15
# If this is `true`, the cursor is temporarily hidden when typing.
#hide_when_typing: false
# Live config reload (changes require restart)
#live_config_reload: true
# Shell
#
# You can set `shell.program` to the path of your favorite shell, e.g.
# `/bin/fish`. Entries in `shell.args` are passed unmodified as arguments to the
# shell.
#
# Default:
# - (macOS) /bin/bash --login
# - (Linux/BSD) user login shell
# - (Windows) powershell
shell:
program: /bin/fish
# args:
# - --login
# Startup directory
#
# Directory the shell is started in. If this is unset, or `None`, the working
# directory of the parent process will be used.
#working_directory: None
# Send ESC (\x1b) before characters when alt is pressed.
#alt_send_esc: true
#mouse:
# Click settings
#
# The `double_click` and `triple_click` settings control the time
# alacritty should wait for accepting multiple clicks as one double
# or triple click.
#double_click: { threshold: 300 }
#triple_click: { threshold: 300 }
# Regex hints
#
# Terminal hints can be used to find text in the visible part of the terminal
# and pipe it to other applications.
#hints:
# Keys used for the hint labels.
#alphabet: "jfkdls;ahgurieowpq"
# List with all available hints
#
# Each hint must have a `regex` and either an `action` or a `command` field.
# The fields `mouse`, `binding` and `post_processing` are optional.
#
# The fields `command`, `binding.key`, `binding.mods` and `mouse.mods` accept
# the same values as they do in the `key_bindings` section.
#
# The `mouse.enabled` field controls if the hint should be underlined while
# the mouse with all `mouse.mods` keys held or the vi mode cursor is above it.
#
# If the `post_processing` field is set to `true`, heuristics will be used to
# shorten the match if there are characters likely not to be part of the hint
# (e.g. a trailing `.`). This is most useful for URIs.
#
# Values for `action`:
# - Copy
# Copy the hint's text to the clipboard.
# - Paste
# Paste the hint's text to the terminal or search.
# - Select
# Select the hint's text.
# - MoveViModeCursor
# Move the vi mode cursor to the beginning of the hint.
#enabled:
# - regex: "(mailto:|gemini:|gopher:|https:|http:|news:|file:|git:|ssh:|ftp:)\
# [^\u0000-\u001F\u007F-\u009F<>\"\\s{-}\\^⟨⟩`]+"
# command: xdg-open
# post_processing: true
# mouse:
# enabled: true
# mods: None
# binding:
# key: U
# mods: Control|Shift
# Mouse bindings
#
# Mouse bindings are specified as a list of objects, much like the key
# bindings further below.
#
# To trigger mouse bindings when an application running within Alacritty
# captures the mouse, the `Shift` modifier is automatically added as a
# requirement.
#
# Each mouse binding will specify a:
#
# - `mouse`:
#
# - Middle
# - Left
# - Right
# - Numeric identifier such as `5`
#
# - `action` (see key bindings)
#
# And optionally:
#
# - `mods` (see key bindings)
#mouse_bindings:
# - { mouse: Middle, action: PasteSelection }
# Key bindings
#
# Key bindings are specified as a list of objects. For example, this is the
# default paste binding:
#
# `- { key: V, mods: Control|Shift, action: Paste }`
#
# Each key binding will specify a:
#
# - `key`: Identifier of the key pressed
#
# - A-Z
# - F1-F24
# - Key0-Key9
#
# A full list with available key codes can be found here:
# https://docs.rs/glutin/*/glutin/event/enum.VirtualKeyCode.html#variants
#
# Instead of using the name of the keys, the `key` field also supports using
# the scancode of the desired key. Scancodes have to be specified as a
# decimal number. This command will allow you to display the hex scancodes
# for certain keys:
#
# `showkey --scancodes`.
#
# Then exactly one of:
#
# - `chars`: Send a byte sequence to the running application
#
# The `chars` field writes the specified string to the terminal. This makes
# it possible to pass escape sequences. To find escape codes for bindings
# like `PageUp` (`"\x1b[5~"`), you can run the command `showkey -a` outside
# of tmux. Note that applications use terminfo to map escape sequences back
# to keys. It is therefore required to update the terminfo when changing an
# escape sequence.
#
# - `action`: Execute a predefined action
#
# - ToggleViMode
# - SearchForward
# Start searching toward the right of the search origin.
# - SearchBackward
# Start searching toward the left of the search origin.
# - Copy
# - Paste
# - IncreaseFontSize
# - DecreaseFontSize
# - ResetFontSize
# - ScrollPageUp
# - ScrollPageDown
# - ScrollHalfPageUp
# - ScrollHalfPageDown
# - ScrollLineUp
# - ScrollLineDown
# - ScrollToTop
# - ScrollToBottom
# - ClearHistory
# Remove the terminal's scrollback history.
# - Hide
# Hide the Alacritty window.
# - Minimize
# Minimize the Alacritty window.
# - Quit
# Quit Alacritty.
# - ToggleFullscreen
# - SpawnNewInstance
# Spawn a new instance of Alacritty.
# - ClearLogNotice
# Clear Alacritty's UI warning and error notice.
# - ClearSelection
# Remove the active selection.
# - ReceiveChar
# - None
#
# - Vi mode exclusive actions:
#
# - Open
# Perform the action of the first matching hint under the vi mode cursor
# with `mouse.enabled` set to `true`.
# - ToggleNormalSelection
# - ToggleLineSelection
# - ToggleBlockSelection
# - ToggleSemanticSelection
# Toggle semantic selection based on `selection.semantic_escape_chars`.
#
# - Vi mode exclusive cursor motion actions:
#
# - Up
# One line up.
# - Down
# One line down.
# - Left
# One character left.
# - Right
# One character right.
# - First
# First column, or beginning of the line when already at the first column.
# - Last
# Last column, or beginning of the line when already at the last column.
# - FirstOccupied
# First non-empty cell in this terminal row, or first non-empty cell of
# the line when already at the first cell of the row.
# - High
# Top of the screen.
# - Middle
# Center of the screen.
# - Low
# Bottom of the screen.
# - SemanticLeft
# Start of the previous semantically separated word.
# - SemanticRight
# Start of the next semantically separated word.
# - SemanticLeftEnd
# End of the previous semantically separated word.
# - SemanticRightEnd
# End of the next semantically separated word.
# - WordLeft
# Start of the previous whitespace separated word.
# - WordRight
# Start of the next whitespace separated word.
# - WordLeftEnd
# End of the previous whitespace separated word.
# - WordRightEnd
# End of the next whitespace separated word.
# - Bracket
# Character matching the bracket at the cursor's location.
# - SearchNext
# Beginning of the next match.
# - SearchPrevious
# Beginning of the previous match.
# - SearchStart
# Start of the match to the left of the vi mode cursor.
# - SearchEnd
# End of the match to the right of the vi mode cursor.
#
# - Search mode exclusive actions:
# - SearchFocusNext
# Move the focus to the next search match.
# - SearchFocusPrevious
# Move the focus to the previous search match.
# - SearchConfirm
# - SearchCancel
# - SearchClear
# Reset the search regex.
# - SearchDeleteWord
# Delete the last word in the search regex.
# - SearchHistoryPrevious
# Go to the previous regex in the search history.
# - SearchHistoryNext
# Go to the next regex in the search history.
#
# - macOS exclusive actions:
# - ToggleSimpleFullscreen
# Enter fullscreen without occupying another space.
#
# - Linux/BSD exclusive actions:
#
# - CopySelection
# Copy from the selection buffer.
# - PasteSelection
# Paste from the selection buffer.
#
# - `command`: Fork and execute a specified command plus arguments
#
# The `command` field must be a map containing a `program` string and an
# `args` array of command line parameter strings. For example:
# `{ program: "alacritty", args: ["-e", "vttest"] }`
#
# And optionally:
#
# - `mods`: Key modifiers to filter binding actions
#
# - Command
# - Control
# - Option
# - Super
# - Shift
# - Alt
#
# Multiple `mods` can be combined using `|` like this:
# `mods: Control|Shift`.
# Whitespace and capitalization are relevant and must match the example.
#
# - `mode`: Indicate a binding for only specific terminal reported modes
#
# This is mainly used to send applications the correct escape sequences
# when in different modes.
#
# - AppCursor
# - AppKeypad
# - Search
# - Alt
# - Vi
#
# A `~` operator can be used before a mode to apply the binding whenever
# the mode is *not* active, e.g. `~Alt`.
#
# Bindings are always filled by default, but will be replaced when a new
# binding with the same triggers is defined. To unset a default binding, it can
# be mapped to the `ReceiveChar` action. Alternatively, you can use `None` for
# a no-op if you do not wish to receive input characters for that binding.
#
# If the same trigger is assigned to multiple actions, all of them are executed
# in the order they were defined in.
#key_bindings:
#- { key: Paste, action: Paste }
#- { key: Copy, action: Copy }
#- { key: L, mods: Control, action: ClearLogNotice }
#- { key: L, mods: Control, mode: ~Vi|~Search, chars: "\x0c" }
#- { key: PageUp, mods: Shift, mode: ~Alt, action: ScrollPageUp, }
#- { key: PageDown, mods: Shift, mode: ~Alt, action: ScrollPageDown }
#- { key: Home, mods: Shift, mode: ~Alt, action: ScrollToTop, }
#- { key: End, mods: Shift, mode: ~Alt, action: ScrollToBottom }
# Vi Mode
#- { key: Space, mods: Shift|Control, mode: Vi|~Search, action: ScrollToBottom }
#- { key: Space, mods: Shift|Control, mode: ~Search, action: ToggleViMode }
#- { key: Escape, mode: Vi|~Search, action: ClearSelection }
#- { key: I, mode: Vi|~Search, action: ScrollToBottom }
#- { key: I, mode: Vi|~Search, action: ToggleViMode }
#- { key: C, mods: Control, mode: Vi|~Search, action: ToggleViMode }
#- { key: Y, mods: Control, mode: Vi|~Search, action: ScrollLineUp }
#- { key: E, mods: Control, mode: Vi|~Search, action: ScrollLineDown }
#- { key: G, mode: Vi|~Search, action: ScrollToTop }
#- { key: G, mods: Shift, mode: Vi|~Search, action: ScrollToBottom }
#- { key: B, mods: Control, mode: Vi|~Search, action: ScrollPageUp }
#- { key: F, mods: Control, mode: Vi|~Search, action: ScrollPageDown }
#- { key: U, mods: Control, mode: Vi|~Search, action: ScrollHalfPageUp }
#- { key: D, mods: Control, mode: Vi|~Search, action: ScrollHalfPageDown }
#- { key: Y, mode: Vi|~Search, action: Copy }
#- { key: Y, mode: Vi|~Search, action: ClearSelection }
#- { key: Copy, mode: Vi|~Search, action: ClearSelection }
#- { key: V, mode: Vi|~Search, action: ToggleNormalSelection }
#- { key: V, mods: Shift, mode: Vi|~Search, action: ToggleLineSelection }
#- { key: V, mods: Control, mode: Vi|~Search, action: ToggleBlockSelection }
#- { key: V, mods: Alt, mode: Vi|~Search, action: ToggleSemanticSelection }
#- { key: Return, mode: Vi|~Search, action: Open }
#- { key: K, mode: Vi|~Search, action: Up }
#- { key: J, mode: Vi|~Search, action: Down }
#- { key: H, mode: Vi|~Search, action: Left }
#- { key: L, mode: Vi|~Search, action: Right }
#- { key: Up, mode: Vi|~Search, action: Up }
#- { key: Down, mode: Vi|~Search, action: Down }
#- { key: Left, mode: Vi|~Search, action: Left }
#- { key: Right, mode: Vi|~Search, action: Right }
#- { key: Key0, mode: Vi|~Search, action: First }
#- { key: Key4, mods: Shift, mode: Vi|~Search, action: Last }
#- { key: Key6, mods: Shift, mode: Vi|~Search, action: FirstOccupied }
#- { key: H, mods: Shift, mode: Vi|~Search, action: High }
#- { key: M, mods: Shift, mode: Vi|~Search, action: Middle }
#- { key: L, mods: Shift, mode: Vi|~Search, action: Low }
#- { key: B, mode: Vi|~Search, action: SemanticLeft }
#- { key: W, mode: Vi|~Search, action: SemanticRight }
#- { key: E, mode: Vi|~Search, action: SemanticRightEnd }
#- { key: B, mods: Shift, mode: Vi|~Search, action: WordLeft }
#- { key: W, mods: Shift, mode: Vi|~Search, action: WordRight }
#- { key: E, mods: Shift, mode: Vi|~Search, action: WordRightEnd }
#- { key: Key5, mods: Shift, mode: Vi|~Search, action: Bracket }
#- { key: Slash, mode: Vi|~Search, action: SearchForward }
#- { key: Slash, mods: Shift, mode: Vi|~Search, action: SearchBackward }
#- { key: N, mode: Vi|~Search, action: SearchNext }
#- { key: N, mods: Shift, mode: Vi|~Search, action: SearchPrevious }
# Search Mode
#- { key: Return, mode: Search|Vi, action: SearchConfirm }
#- { key: Escape, mode: Search, action: SearchCancel }
#- { key: C, mods: Control, mode: Search, action: SearchCancel }
#- { key: U, mods: Control, mode: Search, action: SearchClear }
#- { key: W, mods: Control, mode: Search, action: SearchDeleteWord }
#- { key: P, mods: Control, mode: Search, action: SearchHistoryPrevious }
#- { key: N, mods: Control, mode: Search, action: SearchHistoryNext }
#- { key: Up, mode: Search, action: SearchHistoryPrevious }
#- { key: Down, mode: Search, action: SearchHistoryNext }
#- { key: Return, mode: Search|~Vi, action: SearchFocusNext }
#- { key: Return, mods: Shift, mode: Search|~Vi, action: SearchFocusPrevious }
# (Windows, Linux, and BSD only)
#- { key: V, mods: Control|Shift, mode: ~Vi, action: Paste }
#- { key: C, mods: Control|Shift, action: Copy }
#- { key: F, mods: Control|Shift, mode: ~Search, action: SearchForward }
#- { key: B, mods: Control|Shift, mode: ~Search, action: SearchBackward }
#- { key: C, mods: Control|Shift, mode: Vi|~Search, action: ClearSelection }
#- { key: Insert, mods: Shift, action: PasteSelection }
#- { key: Key0, mods: Control, action: ResetFontSize }
#- { key: Equals, mods: Control, action: IncreaseFontSize }
#- { key: Plus, mods: Control, action: IncreaseFontSize }
#- { key: NumpadAdd, mods: Control, action: IncreaseFontSize }
#- { key: Minus, mods: Control, action: DecreaseFontSize }
#- { key: NumpadSubtract, mods: Control, action: DecreaseFontSize }
# (Windows only)
#- { key: Return, mods: Alt, action: ToggleFullscreen }
# (macOS only)
#- { key: K, mods: Command, mode: ~Vi|~Search, chars: "\x0c" }
#- { key: K, mods: Command, mode: ~Vi|~Search, action: ClearHistory }
#- { key: Key0, mods: Command, action: ResetFontSize }
#- { key: Equals, mods: Command, action: IncreaseFontSize }
#- { key: Plus, mods: Command, action: IncreaseFontSize }
#- { key: NumpadAdd, mods: Command, action: IncreaseFontSize }
#- { key: Minus, mods: Command, action: DecreaseFontSize }
#- { key: NumpadSubtract, mods: Command, action: DecreaseFontSize }
#- { key: V, mods: Command, action: Paste }
#- { key: C, mods: Command, action: Copy }
#- { key: C, mods: Command, mode: Vi|~Search, action: ClearSelection }
#- { key: H, mods: Command, action: Hide }
#- { key: H, mods: Command|Alt, action: HideOtherApplications }
#- { key: M, mods: Command, action: Minimize }
#- { key: Q, mods: Command, action: Quit }
#- { key: W, mods: Command, action: Quit }
#- { key: N, mods: Command, action: SpawnNewInstance }
#- { key: F, mods: Command|Control, action: ToggleFullscreen }
#- { key: F, mods: Command, mode: ~Search, action: SearchForward }
#- { key: B, mods: Command, mode: ~Search, action: SearchBackward }
#debug:
# Display the time it takes to redraw each frame.
#render_timer: false
# Keep the log file after quitting Alacritty.
#persistent_logging: false
# Log level
#
# Values for `log_level`:
# - Off
# - Error
# - Warn
# - Info
# - Debug
# - Trace
#log_level: Warn
# Print all received window events.
#print_events: false
IRB.conf[:USE_MULTILINE] = false if ENV['INSIDE_EMACS'] && ENV['INSIDE_EMACS'] != 'vterm'
IRB.conf[:SAVE_HISTORY] ||= 1000
# I'd love if the next line worked with Ruby, but unfortunately history_dir is out of scope
# https://bugs.ruby-lang.org/issues/1141 has a comment from Matz about it.
# Dir.mkdir(history_dir) unless Dir.exist?(history_dir = File.join(ENV['XDG_DATA_HOME'], 'irb'))
unless Dir.exist?(history_dir = File.join(ENV['XDG_DATA_HOME'], 'irb')) then Dir.mkdir(history_dir) end
IRB.conf[:HISTORY_FILE] ||= File.join(history_dir, 'irb_history')
if [[ "$XDG_CONFIG_HOME" ]]; then
export IRBRC="$XDG_CONFIG_HOME"/irb/irbrc
else
export IRBRC=~/.config/irb/irbrc
fi
# Nano syntax highlighting
include /usr/share/nano/elisp.nanorc
include /usr/share/nano/default.nanorc
include /usr/share/nano/json.nanorc
include /usr/share/nano/cmake.nanorc
include /usr/share/nano/java.nanorc
include /usr/share/nano/sh.nanorc
include /usr/share/nano/changelog.nanorc
include /usr/share/nano/groff.nanorc
include /usr/share/nano/c.nanorc
include /usr/share/nano/asm.nanorc
include /usr/share/nano/po.nanorc
include /usr/share/nano/fortran.nanorc
include /usr/share/nano/postgresql.nanorc
include /usr/share/nano/nanohelp.nanorc
include /usr/share/nano/mgp.nanorc
include /usr/share/nano/ruby.nanorc
include /usr/share/nano/pov.nanorc
include /usr/share/nano/awk.nanorc
include /usr/share/nano/nftables.nanorc
include /usr/share/nano/autoconf.nanorc
include /usr/share/nano/xml.nanorc
include /usr/share/nano/spec.nanorc
include /usr/share/nano/ocaml.nanorc
include /usr/share/nano/objc.nanorc
include /usr/share/nano/nanorc.nanorc
include /usr/share/nano/python.nanorc
include /usr/share/nano/tex.nanorc
include /usr/share/nano/tcl.nanorc
include /usr/share/nano/html.nanorc
include /usr/share/nano/perl.nanorc
include /usr/share/nano/man.nanorc
include /usr/share/nano/rust.nanorc
include /usr/share/nano/lua.nanorc
include /usr/share/nano/javascript.nanorc
include /usr/share/nano/makefile.nanorc
include /usr/share/nano/debian.nanorc
include /usr/share/nano/php.nanorc
include /usr/share/nano/guile.nanorc
include /usr/share/nano/css.nanorc
include /usr/share/nano/go.nanorc
include /usr/share/nano/gentoo.nanorc
include /usr/share/nano/texinfo.nanorc
include /usr/share/nano/mutt.nanorc
include /usr/share/nano/patch.nanorc
-----BEGIN PGP MESSAGE-----
hQIMA341lovNpziwAQ/6A9H6JCfACSWT6gXXghZaEIpxLbNBWPoklPKN9bBaX74P Q3F7i5d/X1ywSxkaKzK8VM7vyeU1qa74ZdqyQBnfDdSTWdnhCmGbaGZfXqr9uCNB UF0DKK/G0bd0cUCXJq6GheXQQFdxupE4yG9yGTtdrS7bvbM4Sd7axK4g5Yxgivj1 sew4faYDYIgNUOhZW+SclDhewp7kJikjS6uMHSYKn3l8IxhtF3nsxzMfYkei0iIO LhrNRjBXjELt0krT4TvFgi+G8njAED8Q4Nas0lOC8GMmjagF+xByfWmYSEQ67Vd4 7MPhQE+UfAphcs9tICOv5yGVkbhAKgUmtv8mjcG+GBMcfOk8yYWT4u6a6Jkiwqlr Sn5jihv6QkG8vC3qHrr8Gk9NC/woq3VY2wsf+SOiky/RD6+4/PCWIfGy/1ZLQgYM H/OEJltYDvJSi7bicfly556PlAKiwC8DhQtjSPDs/Pxce4WaB97d6u7YE1yM+eBh s+BI0Y+ReM/cpMoWiOonf36tWoyEcwnCVZpT3twmLBqBmjeH1dSjgUbWH5thQD4P AIE1EPNIX+bphmbMgYVw144LJdl9AJ8wE6bfsoiDKTgVh1crZVCmdX6vmPQe2fOL PvyMS+YrOLX+KFPquvTNoVFi5/RTEMSeJhrPhf7gputbl4hjzEb3T+eelBwnTjLS wDoB5KF3tPAa3DowR9qodVcKrYUKyFTzO9l96gxj7NN4ja2N4eST7GSil9nL6Zbn /wREaqsh7XqvOdGeoys410E0/TFgQCd0/SaLhCOD+a9znQ6RIbCCM4hdKitlkvwl rlX2LwmjvkTi/DSco8RXaSY279Lzc8sPee7sc9+a77etXub/aPfLvYX4OrmFhpcP 8Ym/xhPhHgJr2apPSmIz2UwEEGT7eqlPzfTpBUg7Dlohqdc2JsHQ8Ks+uh9djPjq w1Xs7pY+p1qxoj2PsWbtXeeQGrFFLKwMV6KjlH6pl9IfqNG4qkDwVtsrAJaQFViV mRS+xzNYe00sRjby =0U1o -----END PGP MESSAGE-----
I’ll write this up later.
Much of this section was stolen borrowed from larstvei.
All changes to the configuration should be done in init.org
, not in
init.el
. Any changes in the init.el
will be overwritten by saving
init.org
. The init.el
in this repo should not be tracked by git, and
is replaced the first time Emacs is started (assuming it has been renamed
to ~/.emacs.d
).
Emacs can’t load .org
-files directly, but org-mode
provides functions
to extract the code blocks and write them to a file. There are multiple
ways of handling this; like suggested by this StackOverflow post, one
could just use org-babel-load-file
, but I had problems with
byte-compilation. Previously I tracked both the org.
- and el.
-files,
but the git commits got a little messy. So here is a new approach.
When this configuration is loaded for the first time, the init.el
is
the file that is loaded. It looks like this:
;;; init.el --- Initialization
;; This file replaces itself with the actual configuration at first run.
;; We can't tangle without org!
;;; Commentary:
;;
;; org-crypt built in since at least 27.2
(require 'org)
(require 'org-crypt)
;; Open the configuration
;;; Code:
(find-file "~/config.org")
;; tangle it
(org-decrypt-entries)
(org-babel-tangle)
(org-encrypt-entries)
;; load it
(load-file "~/config.org")
;; finally byte-compile it
(byte-compile-file (concat user-emacs-directory "init.el"))
(provide 'init)
;;; init.el ends here
It tangles the org-file, so that this file is overwritten with the actual configuration.
There is no reason to track the init.el
that is generated; by running
the following command git
will not bother tracking it:
git update-index --assume-unchanged init.el
If one wishes to make changes to the repo-version of init.el
start
tracking again with:
git update-index --no-assume-unchanged init.el
I want lexical scoping for the init-file, which can be specified in the header. The first line of the configuration is as follows:
;;; -*- lexical-binding: t -*-
The init.el
should (after the first run) mirror the source blocks in
the init.org
. We can use C-c C-v t
to run org-babel-tangle
, which
extracts the code blocks from the current file into a source-specific
file (in this case a .el
-file).
To avoid doing this each time a change is made we can add a function to
the after-save-hook
ensuring to always tangle and byte-compile the
org
-document after changes.
I use Org Crypt
, which has a feature where it will encrypt your
org
file when you save. This breaks tangling. I had to modify this
function to tangle everything first, then encrypt before saving.
(defun my/tangle-init ()
"If the current buffer is 'init.org' the code-blocks are
tangled, and the tangled file is compiled."
;; org-babel-tangle runs save-buffer as a hook. Somewhere along the
;; line the current buffer goes back to init.org, leading to an
;; infinite loop when using before-save-hook. Now we create a
;; tempory buffer with unsaved contents, tangle this buffer, and
;; then save, so unencrypted content is tangled and re-encrypted
;; before saving.
(when (equal (buffer-file-name) (expand-file-name "~/config.org"))
;; Avoid running hooks when tangling.
(let ((prog-mode-hook nil) (before-save-hook nil))
(org-decrypt-entries)
(org-babel-tangle)
(org-encrypt-entries))
(byte-compile-file (concat user-emacs-directory "init.el"))))
(add-hook
'org-mode-hook
(lambda () (add-hook 'before-save-hook 'my/tangle-init nil t)))
Installs Guix
at the system level. They provide a script to help
with installation across multiple architectures that I download and
run.
sudo
is broke and won’t consistently read properly from stdin with
-S. See https://serverfault.com/questions/477968. After struggling for
a long time (check the subheading for how far my plight went), I
decided to create a Comint process.
;; Don't install if already present
(let ((guix-present (condition-case nil
(start-process "guix-test" nil "guix" "--version")
(error nil))))
(unless guix-present
(let ((guix-script
(with-current-buffer
(url-retrieve-synchronously
"https://git.savannah.gnu.org/cgit/guix.git/plain/etc/guix-install.sh"
'silent 'inhibit-cookies)
;; Remove HTTP headers
;; https://emacs.stackexchange.com/questions/12464
(goto-char (point-min))
(re-search-forward "^$")
(delete-region (point) (point-min))
(buffer-string))))
;; root permissions required
;; https://emacs.stackexchange.com/questions/29555
(let ((name "guix-install")
(guix-script-file (make-temp-file "guix-" nil ".sh" guix-script)))
(make-comint-in-buffer name nil "sudo" nil "sh" guix-script-file)
(display-buffer (process-buffer (get-process name))
'(display-buffer-pop-up-window . '(('window-height . 1.0)
('window-width . 0.5)))
nil)))))
I use straight.el for package management. This is boostrap code from the Github repo to set up straight.
(setq straight-repository-branch "develop") ; prebuild support for mu4e
(defvar straight-fix-flycheck t)
(defvar bootstrap-version)
(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))
(straight-use-package 'use-package) ; Install use-package
(setq straight-use-package-by-default t) ; I don't want to type :straight t a billion times
I’m not entirely sure why this is necessary, and more importantly, what better solutions there are. But when byte-compiling Emacs, bind-keys isn’t properly loaded by use-package. This means any custom (and most built-in) keybindings are nonfunctional.
Solution found here.
(use-package bind-key)
I don’t want to worry about stuff breaking because of environment variable weirdness.
(use-package exec-path-from-shell
:demand t
:config
(when (memq window-system '(mac ns x))
(exec-path-from-shell-initialize)))
(use-package no-littering
:demand t
:config
(setq auto-save-file-name-transforms
`((".*" ,(no-littering-expand-var-file-name "auto-save/") t))))
We want to keep the garbage collector from running while we initialize everything. We can reset it later to a more reasonable value. If we didn’t do this, Emacs would hang when running the garbage collector.
(setq-default
gc-cons-threshold most-positive-fixnum ; 8 MiB
gc-cons-percentage 0.6)
Replace the file-name-handler-alist to nil, as regexing is cpu intensive. We need to keep the original value to restore it later. I don’t know all the details behind it, but it sounds helpful!
(defvar default-file-name-handler-alist file-name-handler-alist)
(setq file-name-handler-alist nil)
And now we revert the changes with a startup hook. 16777216
is the
value Doom uses.
(add-hook 'emacs-startup-hook
(lambda ()
(setq gc-cons-threshold 16777216
gc-cons-percentage 0.1
file-name-handler-alist default-file-name-handler-alist)))
Garbage-collect on focus-out. Emacs should feel snappier overall. With Emacs 27.1, focus-out-hook is deprecated.
(add-function :after after-focus-change-function
(lambda () (unless (frame-focus-state) (garbage-collect))))
Apparently this can result in a significant speedup when using fonts larger or smaller than the system default.
(setq frame-inhibit-implied-resize t)
As of [2021-02-18 Thu], tangling everything to early-init.el saved 0.06 seconds.
I don’t need no fancy user interface! These ones are only active when
in a window. Apparently putting this in early-init.el
will speed up
startup even more.
(push '(menu-bar-lines . 1) default-frame-alist)
(push '(tool-bar-lines . 0) default-frame-alist)
(push '(vertical-scroll-bars) default-frame-alist)
And now for a bunch of one liner configurations.
(setq-default
auth-source-save-behavior nil ; Not interested in auth-source
frame-resize-pixelwise t ; Removes empty space at bottom of screen when maximized
help-window-select t ; Select help windows when they appear
inhibit-startup-screen t ; Emacs really could use a more "welcoming" welcome screen
initial-scratch-message "" ; Clear scratch buffer
next-screen-context-lines 6 ; Keep 6 lines of context when using scroll-up/down-command
ring-bell-function 'ignore ; My ears!
scroll-conservatively most-positive-fixnum ; Always scroll by one line
scroll-preserve-screen-position t ; Try to keep point in the same location visually
sentence-end-double-space nil ; Use a single space after dots
show-help-function nil ; Disable help text on most UI elements
uniquify-buffer-name-style 'forward ; Make buffer names unique
use-dialog-box nil ; Apparently compile reverting buffers counts as a mouse command
auto-save-timeout 1200 ; Otherwise Org Crypt will encrypt file constantly
)
(defalias 'yes-or-no-p 'y-or-n-p) ; y is shorter than yes
(delete-selection-mode 1) ; If I selected something, I probably want to edit it.
(global-auto-revert-mode 1) ; If I edit something elsewhere, I probably want to reload
(global-hl-line-mode) ; Highlight the active line
(menu-bar-mode 0) ; Disable the menu bar
(scroll-bar-mode 0) ; Disable the scroll bar
(tool-bar-mode 0) ; Disable the tool bar
(set-default-coding-systems 'utf-8) ; Default to utf-8 encoding
Start Emacs in fullscreen.
(if (eq window-system 'ns)
(set-frame-parameter nil 'fullscreen 'maximized)
(set-frame-parameter nil 'fullscreen 'fullboth))
I already know about Emacs, thank you.
(fset 'display-startup-echo-area-message 'ignore)
I don’t enjoy Emacs messing with my window layouts.
(setq display-buffer-alist
'((".*" (display-buffer-reuse-window display-buffer-same-window))))
(add-to-list 'display-buffer-alist ; reuse windows in other frames
'("." nil (reusable-frames . t)))
(setq even-window-sizes nil) ; display-buffer: avoid resizing
When byte compiling, Emacs will go crazy about references to free
variables. Often these are just (use-package)
macros. Not all packages
behave like this, but enough do that I’m putting this in to hope it
will help.
For context the error looks like
init.el:77:14: Warning: reference to free variable ‘bind-key’
where bind-key
can be the name of many different (but not all)
packages.
;; This has no effect. (Actually, it removed the all-the-icons
;; warning, but caused another)
; (eval-when-compile (straight-use-package 'use-package))
To hide (but not disable) compilation warnings with native-comp, I’ll
change warning-suppress-types
.
(setq warning-suppress-types '((comp)))
While I could use (setq disabled-command-function nil)
, I’d prefer to
disable them piecemeal in the off-chance there’s a disabled command I
actually want to be disabled.
(put 'downcase-region 'disabled nil) ; Is it really that confusing?
(put 'erase-buffer 'disabled nil) ; It's literally in the name
(put 'upcase-region 'disabled nil) ; I reiterate. Is it really that confusing?
A slowly growing list of constants. Many of these are thanks to Centaur Emacs.
(defconst sys/win32p ; I hope I don't need this constant
(eq system-type 'windows-nt)
"Are we running on a WinTel system?")
(defconst sys/linuxp
(eq system-type 'gnu/linux)
"Are we running on a GNU/Linux system?")
(defconst sys/macp
(eq system-type 'darwin)
"Are we running on a Mac system?")
(defconst sys/mac-x-p
(and (display-graphic-p) sys/macp)
"Are we running under X on a Mac system?")
(defconst sys/mac-ns-p
(eq window-system 'ns)
"Are we running on a GNUstep or Macintosh Cocoa display?")
(defconst sys/mac-cocoa-p
(featurep 'cocoa)
"Are we running with Cocoa on a Mac system?")
(defconst sys/mac-port-p
(eq window-system 'mac)
"Are we running a macport build on a Mac system?")
(defconst sys/linux-x-p
(and (display-graphic-p) sys/linuxp)
"Are we running under X on a GNU/Linux system?")
(defconst sys/cygwinp
(eq system-type 'cygwin)
"Are we running on a Cygwin system?")
(defconst sys/rootp
(string-equal "root" (getenv "USER"))
"Are you using ROOT user?")
(defconst emacs/>=25p
(>= emacs-major-version 25)
"Emacs is 25 or above.")
(defconst emacs/>=26p
(>= emacs-major-version 26)
"Emacs is 26 or above.")
(defconst emacs/>=27p
(>= emacs-major-version 27)
"Emacs is 27 or above.")
(defconst emacs/>=25.3p
(or emacs/>=26p
(and (= emacs-major-version 25) (>= emacs-minor-version 3)))
"Emacs is 25.3 or above.")
(defconst emacs/>=25.2p
(or emacs/>=26p
(and (= emacs-major-version 25) (>= emacs-minor-version 2)))
"Emacs is 25.2 or above.")
Custom functions from various sources.
Code and explanations from /u/ouroboroslisp (archive) to try and fix font lock face bleeding out into org headings if there’s only one space. This is most common with source code blocks, although it’s not visible to everyone as some themes may have the same face for source code blocks and the background.
I’ve disabled these functions for now since they didn’t appear to help
at all with this init.org file. Instead, I found
org-fontify-whole-block-delimiter-line
and set that to nil.
Unfontify the last line of a subtree if it’s the end of a source block. This is the line responsible for the bleeding.
;; (defun dwim-unfontify-last-line-of-subtree (&rest _)
;; "Unfontify last line of subtree if it's a source block."
;; (save-excursion
;; (org-end-of-subtree)
;; (beginning-of-line)
;; (when (looking-at-p (rx "#+end_src"))
;; (font-lock-unfontify-region
;; (line-end-position) (1+ (line-end-position))))))
;; (advice-add #'outline-hide-subtree :after #'dwim-unfontify-last-line-of-subtree)
Now we need to refontify that line at the right time. There’s two
things we need to account for. We need to make sure that the
#+end_src
line is fontified when it’s visible. Also we should keep
in mind that any newly revealed (ie. By unfolding subtree with
outline-toggle-children) folded source block headings are also
bleeders and need to have their #+end_src
unfontified also.
It’s also important which functions we choose to advice or modify for this because we want to minimize the amount of work we want to do. Ideally, we’d like a pretty core function so that this behavior would propagate to other functions.
Looking at the source for outline-toggle-children
, I thought
outline-show-heading
was a good choice to advise. Keeping all this in
mind I wrote this advising function.
;; (defun dwim-fontify-last-line-of-block (&rest _)
;; "Do what I mean: fontify last line of source block.
;; When the heading has a source block as the last item (in the subtree) do the
;; following:
;; If the source block is now visible, fontify the end its last line.
;; If it’s still invisible, unfontify its last line."
;; (let (font-lock-fn point)
;; (save-excursion
;; (org-end-of-subtree)
;; (beginning-of-line)
;; (run-hooks 'outline-view-change-hook)
;; (when (looking-at-p (rx "#+end_src"))
;; (setq font-lock-fn
;; (if (invisible-p (line-end-position))
;; #'font-lock-unfontify-region
;; #'font-lock-fontify-region))
;; (funcall font-lock-fn
;; (line-end-position)
;; (1+ (line-end-position)))))))
;; (advice-add #'outline-show-heading :after #'dwim-fontify-last-line-of-block)
Sort words in region alphabetically. If arg is negative, sort them in reverse.
(defun sort-words (reverse beg end)
"Sort words in region alphabetically, in REVERSE if negative.
Prefixed with negative \\[universal-argument], sorts in reverse.
The variable `sort-fold-case' determines whether alphabetic case
affects the sort order.
See `sort-regexp-fields'."
(interactive "*P\nr")
(sort-regexp-fields reverse "\\w+" "\\&" beg end))
Functions used by packages I have installed.
Return t if a font is installed, nil otherwise. Used by
all-the-icons
.
(defun aorst/font-installed-p (font-name)
"Check if font with FONT-NAME is available."
(if (find-font (font-spec :name font-name))
t
nil))
A duo of functions for getting human readable file sizes. Used by
ibuffer-vc
.
(defun ajv/human-readable-file-sizes-to-bytes (string)
"Convert a human-readable file size into bytes."
(interactive)
(cond
((string-suffix-p "G" string t)
(* 1000000000 (string-to-number (substring string 0 (- (length string) 1)))))
((string-suffix-p "M" string t)
(* 1000000 (string-to-number (substring string 0 (- (length string) 1)))))
((string-suffix-p "K" string t)
(* 1000 (string-to-number (substring string 0 (- (length string) 1)))))
(t
(string-to-number (substring string 0 (- (length string) 1))))
)
)
(defun ajv/bytes-to-human-readable-file-sizes (bytes)
"Convert number of bytes to human-readable file size."
(interactive)
(cond
((> bytes 1000000000) (format "%10.1fG" (/ bytes 1000000000.0)))
((> bytes 100000000) (format "%10.0fM" (/ bytes 1000000.0)))
((> bytes 1000000) (format "%10.1fM" (/ bytes 1000000.0)))
((> bytes 100000) (format "%10.0fk" (/ bytes 1000.0)))
((> bytes 1000) (format "%10.1fk" (/ bytes 1000.0)))
(t (format "%10d" bytes)))
)
all-the-icons | https://github.com/domtronn/all-the-icons.el |
all-the-icons-dired | https://github.com/jtbm37/all-the-icons-dired |
I like having pretty icons next to a lot of things. I also don’t like remembering to install them on a new machine.
(use-package all-the-icons
:config
(when (and (not (aorst/font-installed-p "all-the-icons"))
(window-system))
(all-the-icons-install-fonts t))
:defer 1)
I also like having them in dired.
(use-package all-the-icons-dired
:hook (dired-mode . all-the-icons-dired-mode))
doom-themes | https://github.com/hlissner/emacs-doom-themes |
Why install one theme when many will do? Yeah, that sounds right.
(use-package doom-themes
:config (load-theme 'doom-monokai-pro t))
I like being able to see the text on my screen.
(add-to-list 'default-frame-alist '(font . "monospace-9:weight=light"))
all-the-icons-ibuffer | https://github.com/seagle0128/all-the-icons-ibuffer |
ibuffer-vc | https://github.com/purcell/ibuffer-vc |
First and foremost, replace list-buffers
with Ibuffer
(global-set-key (kbd "C-x C-b") 'ibuffer)
Next, I’ll set up some pretty icons.
(use-package all-the-icons-ibuffer
:diminish
:after all-the-icons)
Time to actually make Ibuffer
functional by setting up automatic version
control groups.
FIXME: Currently the *Help*
buffer is not properly aligned with the others.
(use-package ibuffer-vc ; Also consider ibuffer-projectile
:after all-the-icons-ibuffer
:hook (ibuffer . (lambda () (ibuffer-vc-set-filter-groups-by-vc-root) ; Look at combining with custom ibuffer groups with 'ibuffer-projectile-generate-filter-groups
(unless (eq ibuffer-sorting-mode 'alphabetic) ; Obviously that's an ibuffer-projectile exclusive, not ibuffer-vc
(ibuffer-do-sort-by-alphabetic)))) ; https://emacs.stackexchange.com/questions/2181/ibuffer-how-to-automatically-create-groups-per-project
:bind ("C-x C-b" . ibuffer) ; shows some of code behind projectile filter groups
:config
(define-ibuffer-column size-h
(:name "Size"
:inline t
:summarizer
(lambda (column-strings)
(let ((total 0))
(dolist (string column-strings)
(setq total
;; like, ewww ...
(+ (float (ajv/human-readable-file-sizes-to-bytes string))
total)))
(ajv/bytes-to-human-readable-file-sizes total))) ;; :summarizer nil
)
(ajv/bytes-to-human-readable-file-sizes (buffer-size)))
(setq ibuffer-formats
'((mark modified read-only vc-status-mini " "
(icon 2 2 :center :elide)
" "
(name 18 18 :left :elide)
" "
(size-h 9 -1 :right)
" "
(mode 20 20 :left :elide)
" "
(vc-status 16 16 :left)
" "
vc-relative-file))))
which-key | https://github.com/justbur/emacs-which-key |
Emacs has a lot of keybindings. I can’t remember every keybinding. I use a tool to remember every keybinding for me.
(use-package which-key
:defer 1
:diminish
:config (which-key-mode)
(setq which-key-add-column-padding 3)) ; Easier to visually separate columns
linum | Built-in |
I find the linum foreground color too dim (at least with
doom-monokai-pro
), so I set it to match the color of comments. This
should be generic enough to work well with most themes.
(use-package linum
:hook (prog-mode . linum-mode)
:after (doom-themes)
:config
(defun linum-format-func (line)
(let ((w (length (number-to-string (count-lines (point-min) (point-max))))))
(propertize (format (format "%%%dd " w) line) 'face 'linum)))
(setq linum-format 'linum-format-func)
(set-face-attribute 'linum nil :foreground (face-attribute 'font-lock-comment-face :foreground)))
doom-modeline | https://github.com/seagle0128/doom-modeline |
diminish | https://github.com/emacsmirror/diminish |
Since I haven’t gotten around to customizing my modeline yet, I just
use doom-modeline
.
(use-package doom-modeline ; Later, replace with custom following similar process to https://www.gonsie.com/blorg/modeline.html
:hook (after-init . doom-modeline-mode)
:custom ; Could use more use-package-ifying
(doom-modeline-height 20) ; To better employ its features.
(doom-modeline-bar-width 1)
(doom-modeline-icon t)
(doom-modeline-major-mode-icon t)
(doom-modeline-major-mode-color-icon t)
(doom-modeline-buffer-file-name-style 'truncate-upto-project)
(doom-modeline-buffer-state-icon t)
(doom-modeline-buffer-modification-icon t)
(doom-modeline-minor-modes nil)
(doom-modeline-enable-word-count nil)
(doom-modeline-buffer-encoding t)
(doom-modeline-indent-info nil)
(doom-modeline-checker-simple-format t)
(doom-modeline-vcs-max-length 12)
(doom-modeline-env-version t)
(doom-modeline-irc-stylize 'identity)
(doom-modeline-github-timer nil)
(doom-modeline-gnus-timer nil))
To help me when I actually do customize the modeline myself, I’ll have
diminish
to hide my active minor modes.
(use-package diminish)
(use-package emacs
:config (display-time))
dashboard | https://github.com/emacs-dashboard/emacs-dashboard |
Show a dashboard on startup.
(use-package dashboard
:hook (after-init . dashboard-setup-startup-hook)
:bind (:map dashboard-mode-map
("n" . dashboard-next-line)
("p" . dashboard-previous-line))
:config
(set-face-attribute 'dashboard-items-face nil :weight 'normal)
(set-face-attribute 'dashboard-heading nil :weight 'semi-bold)
(set-face-attribute 'dashboard-text-banner nil :weight 'semi-bold)
(setq dashboard-project-backend 'projectile
;; initial-buffer-choice (lambda () (get-buffer "*dashboard*"))
dashboard-set-navigator t
dashboard-startup-banner 1
;; There's a weird interaction with org, org-superstar, and
;; dashboard that breaks fontifying the startup-banner when
;; agenda items are used
dashboard-items '((projects . 8)
(bookmarks . 5)
(recents . 5))
;; override "p" binding for projects, can't be done with :bind
dashboard-item-shortcuts '((recents . "r")
(bookmarks . "m")
(projects . "o")
(agenda . "a")
(registers . "e"))
dashboard-set-heading-icons t
dashboard-set-file-icons t))
beacon | https://github.com/Malabarba/beacon |
Highlight the line the cursor is on when scrolling.
(use-package beacon
:defer 1
:config (beacon-mode 1))
(display-battery-mode)
ivy | https://github.com/abo-abo/swiper |
counsel | https://github.com/abo-abo/swiper |
swiper | https://github.com/abo-abo/swiper |
Let’s start with the backbone of it all. Ivy
provides a
completion engine that counsel
and swiper
build off of.
(use-package ivy
:diminish
:hook (after-init . ivy-mode)
:config
(setq ivy-use-virtual-buffers t ; Recent files and bookmarks in ivy-switch-buffer
ivy-count-format "%d/%d "
ivy-wrap t)) ; Wrap around with next-line and previous-line
counsel
provides many custom functions designed to take advantage of
ivy
, such as counsel-find-file
.
FIXME: I’d prefer to find a way to load counsel
without needing to
use :demand t
. I tried ivy-mode-hook
but that caused issues with prescient
.
(use-package counsel
:diminish
:demand t
:after ivy
:commands counsel-org-goto counsel-org-tag
;; :bind ("C-x b" . counsel-switch-buffer) ; Disabled due to slowdowns
:bind (("M-y" . counsel-yank-pop)
:map ivy-minibuffer-map
("M-y" . ivy-next-line))
:config (counsel-mode))
swiper
is an isearch
alternative, which is good because I don’t
like isearch
.
(use-package swiper
:after ivy
:bind (("C-s" . swiper)
("C-r" . swiper)))
ivy-rich | https://github.com/Yevgnen/ivy-rich |
all-the-icons-ivy-rich | https://github.com/seagle0128/all-the-icons-ivy-rich |
ivy-rich
makes things look purdy.
(use-package ivy-rich
:after (ivy counsel)
:config
(ivy-rich-mode 1)
(setcdr (assq t ivy-format-functions-alist) #'ivy-format-function-line) ; Recommended in Github repo
(setq ivy-rich-parse-remote-buffer nil ; https://github.com/Yevgnen/ivy-rich/issues/47
ivy-rich-parse-remote-file-path nil
ivy-rich-path-style (quote full)))
all-the-icons-ivy-rich
makes the purdy thing look purdy.
(use-package all-the-icons-ivy-rich
:after all-the-icons ivy-rich
:config (all-the-icons-ivy-rich-mode 1)
(set-face-attribute 'all-the-icons-ivy-rich-doc-face nil
:foreground (face-attribute
'font-lock-comment-face :foreground)))
all-the-icons-ivy-rich-doc-face
controls them (possibly indirectly
with inheritance).
I took the same approach as with linum
.
counsel-tramp | https://github.com/masasam/emacs-counsel-tramp |
Provides a interface for using counsel
completion with SSH. Entries
are populated from /.ssh/config
. Connections can also be added using
counsel-tramp-custom-connections
.
Support for docker
and vagrant
is also provided if you are using
docker-tramp
or vagrant-tramp
.
(use-package counsel-tramp
:bind ("C-c t" . counsel-tramp))
prescient | https://github.com/raxod502/prescient.el |
ivy-prescient | https://github.com/raxod502/prescient.el |
company-prescient | https://github.com/raxod502/prescient.el |
prescient
provide a new completion library for ivy
, counsel
, and
and/or selectrum
.
(use-package prescient
:after ivy
:config (prescient-persist-mode) ; Save history
)
ivy-prescient
provides integration between ivy
and prescient
. As
counsel
modifies user options of ivy
, we must load it first.
(use-package ivy-prescient
:after counsel
:config (ivy-prescient-mode)
(setq ivy-prescient-retain-classic-highlighting t)) ; Hard to see matching regions otherwise
company-prescient
provides integration between company
and
prescient
.
(use-package company-prescient
:after company
:config (company-prescient-mode))
projectile | https://github.com/bbatsov/projectile |
counsel-projectile | https://github.com/ericdanan/counsel-projectile |
(use-package projectile
:diminish
:config (projectile-mode +1)
(setq projectile-completion-system 'ivy ; Dashboard support
projectile-git-submodule-command nil ; prevent slowdowns with large submodules
; minimize lag when working with svn on remote server
; https://github.com/bbatsov/projectile/issues/657
projectile-file-exists-local-cache-expire 300)
:bind-keymap ("C-c p" . projectile-command-map))
counsel-projectile
provides integration between projectile
and
counsel
.
(use-package counsel-projectile
:after (counsel projectile)
:config (counsel-projectile-mode))
ace-window | https://github.com/abo-abo/ace-window |
Running other-window
a billion times isn’t exactly enjoyable. What
is enjoyable is executing ace-window
once and typing 1-2 keys to
select a window.
Instead of 0-9, ace-window
will use the home row keys to select a
window.
(use-package ace-window
:defines aw-keys
:commands ace-window
:bind* ("M-o" . 'ace-window) ; * as ibuffer overrides M-o. Consider adjusting as M-o is used for ivy-dispatching-done
:config (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)))
avy | https://github.com/abo-abo/avy |
Easier navigation within a buffer. Run avy-goto-char-2
, type two
characters, then use the home row to select where to move the cursor.
(use-package avy
:bind ("C-;" . avy-goto-char-2))
(use-package dumb-jump
;; Unless hook* is added I need to use this workaround.
;; https://github.com/jwiegley/use-package/pull/916
:init (add-hook 'xref-backend-functions 'dumb-jump-xref-activate)
:commands dumb-jump-xref-activate
;; Requires xref >= 1.1.0 or Emacs >= 28.1
:config (setq xref-show-definitions-function
'xref-show-definitions-completing-read))
This section is for non-language-specific customizations that still help with editing.
highlight-parentheses | https://github.com/tsdh/highlight-parentheses.el |
smartparens | https://github.com/Fuco1/smartparens |
Apparently rainbow-delimiters
provides similar functionality to
highlight-parentheses
, I’ll look into it later.
(use-package highlight-parentheses
:diminish
:hook ((prog-mode org-mode) . highlight-parentheses-mode))
(use-package smartparens
:diminish
:hook (prog-mode . smartparens-mode)
:config (require 'smartparens-config))
wrep | https://github.com/mhayashi1120/Emacs-wgrep |
(use-package wgrep
:defer 1)
company | https://github.com/company-mode/company-mode |
A text-completion framework. Would like to replace RET with C-j like
ivy
.
(use-package company
:defines company-minimum-prefix-length company-frontends company-idle-delay
:diminish
:hook (prog-mode . company-mode)
:config
(setq company-minimum-prefix-length 1)
(setq company-frontends '(company-pseudo-tooltip-frontend
company-echo-metadata-frontend))
(setq company-idle-delay 1))
flycheck | https://github.com/flycheck/flycheck |
Syntax checking for Emacs.
(use-package flycheck
:diminish
:defer 1
:config (setq flycheck-emacs-lisp-load-path 'inherit) ; Fixes "org-mode-map" in comment-dwin-2 from being undefined
(define-key flycheck-mode-map flycheck-keymap-prefix nil)
(setq flycheck-keymap-prefix (kbd "C-c f"))
(define-key flycheck-mode-map flycheck-keymap-prefix
flycheck-command-map)
(global-flycheck-mode)) ; Does not fix issues with functions may not be defined
comment-dwim-2 | https://github.com/remyferre/comment-dwim-2 |
I don’t enjoy how comment-dwim
and comment-line
are two different
keys for very similar functionality. comment-dwim-2
provides that
and a bit more. Sometimes indentation seems weird in elisp with
comments not lining up.
This is currently bugged with enh-ruby-mode
. End of line comments
are not inserted, although it can successfully comment and uncomment
an entire line.
(use-package comment-dwim-2
:config
(defadvice comment-indent (around comment-indent-with-spaces activate) ; Not the cause of enh-ruby-mode issue
(let ((orig-indent-tabs-mode indent-tabs-mode))
(when orig-indent-tabs-mode
(setq indent-tabs-mode nil))
ad-do-it
(when orig-indent-tabs-mode
(setq indent-tabs-mode t))))
;; Disabled for now. I want to remove line comment, keeping the
;; end of line comment unless I press M-; again.
;; Note though, text is killed, not deleted. You can always just
;; use C-e C-y to yank the text back at end of line
;; (defun cd2/inline-comment-command () ; this is the function called when you repeat the command
;; ;; do nothing (not killing the end-of-line comment)
;; (setq this-command nil) ; This is just a trick so that the command can still be called indefinitely
;; )
(define-key org-mode-map (kbd "M-;") 'org-comment-dwim-2)
:bind ("M-;" . comment-dwim-2))
zzz to char | https://github.com/mrkkrp/zzz-to-char |
Replace zap-to-char
and zap-up-to-char
with zzz
equivalents. I
can select a specific character, either forward or back, with the
home row. As opposed to the closest character.
(use-package zzz-to-char
:bind ("M-z" . zzz-to-char))
rbenv | https://github.com/senny/rbenv.el |
inf-ruby | https://github.com/nonsequitur/inf-ruby/ |
robe | https://github.com/dgutov/robe |
rbenv
for Emacs is 7 years old and unmainted. I’d like to replace it
sooner rather than later.
(use-package rbenv
:diminish
:hook (ruby-mode . global-rbenv-mode))
inf-ruby
is something I don’t know how to use well yet. If you use
irb
in shell
, you will want the line IRB.conf[:USE_MULTILINE] =
false
in ~/.config/irb/irbrc
, as otherwise you will just get
downward pointing arrows and no input or output.
Tested ≈ 4/2020, didn’t observe 11/2020 but may still be present.
Here is a trick for guarding the IRB.conf clause so it won’t impact IRB sessions outside of Emacs. (Not tested thoroughly!)
(use-package inf-ruby ; Latest version has --nomultline by default, but not for bundle console, only ruby
:hook (ruby-mode . inf-ruby-minor-mode))
I really want to replace robe
with lsp-mode
and
solargraph
. Having to run a full-blown interpreter seems overkill
and prone to errors.
(use-package robe
:defines company-backends
:diminish
:hook (enh-ruby-mode . robe-mode)
:config (push 'company-robe company-backends))
yaml-mode | https://github.com/yaml/yaml-mode |
Pretty much only one package for YAML.
(use-package yaml-mode
:mode "\\.yml\\'")
AsmMode is a simple assembly programming mode that comes with Emacs. It is based on TextMode. See AssemblyProgramming for alternatives.
AsmMode has some strange (relative to other Emacs modes) defaults for indentation (as of Emacs 24.5): It sets ‘tab-always-indent’ to ‘nil’ so that hitting ‘TAB’ will each time insert a tab stop, pushing the code farther to the right. Therefore I suggest using the following config which resets ‘tab-always-indent’ back to the default:
asm-comment-char
seems to have been deprecated, so I removed it.
https://www.emacswiki.org/emacs/AsmMode
(defun my-asm-mode-hook ()
;; asm-mode sets it locally to nil, to "stay closer to the old TAB behaviour".
(setq tab-always-indent (default-value 'tab-always-indent)))
(add-hook 'asm-mode-hook #'my-asm-mode-hook)
For latex previews, you also need dvipng
. When I migrate to Guix, I
should programmatically install it / add it to the manifest file.
Also in case I ever have this problem in the future, for LaTeX previews to work, you need to enable png support for Emacs.
org | https://orgmode.org/ |
I use a more up-to-date version of Org than what Emacs ships with.
Currently org-adapt-identation
does not work with 'headline-data
.
(At least, I haven’t gotten it work successfully.) Tested 11/2020.
Additionally, I want org to support as many languages as possible
without needing to add them all to org-babel-load-languages
.
I added a function from StackExchange to update \( \LaTeX \) symbols as I zoom in. For time sake, the code that toggles the preview was removed, as Emacs takes quite a while to regenerate the images. When rapidly zooming (e.g. C-mouse-4), Emacs could even halt entirely. I do let it remove existing previews so I don’t have a mix of small and big previews.
I’m currently trying to write advice for org-export-dispatch
to add
the org-latex-logfile-extensions when initially exporting the file.
(use-package org
:mode (("\\.org$" . org-mode))
:hook (org-mode . turn-on-auto-fill) ; Don't make me spam M-q
:bind (("C-c a" . org-agenda)
:map org-mode-map
;; TODO: try to move counsel bindings to use-package counsel
("C-c C-j" . counsel-org-goto)
("C-c C-q" . counsel-org-tag))
:config
(setq org-startup-folded t
org-highlight-latex-and-related '(native)
org-cycle-separator-lines 1
org-log-done 'time
org-adapt-indentation nil
org-fontify-whole-block-delimiter-line nil
org-latex-prefer-user-labels t
org-confirm-babel-evaluate nil
org-agenda-files '("~/org")
org-preview-latex-image-directory (concat (xdg-cache-home) "/emacs/ltximg")
org-format-latex-options (plist-put org-format-latex-options :scale 1.5)
org-blank-before-new-entry '((heading . t) (plain-list-item . t))
org-latex-logfiles-extensions (quote ("lof" "lot" "tex~" "aux" "idx" "log"
"out" "toc" "nav" "snm" "vrb" "dvi"
"fdb_latexmk" "blg" "brf" "fls" "entoc"
"ps" "spl" "bbl"))
org-todo-keywords '((sequence "TODO" "WAITING" "|" "DONE" "CANCELLED"))
org-todo-keyword-faces '(("WAITING" . "magenta")
("CANCELLED" . "orange")
("DONE" . "darkgrey")))
(add-to-list 'org-file-apps '("\\.pdf\\'" . emacs))
(font-lock-add-keywords 'org-mode
'(("^ *\\([-]\\) "
(0 (prog1 ()
(compose-region
(match-beginning 1)
(match-end 1) "•"))))))
(org-babel-do-load-languages
'org-babel-load-languages '((C . t)
(emacs-lisp . t)
(ruby . t)
(gnuplot . t)
(mermaid . t)
(shell . t)))
;; Monospace headings so tags are aligned
(dolist (face '(org-level-1
org-level-2
org-level-3
org-level-4
org-level-5
org-level-6
org-level-7
org-level-8))
(set-face-attribute face nil :family "monospace"))
(defun update-org-latex-fragment-scale ()
(org-latex-preview '(64))
(let ((text-scale-factor (expt text-scale-mode-step text-scale-mode-amount)))
(plist-put org-format-latex-options :scale (* 2.3 text-scale-factor))))
(add-hook 'text-scale-mode-hook 'update-org-latex-fragment-scale))
org-superstar | https://github.com/integral-dw/org-superstar-mode |
I enjoy colored bullets. I might remove
org-superstar-leading-bullets
since it doesn’t bother me too much
and doesn’t seem to work anyway.
(use-package org-superstar
:hook (org-mode . org-superstar-mode)
:config
(org-superstar-configure-like-org-bullets) ; FIXME stars are still visible despite below line
(setq org-superstar-leading-bullet ?\s))
ob-mermaid | https://github.com/arnm/ob-mermaid |
A picture is worth a thousand words, even in Org. I should try to make
it more compatible with other installation paths, including the
default (not hidden). I also include mermaid-mode
, making editing a
lot more tolerable.
(use-package ob-mermaid
:after org
:config
(setq ob-mermaid-cli-path "~/.node_modules/.bin/mmdc"))
;; TODO: defer loading
(use-package mermaid-mode
:config
(setq mermaid-mmdc-location "~/.node_modules/.bin/mmdc"))
gnuplot | https://github.com/emacsorphanage/gnuplot |
While not quite a picture, graphs are also nice to have. This allows
for gnuplot src blocks in org mode. The gnuplot
emacs package might also be
required, although I think it comes built in with recent versions of
org
.
(use-package gnuplot)
Confusingly, Org Crypt
must be loaded before org
.
org-crypt-use-before-save-magic
creates an org-mode hook that
creates a before-save hook to encrypt the file. When loading is
deferred, the org hooks will execute before this hook is added,
meaning headings will not encrypt on save.
I wasn’t able to solve this issue, so I just removed the autoload that
:bind
adds with :demand
.
(use-package org-crypt
:straight nil
:bind ("C-c d" . org-decrypt-entries)
:commands org-decrypt-entries org-encrypt-entries
:config
(org-crypt-use-before-save-magic)
(setq org-crypt-key "1982679C" ; Change to your key
epg-pinentry-mode 'loopback
org-crypt-disable-auto-save t
org-tags-exclude-from-inheritance '("crypt")))
mixed-pitch | https://gitlab.com/jabranham/mixed-pitch |
Mixed pitch is a minor mode that enables mixing fixed-pitch (also known as fixed-width or monospace) and variable-pitch (AKA “proportional”) fonts. It tries to be smart about which fonts get which face. Fonts that look like code, org-tables, and such remain fixed-pitch and everything else becomes variable-pitch. The variable
mixed-pitch-fixed-pitch-faces
is a list of faces that will remain fixed-pitch inmixed-pitch-mode
.
(use-package mixed-pitch
:hook (org-mode . mixed-pitch-mode))
ox-hugo | https://ox-hugo.scripter.co/ |
ox-hugo is an Org exporter backend that exports Org to Hugo-compatible Markdown (Blackfriday) and also generates the front-matter (in TOML or YAML format).
In other words, this is great for blogging. It supports multiple posts
per org
file, separated by top level headings. I suspect this’ll be
my preferred way to edit.
(use-package ox-hugo
:after ox)
This is meant for utility packages that don’t assist with editing, navigation, or similar, but still provide a benefit.
0xc | https://github.com/AdamNiederer/0xc |
A package that provides easy base conversions inside of Emacs.
(use-package 0xc
:commands (0xc-convert 0xc-convert-point 0xc-live-convert))
Esup | https://github.com/jschaf/esup |
Profile Emacs startup times with M-x esup
. There’s an apparent issue
with some combination of straight
, esup
and byte-compiling that
causes Esup
to fail to run, either showing Symbolic link to Git...
or another error message. This contains a fix.
It seems the fix isn’t perfect, Esup is largely underestimating my startup time. When I look in the breakdown, large sections of the code are unaccounted for.
(use-package esup
:commands esup
:config (setq esup-depth 0))
PDF Tools | https://github.com/politza/pdf-tools |
PDF Tools is, among other things, a replacement of DocView for PDF files. The key difference is that pages are not pre-rendered by e.g. ghostscript and stored in the file-system, but rather created on-demand and stored in memory.
[…]
Actually, displaying PDF files is just one part of PDF Tools. Since poppler can provide us with all kinds of information about a document and is also able to modify it, there is a lot more we can do with it.
This package requires a Unix-based OS.
(unless sys/win32p
(use-package pdf-tools
:mode ("\\.pdf\\'" . pdf-tools-install)
;; One of the two of these settings help improve display on my
;; thinkpad x13 hidpi, not sure which lol
;; https://github.com/politza/pdf-tools/issues/51
:config (setq pdf-view-use-scaling t
pdf-view-use-imagemagick t)))
restart-emacs | https://github.com/iqbalansari/restart-emacs |
A small package to restart Emacs within Emacs.
(use-package restart-emacs
:commands restart-emacs
:config (setq restart-emacs-restore-frames t))
unbound | https://www.emacswiki.org/emacs/unbound.el |
Find unbound keys with describe-unbound-keys
and enter a number
representing complexity.
FIXME: Fixed most errors except an Unused lexical variable 'i'
in
defun key-complexity
. The variable is definitely used; I’m not sure
what the issue is.
;;; unbound.el --- Find convenient unbound keystrokes
;; Copyright (C) 2007 Davis Herring
;; Author: Davis Herring <[email protected]>
;; Version: 0.1
;; Maintainer: Davis Herring
;; Keywords: keyboard
;; This file is not part of GNU Emacs.
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor
;; Boston, MA 02110-1301, USA.
;;; Commentary:
;; The only entry point is `describe-unbound-keys'; it prompts for the maximum
;; complexity to allow, which should probably be at least 5 to find enough
;; keys to be worthwhile. Lisp may call just `unbound-keys' to get a list of
;; key representations suitable for `define-key'.
;;; Code:
(eval-when-compile (require 'cl)) ; for `dotimes', `push' (Emacs 21)
(defgroup unbound nil ; Silence group not specified warnings from compiler
"Show unbound keys based on complexity."
:group 'convenience)
(defcustom unbound-modifiers '(control meta shift)
"Modifiers to consider when searching for unbound keys."
:type '(set (const control) (const meta) (const shift)
(const super) (const hyper) (const alt)))
(defvar unbound-key-list
(let (keys)
(dotimes (i (- ?\d ?\ -1))
(push (+ i ?\ ) keys))
(dotimes (i 12)
(push (intern (format "f%s" (1+ i))) keys))
(append '(?\t ?\r ?\e) (nreverse keys)
'(insert delete home end prior next up down left right)))
"Keys to consider when searching for unbound keys.")
(defun key-complexity (key)
"Return a complexity score for key sequence KEY.
Currently KEY must be of the [(control shift ?s) ...] format."
(let ((ret 0))
(dotimes (i (length key) ret)
(setq ret (+ ret (* i 2) (key-complexity-1 (aref key i)))))))
;; This is somewhat biased for US keyboards.
(defun key-complexity-1 (key) ; key:=(modifiers... key)
(+ (if (memq 'control key) 1 0)
(if (memq 'meta key) 2 0)
(if (memq 'shift key) 3 0)
(if (memq 'super key) 4 0)
(if (memq 'hyper key) 4 0)
(if (memq 'alt key) 3 0)
(* 2 (1- (length key)))
(progn
(setq key (car (last key)))
(if (integerp key)
(cond ((and (>= key ?a) (<= key ?z)) 0)
((and (>= key ?A) (<= key ?Z)) 6) ; capitals are weird
((and (>= key ?0) (<= key ?9)) 2)
((memq key '(?\b ?\r ?\ )) 1)
;; Unshifted punctuation (US keyboards)
((memq key '(?` ?- ?= ?\t ?\[ ?\] ?\\ ?\; ?' ?, ?. ?/)) 3)
;; Other letters -- presume that one's keyboard has them if
;; we're going to consider binding them.
((let (case-fold-search)
(string-match
"[016A]" (category-set-mnemonics
(char-category-set key)))) 2)
(t 5))
7))))
;; Quiet the byte compiler
(defvar unbound-keys nil
"Used internally by `unbound-keys'.")
(defun unbound-keys (max &optional map)
"Return a list of unbound keystrokes of complexity no greater than MAX.
Keys are sorted by their complexity; `key-complexity' determines it."
(let (unbound-keys)
(unbound-keys-1 max map nil)
(mapcar 'car (sort unbound-keys (lambda (k l) (< (cdr k) (cdr l)))))))
;; Adds to `unbound-keys'.
(defun unbound-keys-1 (max map pfx)
(dolist (base unbound-key-list)
(dotimes (modi (lsh 1 (length unbound-modifiers)))
(let ((key (list base)))
(dotimes (j (length unbound-modifiers))
(unless (zerop (logand modi (lsh 1 j)))
(push (nth j unbound-modifiers) key)))
(let ((total (vconcat pfx (list key))) comp)
;; Don't use things that get translated and bound. This isn't
;; perfect: it assumes that the entire key sequence is translated.
(unless (or (let ((trans (lookup-key function-key-map total)))
(and (vectorp trans) (key-binding trans)))
;; Don't add `shift' to any graphic character; can't
;; type it, or it's redundant.
(and (memq 'shift key) (integerp base)
(> base ?\ ) (<= base ?~))
;; Don't add `control' when it generates another
;; character we use:
(and (memq 'control key) (integerp base)
(< base ?`)
(memq (- base 64) unbound-key-list))
;; Limit the total complexity:
(> (setq comp (key-complexity total)) max))
(let ((res (if map (lookup-key map (vector key))
(key-binding (vector (if (cdr key) key (car key)))))))
(cond ((keymapp res)
;; Don't add anything after an ESC, to avoid Meta
;; confusion.
(unless (eq base ?\e)
(unbound-keys-1 max res total)))
(res)
(t (push (cons total comp) unbound-keys))))))))))
;;;###autoload
(defun describe-unbound-keys (max &optional map)
"Display a list of unbound keystrokes of complexity no greater than MAX.
Keys are sorted by their complexity; `key-complexity' determines it."
(interactive
(list (read-number "Maximum key complexity: ")
(intern (read-string "Keymap (default global-map): " nil nil "global-map"))))
(unless (keymapp (eval map)) (error "%s is not a keymap" map))
(with-output-to-temp-buffer "*Unbound Keys*"
(let ((keys (unbound-keys max (eval map))))
(princ (format "%s unbound keys in %s with complexity at most %s:\n"
(length keys) map max))
(princ (mapconcat 'key-description keys "\n")))))
(provide 'unbound)
;; Local variables:
;; indent-tabs-mode: nil
;; End:
;;; unbound.el ends here
vterm | https://github.com/akermu/emacs-libvterm |
A capable terminal emulator. This is compatible with irb
multiline.
Projectile also supports creating a named vterm with
projectile-run-vterm
.
(use-package vterm
:commands vterm
:config (setq vterm-timer-delay 0.01
vterm-shell (or (executable-find "fish")
"/bin/bash")))
vterm-toggle | https://github.com/jixiuf/vterm-toggle |
This package provides the command vterm-toggle which toggles between the vterm buffer and whatever buffer you are editing.
(use-package vterm-toggle
:commands vterm-toggle vterm-toggle-cd
:bind ("C-c v" . vterm-toggle))
(use-package eshell
:bind ("C-c E" . eshell)
:straight nil ; built in
:custom
(eshell-scroll-to-bottom-on-input t))
(use-package eshell-syntax-highlighting
:hook (eshell-mode . eshell-syntax-highlighting-global-mode))
magit | https:magit.vc |
I’m certainly not at a point where I fully grasp the intricacies of
magit
(git
alone is enough of a pain!), but I can’t possibly get
better without practice!
(use-package magit
:after transient)
ix | https:github.com/theanalyst/ix.el |
A simple interface to ix.io
, a pastebin. I’m not using a username or
password because I shouldn’t upload anything private to ix.io
anyway.
(use-package ix)
This is a built-in Emacs package. I don’t like the default zoom in
behavior, where you explicitly need to press +
(i.e. Shift-=
)
instead of just =
.
Because it’s built in, there’s no need to download it.
(use-package image-mode
:straight nil
:bind (:map image-mode-map
("=" . image-increase-size)))
A neat little screensaver for buffers.
(use-package zone
:commands (zone-when-idle zone-choose)
:defer 5
:config
(zone-when-idle 600)
(defun zone-choose (pgm)
"Choose a PGM to run for `zone'."
(interactive
(list
(completing-read
"Program: "
(mapcar 'symbol-name zone-programs))))
(let ((zone-programs (list (intern pgm))))
(zone))))
fireplace | https://github.com/johanvts/emacs-fireplace |
Another screensaver package.
(use-package fireplace
:commands fireplace)
snow | https://github.com/alphapapa/snow.el |
(use-package snow
:commands snow)
(use-package elfeed
:bind ("C-c n" . elfeed)
(:map elfeed-search-mode-map
("U" . elfeed-update))
:config (setq elfeed-search-title-max-width 90))
(use-package elfeed-org
:after elfeed
:config
(setq rmh-elfeed-org-files
(list
(concat user-emacs-directory"var/elfeed/rmh-elfeed.org")))
(elfeed-org))
-----BEGIN PGP MESSAGE-----
hQIMA341lovNpziwARAAk9oTy1AnYe4ErAQMkaYeJGPmn8Hbm0R4OIopi1k673t3 Ky0CtViv3FuD3n7BlgxnS11jVBu7w8AUPQelJVhkTDpOtGxoy0wcTeHoXYjSrwG6 vzZvHYjosxqPGKgDRMYFIzROYc9oLgzkBfRfvXj/7kGIWldTOy9XaaeuUr8/TQlq ptmxxTGy1cyzP59SCOgL6LlhpTdUDcpzvXWMNNYnMvrY3Ai8fvBnA2vU/uR/2FZj ZcFC2aaKYHT8ojtoGy8g0TLTFXLKlqMlDoD274KOM/4gEwiW7DPHkJ3Feg7NMf26 nS1qJkcDebQqgJnfbNhGBg2pDEpUXPwt4cg9O7onVyLZGSU0mzbrDEmybsCR5bAw dGVSIyneR3RksovQR3DhsCRkU3XzSn1YX3/vKrfd+3jtlw+72ZwMgJsx7wunUHNo t5GuZ0MZuyJo4n7uG+rnr6WV4EwnzHHbliquyaTJPVCjHNqYb6cMQDcs79zGc1st FRCiqgYLrOMOgI2FzAkCoa9XnnOFXzNIAZ6Qzwfh4fOMwkOy0t1exrb+d3nCTzF+ lmHKgFjj10VSDIWxq++jewKfCLmApQEcYtxBdqKZ0qApqs5y4WlSHvBKs6W524wy pRQtfFpJGGIiJxywY5phZDhuFYE5ak7ELuivh4f4VaFc5SbS7H8edbdgI/TsuXTS 6QGbTuKSXWKSxD2gMiynxOixnxGv+Rmk1BTXP7BDWAM6eYRzKX11jEQJGmbX3UCc uSLWpTlYA+4vsIQO+ePE+bvbNt4/q0H89uB75UijftlKnxdNR2RZuLVDQKoDVrza BEBGz5mcpYRoPNpGtjKVzXBnFKsOUXQRwnwLZUhm/VZ2ypv9KKj4O/TEKDhvXcLB B3rN25HDl6KyQwf00x6y8J9pLFkqJ5guFcm0U3kuxuc5m3/Qmw5KO5Q4zzABBmWW fCUmnnug085D4Doa8E67bmUJOUCWieQ6iuXGfiUMU9S5KnfMjV7jjbjY0PJT0fNe 9BZ5D9NDTHtpVYAOdxHORXAxpdAQJbrWCPehlgrehRkb7bA6MK1EnbfmJVqj50OP L6aqrgRxpVSkti7PXs8rzdnO13+VzdboNgzZwGyECZ1M9I/D65hzwHRRVdMREbQV Tqb2hjpHZAPjDOmEFo5En93wp2Kby8wF5av5c0cEb8+cHPU1sgO543a53saULFR9 7BbZG1Q94O76/G7F3qPlD34kuY4ww7S+h8aqCBTecpXnPXOb/3yApbF91AORnUHQ zfApG8Eq0+T1akzYv82yHHBOnWcXqdP9x04ShHyM+p6vMSSIkKuLCXuT138TYhSS 48jGY5L0nXh577tJcd3TQsjf0DcO7cLWydlApK1YtlRQwEZ9OXNR4AHODJphYU6H SUzcs2AvkMQCYRYyna10UtypcvPAGfntchKbCxmT/ZERQ5ZAoqRXgele3Z9uC+oT SA7athq2IWxP6rZDSHDd6bYArhCI+8wqybozVi/QGWAFKt4A5oFo8EB6PdR84BQg +7HtaG9IadjYrRnwwgcSzsoGPVG73bVjAHjtuJqQcb1hICDuo8Uh6P712d2NTgmC z2Qr58Uhl0p98tN1uvGaZneu3ZHxFpfX1NQ30xiaLDRotuSFywM3CglodGAHiYBb 72g2Vm37QNTGvcdbg+EyYiS2tcHbjKiv4f/zem4i9lQQVoJcqdeY0nkuFOJ55zsW QyvUPxAzF8pV =3C1c -----END PGP MESSAGE-----
I want my/erc-start-or-switch
to select a visible erc
window, if
present, then run erc-track-switch-buffer
.
(defun my/erc-first-visible-window ()
"Returns first visible erc window, or nil if none visible"
(let ((retbuffer nil))
(dolist (buffer (erc-buffer-list) retbuffer)
(when (erc-buffer-visible buffer)
(setq retbuffer buffer)))
(if retbuffer
(get-buffer-window retbuffer 'visible)
nil)))
A wrapper function I modified from Reddit.
(defun my/erc-start-or-switch ()
"Connects to ERC, or switch to last active buffer."
(interactive)
(let ((erc-window (my/erc-first-visible-window)))
(if erc-window (select-window erc-window) nil))
(if (erc-buffer-list)
(erc-track-switch-buffer 1)
(when (y-or-n-p "Start ERC? ")
;; Relies on erc-nick and erc-password being set
(erc :server "irc.libera.chat" :port 6667))))
Basic erc
configurations.
(use-package erc
:straight nil
:commands erc-buffer-list erc-track-switch-buffer erc-buffer-visible
:bind ("C-c e" . my/erc-start-or-switch)
:config
(setq erc-autojoin-channels-alist
'(("libera.chat" "#emacs" "#emacs-beginners"
"#erc" "#gentoo" "#gentoo-embedded"
"#kde" "#libera" "#linux" "#org-mode"
"#pine64" "#sway" "#sway-devel" ))
erc-autojoin-delay 5
erc-autojoin-timing 'ident
erc-fill-function 'erc-fill-static
erc-fill-static-center 16
erc-join-buffer 'bury
erc-hide-list '("JOIN" "PART" "QUIT" "NICK")
;; See https://datatracker.ietf.org/doc/html/rfc1459
;; for explanation of number codes
erc-track-exclude-types '("JOIN" "NICK" "PART" "QUIT" "MODE"
"324" "329" "332" "333" "353" "477"))
(let ((libera-credentials (netrc-credentials "irc.libera.chat")))
(setq erc-nick (nth 0 libera-credentials)
erc-password (nth 1 libera-credentials))))
-----BEGIN PGP MESSAGE-----
hQIMA341lovNpziwARAAnU1E9R8ZD/zt9mmrQiCK41pFJ+5cqsfIgQYEibqUKZJ2 i3q0QEeGhC2OuZ3NccOY/FgMQskZGvZFbwQZNH9piDN473AzhTyFZ15XVHphvVAN Pw5beIOQj48yfu8JMdpOQWLFubriGEXNgRJ5HCxy/o/OJY1UqFd5kas41kNabxns h8JrLhQ/8yk6Cq4qd9M9PvIzvJ9b9LFVrLn4DKlqDF6ixCFTMY0CpdY/X0niY1/D 0Zjwo4wNkYgX4cxl+Cn7QzU5vP+y1G93qy2f9Iaviqd9BNGntGjR/9rpjhckKMX2 vjkDQF/pmgLot0vu9Hpyjp8ihD4vPMuOMv/XZtEal9oDa7ZgkjtDgdUIza3cPXVg pRlDrnfuFjB/tjgA6GfV0YXtFLMvHo0fl18gHiVUDFeauObN+Pz/Bwg5BTHkoCnb rwiaNS5QQ4mh4TTLVqGVuB/AAPIKUnT26ByEHSYR4h6bZeBTC09QUHi0QxeKnPMR nYUa7mCJFuX71v7D3X1ovZP0ZBToISOiyuFB4DWg5Fvy/73mwAQA6dr63R8LLx/U F5uYgUQL+oVKCSQApj58bgORYZ+ojnDS1tHqwF4yiP2PGZLiGfjoSoHK8nC+IYLs 8CGSHMDb3mwyzJyG4O7H/DdSKlzSJvyDr8w/FIImL5pTQ/kUNuW/khjUiYSFp0vS rwGrb04MJ5yo0cz8mVAVVrvvTwiNTgI3bg9vLTjJHkONRV5RnzQWdP54Ir6mXjJl uD3O4UUtW8O78iE6ia07Sfex/gNLb1f1cPtnOHL1YdE8B7kSsNwsw91ZWgLEtIiZ bkaj7p1dsr7auQBDu0BSQtOXVj6B2GqYNoFMtM/7Qb1JQmRti1fdYsP+OM4mgfrF 6PZPNji0poGxWFQZwMfTeKJnJ/nli7NhKWf8NvbBObI= =99d/ -----END PGP MESSAGE-----
-----BEGIN PGP MESSAGE-----
hQIMA341lovNpziwAQ/9GrmpuhRQEp5nphBTGchPZ7CxCK4BKdSJNV4nNGtwUb/k WDNdktslOz/tyW16hX4YODXugKeLScOD01rzTzNwxyZTIlbbAgqmTtLCBKfgF4+p KZDcCm5GfT7Quf2eT7rBy1b7ae4ErtveePVkyDkTzGA+0g3MnLAQzDmLH4irESsK 4E/tDG0iY4v22j+0erRGE/Crv1PZmpjpBAv2FZeazUxy193Ek2lWi/bP0UbjtbUm Ya/r+UOFuehvvzxOSfBwDbgkg+aMxD0G6DblkaV4f7gTDmzURISyD9Sal720x4ve Kr+sF3yeliTKsHlgMV6d4gTDaWha1jhYlaKcx56PIEQLdLEbZFUvnQMv5JLYWtUp DWilQoTCDK1tjaUxzBDCtdMcF1IhxkpdazLXd8Z0e/pBzfPjMTYz7W/EUBlkcKK7 aHvEom3SvaSmk2Tl4a+KkRbJkPn7nQGwMWXYCKmZcih/M4KCRoGqh2dGBQuWDNQY xDD5qzIpjUtYqCsmAA7EGbL1g0FOfgIdRai0GOwL2QZVXTkrxVBVwKlwYbgIMA7d btYTRTCNQTE8tU1wfaYQSv5EWkH38Eb1U5a1ct6lRZkpRK9a/y/AlKHvJN/grxWW wCHYbRH7CIiTLzr9/ANcRN+FYMQYyzK1rNIe+/S6IkazyHOKLjzmUK++LYoU9JLS 6wEGlMqqD019YdVVAbrzAxkg8RIvhaJLkVj6uNKWku+fhuQMAhf1FPHVK7PfJori wN4N3rSq9E8uQImLJZowMHlnJx1bd65cPxEKGy95AItfkB+7bq8k+jUQRb0WBCKM 6dHo7AzTFkRrLJ/i/LVN5O3Do0q5yKhJUg8yC+jyDYibBIrvgJ79cE/WJ0/hVYtZ 2REuGeuqvwNwGeFrviXknRW13uMx02lMXLLiLd6hucDTiQ7O/JiyvfdYkuR5HpBU bq8sx8tu5Rg/DL9f6Y9prJGxHTdfWPMOzFziy6gQJDdA6Z5Lpj/m6ZtQvF9HL560 lOx2XtJTwOAoctdJ1yjlNmDs3xnnRV5OpiJaQo+QTcoHe5h40raDwKDz/fRz9lnf i39cgPy3fqjKCT+9eZYceMhH7yaBk6nyjrYXw5ac990tZCcYcBn2tR2gVZD9cUaN J72TKGAE4Hf7jxsZyDIzYV03qOFKPGVEzxTVWp/Z31Bjt28hlGll/7oFj0kqwyI7 YNh5dB/6zzoblLFxRQfeVAaMv1icOQ6xdVUDRGS+SOS0ehKa4686Bxk7ufwG/8Gt 8RFc7ZI88LM00z3QvLTjHPSMMNmkkgsEVcBsaU3/y2j3NMS7IcKJhcqieFkdM6Fc WZL6kcRE0gXRyEN5OG/Kh11csmaZh1i16YWyjCKaHZGJFT0l85SVg+++mMLy0NcW b4uFKJpSSrPDzTW/vWV/f5K4YQ5zYgg71pqBhFdbcWFxvsWZ33fodmOov4vpJj0Y o1eBJ0tK9pb6/vz9QXcenGL1rnrNlZjvwtrMsrVdDqq8RIwr51V1+RbvhdU4UmCQ uNOdBm5Wyqoi6KJ2V4ZAHeWInECg/P9fNMX8xu3wxjbtZRAS4CtOuC7C52XdHMWO aNGqHlb/dkiI8p7IBRL6tW/9Of7S7vzbYrGiSBaM3Aqb/lj0Ly/F2Yh7FIr329Gl 681J7/urPl5WqOnt0GpFal1NV2F6a/yGCriRio8eIkiHk5D1slnWEymBwZvtVeoC iYyDDyiLiTo0iioVOLjxDAVLhAHAmBXnKJizL0nFJ1teCKui3/T7i/jip37OG7v1 B44evT0OeiTsUFurgNVNjeNuTlIfmNdidmXfnccdOCL1BSJb9ei1M+Es4irfx0UN JIe+6F3qQcK0cYDq75HpGcqOr3OERj3+8/OpPXeP54N2LZbVKnDnHpLr6I/qozQZ mFD3v2M5pHTbCjsSQvewZnm/a51ZoC4Y2CT8hSAmkd/Y3VgstGuoxnINmEUU//OC qUnDzoWQovOp7tvkzCrxBZeEiIJ0ADb8HpbjLOMPASpphNnGnfR9DxWZle2TsUWt lFmxtHs/ragtEcWonVJGU2B4bL7rvPuG3SBVjf6K+kKKeTUgeIdXIXS4Lb6kvqiU nOUBFpeCOPnxA7xDPKNVAvK62zVsH3rW33/UqzAfoQ68lIjoQSyYSYMYLf4EMOHB GmAMdjnb7umIag5VK+yGN5ZRYp8nbk64AcQYWrMFNOcBiWH7/+5yV+ITEB84In+6 ctqarFGmwxmdIhhTkIi6t7pnX3gltZ0oLOVcXEQVTRJ3mhypN+l0V6WuWOSsRBOd Q2nLOnwzCVIBvqOKd4yzhS1WJA+tm7KranMtetOGM2kdW6+fPz/e6ahGvkfKoD4p fwEva6go0wmy/NZVXpyHJ1E8NzZipM+ab2r+ssveX6WxwUx2z540Q2V2+Uli7LPc Xr1ZRYJQKRPi/HvoZsqnq87mfzc3cApgxf/JavZ5o1MpHA1+wG0kH9AvHafCElHY eOv76AnqDlXUrirqhKiHGoW04u95yuUUXiCrg+NbOc2opBVi107Jjgz/fwrx0HlP z3m+trpPZli8stcf7i60EtCtztG6dF1DE1aQBRPBxscz4jCIdh/uD43xC0j7z7lO VlPlfDMBAZS82mA8NtTTxLmExfNFPRlKrLbiasVr0r2yGlGYdLA6mFOVAW9tUFmA CZWpsw5oakmqNcL37hO77C6PqebcvD0W57J/J31IQp01WN44JERtU3dgZlrjpR2k L7j5omdpOrT6kBZPPCingan4zfd5sh3RFo59OXf9mhILZoituU9UievlAgJ0E0w4 ZkJoXUe74VJAiUg4iOPyD8RUBFiB8PFultDww543k0EPqL7J4IlWA6TtKu6jcbfM GgBRJiqys6ghdQSIOLHVZmLmAAC0x/tD90hX8zDgHA7IewxufZFGyGhtjBeGZudD jF2rqxOl3XTB/6IsV14EzLlbS2Q9lAPPuDwMigp0Yaiz64pDblQZVnWMnqZFG9gI slqK4Maw/ufuTmFaN+IwqFoFcHYfI/wuIhhZ8CMa81vxk5EwK74WlwncVTUc7jvI MxPsC/IqnjYMglQdzfEbpDD5qbMdyS92m9YYOVDlqW6fNLjvfQdUBP13xs3DMUDA OAjAfoWoHNuNJACCg2q8juPCIZFo+8g6fk7t7aoCj8b7VjCAOQBDU7NJaTanEYQV jVLzP1VX1R2UFIlB59nX4Cfny+U1VgQKOkWmnDe15XrnyGH8e+BHHp/5fn27tPQz 52ZD0Rs+apR+rESlNxS7crbL5sgFz4Z0JzkeqlVAd0IJn1VnkmicbauX1OB7mDOf V9I6yaZctuj6k6nT6mLfisj4gvkCdZdwcWH2CTqGI1sU9Sj7juX51POJZxqrZyiM r7lHcJ/ZFfWE+T1s9zdrtXnrPAyt9M2TiPX9ljYxJEytwB8ugETYtrsGHPZNEI4i wxy31y95XkqdTh3BuLn7DP6/5iv0SS4BNvISJXzXOtYumNGCs3b8w376Fi2Of/A9 en03kZlSqmFtudZ3CsJiaNsEAtDs/L4FHhF2logfeWk1DOpONXtep3nI7OMZrcoG bySZLXEgLjoppSnGsaRhaWICGzOd8O18a3AGVpviqg7wGfugGzvPztiF/luU56sV Z7sUQJ36xDXcsEoh2JmcltWNOPVZlZvL139zY6A4rEyWXFKbQ0TpsiSxYolQqctb pAxm6E+fs5NOZoJlMgw/ZxKS =ddzL -----END PGP MESSAGE-----
Don’t want to do that. https://jonathanabennett.github.io/blog/2019/05/28/emacs.org-~-may-2019/ might have a solution with tangling. Any drawbacks from loading with old org version then upgrading? This talks about how disabling certain decorations in early init is faster. I’m curious how I can get org-tangle to export some code blocks in one file and other code blocks in another file.If I do this, I should set package-enable-at-startup to nil as well.
And loading org in early init wouldn’t be a bad idea either.
It had previous failed to load in a tty, complaining about listp nil. I’m not reproducing the error now, just keep an eye out?
I would like to have it delay until either opening a gnuplot file or when executing gnuplot source blocks. Additionally it fails to execute src blocks on the first attempt when launching emacs, requiring two attempts.
Failing to execute gnuplot on the first attempt doesn’t seem to just be limited to gnuplot, but C as well. Probably an issue with my babel advice.
Currently files fail to save and a warning periodically appears with it enabled.
-----BEGIN PGP MESSAGE-----
hQIMA341lovNpziwARAAgrDn/EU35uchGWg45SRBHMRaFiRkTXnQT071Xtl7HZfu fGRDR4omvMLYqO69iQO/13ZFPIX+H8Z0fys5y9UDxZlVaWANslb6/HQYzHrZAICH LVHoMzmguxjid0uUb+aK97461kGOdKQLjRLFPKtHGWBJYpkaMyJsYUPTgKhv0F2A JWpk0eCKB8qdpoJBJmqG+M/n6InkZVDJDWru5uB4NgOsUIcUcEFxf/UyM1zHU8x5 sV4FPocoEnVDHkdTozHr+YwtJZjRdnBeVi08FnamUxgtpjHXPQs5NC+DZKW1AULl MrRq9r5fjDmJZjXlae9Sfa3b8O2yzdmoXenn+DFvN3adpRWGxTccfb44IT9HTbiO RkRJy7UUa24z0Q49SF/cpQjaIO8u3OEsk2X1+j/6F67QWv+JzFi1LwtphB6FU94D e58P9q7Aj0e3yF9YRHilMGQe05YCq0rYVHAFVuiNQKne9PgW/xyllac8Zky1uiSy OW5+Ejx3mgtCs8QeFHd7Cs+iPz5EcZQeTQqvjfDJAayGiHdS/XsMxWriAv5VnCq7 CxeHrJ6In0R5Xsl58ynTaMvK+roJfMdNCdnkeUmIr6/v9eVANzve04ktfDVqlOru i4tcHvFOBAzC5gGX6+FK3n6srokTDagBBIQmz9eqo5Nig8ZSBso6t5x7OVQus0/S wK4Bg77IPf5gfx7or/jfj5vBRgy9iWGOKkuwe1NUyDpyk5Kw2ckoGLLAzcs1nBrF hdE8v/qQmdVNOQcPIPWLefoSecKJ287u7DXxUwcecCiLqTmenhXOy0ng9+lnz7/H HfLei6RGA5O6youzB8gXi3avyD1s0cksH5seRE0pE8Rw3nT3gbfqqZNARcPvkGD/ IA6XYEjwS4WOW+zDbhUbobjFncccmeucVqw+eapN1SDU9jO+vBfiTQ3H7VO485H0 cCDySqfAp2+NViQA6p/b216nv34FbNsdD4PYZDZt3D6dLd0V0umftnpwmndBzyCH Fo4a1yIJl07D5iWMNPhkoF8tdjq/2tUkY6xGe4IRPgw0/85nFvzFlaOkCWEDN4aN W9ZD81PzF8Ue4zpRSixVEklJeOH5eBQrN8uLdh4P5uklfb9faVTUBpX1sAOnQ6xP 6kojG3+37mNSCWQ1nYr6DeNhGPA/pqUCbR/Wvw64kQ8= =6CMd -----END PGP MESSAGE-----