Compare commits

...

27 Commits

Author SHA1 Message Date
91bd01472b tag vim pages as TUI 2026-04-16 15:04:58 +02:00
5b13b2259c rework article command 2026-04-15 11:25:07 +02:00
906e56f34c typo 2026-04-15 08:45:08 +02:00
dd5f543db2 ignore output directories 2026-04-15 08:43:08 +02:00
f33009d480 write guide to ed 2026-04-13 07:58:59 +02:00
9d35d04990 fix links 2026-04-10 17:50:17 +02:00
c00c9aed16 begin command-snippets db
command.rec will be stored here, and generate articles.
2026-03-26 22:44:23 +01:00
5f4873fec5 Merge branch 'master' of ssh://soft.dmz.rs:2222/lk 2026-03-19 19:20:13 +01:00
44cbac7a98 refactor make article 2026-03-19 19:17:54 +01:00
cbebcb4fdc do not build database without request 2026-03-19 19:17:54 +01:00
974ac84cbc fix wireguard setup 2026-03-19 19:17:54 +01:00
4bc128cdec typo 2026-03-19 19:17:53 +01:00
cc8e051501 remove duplicate names 2026-03-19 19:17:53 +01:00
616ac6a2a8 typos 2026-03-19 19:17:53 +01:00
ce35cd1838 newsraft feeds change 2026-03-19 19:17:53 +01:00
70871b8944 fix yay install 2026-03-19 19:17:53 +01:00
995659730f automatic nethack 2026-03-19 19:17:53 +01:00
4136515526 add otp with pass 2026-03-19 19:17:53 +01:00
e58202c37e add mpd with pipewire 2026-03-19 19:17:53 +01:00
aee3437156 note searching void packages 2026-03-19 19:17:53 +01:00
c3d4109114 nginx logs with recfiles 2026-03-19 19:17:53 +01:00
7e7628a0e3 note clearing search highlights 2026-03-19 19:17:53 +01:00
5022a3de7d fix vim search 2026-03-19 19:17:53 +01:00
0479274245 vim linewrap 2026-03-19 19:17:53 +01:00
4a25476fd6 record terminal with script 2026-03-19 19:17:53 +01:00
cc7d907d6d ansible notes 2026-03-19 19:17:53 +01:00
a7c18c5ca8 [Networking] tor update 2026-03-07 02:01:04 +01:00
37 changed files with 769 additions and 112 deletions

View File

@@ -7,12 +7,12 @@ FZF != command -v sk || command -v fzy || command -v fzf || \
ifeq "$(FZF)" "/usr/bin/fzy"
FZF += -i
else
FZF += --print-query | cat
FZF += --print-query | tail -1
endif
spill_contents = sed -e '1,/---/d'
help: .git/info/exclude ## Print the help message
help: ## Print the help message
@awk 'BEGIN {FS = ":.*?## "} /^[0-9a-zA-Z._-]+:.*?## / {printf "\033[36m%s\033[0m : %s\n", $$1, $$2}' $(MAKEFILE_LIST) | \
sort | \
column -s ':' -t
@@ -32,8 +32,11 @@ $(foreach dir, $(categories), \
$(eval .dbs/$(dir).rec: $(wildcard $(dir)/*)) \
)
.dbs/:
%/:
mkdir $@
echo '*' > $@.gitignore
include cmd.mk
$(databases): .dbs/%.rec: %/ | .dbs/
$(info making $(@F))
@@ -73,18 +76,6 @@ default += .git/info/exclude
.PHONY: database
database: $(default) ## Make a recfiles database
.PHONY: article
article: ## Write an article
@path=$$(find $(categories) -type d | sort | uniq | $(FZF)) ;\
read -p "Title: " title ;\
filename="$$(echo "$$title" | tr '[:upper:]' '[:lower:]' | tr ' ' '_')" ;\
mkdir -p $$path ;\
printf '%s\n' '---' >> $$path/$$filename.md ;\
printf 'title: "%s"\n' "$$title" >> $$path/$$filename.md ;\
printf 'tags: [ "%s" ]\n' "$$path" | tr '[:upper:]' '[:lower:]' | sed 's#\/#", "#g' >> $$path/$$filename.md ;\
printf '%s\n\n' '---' >> $$path/$$filename.md ;\
$(EDITOR) +5 "$$path/$$filename.md"
.dbs/map.fmt:| .dbs/
printf '%s\n' '[ {{requires[0]}} ] --> [ {{title}} ] {border-style: dashed;}' > $@
printf '%s\n' '[ {{requires[1]}} ] --> [ {{title}} ] {border-style: dashed;}' >> $@
@@ -100,3 +91,24 @@ map: db.rec .dbs/map.fmt ## Show knowledge dependency map
.PHONY: clean
clean: ## Remove all generated files
$(RM) $(default)
.PHONY: article
article: **/ **/**/ ## Write a new article
category=$(shell echo $^ | tr ' ' '\n' | $(FZF) ) \
&& read -p "Article title? " name \
&& filename="$$(echo "$$name" \
| cut -d: -f1 \
| tr -cd '[:alpha:]' | tr '[A-Z ]' '[a-z_]' )" \
&& $(MAKE) -e TITLE="$$name" "$$category"/"$$filename.md"
%.md:
[ -d "$(@D)" ] || mkdir $(@D)
printf '%s\n' '---' >> $@
printf 'title: %s\n' '$(TITLE)' >> $@
tags="$$(echo $(@D) | sed 's#/$$#"# ; s#/#", "#g ; s#^#"#' )" \
&& printf 'tags [ %s ]\n' "$$tags" >> $@
printf '%s\n\n' '---' >> $@
$(EDITOR) +5 $@
git add $@
git commit -m"article: $(TITLE)"

View File

@@ -1,36 +0,0 @@
---
title: "column"
tags: [ "basics", "format", "json" ]
---
Put output into column.
```sh
du -h /etc/* | column
```
Reformat file with an explicit separator (`-s`):
```sh
column -ts: /etc/passwd
```
Give columns names (`-N`), so you can hide some (`-H`):
```sh
column -ts: -N User,PW,UID,GID,Description,Home,shell -H PW,GID /etc/passwd
```
Reorder with `-O` (unspecified items remain):
```sh
column -ts: -N User,PW,UID,GID,Description,Home,shell -H PW,GID -O User,Description,shell /etc/passwd
```
Output to json format with `-J`:
```sh
column -J -ts: -H PW,GID,shell -N User,PW,UID,GID,Description,Home,shell /etc/passwd
```

View File

@@ -5,6 +5,7 @@ tags: [ "fun" ]
- `asciiquarium`
- `cbonsai -lim "$(fortune)"`
- `printf 'w\na\n' | ssh -tt nethack@alt.org`
```sh
cow=$(cowsay -l | sort -R | head -1)

View File

@@ -30,6 +30,11 @@ Done
- If you have a command, Control + d will execute the command.
- If you have nothing, `exit`.
Clear Search Highlights
=======================
`<Esc>+u`
Input Run-Commands (`~/.inputrc`)
=================================

25
cmd.mk Normal file
View File

@@ -0,0 +1,25 @@
cmds != recsel command.rec -t command -G bin -U -CP bin
lists = $(patsubst %,lists/%.md, $(cmds))
default += $(lists)
get_title = printf 'title: "%s"\n' '${1}'
get_tags = recsel -t $(basename $<) $< -G bin \
-e 'bin = "$(1)"' -U -CP tag | \
sed 's/.*/"&",/g' | \
tr '\n' ' ' | \
sed 's/.*/tags: [ &]/'
list_commands = recsel -t $(basename $<) $< -e 'bin = "$(1)"' | \
recfmt -f lists.fmt
lists/%.md: command.rec | lists/
@printf '%s\n' '---' > $@
@$(call get_title,$(basename $(notdir $@))) >> $@
@$(call get_tags,$(basename $(notdir $@))) >> $@
@printf '\n%s\n' '---' >> $@
@$(call list_commands,$(basename $(notdir $@))) >> $@
.PHONY: cmd
cmd: $(lists) ## Big lists of commands

51
command.rec Normal file
View File

@@ -0,0 +1,51 @@
%rec: command
%doc: shell command examples
%type: aim line
%allowed: aim cmd bin tag
aim: Put output into column
cmd: du -h /etc/* | column
bin: column
tag: format
aim: Reformat file with an explicit separator (`-s`)
cmd: column -ts: /etc/passwd
bin: column
tag: format
aim: Give columns names (`-N`), so you can hide some (`-H`)
cmd: column -ts: -N User,PW,UID,GID,Description,Home,shell -H PW,GID /etc/passwd
bin: column
tag: format
aim: Reorder with `-O` (unspecified items remain)
cmd: column -ts: -N User,PW,UID,GID,Description,Home,shell -H PW,GID -O User,Description,shell /etc/passwd
bin: column
tag: format
aim: Output to json format with `-J`
cmd: column -J -ts: -H PW,GID,shell -N User,PW,UID,GID,Description,Home,shell /etc/passwd
bin: column
tag: format
tag: json
aim: Make a QR Code image:
cmd: qrencode 'https://play.google.com/store/apps/details?id=org.briarproject.briar.android' -o "$FILE".png
bin: qrencode
tag: qr
aim: Make a QR Coded message in the terminal:
cmd: qrencode -t ansi "Hello World"
bin: qrencode
tag: qr
aim: Read a QR Code image:
cmd: zbarimg $FILE
bin: qrencode
tag: qr
aim: Show wifi QR code (only with Network Manager):
cmd: nmcli device wifi show-password
bin: qrencode
tag: qr
tag: wifi

View File

@@ -129,7 +129,7 @@ Refreshing keys will tell you if some key you have contains a signature from som
gpg --refresh-keys
```
You can use the [crontab](../../basics/cron.md) to refresh keys, but this will mostly fail, since keyservers often don't hold the right data.
You can use the [crontab](../../system/cron.md) to refresh keys, but this will mostly fail, since keyservers often don't hold the right data.
# Export

View File

@@ -1,6 +1,6 @@
---
title: "Interactive String Substitution"
tags: [ "data", "vim", "substitution" ]
tags: [ "data", "vim", "substitution", "replace", "TUI" ]
---
Want to find and replace, but also confirm each instance?

View File

@@ -44,11 +44,24 @@ You can get an RSS feed from any YouTube video with this script:
```
#!/bin/sh
CHANNEL_ID="$(curl -s "$1" | tr ',' '\n' | grep -Po 'channelId":"\K[\w+-]+' | tail -1)"
FEED_URL="https://www.youtube.com/feeds/videos.xml?channel_id=$CHANNEL_ID"
CHANNEL_NAME="$(curl -s "$FEED_URL" | grep -m 1 -Po 'title\>\K[\w\s]+')"
set -e
printf '%s "%s"\n' "$FEED_URL" "$CHANNEL_NAME"
db=~/rec/feeds.rec
rec="${2:-$db}"
[ ! -z "$1" ] || {
echo "Give me a youtube URL"
exit 1
}
[ -w "$rec" ] || touch "$rec"
CHANNEL_ID="$(curl -s "$1" | tr ',' '\n' | grep -Po 'channelId":"\K[\w+-]+' | tail -1)"
URL="https://www.youtube.com/feeds/videos.xml?channel_id=$CHANNEL_ID"
Name="$(curl -s "$URL" | grep -m 1 -Po 'title\>\K[\w\s]+')"
recins --verbose -t Feed -f Name -v "${Name}" -f URL -v "${URL}" -f Category -v Videos -f Rating -v 3 -f Working -v yes "$rec"
```

View File

@@ -1,6 +1,6 @@
---
title: "pass"
tags: [ "data" ]
tags: [ "data", "credentials", "secrets" ]
requires: "GPG Basics"
---
@@ -28,7 +28,7 @@ To add a basic password, e.g. for `$WEBSITE`:
pass $WEBSITE
```
To insert a multiline password, e.g. with a login name:
To insert a multi-line password, e.g. with a login name:
```sh
pass add -m $WEBSITE

48
data/pass_otp.md Normal file
View File

@@ -0,0 +1,48 @@
---
title: "pass with otp"
tags: [ "data", "credentials", "secrets", "2fa", "otp" ]
requires: "pass"
---
Need a Microsoft or Google authenticator?
No you don't.
These usually come in the form of QR codes.
```qr code
                                 
    █▀▀▀▀▀█ ▀ ▀▀▀ ▀ ▄ █▀▀▀▀▀█    
    █ ███ █ ▄▄▀▄▄▀▄▄▀ █ ███ █    
    █ ▀▀▀ █ ██ ▀▄██▀▀ █ ▀▀▀ █    
    ▀▀▀▀▀▀▀ █ █▄▀ █ █ ▀▀▀▀▀▀▀    
    █▄▄ █▄▀▀██ ▄▄▀▀▄██▀▀██ ▄▀    
    ▄██▄▀█▀█ ▀▄▀ █▀▀▀█ ▀▀▀█▄     
    ▄ ▄▄█ ▀▀ ▄▄▀▀█▄█ ▀▀ ▄▀▀█▀    
      █ ▀ ▀▀█▀▀ ▄ ▄█▀▄▀██▀█▄     
    ▀▀▀ ▀ ▀ █▄▄▀▄▀▀▄█▀▀▀█▀▀      
    █▀▀▀▀▀█ ▀▄ █▀█▀ █ ▀ █▄▄      
    █ ███ █ ▀ ▄ ▀█▄ ████▀▀█▄█    
    █ ▀▀▀ █  ▄▀ ▄ ▄▄ ██▄▄█▄█     
    ▀▀▀▀▀▀▀ ▀ ▀▀ ▀▀▀ ▀▀   ▀▀▀    
                                 
                                 
```
Download the code, and get the information out:
```sh
zbarimg qr.png
otp="$(zbarimg qr.png | sed 's/QR-Code://')"
otp_name=site.org.otp
echo "${otp}" | pass otp add --echo "${otp_name}"
```
Show the OTP:
```sh
pass otp "${otp_name}"
```

View File

@@ -43,8 +43,8 @@ recset -f "$new_field" --delete $database
```
- [Extended example](recfiles/extended.md)
- [Playing with board games data](recfiles/Board_Games.md)
- [Playing with IP addresses](recfiles/IP_ASN.md)
- [Playing with board games data](recfiles/board_games.md)
- [Playing with IP addresses](recfiles/ip_asn.md)
- [Manage LaTeX Bibliographies](recfiles/bibliography.md)
- [Fixes](recfiles/recfixes.md)

View File

@@ -0,0 +1,65 @@
---
title: "nginx logs with recfiles"
tags: [ "data", "recfiles", "logs" ]
requires: [ "Recfiles", "nginx" ]
---
The standard `nginx` log format has such a lack of consistency or meaning that you might squint your face into a whirlpool making sense of them:
```nonsense
18.97.14.85 - - [16/Nov/2025:00:52:12 +0100] "GET /posts/learning_without_experts/content.html HTTP/1.1" 200 1704 "-" "CCBot/2.0 (https://commoncrawl.org/faq/)"
57.141.0.25 - - [16/Nov/2025:00:52:18 +0100] "GET /posts/hope_you_win/ HTTP/1.1" 200 61997 "-" "meta-externalagent/1.1 (+https://developers.facebook.com/docs/sharing/webmasters/crawler)"
201.17.157.249 - - [16/Nov/2025:00:52:19 +0100] "GET https://ttrpgs.com/post/wp/ HTTP/1.1" 200 45202 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
47.246.164.151 - - [16/Nov/2025:00:52:22 +0100] "GET https://ttrpgs.com/css/styles.dc38388a8f0b890e788bd3a99b7495d14e7d5ac4359ed3b49abeb778497863b284ad4cc7e496ef58c84139295f9bafed82f5a41345eda86bd2d429cccb7c2596.css HTTP/1.1" 200 27109 "https://ttrpgs.com/post/wp/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
47.246.164.154 - - [16/Nov/2025:00:52:22 +0100] "GET https://ttrpgs.com/fonts/Metropolis-MediumItalic.woff2 HTTP/1.1" 200 28100 "https://ttrpgs.com/css/styles.dc38388a8f0b890e788bd3a99b7495d14e7d5ac4359ed3b49abeb778497863b284ad4cc7e496ef58c84139295f9bafed82f5a41345eda86bd2d429cccb7c2596.css" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
47.246.164.135 - - [16/Nov/2025:00:52:22 +0100] "GET https://ttrpgs.com/fonts/Metropolis-Regular.woff2 HTTP/1.1" 200 24152 "https://ttrpgs.com/css/styles.dc38388a8f0b890e788bd3a99b7495d14e7d5ac4359ed3b49abeb778497863b284ad4cc7e496ef58c84139295f9bafed82f5a41345eda86bd2d429cccb7c2596.css" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
```
Someone created this logging format on purpose, to make sure nobody could parse it with a hundred `column`, `cut`, or `awk` pipes.
The problem lies in `/etc/nginx/nginx.conf`:
```conf
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
```
Despite a request of three strings, this format returns one string.
It can output to recfile format like this:
```conf
log_format main '\nIP: $remote_addr\n'
'User: $remote_user\n'
'Date: $time_local\n'
'Request: $request\n'
'Status: $status\n'
'Bytes: $body_bytes_sent\n'
'Referrer: $http_referer\n'
'Agent: $http_user_agent\n'
'XForward: $http_x_forwarded_for\n';
access_log /var/log/nginx/access.rec main;
```
Note the newline (`\n`) symbol, required to start a new entry on a new line.
1. `cp /etc/nginx.conf /etc/nginx.conf.bak`
1. Change `/etc/nginx.conf` to match the format above.
1. Check the file works with `nginx -t`.
1. Restart the `nginx` service.
1. Access that web page to make sure that at least one log exists.
1. Check the file with `recfix /var/log/nginx/access.rec`.
Once it works, you can add the usual recfile headers:
```sh
sed -i '1 i \ ' /var/log/nginx/access.rec
sed -i '1 i %rec: Weblog' /var/log/nginx/access.rec
sed -i '2 i %doc: nginx access logs' /var/log/nginx/access.rec
```

View File

@@ -36,7 +36,7 @@ git clone http://localhost:23232/${some_repo}.git
### `https` Setup
Put this file at `/etc/nginx/sites-enabled/$DOMAIN.tld`, then set up standard certificates with [nginx](../networking/website/nginx.md).
Put this file at `/etc/nginx/sites-enabled/$DOMAIN.tld`, then set up standard certificates with [nginx](../../networking/website/nginx.md).
(replace `${DOMAIN_NAME}` with your domain's name).

View File

@@ -129,7 +129,7 @@ vi /etc/locale.gen
locale-gen
```
Make your keyboard changes permenent with:
Make your keyboard changes permanent with:
```sh
vi /etc/vconsole.conf

View File

@@ -6,8 +6,9 @@ requirements: [ "pacman" ]
```sh
pacman --sync --noconfirm --needed base-devel gcc git
git clone https://aur.archlinux.org/yay.git /tmp/yay
makepkg -C !$ -si
git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si
```
The flags are mostly the same as in `pacman`.

View File

@@ -22,6 +22,12 @@ Search with regex:
xbps-query --regex -Rs 'cow(s)?\w'
```
Search for `genfstab`:
```sh
xlocate genfstab
```
List what's required for cowsay
```sh

6
lists.fmt Normal file
View File

@@ -0,0 +1,6 @@
{{aim}}
```{{shell}}
{{cmd}}
```

View File

@@ -5,9 +5,17 @@ tags: [ "networking" ]
# Get a Hostname
[onion hidden service guide](https://community.torproject.org/onion-services/setup/)
```sh
sudo vim /etc/tor/torrc
```
Uncomment the lines about `/var/lib/tor/hidden_services`, including port 22 (or whatever); restart tor, then go to that directory, and cat the hostname.
# SSH over tor
install package `torsocks`, and add it before `ssh` command, for easier use, add it to `.ssh/config`
`torsocks ssh user@{someonionhash}.onion`

View File

@@ -48,7 +48,7 @@ echo 'net.ipv4.ip_forward=1' > /etc/sysctl.d/wg.conf
```
```sh
systemctl enable --now wg-quiqck@wg0
systemctl enable --now wg-quick@wg0
```
```sh
@@ -67,7 +67,7 @@ Be root.
Install `wireguard-tools` on the client.
Copy the client private key and server public key to the server (or just fill in the variables).
Copy the client server public key to the server (or just fill in the variables).
```sh

83
sound/mpd_pipewire.md Normal file
View File

@@ -0,0 +1,83 @@
---
title: "mpd with pipewire"
tags: [ "sound", "pipewire" ]
requirements: [ "pipewire" ]
---
# Setup
## Configuration
This is a minimum configuration file for /etc/mpd.conf
> music_directory "/var/lib/mpd/music"
>
> playlist_directory "/var/lib/mpd/playlists"
>
> db_file "/var/lib/mpd/mpd.db"
>
>
> pid_file "/run/mpd/mpd.pid"
>
> state_file "/var/lib/mpd/mpdstate"
>
>
> user "mpd"
>
> audio_output {
> type "pulse"
> name "My Pulse Output"
> }
>
## Set Pulseaudio to Run System-Wide
```bash
sudo mkdir -p /etc/pipewire/pipewire-pulse.conf.d
cat > /etc/pipewire/pipewire-pulse.conf.d/pulse-server.conf << "EOF"
pulse.properties = {
server.address = [
"unix:native"
"tcp:4713" # IPv4 and IPv6 on all addresses
]
}
EOF
```
Give `mpd` access to pulse:
```sh
grep pulse /etc/group | cut -d: -f1
grep pulse /etc/group | cut -d: -f1 | while read g; do
sudo usermod -aG $g mpd
done
```
Working with mpd will be easier if you have access to its files, so maybe:
```sh
sudo usermod -aG mpd $USER
```
Remember to reboot.
# Troubleshooting
Check pulse is working.
```sh
ss | grep 4713
```
# Notifications (AUR)
Install `mpd-notification` and then start the service:
```sh
systemctl --user enable mpd-notification
```

12
sound/pipewire.md Normal file
View File

@@ -0,0 +1,12 @@
---
title: "pipewire"
tags: [ "sound" ]
---
Install `wireplumber` and `pipewire`, then add your user to any `pipewire` group.
```sh
sudo ln -s /usr/share/examples/pipewire/20-pipewire-pulse.conf /etc/pipewire/pipewire.conf.d/20-pipewire-pulse.conf
sudo ln -s /usr/share/examples/wireplumber/10-wireplumber.conf /etc/pipewire/pipewire.conf.d/10-wireplumber.conf
```

View File

@@ -14,12 +14,27 @@ Say 'hello' to yourself:
ansible --module-name=ping localhost
```
Ansible takes a lot of information about each machine during setup:
```sh
TMP=$(mktemp)
ansible --module-name=setup localhost | tee $TMP
less !$
```
If you have `jq`, you can pull out info:
```sh
sed -i 's/.*SUCC.*/{/' $TMP
jq '.ansible_facts.ansible_distribution' < $TMP
```
Upgrade through the package manager.
`packager=apt` (or `pacman` or `xbps`,...)
```sh
packager=apt
packager="$( jq -r '.ansible_facts.ansible_pkg_mgr' < $TMP )"
ansible --module-name=${packager} --args "upgrade=yes" localhost
```
@@ -87,4 +102,8 @@ ansible-inventory --list -y -i
ansible-vault view sec.yml --vault-pass-file pass.sh
```
community.general.say voice=en_GB msg="Testing 123"
Install `espeak', then make the computer say something:
```sh
ansible --module-name=say --args "msg='testing'" localhost
```

View File

@@ -178,6 +178,6 @@ In this case, the makefile can see that `backup` depends on the current backup f
# The Rest
- [File patterns](Makefiles/patterns.md)
- [Makefile graphs](Makefiles/graph-easy.md)
- [In-build help](Makefiles/help.md)
- [File patterns](makefiles/patterns.md)
- [Makefile graphs](makefiles/graph-easy.md)
- [In-build help](makefiles/help.md)

View File

@@ -3,7 +3,7 @@ title: "Makefile Patterns"
tags: [ "system", "make" ]
---
Using the [basic example](../Makefile.md), you can make a complete backup of all backup files.
Using the [basic example](../makefiles.md), you can make a complete backup of all backup files.
This file will depend upon everything inside the `$(storage_directory)`.
Unlike `bash`, you can't just say `storage_directory/*`: the pattern must be stated as a 'wildcard'.

View File

@@ -1,28 +0,0 @@
---
title: "QR Codes"
tags: [ "qrencode", "zbar" ]
---
Make a QR Code image:
```sh
qrencode 'https://play.google.com/store/apps/details?id=org.briarproject.briar.android' -o "$FILE".png
```
Make a QR Coded message in the terminal:
```sh
qrencode -t ansi "Hello World"
```
Read a QR Code image:
```sh
zbarimg $FILE
```
Show wifi QR code (only with Network Manager):
```sh
nmcli device wifi show-password
```

71
vision/record_terminal.md Normal file
View File

@@ -0,0 +1,71 @@
---
title: "Record a Terminal Session"
tags: [ "vision", "share" ]
---
Record a terminal command, then press 'Control + d' to exit.
```sh
script --timing=time.log stat.txt
ls -a
ls -al
stat ~/.bashrc
^D
```
Replay the session:
```sh
scriptreplay --timing=time.log stat.txt
```
Try a bare command, without any timing:
```sh
script -c 'top | lolcat' loltop
nl loltop
```
Has your terminal messed up?
Is the cursor hiding?
Reset it!
```sh
reset
```
If you can't see any keys, keep typing anyway: have faith in your terminal.
This `loltop` file will not play properly as it has no timings file.
But you can cheat the system and use your other timings file:
```sh
scriptreplay --timing=time.log loltop
```
This will mostly not work well, but it shows how the timing file works:
```text
0.033401 23
0.044513 8
0.000016 219
1.349324 114
0.179106 1
0.088790 1
0.072821 1
0.358337 2
0.000254 9
0.004720 52
0.000084 21
0.155462 671
```
I think it works like this?
| How long it took | to type *n* characters |
|:----------------:|:----------------------:|
| 0.033401 | 23 |
| 0.044513 | 8 |
| 0.000016 | 219 |
| 1.349324 | 114 |

260
writing/ed.md Normal file
View File

@@ -0,0 +1,260 @@
---
title: "Ed: The Standard Editor"
tags: [ "writing", "guide" ]
---
`ed` was designed for real terminals, i.e. a typewriter.
You would type a command to the computer, and it would type out any errors.
It would not waste paper, ink, and time by typing out `COMMAND RUN SUCCESSFULLY` after each command.
A silent machine meant a happy machine.
# Basic Usage
Open a file:
```sh
ed file.md
```
Insert a new line.
1. Press `i<Return>`
1. Type the line.
1. Finish your edit with single dot.
```ed
i
dear diary,
.
```
Print the current line:
```ed
p
```
Change the current line:
```ed
c
Dear diary,
.
```
Delete the current line:
```ed
d
```
Write the 'buffer' to disk:
```ed
w
```
Quit:
```ed
q
```
# Working with Lines
Open that file:
```ed
ed file.md
```
Add a line:
```ed
a
Fortune of the day:
.
```
Run `fortune`, and place the results inside the current buffer:
```ed
r!fortune
?
```
The `?` indicates an error. We can ask what the error was with the command
`h`:
```ed
r!fortune
?
h
Unexpected command suffix
```
The command `r` has something after it which makes no sense. It should have a
space after the `r`!
```ed
r !fortune
42
```
That last line means `ed` has 42 characters in its buffer.
Read the current line, and show the line number:
```ed
n
2 How many weeks are there in a light year?
```
This means we are on line 2.
Fill up the file with fortunes:
```ed
r !for x in 1 2 3 ; do echo --- && fortune ; done
```
Print out which line in the file we are currently on:
```ed
=
12
```
There are twelve lines. Go back up to line 3:
```ed
3
---
```
So line 3 just has our delimiter: `---`.
Whenever you hit enter, `ed` prints the current line then moves to the next
line.
```ed
I would have promised those terrorists a trip to Disneyland if it would have
gotten the hostages released. I thank God they were satisfied with the
missiles and we didn't have to go to that extreme.
```
Go back a few lines:
```ed
-3
```
Print out 'current line', using the dot:
```ed
.
```
Print current line with the number of that line:
```ed
.n
11 Possessions increase to fill the space available for their storage.
```
Print and number the next three lines:
```ed
.,+3n
9 You have no real enemies.
10 ------
11 Possessions increase to fill the space available for their storage.
```
Skip ahead four lines:
```ed
+4
?
h
Invalid address
```
This is an `invalid address` because there are no more lines, so `ed` cannot print them.
# All Commands
Meta Commands
-------------
| Aim | Command |
|:------------------------------------------------|:---------------:|
| Explain an error (`?`) | `h` |
| Show a prompt when `ed` can take a command. | `P` |
| Change the default filename to `rec.txt`. | `f rec.txt` |
| Save the file. | `w` |
| Append a line after line 8. | `8a` |
| Move three lines down. | `+3` |
| Move four lines back. | `-4` |
| Move to the last line. | `$` |
Create
------
| Aim | Command |
|:--------------------------------------------------------------------|:---------------:|
| Insert a line before line 5. | `5i` |
| Append a line after line 8. | `8a` |
| Read all of `~/.profile` into the current position. | `r ~/.profile` |
| Run `dir` and place the results into the current position. | `r !dir` |
| Copy lines 10 to 15 to line 23. | `10,15t23` |
Read
------
| Aim | Command |
|:--------------------------------------------------------|:--------------:|
| Print current line. | `.` or `p` |
| Read lines 1 to 10. | `1,10p` |
| Print and number lines 2 to 7. | 2,7n |
| Find the next line ending with `fi` | /fi$/n |
| Show the number of the next line starting with `if`. | `/^if/=` |
| Find the line which contains `HOME`. | `?HOME?` |
| Print the next five lines literally (showing tabs). | `.,+5l` |
| Print from here till the end of the file. | `.,$p` |
| Show all lines with `HOME` and show their numbers. | `g/HOME/n` |
Update
------
| Aim | Command |
|:------------------------------------------------|:------------------------:|
| On line 30, substitute `less` with `less -R` | `30s/less/less -R/` |
| Change each line starting `#` to `##` | `,s^# /## /g` |
| Move lines 50 to 55 to line 20. | `50,55m20` |
Delete
------
| Aim | Command |
|:------------------------------------------------|:-----------:|
| Delete line 4. | `4d` |
| Delete from here to four lines down. | `.,+4d |
| Delete all lines starting with `#`. | `g/^#/d` |

View File

@@ -1,6 +1,6 @@
---
title: "vim basics"
tags: [ "vim", "basic" ]
tags: [ "vim", "basic", "TUI" ]
---
## Instant nano replacement
@@ -20,6 +20,5 @@ Keybind to exit this mode is `Ctrl+q`
- [Learning Vim](vim/vi.md)
- [Navigation](vim/navigate.md)
- [Completion](vim/completion.md)
- [Search](vim/search.md)
- [Window Splits](vim/windows.md)
- [Use vim bindings in bash](vim/vim_in_bash.md)

View File

@@ -1,6 +1,6 @@
---
title: "vim completion"
tags: [ "vim", "completion" ]
tags: [ "vim", "completion", "TUI" ]
requires: [ "vim basics" ]
---

32
writing/vim/linewrap.md Normal file
View File

@@ -0,0 +1,32 @@
---
title: "vim linewrap"
tags: [ "vim", "format", "linewrap", "TUI" ]
requires: [ "vim basics" ]
---
Wrap lines in a file to 80 characters with `gqG`.
Take this markdown file:
```markdown
This is a looooooooooooooooooooooooong line, and reeeeeeeeeeeeeeding it can be a paaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiiiiiiiiiiiiin in the aaaaaaaaaaaaaaaaaaaaaaaarse.
```
Reformat the line to the proper text width by pressing `gqw`.
The output looks like this:
```markdown
This is a looooooooooooooooooooooooong line, and reeeeeeeeeeeeeeding it can be
a paaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiiiiiiiiiiiiin in the
aaaaaaaaaaaaaaaaaaaaaaaarse.
```
This works with chunks of text in visual mode.
Change what width the text should be:
```vim
:set textwidth=100
```

View File

@@ -1,6 +1,6 @@
---
title: "vim navigation"
tags: [ "vim", "navigation" ]
tags: [ "vim", "navigation", "TUI" ]
requires: [ "vim basics" ]
---

View File

@@ -1,6 +1,6 @@
---
title: "vim search"
tags: [ "vim", "search" ]
title: "find and replace"
tags: [ "vim", "search", "replace", "find", "TUI" ]
requires: [ "vim basics" ]
---
Search for the next and or previous occurrence of the word under your cursor with `*` and `#`.
@@ -9,7 +9,11 @@ Search and replace the first 'one' found with 'two':
`:%s/one/two/`
Same, but replace 'one' globally:
Run the last substitution globally:
`g&`
Same, but just replace 'one' globally:
`:%s/one/two/g`

View File

@@ -1,6 +1,6 @@
---
title: "How to Learn `vim`"
tags: [ "vim", "learning" ]
tags: [ "vim", "learning", "TUI" ]
requires: [ "vim basics" ]
---

View File

@@ -1,6 +1,6 @@
---
title: "vim in bash"
tags: [ "vim", "bash", "inputrc" ]
tags: [ "vim", "bash", "inputrc", "TUI" ]
requires: [ "vim basics" ]
---

View File

@@ -1,6 +1,6 @@
---
title: "vim windows"
tags: [ "vim" ]
tags: [ "vim", "TUI" ]
requires: [ "vim basics" ]
---

View File

@@ -1,6 +1,6 @@
---
title: "Vim Tricks"
tags: [ "vim" ]
tags: [ "vim", "TUI" ]
requiered: [ "ssh" ]
---