Reorganize notes

This commit is contained in:
Akemi Izuko 2023-12-23 20:13:52 -07:00
parent c516e9c3ad
commit 62d3bbcb44
Signed by: akemi
GPG key ID: 8DE0764E1809E9FC
35 changed files with 2524 additions and 21 deletions

View file

@ -1,36 +1,33 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Read notes files from ~/.configs_pointer/notes print_help() {
if [[ $1 =~ '-h' ]]; then cat <<HELP
printf 'Open notes files from ~/.configs_pointer/notes\n' Quickly open notes files from ~/.configs_pointer/notes
No arguments required
HELP
}
if [[ -n "$1" ]]; then
print_help
exit 0 exit 0
elif ! [[ -h ~/.configs_pointer ]]; then elif ! [[ -h ~/.configs_pointer ]]; then
cat <<ERR printf 'Please set up a symlink ~/.config_pointer to the configs directory\n'
Pointer to configs not found
Please set up a symlink ~/.config_pointer to the configs directory
ERR
exit 1
elif ! command -v fzf &>/dev/null; then
printf 'Requires fzf\n'
exit 1 exit 1
fi fi
cd ~/.configs_pointer/notes || exit 2
# Fzf for notes file declare -r notes_file="$(fd -e 'md' | fzf)"
if command -v fd &> /dev/null; then
notes_file=~/.configs_pointer/notes/"$(fd '.md' ~/.configs_pointer/notes -x basename | fzf)"
else
notes_file="$(find ~/.configs_pointer/notes -type f | fzf)"
fi
# Use best available pagenator # Use best available pagenator
if command -v nvim &>/dev/null; then if [[ -z "$notes_file" ]]; then
printf "No note file selected\n"
exit 1
elif command -v nvim &>/dev/null; then
nvim -R "${notes_file}" nvim -R "${notes_file}"
elif command -v vim &>/dev/null; then elif command -v vim &>/dev/null; then
vim -R "${notes_files}" vim -R "${notes_file}"
elif command -v bat &>/dev/null; then elif command -v bat &>/dev/null; then
bat --paging=always "${notes_file}" bat --paging=always "${notes_file}"
else else
less "${notes_file}" less "${notes_file}"
fi fi

View file

@ -0,0 +1,248 @@
Further recommendations to set your system, after having already run the
`install.sh` script. A package manager is the cleanest way to install any of the
apps listed here. Unless specified, these are all open source
# Mac OS
## Shell
Non-graphic open source applications. Use `brew install --formula` unless
otherwise specified
`pbpaste` except for images. Redirect output to file with `pngpaste - > img.png`
```
pngpaste
```
GNU's `coreutils`. Apple has most by default, though they're very outdated
```
coreutils
```
File manager for quickly jumping around directories. Not essential
```
vifm
```
Quickly search stackoverflow for answers to any query
```
so
```
Checks your shell scripts and suggests fixes to potential errors
```
shellcheck
```
Non-graphic image manipulator. Very useful in scripts and often a dependency
```
imagemagick
```
A much better python REPL and integrates nicely with vim's IPython plugin
```
ipython
```
The largest support converting documents types, such as markdown to pdf
```
pandoc
```
`ctags` with a lot more language support
```
universal-ctags
```
`cut`, `sed`, `grep`, `xargs`, `printf`, etc, for all your stream editing needs
```
gawk
```
Foreign filesystems on mac. `sshfs` from `brew install gromgit/fuse/sshfs-mac`
```
sshfs macfuse
```
A javascript runtime for servers. It's also useful for shell scripts
```
node
```
### Applications
Applications that should be considered for installation on any mac. Everything
listed here is open source. Use `brew install --cask` unless otherwise specified
Hotkey daemon for MacOS. Config files can be set up with the install script.
Either `brew services` or launchd can be used to start `skhd` automatically
```
skhd ✔️
```
The most widely used media player capable of decoding almost any format
```
vlc ✔️
```
Pairs with `vlc` to watch videos with others remotely
```
syncplay
```
Really powerful flashcard memorization software
```
anki
```
Pdf reader with contents lists and double display
```
skim
```
Installs both a gui version of vim and a more featured non-graphic version too
```
[nvchad]
[VapourNvim]
macvim
```
Best torrent client. No-nonsense and a nice interface
```
qbittorrent
```
Output or capture system-audio by providing a virtual output device
```
blackhole-2ch
```
### Power tools
Heavier applications that should be installed only on capable systems. Use `brew
install --cask` unless otherwise specified. These are all open source
Full video editor that puts iMovie to shame. Exports require a lot of cpu power
```
shotcut
```
Emulator for any operating system. Configuration is complicated. See examples in
`shell/qemu/`
```
qemu ✔️
```
Linux subsystem for mac. Essentially qemu + sshfs automated
```
lima
```
Image editing similar to Photoshop, except free and with wider platform support
```
gimp
```
Full latex support. Vim configuration and snippets are already setup. Takes
almost 10G for a base installation and runs hot
```
mactex ✔️
```
### Proprietary
Screenshot tool to fill the gap between Mac OS's screenshots and gimp
```
brew install --cask skitch
```
Alternative screenshot tool, with a few more markup options
```
brew install --cask flameshot
```
### Extra nonsense
Make banners for titles
```
figlet
```
## Mapping from linux
Macs aren't even close to Linux in virtualisation capabilities, window managers,
and customizability in general. However, if you're unfortunate enough to find
yourself with a macbook, all is not lost. Here's a rough porting guide:
| sWayland | MacOS |
| --------------------- | -------- |
| SwayWM | [Yabai](https://github.com/koekeishiya/yabai) |
| xRemap | [Karabiner-Elements](https://karabiner-elements.pqrs.org/) |
| ~/.config/sway/config | [skhd](https://github.com/koekeishiya/skhd) |
| swhkd | [skhd](https://github.com/koekeishiya/skhd) |
| wtype | [skhd](https://github.com/koekeishiya/skhd) |
| systemd | Launchd |
| Zathura | [Skim](https://skim-app.sourceforge.io/) |
| Fuzzel | [Choose](https://github.com/chipsenkbeil/choose) or Spotlight |
| udisksctl | `diskutil`
| ~/.local/share/fonts | FontBook |
| wl-clipboard | `pbcopy` `pbpaste` |
| sshd | System Preference -> Sharing -> Remote Login |
| Super/Ctrl | Command |
| Alt | Opt |
For Xorg users, `yabai` is to `skhd` what `bspwm` is to `sxhkd`. Also `launchd`
is wayyy less capable than `systemd` and rarely gets used. The `launchd` script
in `./bin` wraps around all the commands you'll ever need
To use open source apps, run `sudo spctl --master-disable`, then head to System
Preferences -> Security & Privacy -> General and select Anywhere at the bottom.
You can check it's working with `spctl --status`
While you're here, you can go under Software Updates and uncheck everything
## Window managers
MacOS only allows the default Quartz Compositor, a floating window manager with
too many animations and almost no keyboard controls. There are two open source
tiling window managers, which are just scripts overtop Quartz Compositor as
alternatives. [Amethyst](https://github.com/ianyh/Amethyst) and
[Yabai](https://github.com/koekeishiya/yabai)
Amethyst provides basic tiling of windows and basic keyboard controls. Yabai is
effectively a port of bspwm to MacOS and has much more extensive configuration
than Amethyst, notably controlling workspaces. Unfortunately they don't hold a
candle to Linux managers. Both can be very laggy and Yabai specifically often
freezes up for a few seconds, though these are the only options.
To use Yabai, boot into recovery mode, and disable SIP [as explained
here](https://github.com/koekeishiya/yabai/wiki/Disabling-System-Integrity-Protection).
Despite what apple says, this doesn't make the system immediately explode.
Actually there's no difference at all, except being able to use Yabai

View file

@ -0,0 +1,175 @@
# Linux
## Fonts
Many scripts assume you have access to [Meslo LGM
NerdFont](https://github.com/ryanoasis/nerd-fonts/tree/master/patched-fonts/Meslo/M).
These can be replaced easily with any other nerd font. Other fonts may lack
support for the right character set
```
$ mv -i downloaded-fonts/* ~/.local/share/fonts
# mv -i downloaded-fonts/* /usr/local/share/fonts
```
See the [ArchWiki](https://wiki.archlinux.org/title/fonts#Manual_installation)
for more information. TexLive downloads a lot of additional fonts by default too
## xRemap
Remapping keys is done through `xremap`. Despite the name, it works flawlessly
on Wayland, at least in Sway
Depending on your environment, you need to install a different binary, all of
which are available through `cargo`. For example `cargo install xremap
--features sway`. Check [here for more
options](https://github.com/k0kubun/xremap#installation).
If you're using systemd, run the following:
```
# ln -s ~/.configs_pointer/xremap/config{_console,}.yml
# mkdir -p /etc/xremap
# ln -s {~/.configs_pointer,/etc}/xremap/config.yml
# cp ~/.configs_pointer/systemd/xremap.service /etc/systemd/system/xremap.service
# cp ~/.cargo/bin/xremap /usr/local/bin/xremap
# systemctl enable xremap.service
# systemctl start xremap.service
# switch_keyboards.sh pc
```
You can toggle between Mac-style keyboard and standard keyboard with
`switch_keyboards.sh` see the doc-comment `vi $(which switch_keyboards.sh)` for
more information
`sway/config` acts as a hotkey daemon and `wtype` can synthesize input
## Sway
To run sway, install the `sway` and `swaylock` packages. Both configs reference
`default_wallpaper.png` in their respective directories. Put your wallpaper
there or change the corresponding `config` file
If sway is acting up, try setting/unsetting `WAYLAND_DISPLAY` and `SWAYSOCK`.
`swaymsg` also takes an `-s` option which can specify the socket manually
Sway doesn't adjust the gamma on external displays. Compared to MacOS,
everything looks very washed-out and low contrast. Using `wl-sunset` with `-t
4000 -T 6500 -g 0.9` brings MacOS-like gamma curves
For more information about sway, read the [i3 User's
Guide](https://i3wm.org/docs/userguide.html). Particularly chapters 3 and 4 are
very important for sway
## Multilingual input (fcitx)
IME-style inputs require a complicated setup on wayland. The method described
here unfortunately scales like Xwayland. That is to say it's very blurry on a
HiDPI display. Also, IMEs don't work in Alacritty yet. Consider [foot
terminal](https://codeberg.org/dnkl/foot) if this is important
If you only need an IME in Chromium, [Google Input
Tools](https://chrome.google.com/webstore/detail/google-input-tools/mclkkofklkfljcocdinagocijmpgbhab)
is a pretty decent solution. It scales properly on wayland and doesn't require a
spotty setup. However, it doesn't work in the search bar and makes network calls
for kanji lookups, which can be really slow
Otherwise you can use fcitx5. Choose a supported IME based on what language you
need [here](https://wiki.archlinux.org/title/Input_method). For the example
below we'll install Mozc
```bash
please pacman -S fcitx5 fcitx5-configtool fcitx5-gtk fcitx5-qt fcitx5-mozc
please pacman -S gtk4 # For Chromium support
```
Next add these lines to `/etc/environment`
```
GTK_IM_MODULE=fcitx
QT_IM_MODULE=fcitx
XMODIFIERS=@im=fcitx
MOZ_ENABLE_WAYLAND=1
```
Currently, Chromium will only interface with fcitx5 when it's running on the
non-default gtk4. Add `--gtk-version=4` to `~/.config/chromium-flags.conf`. As
of writing, this breaks Chromium's built-in file manager, the one for picking
files. Use Firefox for a better fcitx5 experience
Open fcitx5-configtool to set the required keyboards and change the global
hotkey. For Mozc, you'd move the Mozc keyboard to the left. Not the other
Japanese keyboards, those are not IME-based
You may need to reboot wayland or possibly the entire system. Fcitx5 will now be
available will the following command. Consider adding the following to
`sway/config` if you want it on startup, or use `<M-i>` to toggle in on/off
```bash
fcitx5 -d --replace
```
## AV1 media
AV1 is the hottest new codec on the block, providing compression levels better
than h265. I've seen it 200x smaller than png, with the same resolution and
color space
To store images as avif, use `magick convert my_image_name.{png,avif}`. `viu`
has no support for avif. `imv` supports it out of the box. `vimiv` requires a qt
plugin for support:
```bash
please pacman -S libavif
# Get the latest release from below, for example
# https://github.com/novomesk/qt-avif-image-plugin/releases/latest
curl -LO 'https://github.com/novomesk/qt-avif-image-plugin/archive/refs/tags/v0.5.0.tar.gz'
tar xf qt-avif-image-plugin-0.5.0.tar.gz
cd qt-avif-image-plugin-0.5.0
./build_libqavif_dynamic.sh
please make install
```
## Chromium
Chromium does not support screen sharing by default on wayland. To add support
go into `chrome://flags` and enable the "WebRTC PipeWire support" flag. Next
download the following a reboot to allow screen sharing
```bash
please pacman -S xdg-desktop-portal-wlr libpipewire02
```
Consider disabling "Continue running background apps when Chromium is closed" in
settings
Fix the default fonts in `chrome://settings/fonts`. These are the fallback fonts
For the really daring, change your download location to `/dev/shm`. This is a
ramdisk which clears all its content on reboot
## Firefox
Firefox will start on xorg by default, unless the `MOZ_ENABLE_WAYLAND=1`
environment variable is set. Incognito is enabled through the `--private-window`
flag
Firefox uses `about:config` stored in
`~/.mozilla/firefox/<random-hash>.default-release/prefs.js`. These are the
equivalent of Chromium flags. For these configs, simply switch
`ui.key.menuAccessKeyFocuses` to false, to avoid conflicts with xremap
## Backlights
Laptops usually control the backlight via apci. One program to control this is
[light](https://github.com/haikarainen/light). By default light requires the use
of root privileges to modify devices. Use systemd rules and the video group to
allow unprivileged users to run it normally:
```bash
curl -LO 'https://raw.githubusercontent.com/haikarainen/light/master/90-backlight.rules'
please mkdir -p /usr/lib/udev/rules.d
please cp 90-backlight.rules /usr/lib/udev/rules.d
# Add your user to the video group
please usermod -aG video emiliko
```

34
notes/linux/aerc.md Normal file
View file

@ -0,0 +1,34 @@
# Aerc - Allegedly "the world's best email client"
A terminal email client that's pretty decent out-of-the-box. Configuration is
divided between 3 files, the most important one is accounts.conf described here
```bash
please pacman -S aerc w3m dante
```
You'll need an app password to login. This can be put directly after the email.
Gmail has one [here for
example](https://support.google.com/accounts/answer/185833?hl=en)
```
source = `imaps://emiliko%40gmail.com:passwordhere123@imap.gmail.com:993`
```
Or alternatively use the `source-cred-cmd` to retrieve a password through a
program like `pass`, as shown below
```
[Gmail]
source = `imaps://emiliko%40gmail.com@imap.gmail.com:993`
source-cred-cmd = `pass show gmail/primary/app_password`
outgoing = `smtps+plain://emiliko%40gmail.com@smtp.gmail.com:465`
outgoing-cred-cmd = `pass show gmail/primary/app_password`
default = INBOX
from = Emiliko Mirror <emiliko@gmail.com>
copy-to = Sent
check-mail = 1m
```
For other email providers, look up their server names and port, for example
Fastmail has them [listed
here](https://www.fastmail.help/hc/en-us/articles/1500000278342)

View file

@ -0,0 +1,28 @@
# Airpods - bluetooth audio
Bluetooth headsets may be unusable with pulse audio by default. Particular
symptoms include cutting out and compressed playback. This is completely
independent of the speaker setup, so it won't mess up the config there
Start by finding your bluetooth card's name with
$ pactl list | grep -Pzo '.*bluez_card(.*\n)*'
This also shows the latency in the output section. It should be 0. Now increase
the latency. 50000 is a good choice for airpods pro
$ pactl set-port-latency-offset bluez_card.00_8A_76_4D_9B_BB headphone-output 50000
$ systemctl restart bluetooth
That should fix the cutting out issues. Not connect the airpods
$ bluetoothctl
[bt]# power on
[bt]# default-agent
[bt]# scan on
[NEW] Device 00:8A:76:4D:9B:BB Annas Airpods
[bt]# trust 00:8A:76:4D:9B:BB
[bt]# pair 00:8A:76:4D:9B:BB
[bt]# connect 00:8A:76:4D:9B:BB
You may need to redirect pulse audio's output to the airpods. Referenced from
[here](https://askubuntu.com/questions/475987/a2dp-on-pulseaudio-terrible-choppy-skipping-audio)

177
notes/linux/gnupg.md Normal file
View file

@ -0,0 +1,177 @@
# GnuPG
Key files are a secure method for certifying credentials digitally. Everything
is stored in `~/.gnupg` and controlled through `gpg`. It's quite complicated...
See `tldr gpg` for encryption, [devhints](https://devhints.io/gnupg) for a
cheat sheet, the [Archwiki](https://wiki.archlinux.org/title/GnuPG) for a
technical explanation and the [Debian wiki](https://wiki.debian.org/Subkeys) for
a newbie-friendly one
Terminology:
* Public key - The one to share
* Private key - The one to not share
* Primary key - ??
* Subkey - ??
* Keygrip - The name of the key file
* Key ID - The last few (8-16) characters of a fingerprint
* Fingerprint - A unique identifier for a key
* Keyring - Your entire collection of public or private keys
* User ID - Email, part of name, Key ID, or Fingerprint of a key
Consider this example output:
```bash
$ gpg --list-secret-keys --with-subkey-fingerprint --with-keygrip --keyid-format=long
# ///--- Short for "secret key". It's "pub" for public keys
# vvv vvvvvvvvvvvvvvvv Key ID
> sec ed25519/ABCDEFG123456789 4040-04-04 [SC] [expires: 4040-04-04]
> DDEEDF222222222222222222ABCDEFG123456789
# ^^^^^^^^^^^^^^^^ Key ID also here
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Fingerprint
> Keygrip = DDEBBA3482394AEE23432DEE32432BB2432432EE
# Key is ~/.gnupg/private-keys-v1.d/DDEBBA3482394AEE23432DEE32432BB2432432EE.key
> uid [ultimate] Emiliko Mirror <emiliko@mami2.moe>
# ///--- Short for "secret subkey". It's "sub" for public subkeys
# vvv vvvvvvvvvvvvvvvv Key ID
> ssb cv25519/987654321ABCDEED 4040-04-04 [E] [expires: 4040-04-04]
> 32423BDDAAAAAAAAAAAAAAAA987654321ABCDEED
# ^^^^^^^^^^^^^^^^ Key ID also here
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Fingerprint from --with-subkey-fingerprint
> Keygrip = 2493ADDEDDDFEFEFE23432432FDEEFDD24324232
# Key is ~/.gnupg/private-keys-v1.d/2493ADDEDDDFEFEFE23432432FDEEFDD24324232.key
```
Providing the `--fingerprint` flag will alter the output slightly, tho it's the
same fingerprint, for example:
```bash
> sec ed25519/ABCDEFG123456789 4040-04-04 [SC] [expires: 4040-04-04]
> Key fingerprint = DDEE DF22 2222 2222 2222 2222 ABCD EFG1 2345 6789
# Key ID is now here ^^^^^^^^^^^^^^^^^^^
> Keygrip = DDEBBA3482394AEE23432DEE32432BB2432432EE
> uid [ultimate] Emiliko Mirror <emiliko@mami2.moe>
> ssb cv25519/987654321ABCDEED 4040-04-04 [E] [expires: 4040-04-04]
> Key fingerprint = 3242 3BDD AAAA AAAA AAAA AAAA 9876 5432 1ABC DEED
# Key ID is now here ^^^^^^^^^^^^^^^^^^^
> Keygrip = 2493ADDEDDDFEFEFE23432432FDEEFDD24324232
```
## Creating a new key
This closely follows the Archwiki, with an elliptic cipher
```
gpg --full-gen-key --expert
> (9) ECC and ECC
> (1) Curve 25519
> 1y # Optional, 1 year is recommended
> Your Name # This will be visible in the public key
> emiliko@mami2.moe # This is also visible in the public key
> No comment
> Put a password on the primary key
```
## Signing and verification
Git commits, binaries and really any file can be signed by a private key to
prove authenticity of the file. For github, you'll need to paste your public key
to your profile settings
```bash
gpg --list-secret-keys --keyid-format=long
gpg --armor --export <user-id> | wl-copy
```
Git commits aren't signed by default. Either explicitly sign at commit time,
with `git commit -S`, or add the following to your ~/.gitconfig. If the signing
key you specify is a subkey, add an ! mark at the end
```toml
[user]
name = Emiliko Mirror
email = emiliko@mami2.moe
signingkey = ABCDEF1234567890
[commit]
gpgsign = true
```
## Encryption
Gpg can encrypt pretty much anything. Consider bundling into a tarball
beforehand if it's more than one file
The `-a/--armor` flag will make sure the encrypted file is made up entirely of
ascii characters, which is easier to copy/paste than binary nonsense
Encryption can be symmetric or asymmetric. Symmetric encryption uses 1 key and a
password to encrypt. To decrypt, use the same key and re-enter the same
password
### Symmetric encryption
Symmetric encryption uses 1 key and 1 password to encrypt. To decrypt, you'll
need the same key and the same password
### Asymmetric encryption
Asymmetric encryption is meant for sending to a specific receiver. It uses 1
public key to encrypt. To decrypt, you'll need the private key pair to that
public key. `pass` uses this one
```bash
gpg -e -o encrypted_file -r emiliko@mami2.moe secret_file
# Then emiliko can decrypt it with her private key
gpg -d -o secret_file encrypted_file
```
## Moving keys
You'll want to export your keys to other devices. Ideally, you'd only export
subkeys and not the primary key. The primary key should be stored offline and
used to generate revocation certificates for compromised subkeys
```bash
gpg -o pub_key.pgp -a --export emiliko@mami2.moe
gpg -o sec_key.pgp -a --export-secret-key emiliko@mami2.moe
scp pub_key.gpg emiliko@192.168.0.1:/tmp/safe_directory
scp sec_key.gpg emiliko@192.168.0.1:/tmp/safe_directory
gpg --import pub_key.gpg
gpg --import sec_key.gpg
```
A safer method skips the creation of any intermediary files by sending it
through ssh right away
```bash
gpg --export-secret-key <user-id> | ssh emiliko@192.168.0.1 'gpg --import'
# Or if you're on the receiving system
ssh emiliko@192.168.0.1 'gpg --export-secret-key emiliko@mami2.moe' | gpg --import
```
In either case, or actually whenever importing your keys, you'll need to edit
the trust level after importing it
```bash
gpg --list-keys # Get the Key ID here
gpg --edit-key <user-id>
> trust
> 5 # If it's your own key
> y
> quit
```
For use with `pass`, you can check if your encryption key is working by trying
to add a new password, like `pass insert -e something` and see if it succeeds
## Backing up keys
Keys should be backed up on offline, physically inaccessible, media. Usb sticks
you leave at home or a piece of paper are both good choices. For the paper
version see `paperkey`
```bash
gpg -o /run/media/my_usb/keys.gpg --export-options backup --export-secret-keys emiliko@mami2.moe
```
Now later, or on another device, you can restore these keys
```bash
gpg --import-options restore --import keys.gpg
```
Then edit the trust level, as with the other transfer methods

View file

@ -0,0 +1,220 @@
# Networks
This file covers wifi and bluetooth connections on linux
Required packages for the guide:
- systemd
- NetworkManager
- `bluetoothctl`
Optional GUI tools to make this easier:
- `pacman -S nm-connection-editor`
- `pacman -S blueberry`
# Basic networks
For Archlinux, choose between NetworkManager and netctl for your networking
needs. NetworkManager comes from the GNOME project and is fully feature packed
from the getgo. Netctl is a set of light shell scripts that rely on external
packages for networking, so a bit harder to install
Both can be checked with systemd
```bash
systemctl status netctl.service
systemctl status NetworkManager.service
```
**Make sure only one is running and enabled**. Using both at the same time will
result in system slowdowns, especially at boot times
## NetworkManager and netctl conflict
If your system is running some `/sys/.../subnet...` for 90s at startup, likely
netctl is trying to start up a device, though the device name has changed.
Places to check:
/etc/NetworkManager/system-connections/
cd /etc/systemd/system/multi-user.target.wants/ && rg enp0s3
vi /etc/systemd/system/multi-user.target.wants/netctl@enp4s0.service
vi netctl@enp4s0.service
If you are using both by accident, make sure to use the native disable in
addition to the systemd disable. For example, with netctl:
systemctl disable netctl
systemctl disable netctl@enp4s0.service
netctl disable enp4s0
## Public networks
Public networks often use a captive portal to make users accept their terms and
conditions
1. Connect to the network using `nmtui` or similar
2. Use a GUI browser and navigate to any site
3. If that doesn't work, try navigating to a non-https using page
4. If that doesn't work, try navigating to a site you've never visited in incognito
5. If that doesn't work, try navigating to the router at 192.168.[0-1].[0-1]
# Bluetooth
Before starting bluetooth, make sure bluetooth.service is running, otherwise
nothing will work
```bash
systemctl start bluetooth.service
```
You may optionally install the `blueberry` GUI package. It's quite light and
limited, though it's a good way to check if your devices are connected
## Keyboard
Start `bluetoothctl`. The command sequence to connect will look something like:
$ bluetoothctl
[bluetooth]# power on
[bluetooth]# agent off
[bluetooth]# agent KeyboardOnly
[bluetooth]# scan on
[bluetooth]# pair <MAC-ADDR>
[bluetooth]# trust <MAC-ADDR>
[bluetooth]# connect <MAC-ADDR>
[bluetooth]# quit
When you turn `scan on`, the list may explode with various mac addresses. Try to
find your keyboard amongst those. During the `pair` section, `bluetoothctl` may
prompt you with 6 digits. Type those on the keyboard and possibly hit enter
after them
See the [Archwiki page](https://wiki.archlinux.org/title/bluetooth_keyboard) for
more info
## Bluetooth headphones
This section connected AirPods Pro. Setup may differ for other devices
Start by connecting your headphones with a very similar set of steps as the
keyboard guide above. Use `default-agent` instead of `agent KeyboardOnly`. For
example:
$ bluetoothctl
[bt]# power on
[bt]# default-agent
[bt]# scan on
[NEW] Device 00:8A:76:4D:9B:BB Annas Airpods
[bt]# trust 00:8A:76:4D:9B:BB
[bt]# pair 00:8A:76:4D:9B:BB
[bt]# connect 00:8A:76:4D:9B:BB
Once connected, blue headphones may cutout or just not play back anything. This
is a PulseAudio issue. The bluetooth sound latency may need to be adjusted
Start by finding your bluetooth card's name with
$ pactl list | grep -Pzo '.*bluez_card(.*\n)*'
Next increase the audio latency. 50000ms seems to work well for AirPods Pro,
though this is likely [different for other
headphones](https://askubuntu.com/questions/475987/a2dp-on-pulseaudio-terrible-choppy-skipping-audio)
$ pactl set-port-latency-offset bluez_card.00_8A_76_4D_9B_BB headphone-output 50000
$ systemctl restart bluetooth.service
Repeat the steps above, adjusting the bluetooth sound latency, until it works.
Consider using the `blueberry` GUI to quickly reconnect the headphones on each
bluetooth.service restart. Don't forget to relaunch `blueberry` every time too
```bash
kill $(pgrep ^blueberry$) && systemctl restart bluetooth.service && blueberry &
```
# Enterprise networks
Large organizations, like universities, use enterprise security on their
networks. These require an account to login, not just a password
The guide below assumes the network's name is "UWS" and your login username is
"emiliko"
You can install the optional `nm-connection-editor` to make things easier
$ nmcli device wifi list
This should show the network you're looking for
If your network is not using PAP authentication, it may be possible to just
connect with a simple password, try:
```bash
nmcli --ask device wifi connect UWS
```
Otherwise run this line, replacing the necessary information in the line above.
Particularly `UWS`, `emiliko` and `wlan0`. For `wlan0`, find your wifi device
with `ip link`. `enp...` is usually ethernet
```bash
nmcli connection add type wifi con-name "UWS" ifname wlan0 ssid "UWS" -- wifi-sec.key-mgmt wpa-eap 802-1x.eap ttls 802-1x.phase2-auth mschapv2 802-1x.identity "emiliko"
```
## Option 1: With nm-connection-editor
Open `nm-connection-editor`. Go into "Wifi-Security" and make it look like:
WPA & WPA2 Enterprise
Tunnled TLS
CA Certificate: (None)
Check No CA certificate required
Inner authentication: PAP
Type in your login credentials at the bottom. Now run
## Option 2: Without nm-connection-editor
If you don't have the GUI tool `nm-connection-editor` and no way to install it,
you can try editing the network's profile directly. The relevant file is at
`/etc/NetworkManager/system-connections/UWS.nmconnection`
This file should look something like below, with relevant information replaced.
The file can only be accessed by root
```
[connection]
id=UWS
uuid=cb62f680-e1da-41c9-bfa0-35e7ef6f5137
type=wifi
interface-name=wlan0
timestamp=1657043376
[wifi]
mode=infrastructure
ssid=UWS
[wifi-security]
key-mgmt=wpa-eap
[802-1x]
eap=ttls;
identity=emiliko
password=PutYourPasswordInPlainTextHere_YesPlainText
phase2-auth=pap
[ipv4]
method=auto
[ipv6]
addr-gen-mode=stable-privacy
method=auto
[proxy]
```
Alternatively, use the file above as a reference to edit it via
```bash
nmcli connection edit UWS
```
## After setting up above
```bash
nmcli device wifi connect UWS
```
NetworkManager takes a bit, about 30s, to finish authentication. This will also
happen during boot, so you can't use the network right away
If your network does not use PAP authetication, it might just work to type the
password in
```bash
nmcli --ask device wifi connect UWS
```

19
notes/linux/pass.md Normal file
View file

@ -0,0 +1,19 @@
# Pass - The Unix password manager
Forget proprietary password managers that require a subscription, use `pass` to
generate, store, and retrieve all your passwords through your gpg key
```bash
pass init emiliko@mami2.moe
pass insert university/password
pass insert -e university/username
```
Passwords, or rather entire files can be retrieved to stdout, the clipboard, or
a qrcode. Stdout will show multiline files. `-c` will only copy the first line
to `wl-clipboard` for `PASSWORD_STORE_CLIP_TIME` or 45s
```bash
pass [show] university/password
pass [show] -c university/password
pass [show] -q university/password
```

26
notes/linux/ramdisks.md Normal file
View file

@ -0,0 +1,26 @@
# Ramdisks
Ram is fast and files sometimes need to be quick. Disks via ramfs and tmpfs
allow us to mount a file system entirely in the ram, and it's supported by the
linux kernel out of the box
Tmpfs is the newer version of ramfs, with the only difference being that tmpfs
has a maximum size that it won't exceed. Ramfs doesn't actually bound its own
size, so the system can run out of memory
# mount -t tmpfs -o uid=1000,size=1g tmpfs /home/emiliko/mnt
Mounts a temporary file system with a maximum size of 1GB at ~/mnt. Ramdisks
only use the size they need, so mounting this blank file system won't take up
any ram at first
Unmounting a ramdisk will clear everything off, which happens every time the
system is powered off
Linux systems come with a `/dev/shm` directory by default, which is a ramdisk
accessible by all users. To find the size of a ramdisk use `df -h /dev/shm`. To
check which ramdisks are mounted, use `findmnt` or `mount`
For more information:
- `man 8 mount`
- `man 5 tmpfs`
- [ArchWiki](https://wiki.archlinux.org/title/tmpfs)

View file

@ -0,0 +1,50 @@
# Mounting disks
On MacOS, there's `diskutil` which handles everything to do with disks and
partitioning all in one. It also has a graphical frontend. Macs by default
automatically mount readable external media into `/Volumes` and nothing explicit
needs to be done, although `diskutil` can trigger this as well
In Linux, the functionality of this tool is broken up into `fdisk`, `lsblk`,
`df`, `parted`, and `mount`. For querying information, these overlap heavily and
can often be used interchangeably. `lsblk` is often sufficient to query external
drives, with the following options:
```bash
lsblkf -o name,label,fstype,mountpoint,size,state
```
However, `mount` is a particularly bad substitute for `diskutil`. For one it
needs root privileges for something as simple as mounting a usb stick. It also
doesn't create mount pointer for us in `/Volumes`, we have do to that manually
Instead, it's a good idea to install `udisks2`. "Easier" distros typically come
with this or something similar preinstalled. `udisksctl` is much more similar to
`diskutil`. It'll mount drives without requiring root into
`/run/media/<username>/`, using the EFI label for that partition
```bash
udisksctl help
udisksctl mount -b /dev/sda2
udisksctl mount -b /dev/sda3
```
You can mount multiple partitions from the same block device at the same time
Do not try to mix `mount` and `udisksctl`! This can lead to some severe
nonsense, like ghost disks. Before using `udisksctl` consider checking the
output of `mount`. Note that `lsblk` may know less than `mount` and `df`
There are no guarantees that an external drive will have any particular name.
This is problematic in scripts and requires an `lsblk` every time before
mounting external media. Instead you can use the automatically created symlink
in `/dev/disk/by-*`. For example, a partition with label `hey_hey` can always be
mounted with
```bash
udisksctl mount -b /dev/disk/by-label/hey_hey
```
There can presumably be problems with conflicting partition labels, though it's
better not to use `udisksctl` in that case either. `/dev/disk/by-id/*` uses WWID
for identification, which is stored on the hardware for the drive and guaranteed
to be universally unique. That's a better idea for the fstab file

46
notes/linux/veracrypt.md Normal file
View file

@ -0,0 +1,46 @@
# Veracrypt
A cross-platform block device encryption program with support for passwords,
keys, hidden volumes, and manual PIM setting for security
Here we use `alias vera='veracrypt -t'` for the non-graphic interface
AES is the best all-round choice of cipher. Sha256 is the best choice of hash
Keyfiles must be prepared before locking a volume. `vera --create-keyfile` can
create one, or just use a few 100 bytes from /dev/urandom in a file.
Veracrypt devices must be mounted on a directory and require root access to use
`mount`
Dismount volumes with the `-d` option, providing a path to the mount point, the
name of the volume, or nothing to unmount all veracrypt volumes. Sometimes
veracrypt may fail to unmount. To check which process is using the container use
```bash
please fuser -vm <mount-point>
# For the really desperate
lsof
# Or if it must be closed no matter what process is using it
vera --force --dismount
umount -f <mount-point>
```
## Creating a new volume interactively
Start with `vera -c`. The most sensible default are:
```
Volume type: Normal
Volume path: /home/emiliko/file_name # Use absolute path!
Volume size?
Encryption Algorithm: (1) AES
Hash algorithm: (1) SHA-512
Filesystem: (8) Btrfs
```
## iNode problems
If you're making a very small container, you may run into inode issues. Btrfs
doesn't use inodes, so it should be ideal. However, btrfs requires a file system
over 1M for sure
Ext4 uses inodes and by default won't have nearly enough on a small drive. For
example, the default is 96 inodes for a 1M drive

128
notes/macos/apple_bsd.md Normal file
View file

@ -0,0 +1,128 @@
# Apple corner
MacOS is a BSD derivative that constantly does things differently under the
hood. While most things are Unix compatible, some things are just different
### Basic setup
MacOS requires a few manual interventions to get the system working
# spctl --master-disable
Reveals the option in "Security & Privacy" to run apps from any developer
~/Library/Sounds/madoka_error.aiff
Sound files stored in this directory are available under Sound -> Sound Effects
~/Library/KeyBindings/DefaultKeyBinding.dict
Allows basic remapping for system-wide key binds. Use `skhd` for complex hotkeys
### Basic commands
$ echo 'hello' | pbcopy
$ pbpaste > note.txt
Interact with the system clipboard through terminal. This does not work for
images. Install `pngpaste` for that functionality
$ say 'something'
Says string with system voice. Useful as a notification for when a task is done
$ afplay
Plays the audio of an audio file, such as an `mp3` or `wav`
### Disk Utility
$ diskutil list
Lists all the volumes the system currently sees. This works for unmounted and
encrypted partitions as well
$ diskutil mount disk1s1
Mounts `disk1s1`. Most useful to mount USB drives without physically reseeding
$ diskutil apfs unlockVolume disk1s1
Unlocks and mounts an apple file system volume
### Launch daemon
Systemd for MacOS. It will automatically load scripts in designated directories
on login. It can also be controlled manually through `launchctl`
$ launchctl load -w ~/Library/LaunchAgents/com.skhd.plist
$ launchctl unload -w ~/Library/LaunchAgents/com.skhd.plist
Loads and starts the skhd daemon. `<key>Label</key>` must be the same to unload
# launchctl list | grep skhd
Check the status of a running process. First number is the PID, second number is
the exit code. If the second number isn't 0 or there's no PID something broke
/Users/emiliko/Library/LaunchAgents/com.launcher.plist
This file will be started automatically on emiliko's login. All paths provided
in must be absolute paths from root. Use `/Users/emiliko/` not `~/`
/Users/emiliko/Library/LaunchAgents/com.launcher.plist
<key>StandardOutPath</key>
<string>/tmp/skhd.out</string>
<key>StandardErrorPath</key>
<string>/tmp/skhd.err</string>
Redirects stdout and stderr. Watch these files with `tail -f /tmp/skhd.err | nl`
### Installing SSHFS on Mac
To set up ssh filesystem (sshfs) on a mac, follow these steps on the client:
$ brew install --cask osxfuse
Installs `osxfuse`. This is an open source tool to extend your mac's fs support
https://osxfuse.github.io/
$ curl https://github.com/osxfuse/sshfs/releases/download/osxfuse-sshfs-2.5.0/sshfs-2.5.0.pkg
Recently brew removed sshfs from its supported casks, since it relies on closed
source code. Instead, you'll need to install it directly from the download link
See ssh_notes for using SSHFS
### OSA script
MacOS's GUI can often be controlled through the use of Apple's `osascript`.
Notably, this can allow shell programs to give GUI notifications
osascript -e 'display notification "'"${message}"'
Sends the system notification with the contents of `$message`
osascript -e 'display notification "'"${msg}"'" with title "Skhd"'
Adds a "Skhd" as a title to the notification
osascript -e 'display notification "'"${msg}"'" with title "Skhd" subtitle
"Could not save image"'
Further adds a subtitle for the notification
afplay $(defaults read .GlobalPreferences.plist \
| awk '/sound.beep.sound"/ { gsub(/(.*= ")|(";)/, "", $0); print }')
Plays the default system error sound through the current audio output device
## FreeBSD corner
Keep in mind that MacOS is based on a really old FreeBSD and NetBSD kernel, so
many sections here will somewhat apply to Macs as well
#### Users and groups
Various commands for managing system permissions. Many can be, at least
somewhat, run the user themselves with their password
# adduser
# rmuser
$ chpass # edit user account settings, like login name and expiry
$ passwd # change a user's password
$ pw # a cli frontend for the settings files above. More advanced
https://docs.freebsd.org/en/books/handbook/basics/#users-modifying
/etc/group
$ id emiliko
Shows groups a user belongs to. User seems to implicitly belong to their group
rwxr-x---x .
rwxr-x-r-- secret_file
rwxr-x-rw- no_touching
Oddly, the `x` on the directory here means means all other users:
- Can `cd` into the directory
- Cannot `ls` in this directory
- Can read the file `secret_file` using something like `vim secret_file`
- Can write to `no_touching`. Vim can only do this with `:x!` not `:w!`
# service sshd restart
Reboots the ssh daemon. Users connected through ssh won't lose connection, if
the reboot is successful
[//]: # ex: set ft=markdown:tw=80:

View file

@ -0,0 +1,21 @@
# Groups in macos
```bash
sudo dscl . -create /groups/newgroupname
sudo dscl . -append /groups/newgroupname gid 4200
```
Creates a new group. Alternatively use System Preferences -> Users and Groups
```bash
id -Gn emiliko
```
List all the groups `emiliko` belongs to
```bash
sudo chmod -R g=u .
```
Set the group privileges of the file hierarchy rooted at `.` to be the same as
the user. Very nice to convert a directory to be editable by ssh users

37
notes/macos/macos_qemu.md Normal file
View file

@ -0,0 +1,37 @@
# Qemu
Optimized options that seem to work on MacOS:
```bash
-m 4G -smp 6 # Resources: Use 4GB memory and 6 cpus
-machine type=q35,accel=hvf # Machine: Default is `pc`. `q35` should be better. Haven't noticed any perfomance gains
# Hypervisor: Uses HyperVisorFramework to speed up qemu a LOT, ~6x
-drive file=archlinux.qcow2,media=disk,if=virtio # Boot: Points to the image
-nic user,hostfwd=tcp::10022-:22 # Network: Forward host port 10022 to guest 22, so `ssh -p10022 user@localhost` should work
# Display options on MacOS:
# If you launch this script in the background, the same terminal can be
# used to ssh into qemu. After exiting, tmux's scrollback breaks. Opening
# and closing [n]vim fixes this...
-nographic
# Doesn't do anything noticably different from just -nographic
-monitor none -curses -nographic
# Support a 4k instance on MacOS. A spice server would be better. It's
# really laggy with KDE, to the point of unusable
-vga virtio -full-screen -display cocoa
# Only supports 1080p. MacOS must use a cocoa display. Compared to above
# the display scales by 2x which makes text bigger tho more blurry
-vga std -display cocoa
```
# Qemu fully nongraphic
MacOS can't use `-display ncurses` properly with qemu. Ncurses requires a linux
kernel to work properly. Instead use `-nographic` and launch the process in the
background. Bash uses `&` for backgrounding. You can now SSH into the qemu
instance.
Bonus:
For shared file systems, there are two options on Macs:
- MacFUSE - Manually setup and mount with sshfs. It's much easier to use
- lima - Tries to do reverse sshfs for you and forwards ports too. This one is
pretty new and questionably useful compared to manually using sshfs

View file

@ -0,0 +1,37 @@
Notes python and IPython
## Python
#### Virtual envs
Virtual environments are the `chroot` and `jails` of python. They essentially
temporarily append to the path and source locally installed versions of packages
$ python3 -m venv jail
Creates a new python in
$ source jail/bin/activate
$ deactivate
Start and stop the venv. The `$PS1` should indicate which one is active
$ pip install numpy ipython
Installs latest versions of packages to the venv. Use `pip` not `pip3` in venvs
## IPython
For a full blown IDE experience in shell, you'll want to use the IPython REPL.
Follow the vim ipython setup instructions to use it rStudio style
#### Magic in scripts
>>> from IPython import get_ipython
>>> get_ipython().magic('reset -f')
Functions exactly like typing `%reset -f` in the IPython interpreter. When
sourcing entire files, percent magic syntax won't work
#### Graphical interface
For certain applications, such as plotting graphs, a gui becomes much more
capable than a terminal. `matplotlib` can be easily set up to open a
live-updating gui window controlled by `ipython`
>>> get_ipython.magic('pylab')
In [01]: %pylab
Starts up a gui for plots. It may not open until the first figure is created
[//]: # ex: set ft=markdown tw=80:

64
notes/python/jupyter.md Normal file
View file

@ -0,0 +1,64 @@
# Jupyter
Despite being one of the most prolific modern languages, python suffers from a
dangerous amount of not-invented-here syndrome. Prepare to fight on all fronts
while python reinvents the wheels, though makes it square, just since a
text-based terminal is too intimidating for new cs students
Firstly you'll want to install python and all the other required packages:
```
# pacman -S python python-pip
# pacman -S jupyter_console python-qtconsole python-ipython-genutils
# pacman -S python-pynvim # For neovim only
```
Next you'll want to generate the configs required for Vim to connect with
Jupyter. Follow this section of the
[readme](https://github.com/jupyter-vim/jupyter-vim#jupyter-configuration).
Jupyter does not come with manpages, though it does give useful support by using
`-h` for any of its subcommands
Now we need to make a virtual environment, otherwise pip will pollute package
dependencies all over the system. Create a new environment directory:
```
$ python3 -m venv new_env_dir
$ cd new_env_dir
$ . bin/activate
```
Now you can install packages with pip, so long as the prompt stays "activated".
If you aren't sure, open another pane and reactivate from there
```
$ python -m pip install ipykernel
$ python -m pip install numpy matplotlib networkx
```
Trying to use Jupyter now still won't work. Since virtual environments are very
thin layer that just modifies some environment variables, Jupyter will still run
as if it's being run from a normal shell. We'll need to attach this venv as a
separate kernel on the system Jupyter installation. For example:
```
$ python3 -m ipykernel install --user --name=my_kernel_name
```
Now Jupyter should see it. You can use any shell from here on, not just the
venv-activated one
```
$ jupyter kernelspec list
```
We can connect to this kernel with an option
```
$ jupyter console --kernel=my_kernel_name
```
Removing the kernel later is easy too
```
$ jupyter kernelspec remove my_kernel_name
```

View file

@ -0,0 +1,33 @@
# REPL interaction
Vim can take advantage of read evaluate print loops (REPL) to run code 'cells'.
This is similar to the experience in Jupyter notebooks, Colab, and RStudio
# IPython
This is for the IPython interpreter. The normal python REPL isn't as easy to use
```vim
Plug 'jpalardy/vim-slime'
```
Necessary for any sort of REPL interaction through vim. Lets vim send text to
other terminals or tmux panes
```vim
Plug 'hanschen/vim-ipython-cell'
```
Plugin provides many conveniences for interacting with REPLs, such as one-line
execution, highlighted cell delimiters, and navigation between cells
# Julia
Use the same setup as the IPython REPL, except modify the evaluation string
```vim
let g:ipython_cell_run_command = 'Base.run(`clear`); include("{filepath}")'
let g:ipython_cell_cell_command = 'include_string(Main, clipboard())'
```
Julia equivalents for pasting the clipboard and executing a file

View file

@ -0,0 +1,8 @@
qemu-system-x86_64 \
-m 4G \
-boot d \
-display cocoa \
-machine type=q35,accel=hvf \
-smp 2 \
-drive file=archlinux-2021.01.01.qcow2,media=disk,if=virtio \
-cdrom /Users/emiliko/documents/safe/arch_vm/archlinux-2021.01.01-x86_64.iso

View file

@ -0,0 +1,50 @@
#!/usr/bin/env bash
# Qemu booting on MacOS
qemu-system-x86_64 \
-m 4G -smp 6 \
-nographic \
-accel hvf \
-drive file=archlinux-2021.01.01.qcow2,media=disk,if=virtio \
-nic user,hostfwd=tcp::10022-:22 &> /dev/null
exit 0
# Above invocation explained
-m 4G -smp 6 # Resources: Use 4GB memory and 6 cpus
-machine type=q35,accel=hvf # Machine: Default is `pc`. `q35` should be better, tho haven't noticed anything
# Hypervisor: Uses HyperVisorFramework to speed up qemu a LOT, ~6x
-drive file=archlinux.qcow2,media=disk,if=virtio # Boot: Points to the image
-nic user,hostfwd=tcp::10022-:22 # Network: Forward host port 10022 to guest 22, so `ssh -p10022 user@localhost` should work
# Display options:
# If you launch this script in the background, the same terminal can be
# used to ssh into qemu. After exiting, tmux's scrollback breaks. Opening
# and closing [n]vim fixes this...
-nographic \
# Doesn't do anything noticably different from just -nographic
-monitor none -curses -nographic \
# Support a 4k instance on MacOS. A spice server would be better. It's
# really laggy with KDE, to the point of unusable
-vga virtio -full-screen -display cocoa \
# Only supports 1080p. MacOS must use a cocoa display. Compared to above
# the display scales by 2x which makes text bigger tho more blurry
-vga std -display cocoa \
# Previously used presets:
-monitor none \
-vga virtio -full-screen -display cocoa \ # 4k supported, though it's really slow at 4k
-vga std \ # Normal run, only supports up to 1080p
-accel hvf \
# possible
-vga virto \
-enable-kvm \
#
-net tap,script=/Users/emiliko/documents/safe/arch_vm/tap-up,downscript=/Users/emiliko/documents/safe/arch_vm/tap-down
-nographic \
-chardev stdio,id=char0 \
-serial chardev:char0 \
-monitor none \
-net nic,model=virtio,macaddr=54:54:00:55:55:55 \

14
notes/qemu/qemu_start.sh Normal file
View file

@ -0,0 +1,14 @@
qemu-system-x86_64 \
-m 4G \
-smp 6 \
-boot d \
-display cocoa \
-vga std \
-serial stdio \
-machine type=q35,accel=hvf \
-drive file=archlinux-2021.01.01.qcow2,media=disk,if=virtio \
-nic user,hostfwd=tcp::10022-:22
#-net tap,script=/Users/emiliko/documents/safe/arch_vm/tap-up,downscript=/Users/emiliko/documents/safe/arch_vm/tap-down
#-net nic,model=virtio,macaddr=54:54:00:55:55:55 \

27
notes/shell/chrontab.md Normal file
View file

@ -0,0 +1,27 @@
# Crontab
Run programs at a given time. Useful for system cleanups and updates
```bash
crontab -e
```
Edit your crontab file
Syntax looks like (min, hour, day, month, year). Note these are absolute values,
so putting something like `* 1 * * *` will run the program at `1:00am` every
day. To understand these times use [this](https://crontab.guru/) Example crontab
file:
```bash
PATH=/usr/local/bin:/bin:/usr/bin
HOME=/home/emiliko
* * * * * ~/program_1.sh # Every minute, on the minute
* * * * * (sleep 30; ~/program_1.sh) # Every minute at 30s in
1 * * * * ~/program_2.sh # Every hour at :01 minute
1 * 3 * * ~/program_3.sh # Every day at 3:01am
```
Since crontab doesn't support resolutions greater than 1 minute, a workaround
with `sleep` can be used instead. `program_1.sh` above effectively runs every
30s

View file

@ -0,0 +1,19 @@
# Extract subtitles with ffmpeg
```
ffmpeg -i Movie.mkv -map 0:s:0 subs.srt
```
Extract subtitles from the mkv file. This one extracts the 0th subtitle track.
To extract the first, use `-map 0:s:1`
```
ffmpeg -ss 10 -t 10 Movie.mkv audio.mp3
```
Another curious thing is [ffmpeg's treatment of arguments](ffmpeg relative). All arguments that
come before a file are applied to that file only. The remainder of the command
is relative to those inital args. This means seeking forward 10s then cutting
10s will actually cut out the 10-20s interval
[ffmpeg relative]: https://stackoverflow.com/questions/46508055/using-ffmpeg-to-cut-audio-from-to-position

52
notes/shell/fifo.md Normal file
View file

@ -0,0 +1,52 @@
# Shell pipes and fifo
Most bash "blocks" accept a redirection parameter at the end of their
declaration. This can replace where the output and errors are going
```bash
fn () {
echo "error" >&3
} 3>&2 2>file
# Prints "error" to the standard error. The real stderr is stored in ./file
```
- Functions, as above
- Sub-shells: `(echo "one"; echo "two") > file`
- Loops: `while (1); do echo "loop"; done > file`
Remember that redirection syntax looks like `[fd][< | >][&fd | file_path]`,
where `fd` is the index in the process' file descriptors. This works for `<` as
well. `|&` is identical to using `2>&1 |`
The order of IO redirection matters. Redirection will go to wherever the
redirected destination currently goes. Redeclaring a redirection doesn't work
```
┌3 writes to stdout
│ ┌stdout writes to stderr
│ │ ┌stderr writes to where 3 writes, so stdout
│ │ │
echo "one" 3>&1 1>&2 2>&3
```
To do this for the entire shell or script, use `exec`
```bash
exec 4>&1 # Holds onto reference to stdout
exec 1>/dev/null # Silences stdout and loses track of it
exec 1>&4 4>&1 # Restore stdout through reference in 4 and close 4
# Everything back to normal
```
`mkfifo` creates a named pipe, which can be easier to interact with between
scripts. Make sure it's being held open at use
```bash
mkfifo fifo
cat fifo >ofif & # Holds open fifo pipe and copies anything in there to ofif
exec 3>fifo # fd 3 reffers to pipe fifo
echo "double" >&3 # Writes to fifo. >fifo would close the pipe right after
exec 3>&- # Manually close the open pipe
```
The example above works similar to `tee` in logging everything in the pipe

View file

@ -0,0 +1,26 @@
# Using fzf correctly
```
^r Pull command out of bash history
^t Complete file names relative to cwd
```
Standard shortcuts
```bash
mv **<TAB>
mv ./**<TAB>
```
When tabbing after `**`, fzf will complete the path. This works with other
destinations like `~/Downloads/**<TAB>`
Fzf also automatically completes most common commands, like `ssh`, `kill`, and
`unset`. Note that most of these still require `**`, they just complete what's
expected instead of file paths
You can set up additional completions in a bash config file
```bash
_fzf_setup_completion path mpv
```

206
notes/shell/git_notes.md Normal file
View file

@ -0,0 +1,206 @@
## Quick start
Git is an indispensable tool for code development, though in reality you'll only
use a few commands on a day to day basis. This section provides a quick overview
of those commands
```
$ git fetch
$ git status -s
$ git diff file_1
$ git add some_dir
$ git commit -m "Changed some directory"
$ git switch -c new_branch
$ git restore file_2
$ git commit -a
$ git log --graph --all --oneline --decorate | less
$ git push
```
The above represent ~90% of git commands you'll use. For some of these, like the
`git log` command, you should setup aliases
#### Manual pages
$ man gittutorial
$ man giteveryday
Some useful manual pages for referencing non-specifics
$ man git-rebase
$ git help rebase
$ tldr git rebase
For information on a single command, add a hyphen to separate out the
subcommand. If using `tldr` type the command as you normally would
#### Referencing commits
While most git commands default to `HEAD` without a commit passed, they often
accept other commits to operate on. Some commands also need another commit to
operate, like `git merge`
$ git show HEAD # References the current HEAD
$ git show HEAD^ # References one commit above the HEAD
$ git show HEAD^^ # Two commits above HEAD
$ git show HEAD~4 # 4 commits above HEAD
$ git show a22a398 # Commit starting with SHA1 a22a398
$ git show v0.2.0 # Commit tagged with v0.2.0
$ git show master # Tip of the master branch
$ git show origin/dev # Tip of the local copy of the origin's dev branch
Various examples of referencing commits. These can be mixed together for more
complicated referencing, though that's not too common
$ git show HEAD~4.. # All commits from 4 commits before to HEAD
$ git show v2.0..HEAD^ # Commits from tag v2.0 to one before HEAD
Some commands accept ranges of references. As expected, if one end of the range
is missing, it'll use a default upper/lower bound
$ git merge origin/master^
Merges one before the tip of the local copy of the origin's, possibly outdated,
master branch to the current branch. Very useful when working offline
## Project setup
#### New projects
$ git init
Create a new git repository in the current directory with a master branch
$ git remote add origin git@github.com:Aizuko/configs.git
$ git remote add origin ssh://git@github.com:22/Aizuko/configs.git
Sets up a remote origin on GitHub. This example uses ssh to connect, though
often http will also be supported. The second example specifies port 22
$ git push --set-upstream origin master
Pushes the master branch to the remote origin
#### Using a previous project
$ git clone ssh://git@github.com/Aizuko/configs.git
$ git clone https://github.com/Aizuko/configs.git
Clone a git repository from a remote. Everything will automatically be setup
$ git clone -b dev --single-branch --depth=1 ssh://git@github.com:22/Aizuko/configs.git
Clone the tip of the dev branch. Useful for saving storage, if you only need the
latest commit
.git/config
[remote "origin"]
- fetch = +refs/heads/dev:refs/remotes/origin/dev
+ fetch = +refs/heads/*:refs/remotes/origin/*
Sets git to synchronize all branches from origin, instead of just `dev`
$ git remote -v
List the remotes for this repository. Often useful if you want to change the
connection protocol
$ git remote set-url origin git@github.com:Aizuko/configs.git
Changes a remote. You'll rarely use this outside of changing protocols
$ git clone --depth=1 git://github.com/Aizuko/configs.git
Quick way to clone a Github repository without needing to login
$ git remote add upstream git@github.com:22/Aizuko/configs.git
Sets up another remote to track. Particularly important with forked branches
## Branches
Branches are a way to organize workflow into separate goals. This allows commits
for a feature that is still in development. Git recommends making a lot of cheap
branches and deleting them once merged
$ git branch -a
Lists all the branches on the local system
#### Git checkout changes
`git checkout` was one of the most common commands to run in git, since it
handled way too much. Starting in git 2.23 the command has been split into two
new commands. `switch` deals with branches while `restore` resets files
$ git restore file.txt
$ git checkout file.txt
Restore a file to how it was in the `HEAD's` commit
$ git restore --source HEAD^ file.txt
$ git checkout HEAD^ file.txt
Restore the file to match the commit one before the `HEAD`
$ git switch master
$ git checkout master
Switch to the `master` branch
$ git switch -c dev
$ git checkout -b dev
Create a new branch called `dev`
#### Removing branches
Once a branch's goal has been achieved and merged, there's no use in keeping it
around. Having a bunch of old branches is simply confusing
$ git branch --merged
Shows which branches have been merged. Many of these are often safe to delete
$ git branch -d merged_branch
Deletes a branch locally. Only deletes branches that have been fully merged into
an upstream, so often the remote. There's no fear in losing commits this way
$ git branch -D deadend_branch
$ git branch -f -d deadend_branch
Force deletes a local branch, regardless of whether it's been merged. You can,
and likely will, lose commits this way. This should only be used for local
experimental branches that quickly hit a dead end in development
$ git push origin --delete merged_branch
Deletes the branch on the remote repository as well
#### Tagging
Tags can be added to make referencing certain commits easier. Tags can often be
used instead of the rather complicated SHA1 to reference commits
$ git tag -a v0.1.0 a22a398
$ git tag -a v0.1.0 a22a398 -m "First version"
Creates an annotated tag for the commit `a22a398`. The tag will be automatically
signed
$ git tag -a -f v0.2.0 a22a398 -m "Add compact statusline"
Overwrite previous tag for a commit with a new tag. This isn't a problem for
tags that are only local to the system. Do not attempt for remote tags
$ git push origin v0.1.0
$ git push origin --tags v0.1.0 v0.2.0
Push up locally created tags to the remote. Tags need to be explicitly pushed.
Note that undoing tag pushes is really hard and shouldn't be done
## Ignoring files
In general there are 2 types of files you won't want to track with git: build
artifacts and files specific to your computer. Stopping git from tracking these
is done through git ignore pattern files
./.gitignore
Sits in the root of a git repository as a local ignore file. This will be
committed to the repository, so other users will ignore the same files
./.git/info/exclude
Acts like a `.gitignore` file specific to your system's repository. It will not
be committed. Useful for random files you have lying around
~/.gitignore_global
A `gitignore` that applies to every repository for the user. It will not be
committed to any particular repository, so it's more similar to a git exclude
file. It doesn't need any particular name, just source it in `~/.gitconfig`:
```
[core]
excludesfile = ~/.gitignore_global
```
`.gitignore` files use pattern matching similar to regex
target
target/**/*
Ignores anything in and including the `./target` directory
target/notes_[0-9].md
target/notes_?.md
Doesn't track any note files from 0-9, though will track anything higher, such
as `target/notes_12.md`. A `?` matches any one character, in this case also
matching `target/notes_a.md`
!target/*_notes_*/lec_*.md
Track any lecture file in any notes directory in `target`. This can match paths
like `target/cmput_notes_1/lec_2.md` and `target/japan_notes_12/lec_passive.md`
$ git rm --cached file.txt
In shell, removes a currently tracked file from tracking. This won't remove the
file from your system. Useful when you start ignoring a previously tracked file
[//]: # ex: set ft=markdown:tw=80:

View file

@ -0,0 +1,32 @@
# JQ, stream json parser
`jq` is a minimal json parser that's pretty useful in shell scripts. It can
quickly filter json outputs for reading something. Most languages, for example
js, have much faster json-parsers built-in, so it's better to use those when
possible
Json output usually comes in one of two forms, either a single json object, or
an array of jsons. To extract jsons we can use
```bash
yabai -m query --windows --window | jq '.' # Already a single json
yabai -m query --windows | jq '.[]' # Iterates through array
```
`jq` takes in a filter on the right side, after a pipe-like separator. The
output will just be the that value for single fields
```bash
yabai -m query --windows | jq '.[] | .id' # Id of every window
yabai -m query --windows | jq '.[] | .id, .app' # ID and name
yabai -m query --windows | jq '.[] | .frame.x' # x field in frame field
```
Your output can be either raw values, json objects, or arrays:
```bash
yabai -m query --windows | jq '.[] | .id' # Raw id
yabai -m query --windows | jq '.[] | { id: .id }' # Id objects
yabai -m query --windows | jq '.[] | [{ id: .id }]' # Id objects in individual arrays
yabai -m query --windows | jq '[.[] | { id: .id }]' # Id objects in one array
```

134
notes/shell/ssh_notes.md Normal file
View file

@ -0,0 +1,134 @@
# SSH
OpenSSH (ssh) is a secure protocol for connecting to computers/servers remotely.
Its uses are infinite, from connecting to clouds to making your laptop a desktop
### Basics
$ ssh -p 10022 emiliko@192.168.0.12
$ ssh -p 10022 emiliko@localhost
Connects to user `emiliko` on host address `localhost` via port `10022`. Port
`22` is the default for ssh
$ ssh emiliko@68.185.68.169
To connect over WAN, there're some additional setup on the server-side:
1. Set your IPv4 address manually. This usually requires setting manual DNS
servers. `1.1.1.1` and `1.0.0.1` are a good choice
2. Set up port forwarding for port 22 on the router to your manual local IPv4
3. Find your router's public IP address and use that as the host address
$ dig +short myip.opendns.com @resolver1.opendns.com
$ host myip.opendns.com resolver1.opendns.com
$ curl --silent https://ifconfig.me/ip
Finds your network's public IP address. This'll the server's be the host address
### Setting up ssh and ssh keys
# pacman -S openssh
Update or install ssh. It's often packaged as `openssh` and installs `ssh`
# systemctl enable sshd
Starts up the ssh daemon. The system should now be able to accept ssh
connections. On macOS, use Preferences -> Sharing -> Remote Login
$ ssh-keygen -t ed25519
$ ssh-keygen -t ed25519 -f ~/.ssh/arch_qemu_ed25519 -C "For arch qemu"
Generate a `ed25519` key pair. Interactively or through flags, this will add a
comment at the end of the public key and save it in the designated file
$ ssh-copy-id -i ~/.ssh/key_file.pub emiliko@localhost
$ cat ~/.ssh/key_file.pub | ssh emiliko@localhost "mkdir -p ~/.ssh && cat >>
~/.ssh/authorized_keys"
Copy an ssh key to the host. Either one will give you the power of ssh keys
$ ssh-keygen -pf ~/.ssh/key_file
Change the passphrase on the key
### Using ssh keys
$ ssh -i ~/.ssh/identify_file emiliko@localhost
Login to user using the identity file. This points to your private key. If the
file is secured by a passphrase, you'll need to retype it every time
$ eval $(ssh-agent) && ssh-add ~/.ssh/key_file.pub
Start the ssh agent and add a key file to it. This uses the path of the public
key file. The agent prevents the need to retype the passphrase on this terminal
$ ssh -A emiliko@localhost
Forwards the ssh agent to the destination system. Only useful if you plan to ssh
from that system
$ scp -P 10022 ~/file emiliko@localhost:~/dir/
Copies file between systems. `cp` except across systems. This uses the same
login methods, key or password, as `ssh`. Port option must be capitalized
$ scp ~/file alias:~/dir/
Copies file between systems, using `alias` from `~/.ssh/config` as the
destination system. This will automatically specify a user, identity key, etc...
$ ssh -L 2222:localhost:3333 emiliko@192.168.0.12
Creates an ssh tunnel connecting localhost:3333 on the host server to port 2222
on the client. Useful for webpages and IDE notebooks
### SSH keys with git
After setting up ssh keys in both GitHub and your computer, you'll need to
change repositories to use ssh instead of the http protocol
$ git remote -v
Echos a list of remote sources for the current repository. If the URLs start
with `http`, ssh protocol is not being used to connect to the remote sources
$ git remote add origin git@github.com:Aizuko/configs.git
$ git remote set-url origin ssh://git@github.com:22/Aizuko/configs.git
Use ssh protocol when connecting to remote origin. `add` is for new projects
which don't have an origin yet. `set-url` is for existing projects using http
### Mounting remote filesystems with SSHFS
SSH can mount a remote file system as if it's a laggy disk connected to your
system. This can be a nice way to locally view and edit remote files
Disclaimer: These commands have only been tested on MacOS using macFUSE
$ mount
Lists all the current mount points
$ mkdir ~/mnt
$ sshfs emiliko@192.168.0.12:/Users/emiliko ~/mnt
$ sshfs emi:/Users/emiliko ~/mnt
Mounts the Emiliko's home directory to `~/mnt`. Do not try `emi:~/` as bash
tilde will expand relative to the host. Specify the remote path from the root
$ umount emiliko@192.168.0.12:/Users/emiliko
$ umount !sshfs:1
Unmount the remote filesystem. Remember to type out the full remote path
$ sshfs -o cache=no emi:/home/emiliko ~/mnt
$ umount !sshfs:3
Disable caching to reconnect on every command. Prevents false directory listings
$ pgrep -lf sshfs
$ ps aux | grep -i sshfs
$ kill -9 10364
# umount -f ~/mnt
Forcefully unmount the filesystem
#### SSH Forwarding
$ ssh -p10011 -NL 7000:localhost:8080 emiliko@localhost &
$ ssh -NL 7000:localhost:8080 emi &
Opens an ssh tunnel between `7000` on the client and `localhost:8080` on the
server. Best used with `&`, as in line 2, to avoid obstructing the current pane
#### SSH config
~/.ssh/config
Host paraarch
User emiliko
Hostname 192.168.0.12
Port 22
IdentityFile ~/.ssh/parallels_arch_ed25519
IdentitiesOnly=yes
Adds a new host `paraarch` to the ssh config. `paraarch` can be used instead of
the host name and it will automatically specify these flags. `IdentitiesOnly`
resolves some issues relating to multiple failed connection attempts
~/.ssh/config
Host github.com
Hostname github.com
IdentityFile ~/.ssh/github_key_ed25519
When pulling from remote origin `git@github.com`, this key will be used
[//]: # ex: set ft=markdown:tw=80:

View file

@ -0,0 +1,5 @@
# SSH port forwarding
ssh -p10011 -NL 7000:localhost:8080 emiliko@localhost &
Opens an ssh tunnel without obstructing the current terminal. Syntax for the
tunnel looks like:
<client_port>:<url_from_host:host_port>

406
notes/shell/unix_bash.md Normal file
View file

@ -0,0 +1,406 @@
# Bash
###### Process priority
Since the processor must decide priority, it uses a scale from -20 through 20 to
rank what has priority, with -20 being the highest priority. By default,
processes launched by the user start with a niceness of 0
# nice --10 ./start_qemu.sh
# nice -n -10 ./start_qemu.sh
Starts the process, in this case `start_qemu.sh`, with a given niceness level,
in this case `-10`. The `-n` option increments from the base value, usually 0
# renice -2 1244
# renice -n -2 1244
Changes the niceness of a running process via process id, in this case 1244.
`-n` increments niceness from the current value, in this case by `-2`
$ ps -fl -C 1244
Check the niceness of process with id 1244
###### Job Control in Bash
You should not use jobs if you can help it! Especially when it comes to
input/output jobs are terribly unclear. Only use them for tasks that will never
ask for input or give an output. Use a multiplexer (`tmux`) instead
$ python -m SimpleHTTPServer 3000 &
Starts a process, in this case the python server, in the background. Just append
a `&` at the end
*Oh no, I didn't launch the process in the background*
^z
If you want to move suspend the current process, `^z` will suspend and stop it
$ bg %2
$ bg 2
$ %2 &
Continues the stopped job in the background. In this case, we use job identifier
1, which will start that specific job. You can omit the `%` with `bg`
$ fg %2
Bring a job back to the foreground. Uses identifiers much like `bg`
$ jobs -l
List all background jobs running. `-l` shows their process id
$ kill %2
Kills a background job, via identifiers. The `%` is not optional here!
$ wait %2
Waits for job identifier `2` to finish. Passing no arguments waits for all
background jobs
$ wlsunset -t 4000 -T 65000 -g 0.9 &
$ disown %1
Launches `wlsunset` in the background. Then, assuming it's job 1 under `jobs`,
disowns the process. The shell can now close with the process still running
$ wlsunset -t 4000 -T 65000 -g 0.9 & disown
Same as above. More compact
$ { wlsunset -t 4000 -T 65000 -g 0.9 & } &
$ ( wlsunset -t 4000 -T 65000 -g 0.9 & ) &
Same as above, background and disowns the subshell. `{}` execute the subshell in
the current shell's context, while `()` start a fresh shell. `{}` are also used
in brace expansion, so they need to be delimited by spaces
###### Vim editing for Bash
$ set -o vi
Makes bash use vi key binds. Note, this uses `vi` not `vim` bindings. Generally
this isn't recommended, even for complete vim users
$ export EDITOR='vim'
Bash will run the specified command when looking for an editor
<C-x><C-r>
Open current shell line in editor. Really powerful for long lines
See the (Ex section)[#Batch-editing-with-ex] for batch editing with vim
in `ex` mode
###### Stop yourself from deleting files
$ chmod a-w safe_directory
Prevents writing to the directory. Writing, in the sense of editing files is
still controlled by file permissions, you just can't remove or make new ones
# chown other_user safe_directory; chmod 755 safe_directory
Makes another user own the directory. All others uses cannot make/remove files.
Same as above, if ownership is given to root, though a bit more explicit
# touch safe_directory/file
# rm safe_directory/file
You can still create and delete files in this directory with root
###### Reusing commands
See HISTORY EXPANSION in `man bash` for more information
$ sudo !!
$ sudo !-1
Recalls the last command and runs it as root. Notice the `-1` can be any number
to recall older commands
$ !man
Rerun the last command starting with the string `man`
$ !?diff?:p
Print the last command that contained the string `diff`
$ mv !:2 ../!:2
Substitutes `!:2` with the second argument of the previous command. The command
itself is `!:0`, so it's the second argument. Here it moves a directory up
$ mv !^ !^'_name'
$ mv !$ !$'_name'
`$` and `^` are aliases for the first and last arguments. Here it changes a file
or directory name by adding `_name` at the end
$ vim -p !touch:*
$ vim -p !touch:2-4
$ vim -p !:2*
Expands argument ranges from the last `touch` command. `*`, `1-*` and `1*` are
synonymous. If no string is specified, like `!:*`, the last command is used
$ vim -o !touch:1*
Open a new window for every argument in the most recent command starting with
`touch`
$ ^touch^vim -o^
$ !!:s/touch/vim -o
$ !!:&
Replay the last command replacing the first instance of `touch` with `vim -o`.
The third line replaces `&` with the last substitution
$ vim -o !touch:*:gs/html/md
Recall all the arguments of the last `touch` command. Replace all instances of
`html` with `md` then pass those to `vim -o`
$ cat !!:$:s/machine/human
Substitute in the last argument from the previous command with `human`
<C-r>
<C-s>
Search backward or forward for input string. Use multiple times to scroll
awk '{a[NR] = $0} END { for (i = NR; i > 0; i--) print a[i] }' # rev lines
<C-r># rev lines
Replays the tagged command. Use trailing comments to act as a tag
diff ~/Downloads/{before,after}.txt
Checks if `before.txt` and `after.txt` are different. Braces are duplicated
$ !if:gs/$c/$a
Replace all the variables $c with $a in the previous command starting with if
So the general structure of recall is
```
!<cmd-identifier>[:<arg-range>][:<operator>]
```
###### Automated interactive input
$ yes | rm -ir /deep_dir
Bypasses interactive y/N prompt given by the `rm` command for every thing in that
directory. `yes` prints an infinite number of 'y\n' to any program
$ printf 'y\nn\ny\n' | rm -ir /small_dir
Will remove the first and third file automatically, then ask you for further
input
$ rm -ir /deep_dir < pre_made_input.txt
Enters the file contexts to the interactive prompt. Line breaks are like '\n'.
Very helpful if you're using this order of input over and over
###### Bash scripting
Bash is an awful scripting language in every sense except portability. Always
install and use `shellcheck` after writing a script
bash_script.sh
#!/bin/bash
#!/usr/bin/env bash
#!/usr/bin/env -S awk -f ${SOMEFILE}
Use shebang at the top to declare an interpreter. Using `env` is considered more
portable, though the `-S` option is required for anything longer than one word
$ echo ${myvar:-not here}
$ echo ${myvar:-"not here"}
Expands to `$myvar` if it's set, otherwise expands to string "not here"
$ for i in $(seq 0 9); do python -c "print(ord('$1'))" & done
Asynchronously print the ASCII codes for range `[0, 9]`
###### Other Bash uses
$ compgen -c git
See the possible completion for the given word. This is what tab uses
$ time bash -c "make && ./a.out; rm ./a.out"
Times multiple separate bash commands
## Ed for terminal file editing
Ed is the original text editor for Unix systems, which still is useful for batch
editing scripts. Ranges are very similar to vim's
$ ed -p '> :' file1
Open `file1` with ed. Useful for writing a script
:n Print the current line enumerated
:100 Moves to line 100 and prints it
:ka Set a mark `a`
:'a Move to mark `a`
:i Open line above current line in insert mode. Like vim's `o`
:a Open line below current line in insert mode. Like vim's `O`
. Exit insert mode. Should be the only character on the line
Various basic commands. Most commands accept ranges, like vim's. Unlike vim, all
commands operate on entire lines at once
:g/Style/p\
a\
Style line is above ^^^^\
.\
n
For all lines matching the regex, run the command sequence. `\` separate lines
#### Batch editing with ex
Ex is vim's equivalent of `ed` and `ex` is symlinked as `vim -e` on many
systems. It's equivalent to vim's command line, similar to `ed`, though many
commands are different
$ ex file
$ vim -Nes file
Roughly equivalent ways of entering ex-mode. `Q` also works from within vim
:g/re/p Globally exectute a command on lines with /re/
:v/re/p Inverse of :g. Executes on all lines without /re/
:3,6co$ Copy lines [3,6] to the end of the document
:3m6 Move line 3 to line 6
:z=3 Pretty print lines in [-2,+2]
Some infrequently used vim commands are very important in ex-mode
:g/re/z3
Prints all the lines and line numbers that contain regex `re`
:g/bash/exe "normal! cfish\<esc>" | undo | nu
Changes every line with "bash" to "fish", undoes that, then prints the line
:g/string/nu | g/num/nu
Does NOT print all the lines with `string` or `num`. This prints all the lines
with `string` then reprints them if they also have `num`. `:g` only uses a new
line to delimit its commands from the next set!
Batch editing style (in bash):
1. Here-string: For only one command, here-strings are a quick and easy choice
$ for f in $(find ~/); do vim -Nes <<<"g/re/p"; done
Prints all lines with `re` in the home directory. Be careful chaining with `:g`
2. Here-ansi-c-string: Allows including c-style escape sequences
$ for f in $(find ~/); do vim -Nes <<< $'g/re/nu\n3'; done
Prints all lines with `re` then moves to line 3. Often can be avoided with `|`
3. Here-documents: Probably the best choice for quick batch edits
$ for file in $(fd -at type subs_)
do
vim -Nes $file <<'DOC'
g/^Stl/exe "norm! cStyle: new\<CR>\<esc>"
$ | a
# ex: ff=unix:
.
wq
DOC
done
Changes The style lines and appends a modeline to files found by `fd`
$ for file in ~/.bash*; do vim -Nes $file <<EOF
a
# ex: set syntax=bash:ff=unix:
.
wq
EOF
done
Adds a mode line to all bash dot files in the home directory
4. Sourced documents: Better for recurring batch edits
$ fd -a subs_ -x ex < change_font
$ fd -a subs_ -x vim -Nes < change_font
Changes font for all subtitle files. Similar to `vim -S $file`
#### Best practices
Use `-t file` in `fd`, otherwise `ex` may stop when it hits a directory
Recent version of `fd` seems to consume here-documents and strings. To avoid
this, use the bash `for` loop syntax as below:
$ for file in $(fd -at file .); do vim -Ne $f <<<$'nu'; done
Or with here-documents
$ for file in $(fd -at file .); do vim -Ne $f <<doc
nu
doc
done
#### Batch editing manually
fd -t file . -X awk '$0 ~ / ex:/ { print FILENAME }' | xargs -o vim
Open all files containing ` ex:` in vim as separate buffers
## Awk the programming language
AWK is an old, though surprisingly useable stream-editing language. It's a POSIX
compliant tool to bundle `grep`, `sed`, `printf`, `cut`, `xargs`, and more all
into one scripting language. Most its use comes in bash scripts or one-liners to
quickly extract information from a text stream. The man pages are really good!
Much of the standard control flow is the same as C. Variables don't need to be
initialized before use, ex: `i+=1`. Many functions will perform on `$0` if no
argument is given
#!/usr/bin/env -S awk -f
#!/usr/bin/env -S awk -F: -f
Use the string option on `env` to be able to specify the necessary `-f` option
substr(str, start_pos, chars_cut) // Cut out part of a string
length([str]) // Length of str, or $0 if no argument is given
index(str, search_str) // Find starting index of match in str
match(str, /reg/) // Return index. Set RSTART and RLENGTH
split(str, array, fs) // Split str into array elements on FieldSeperator
sub(/reg/, new_str, str) // Subs new_str for first /reg/ match in str
sub("match", new_str, str) // Subs new_str for first string "match" in str
gsub(/reg/, new_str, str) // Above just global
The core awk functions with odd argument order
printf, sprintf, system, tolower, toupper, exp, log...
Core awk functions without odd argument order
### Built in variables
NR Current line's number. Literally "number of reads". Starts at 1
NF Number of fields in this line. `$NR` expands to the last field's value
RSTART Field number of last `match()`
RLENGTH How many characters long the last `match()` was
$0 The entire line of text
$1 Where `1` is the `1th` field in the line
### Regular expression
Regular expressions are supported. They're a separate type from strings. Unlike
most modern regex interpreters, escape sequences such as `\s` and `\d` aren't
supported. Instead use POSIX compliant versions `[:space:]` and `[:digit:]`
Inverting a regex is done by defining a `!` in front. For example
$0 !~ /hello/
$0 ~ !/hello/
$0 ~ /[^(hello)]/
If you want to store a regex in a variable for later use, DO NOT store an actual
regex type. Store the regex as a string instead, effectively replacing the
encapsulating `/` with `"`
my_regex = "hello[:space:]+you"
$0 ~ my_regex
Notably, using a regex instead of a string in this situation results in odd
silent errors that mostly work. These can be hard to debug, so watch out
### Recipes
$ cat file.txt | awk 'tolower($0) ~ /word/ { print $0 }'
$ cat file.txt | awk 'tolower($0) ~ /word/'
$ cat file.txt | grep -i 'word'
Searches through given piped text for 'word' in any casing
$ cat file.txt | awk -F ',' '
{ commas += NF - 1 }
END { print "Commas counted:", commas }'
Counts the number of commas in a file.
$ awk -F '\t' '{ print $0 }' demo.txt
$ awk -F '\t' demo.txt
Uses tabs are a files separator between "lines"
$ current_window_id=$(chrome-cli list windows | awk -F ' ' \
'NR == 1 { gsub(/[\[\]]/, "", $1); print $1 }')
Parses the window id from `[999] Some Title` to `999`
$ ls -la | awk 'match($NF, /[0-9]+/) { print substr($NF, RSTART, RLENGTH) }' >
coffees.nh
Checks if the last argument is a string of consecutive numbers. Notice how `$NF`
uses that `NF` is the last number to index the last field like `$3`
### Advanced examples
END {
arr["hello"] = 2; arr["other"]++; arr["some"] += 10;
printf "Hello: %d, Other: %d, Some: %d, None: %d\n",
arr["hello"], arr["other"], arr["some"], arr["none"];
}
>>> Output: Hello: 2, Other: 1, Some: 10, None: 0
Arrays can be indexed by strings! This allows for counting words or lines
$ awk '!($0 in uniq) { uniq[$0]; print }' duplicates.txt > uniques.txt
Removes duplicate lines. This uses the relational operator `(expr, expr... arr)`
to check if an element with the string's index has been initialized in the array
$ awk '!unique[$0]++' duplicates.txt > uniques.txt
Removes duplicate lines. This exploits awk's automatic initialization of
variables with falsey values, 0 here, then turns that index truthy with `++`
<!-- ex: set ft=markdown tw=80: -->

View file

@ -0,0 +1,8 @@
# Unix file times
Unix files store 3 time stamps: Modified, Accessed, Changed. These can be seen
with `ls -l`. The `stat` command can list these times as well, particularly with
something like `--format='%y'`
`touch` can change times directly. To use the times of another file, provide it
via the `-r` option, then constrain the times you want to change. For example
the `-m` flag will only copy over the modified time

32
notes/vim/tee.md Normal file
View file

@ -0,0 +1,32 @@
# Tee command
Duplicate piped output between a file and the stdout
```bash
sudo echo "something" > root_file
```
This won't work since output redirection is always done with user privileges.
Instead we use:
```bash
echo "something" | sudo tee root_file
echo "something" | sudo tee root_file &>/dev/null
```
Now the redirection will be executed with root privileges. Stdout can be
silenced to get the same effect as before. Tee can also copy output to multiple
files, or act like `>>` with `-a`
```bash
echo "something" | tee file1 | tee file2 > file3
```
It's very useful in vim, when you forget to use root privileges when editing a
root-only file:
```bash
:w ! sudo tee %
```
Note that neovim doesn't support interactive sessions through external commands
yet, so this only works in vim

View file

@ -0,0 +1,46 @@
# Vifm: Moving files
There are a few ways to move files in vifm, all of which hinge on using a
selection paired with some sort of command
### Selections
These selections and filters get cleared once you change directories
1. Not selecting anything implicitly selects anything under your cursor
2. `za` toggles dotfile visibility
3. `t` adds a single file to the selection from the directory
4. `V` visual mode selects files in a range
5. `=` quick filter that is case-sensitive
These filters are permanent, in that they're retained between directory
switches and apply to all directories
1. `zf` adds the current selection to the permanent filter
2. `:filter <regex>` hides all matching files in all directories
3. `:filter! <regex>` inverse of above filter, only shows these files
These are then controlled with
- `zO` Unset the permanent filter
- `zR` Stash the permanent filter
- `zM` Pop the stashed permanent filters
These are best paired with visual mode to quickly select a bunch of files
### Moving files
A simple `:m` will move all selected files to the location in the other pane.
Using `:sync %d` can set the opposing pane to the current one
Alternatively you can yank into a register, say `"ay`, then move all files in
the register to your current location with `:put a`
Also, don't forget there are other tools that can be better for the job. For
example batch renaming should be done through `mmv`
```
:!mmv './*_EP*.srt' './Documents/subtitles/kaguya_S1_#1.srt'
```
Bash for-loops paired with `fd` or `rg -l` can be used for fine-tuning too

View file

@ -0,0 +1,17 @@
# Vim backtick expansion
```
:h backtick-expansion
```
Essentially allows command substitution with shell or vim commands. Requires a
lot of escaping special symbols though
```bash
:e `mktemp`
:e `=tempname()`
```
Edit a new temporary file. Very useful in gui contexts when you just quickly
need to jot something down. The equal sign in the second line expands a vim
function instead of calling a shell

53
notes/vim/vim_macros.md Normal file
View file

@ -0,0 +1,53 @@
# Vim Power Macros
### Recording
When recording macros, best practice is to start with a `0` motion and try to
use absolute motions to the line like `A` not `w`
Macros are a register, so they can be edited the same way as one. In fact `@` is
just a shortcut for `:normal <paste-register-here>`. They can be viewed with
`:reg`
Modifying macros:
- `"lp` paste register `l`
- `<C-v><C-k>` literally inserts `<C-k>` as a key motion. Useful for pseudo-esc
Saving macros:
- `"lyy` copy line into register `l`
- `:'<,'>y l` copy selected line into register `l`
- `{Visual}"ly` copy selection into register `l`. Doesn't have `<C-j>` at the end
On the line:
- `<C-r>l` pastes the `l` register in insert mode
- `:let @l = "<rec>"` sets the `l` register as `<rec>`
- `:let @L = "<rec>"` appends `<rec>` to register `l`
- `"i\<esc>"` in a string escapes to literal key strokes, like `<C-v>` inserts
Escaping keystrokes, from the last example, only works with double quoted
strings. You can check in `:reg` to see the literal expansion
### Replaying macros
The older convention for batch macros was adding `j` at the end of the macro,
and using absolute motions:
- `4@l` replay the macro 4 times
A newer solution is to execute registers over command line through `:normal`.
Macros executed this way always starts in the left-most column, so prepend `0`
to your macro for consistency
Command style:
- `:norm[al][!] @l` can be used to replay macros. Keep the `!` to not use maps
- `:'<,'>norm! @l` replays the macro over every select line
- `:g/re/norm! @l` replays the macro over lines with a matching regex
Oddly, while `:norm! @l` doesn't see maps for `@l`, it will see mapping in the
register internally. So
```
:nnoremap <C-k> <esc>
:let @l = "Ihello\<C-k>"
:norm! @l
```
will still read `<C-k>` as `<esc>` when executing

View file

@ -0,0 +1,28 @@
# Executing special keys
Vim's `:exe[cute]` will read special keys when they're escaped in double quotes:
```vim
exe "normal! i\<C-v>u049c\<C-v>u03b1\<C-v>u03c4\<C-v>u212f!\<ESC>"
" Writes Ҝατℯ
```
You can use this to quickly script difficult macros, like the one above
```
:exe "normal! i\<C-v>u049c\<C-v>u03b1\<C-v>u03c4\<C-v>u212f!\<ESC>"<CR>
```
# Effective Unicode in vim
```
Demo unicodes: │┌┴─┐
```
Use `ga` in vim to display encoding information about the character under the
cursor. We'll use the hex value. In insert mode use `<C-v>u` followed by the hex
number to type in Unicode literally. The above can be written with
```
:normal! i<C-v>u2502<C-v>u250c<C-v>u2500<C-v>u2510<ESC>
```