diff options
Diffstat (limited to 'src/tools')
-rw-r--r-- | src/tools/README.md | 0 | ||||
-rw-r--r-- | src/tools/awk.md | 126 | ||||
-rw-r--r-- | src/tools/bash.md | 169 | ||||
-rw-r--r-- | src/tools/emacs.md | 86 | ||||
-rw-r--r-- | src/tools/fish.md | 185 | ||||
-rw-r--r-- | src/tools/gdb.md | 162 | ||||
-rw-r--r-- | src/tools/git.md | 130 | ||||
-rw-r--r-- | src/tools/radare2.md | 27 | ||||
-rw-r--r-- | src/tools/tmux.md | 110 | ||||
-rw-r--r-- | src/tools/zsh.md | 125 |
10 files changed, 1120 insertions, 0 deletions
diff --git a/src/tools/README.md b/src/tools/README.md new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/tools/README.md diff --git a/src/tools/awk.md b/src/tools/awk.md new file mode 100644 index 0000000..38b0cb1 --- /dev/null +++ b/src/tools/awk.md @@ -0,0 +1,126 @@ +# awk(1) + +```markdown +awk [opt] program [input] + -F <sepstr> field separator string (can be regex) + program awk program + input file or stdin if not file given +``` + +## Input processing + +Input is processed in two stages: +1. Splitting input into a sequence of `records`. + By default split at `newline` character, but can be changed via the + builtin `RS` variable. +2. Splitting a `record` into `fields`. By default strings without `whitespace`, + but can be changed via the builtin variable `FS` or command line option + `-F`. + +Fields are accessed as follows: +- `$0` whole `record` +- `$1` field one +- `$2` field two +- ... + +## Program + +An `awk` program is composed of pairs of the form: +```markdown +pattern { action } +``` +The program is run against each `record` in the input stream. If a `pattern` +matches a `record` the corresponding `action` is executed and can access the +`fields`. + +```markdown +INPUT + | + v +record ----> ∀ pattern matched + | | + v v +fields ----> run associated action +``` + +Any valid awk `expr` can be a `pattern`. + +### Special pattern + +awk provides two special patterns, `BEGIN` and `END`, which can be used +multiple times. Actions with those patterns are **executed exactly once**. +- `BEGIN` actions are run before processing the first record +- `END` actions are run after processing the last record + +### Special variables + +- `RS` _record separator_: first char is the record separator, by default + <newline> +- `FS` _field separator_: regex to split records into fields, by default + <space> +- `NR` _number record_: number of current record + +### Special statements & functions + +- `printf "fmt", args...` + + Print format string, args are comma separated. + - `%s` string + - `%d` decimal + - `%x` hex + - `%f` float + + Width can be specified as `%Ns`, this reserves `N` chars for a string. + For floats one can use `%N.Mf`, `N` is the total number including `.` and + `M`. + +- `strftime("fmt")` + + Print time stamp formatted by `fmt`. + - `%Y` full year (eg 2020) + - `%m` month (01-12) + - `%d` day (01-31) + - `%F` alias for `%Y-%m-%d` + - `%H` hour (00-23) + - `%M` minute (00-59) + - `%S` second (00-59) + - `%T` alias for `%H:%M:%S` + + +## Examples + +### Filter records +```bash +awk 'NR%2 == 0 { print $0 }' <file> +``` +The pattern `NR%2 == 0` matches every second record and the action `{ print $0 }` +prints the whole record. + +### Capture in variables +```bash +# /proc/<pid>/status +# Name: cat +# ... +# VmRSS: 516 kB +# ... + +for f in /proc/*/status; do + cat $f | awk ' + /^VmRSS/ { rss = $2/1024 } + /^Name/ { name = $2 } + END { printf "%16s %6d MB\n", name, rss }'; +done | sort -k2 -n +``` +We capture values from `VmRSS` and `Name` into variables and print them at the +`END` once processing all records is done. + +### Run shell command and capture output +```bash +cat /proc/1/status | awk ' + /^Pid/ { + "ps --no-header -o user " $2 | getline user; + print user + }' +``` +We build a `ps` command line and capture the first line of the processes output +in the `user` variable and then print it. diff --git a/src/tools/bash.md b/src/tools/bash.md new file mode 100644 index 0000000..a4df7da --- /dev/null +++ b/src/tools/bash.md @@ -0,0 +1,169 @@ +# bash(1) + +## Expansion + +### Generator + +```bash +# generate sequence from n to m +{n..m} +# generate sequence from n to m step by s +{n..m..s} + +# expand cartesian product +{a,b}{c,d} +``` + +### Parameter +```bash +# default param +bar=${foo:-some_val} # if $foo set, then bar=$foo else bar=some_val + +# check param set +bar=${foo:?msg} # if $foo set, then bar=$foo else exit and print msg + +# indirect +FOO=foo +BAR=FOO +bar=${!BAR} # deref value of BAR -> bar=$FOO + +# prefix +${foo#prefix} # remove prefix when expanding $foo +# suffix +${foo%suffix} # remove suffix when expanding $foo + +# substitute +${foo/pattern/string} # replace pattern with string when expanding foo +# pattern starts with +# '/' replace all occurences of pattern +# '#' pattern match at beginning +# '%' pattern match at end +``` + +> Note: `prefix`/`suffix`/`pattern` are expanded as [pathnames](#pathname). + +### Pathname + +```bash +* match any string +? match any single char +\\ match backslash +[abc] match any char of 'a' 'b' 'c' +[a-z] match any char between 'a' - 'z' +[^ab] negate, match all not 'a' 'b' +[:class:] match any char in class, available: + alnum,alpha,ascii,blank,cntrl,digit,graph,lower, + print,punct,space,upper,word,xdigit +``` + +Wit `extglob` shell option enabled it is possible to have more powerful +patterns. In the following `pattern-list` is one ore more patterns separated +by `|` char. + +```bash +?(pattern-list) matches zero or one occurrence of the given patterns +*(pattern-list) matches zero or more occurrences of the given patterns ++(pattern-list) matches one or more occurrences of the given patterns +@(pattern-list) matches one of the given patterns +!(pattern-list) matches anything except one of the given patterns +``` +> Note: `shopt -s extglob`/`shopt -u extglob` to enable/disable `extglob` +> option. + +## I/O redirection + +> Note: The trick with bash I/O redirection is to interpret from left-to-right. + +```bash +# stdout & stderr to file +command >file 2>&1 +# equivalent +command &>file + +# stderr to stdout & stdout to file +command 2>&1 >file +``` + +### Explanation + +```bash +j>&i +``` +Duplicate `fd i` to `fd j`, making `j` a copy of `i`. See [dup2(2)][dup2]. + +Example: +```bash +command 2>&1 >file +``` +1. duplicate `fd 1` to `fd 2`, effectively redirecting `stderr` to `stdout` +2. redirect `stdout` to `file` + +## Completion + +The `complete` builtin is used to interact with the completion system. +```bash +complete # print currently installed completion handler +complete -F <func> <cmd> # install <func> as completion handler for <cmd> +complete -r <cmd> # uninstall completion handler for <cmd> +``` + +Variables available in completion functions: +```bash +# in +$1 # <cmd> +$2 # current word +$3 # privous word + +COMP_WORDS # array with current command line words +COMP_CWORD # index into COMP_WORDS with current cursor position + +# out +COMPREPLY # array with possible completions +``` + +The `compgen` builtin is used to generate possible matches by comparing `word` +against words generated by `option`. +```bash +compgen [option] [word] + +# usefule options: +# -W <list> specify list of possible completions +# -d generate list with dirs +# -f generate list with files +# -u generate list with users +# -e generate list with exported variables + +# compare "f" against words "foo" "foobar" "bar" and generate matches +compgen -W "foo foobar bar" "f" + +# compare "hom" against file/dir names and generate matches +compgen -d -f "hom" +``` + +### Example +Skeleton to copy/paste for writing simple completions. + +Assume a program `foo` with the following interface: +```bash +foo -c green|red|blue -s low|high -f <file> -h +``` + +The completion handler could be implemented as follows: +```bash +function _foo() { + local curr=$2 + local prev=$3 + + local opts="-c -s -f -h" + case $prev in + -c) COMPREPLY=( $(compgen -W "green red blue" -- $curr) );; + -s) COMPREPLY=( $(compgen -W "low high" -- $curr) );; + -f) COMPREPLY=( $(compgen -f -- $curr) );; + *) COMPREPLY=( $(compgen -W "$opts" -- $curr) );; + esac +} + +complete -F _foo foo +``` + +[dup2]: http://man7.org/linux/man-pages/man2/dup.2.html diff --git a/src/tools/emacs.md b/src/tools/emacs.md new file mode 100644 index 0000000..b288fb1 --- /dev/null +++ b/src/tools/emacs.md @@ -0,0 +1,86 @@ +# emacs(1) + +## help +```markdown + C-h ? list available help modes + C-h f describe function + C-h v describe variable + C-h c <KEY> print command bound to <KEY> + C-h k <KEY> describe command bound to <KEY> + C-h b list buffer local key-bindings + <kseq> C-h list possible key-bindings with <kseq> + eg C-x C-h -> list key-bindings beginning with C-x +``` + +## package manager +```markdown + package-refresh-contents refresh package list + package-list-packages list available/installed packages +``` + +## window +```markdown + C-x 0 kill focused window + C-x 1 kill all other windows + C-x 2 split horizontal + C-x 3 split vertical +``` + +## yank/paste +```markdown + C-<SPACE> set start mark to select text + M-w copy selected text + C-w kill selected text + C-y paste selected text + M-y cycle through kill-ring +``` + +## block/rect +```markdown + C-x <SPC> activate rectangle-mark-mode + M-x string-rectangle <RET> insert text in marked rect +``` + +## mass edit +```makrdown + C-x h mark whole buffer (mark-whole-buffer) + M-x delete-matching-line <RET> delete lines matching regex + M-x % search & replace region (query-replace) + C-M-x % search & replace regex (query-replace-regexp) +``` + +## grep +```markdown + M-x find-grep <RET> run find-grep result in *grep* buffer + n/p navigate next/previous match in *grep* buffer +``` + +## lisp mode +```markdown + M-x lisp-interaction-mode activate lisp mode + C-M-x evaluate top expr under cursor + C-x C-e eval-last-sexp + C-u C-x C-e eval-last-sexp and prints result in current buffer +``` + +## narrow +```markdown + C-x n n show only focused region (narrow) + C-x n w show whole buffer (wide) +``` + +## org +```markdown + M-up/M-down re-arrange items in same hierarchy + M-left/M-right change item hierarchy + C-RET create new item below current + C-S-RET create new TODO item below current + S-left/S-right cycle TODO states +``` + +### org source +```markdown + <s TAB generate a source block + C-c ' edit source block (in lang specific buffer) + C-c C-c eval source block +``` diff --git a/src/tools/fish.md b/src/tools/fish.md new file mode 100644 index 0000000..2cc763e --- /dev/null +++ b/src/tools/fish.md @@ -0,0 +1,185 @@ +# fish(1) + +## Quick Info +Fish initialization file `~/.config/fish/config.fish` + +Switch between different key bindings: +- `fish_default_key_bindings` to use default key bindings +- `fish_vi_key_bindings` to use vi key bindings + +## Variables +Available scopes +- `local` variable local to a block +- `global` variable global to shell instance +- `universal` variable universal to all shell instances + preserved across + shell restart + +### Set/Unset Variables +```text +set <name> [<values>] + -l local scope + -g global scope + -U universal scope + -e erase variable + -S show verbose info + -x export to ENV + -u unexport from ENV +``` + +### Lists +In `fish` all variables are lists (start with index `1`, but lists can't +contain lists. +```text +set foo a b c d + +echo $foo[1] # a +echo $foo[-1] # d +echo $foo[2..3] # b c +echo $foo[1 3] # a c +``` + +`$` can be seen as dereference operator. +```text +set foo a; set a 1337 +echo $$foo # outputs 1337 +``` + +Cartesian product. +```text +echo file.{h,cc} +# file.h file.cc + +echo {a,b}{1,2} +# a1 b1 b2 +``` + +### Special Variables (Lists) +```text +$status # exit code of last command +$pipestatus # list of exit codes of pipe chain + +$CMD_DURATION # runtime of last command in ms +``` + +#### `*PATH` +Lists ending with `PATH` are automatically split at `:` when used and joined +with `:` when exported to the environment. +```text +set -x BLA_PATH a:b:c:d +echo $BLA_PATH # a b c d +env | grep BLA_PATH # BLA_PATH=a:b:c:d +``` + +## Command Handling +```text +# sub-commands are not run in quotes +echo "ls output: "(ls) +``` + +### I/O redirection +```text +# 'noclobber', fail if 'log' already exists +echo foo >? log +``` + +## Control Flow +### `if` / `else` +```text +if grep foo bar + # do sth +else if grep foobar bar + # do sth else +else + # do sth else +end +``` + +### `switch` +```text +switch (echo foo) +case 'foo*' + # do start with foo +case bar dudel + # do bar and dudel +case '*' + # do else +end +``` + +### `while` Loop +```text +while true + echo foo +end +``` + +### `for` Loop +```text +for f in (ls) + echo $f +end +``` + +## Functions +Function arguments are passed via `$argv` list. +```text +function fn_foo + echo $argv +end +``` +### Autoloading +When running a command fish attempts to autoload a function. The shell looks +for `<cmd>.fish` in the locations defined by `$fish_function_path` and loads +the function lazily if found. + +This is the preferred way over monolithically defining all functions in a +startup script. + +### Helper +```text +functions # list al functions +functions foo # describe function 'foo' +functions -e foo # erase function 'foo' + +funced foo # edit function 'foo' + # '-e vim' to edit in vim +``` + +## Prompt +The prompt is defined by the output of the `fish_prompt` function. +```text +function fish_prompt + set -l cmd_ret + echo "> "(pwd) $cmd_ret" " +end +``` +> Use `set_color` to manipulate terminal colors. + + +## Useful Builtins +```text +# history +history search <str> # search history for <str> +history merge # merge histories from fish sessions + +# list +count $var # count elements in list + +# string +string split SEP STRING +``` + +## Keymaps +```text + Shift-Tab ........... tab-completion with search + Alt-Up / Alt-Down ... search history with token under the cursor + Alt-l ............... list content of dir under cursor + Alt-p ............... append '2>&1 | less;' to current cmdline +``` + +## Debug +```text + status print-stack-trace .. prints function stacktrace (can be used in scripts) + breakpoint ................ halt script execution and gives shell (C-d | exit + to continue) +``` diff --git a/src/tools/gdb.md b/src/tools/gdb.md new file mode 100644 index 0000000..7a43ca1 --- /dev/null +++ b/src/tools/gdb.md @@ -0,0 +1,162 @@ +# gdb(1) + +# CLI + +```markdown + gdb [opts] [prg [-c coredump | -p pid]] + gdb [opts] --args prg <prg-args> + opts: + -p <pid> attach to pid + -c <coredump> use <coredump> + -x <file> execute script <file> before prompt + -ex <cmd> execute command <cmd> before prompt + --tty <tty> set I/O tty for debugee +``` + +# Interactive usage + +```markdown + tty <tty> + Set <tty> as tty for debugee. + Make sure nobody reads from target tty, easiest is to spawn a shell + and run following in target tty: + > while true; do sleep 1024; done + + set follow-fork-mode <child | parent> + Specify which process to follow when debuggee makes a fork(2) + syscall. + + sharedlibrary [<regex>] + Load symbols of shared libs loaded by debugee. Optionally use <regex> + to filter libs for symbol loading. + + break [-qualified] <sym> thread <tnum> + Set a breakpoint only for a specific thread. + -qualified: Tred <sym> as fully qualified symbol (quiet handy to set + breakpoints on C symbols in C++ contexts) + + rbreak <regex> + Set breakpoints matching <regex>, where matching internally is done + on: .*<regex>.* + + command [<bp_list>] + Define commands to run after breakpoint hit. If <bp_list> is not + specified attach command to last created breakpoint. Command block + terminated with 'end' token. + + <bp_list>: Space separates list, eg 'command 2 5-8' to run command + for breakpoints: 2,5,6,7,8. + + info functions [<regex>] + List functions matching <regex>. List all functions if no <regex> + provided. + + info variables [<regex>] + List variables matching <regex>. List all variables if no <regex> + provided. + + info handle [<signal>] + Print how to handle <signal>. If no <signal> specified print for all + signals. + + handle <signal> <action> + Configure how gdb handles <signal> sent to debugee. + <action>: + stop/nostop Catch signal in gdb and break. + print/noprint Print message when gdb catches signal. + pass/nopass Pass signal down to debugee. + + catch signal <signal> + Create a catchpoint for <signal>. +``` + +# User commands (macros) + +Gdb allows to create & document user commands as follows: +```markdown + define <cmd> + # cmds + end + + document <cmd> + # docu + end +``` + +To get all user commands or documentations one can use: +```markdown + help user-defined + help <cmd> +``` + +# Hooks + +Gdb allows to create two types of command `hooks` +- `hook-` will be run before `<cmd>` +- `hookpost-` will be run after `<cmd>` +```markdown + define hook-<cmd> + # cmds + end + + define hookpost-<cmd> + # cmds + end +``` + +# Examples + +## Catch SIGSEGV and execute commands +This creates a `catchpoint` for the `SIGSEGV` signal and attached the `command` +to it. +```markdown + catch signal SIGSEGV + command + bt + c + end +``` + +## Run `backtrace` on thread 1 (batch mode) +```markdown + gdb --batch -ex 'thread 1' -ex 'bt' -p <pid> +``` + +## Script gdb for automating debugging sessions +To script gdb add commands into a file and pass it to gdb via `-x`. +For example create `run.gdb`: +```markdown + set pagination off + + break mmap + command + info reg rdi rsi rdx + bt + c + end + + #initial drop + c +``` +This script can be used as: +```markdown + gdb --batch -x ./run.gdb -p <pid> +``` + +# Know Bugs + +## Workaround `command + finish` bug +When using `finish` inside a `command` block, commands after `finish` are not +executed. To workaround that bug one can create a wrapper function which calls +`finish`. +```markdown + define handler + bt + finish + info reg rax + end + + command + handler + end +``` diff --git a/src/tools/git.md b/src/tools/git.md new file mode 100644 index 0000000..a4af0cf --- /dev/null +++ b/src/tools/git.md @@ -0,0 +1,130 @@ +# git(1) + +## staging +```markdown + git add -p [<file>] ............ partial staging (interactive) +``` + +## Remote +```markdown + git remote -v .................. list remotes verbose (with URLs) + git remote show [-n] <remote> .. list info for <remote> (like remote HEAD, + remote branches, tracking mapping) +``` + +## Branching +```markdown + git branch [-a] ................ list available branches; -a to include + remote branches + git branch -vv ................. list branch & annotate with head sha1 & + remote tracking branch + git branch <bname> ............. create branch with name <bname> + git checkout <bname> ........... switch to branch with name <bname> + git checkout --track <branch> .. start to locally track a remote branch + git push -u origin <rbname> .... push branch to origin (or other remote), and + setup <rbname> as tracking branch +``` + +## Resetting +```markdown + git reset [opt] <ref|commit> + opt: + --mixed .................... resets index, but not working tree + --hard ..................... matches the working tree and index to that + of the tree being switched to any changes to + tracked files in the working tree since + <commit> are lost + git reset HEAD <file> .......... remove file from staging + git reset --soft HEAD~1 ........ delete most recent commit but keep work + git reset --hard HEAD~1 ........ delete most recent commit and delete work +``` + +## Tags +```markdown + git tag -a <tname> -m "descr" ........ creates an annotated tag (full object + containing tagger, date, ...) + git tag -l ........................... list available tags + git checkout tag/<tname> ............. checkout specific tag + git checkout tag/<tname> -b <bname> .. checkout specific tag in a new branch +``` + +## Diff +```markdown + git diff HEAD:<fname> origin/HEAD:<fname> ... diff files for different refs + git diff -U$(wc -l <fname>) <fname> ......... shows complete file with diffs + instead of usual diff snippets +``` + +## Log +```markdown + git log --oneline .... shows log in single line per commit -> alias for + '--pretty=oneline --abbrev-commit' + git log --graph ...... text based graph of commit history + git log --decorate ... decorate log with REFs +``` + +## File history +```markdown + git log -p <file> ......... show commit history + diffs for <file> + git log --oneline <file> .. show commit history for <file> in compact format +``` + +## Patching +```markdown + git format-patch <opt> <since>/<revision range> + opt: + -N ................... use [PATCH] instead [PATCH n/m] in subject when + generating patch description (for patches spanning + multiple commits) + --start-number <n> ... start output file generation with <n> as start + number instead '1' + since spcifier: + -3 .................. e.g: create a patch from last three commits + <commit hash> ....... create patch with commits starting after <commit hash> + + git am <patch> ......... apply patch and create a commit for it + + git apply --stat <PATCH> ... see which files the patch would change + git apply --check <PATCH> .. see if the patch can be applied cleanly + git apply <PATCH> .......... apply the patch locally without creating a commit + + # eg: generate patches for each commit from initial commit on + git format-patch -N $(git rev-list --max-parents=0 HEAD) + + # generate single patch file from a certain commit/ref + git format-patch <COMMIT/REF> --stdout > my-patch.patch +``` + +## Submodules +```markdown + git submodule add <url> [<path>] .......... add new submodule to current project + git clone --recursive <url> ............... clone project and recursively all + submodules (same as using + 'git submodule update --init + --recursive' after clone) + git submodule update --init --recursive ... checkout submodules recursively + using the commit listed in the + super-project (in detached HEAD) + git submodule update --remote <submod> .... fetch & merge remote changes for + <submod>, this will pull + origin/HEAD or a branch specified + for the submodule + git diff --submodule ...................... show commits that are part of the + submodule diff +``` + +## Inspection +```markdown + git ls-tree [-r] <ref> .... show git tree for <ref>, -r to recursively ls sub-trees + git show <obj> ............ show <obj> + git cat-file -p <obj> ..... print content of <obj> +``` + +## Revision Specifier +```markdown + HEAD ........ last commit + HEAD~1 ...... last commit-1 + HEAD~N ...... last commit-N (linear backwards when in tree structure, check + difference between HEAD^ and HEAD~) + git rev-list --max-parents=0 HEAD ........... first commit +``` diff --git a/src/tools/radare2.md b/src/tools/radare2.md new file mode 100644 index 0000000..673c911 --- /dev/null +++ b/src/tools/radare2.md @@ -0,0 +1,27 @@ +# radare2(1) + +## print +```markdown + + pd <n> [@ <addr>] # print disassembly for <n> instructions + # with optional temporary seek to <addr> +``` + +## flags +```markdown + fs # list flag-spaces + fs <fs> # select flag-space <fs> + f # print flags of selected flag-space +``` + +## help +```markdown + ?*~<kw> # '?*' list all commands and '~' grep for <kw> + ?*~... # '..' less mode /'...' interactive search +``` + +## relocation +```markdown + > r2 -B <baddr> <exe> # open <exe> mapped to addr <baddr> + oob <addr> # reopen current file at <baddr> +``` diff --git a/src/tools/tmux.md b/src/tools/tmux.md new file mode 100644 index 0000000..04b1111 --- /dev/null +++ b/src/tools/tmux.md @@ -0,0 +1,110 @@ +# tmux(1) + +Terminology: +- `session` is a collection of pseudo terminals which can have multiple + `windows` +- `window` uses the entire screen and can be split into rectangular `panes` +- `pane` is a single pseudo terminal instance + +# Tmux cli +```markdown +# Session +tmux creates new session +tmux ls list running sessions +tmux kill-session -t <s> kill running session <s> +tmux attach -t <s> [-d] attach to session <s>, detach other clients [-d] +tmux detach -s <s> detach all clients from session <s> + +# Environment +tmux showenv -g show global tmux environment variables +tmux setenv -g <var> <val> set variable in global tmux env + +# Misc +tmux source-file <file> source config <file> +tmux lscm list available tmux commnds +tmux show -g show global tmux options +tmux display <msg> display message in tmux status line +``` +## Scripting +```markdown +# Session +tmux list-sessions -F '#S' list running sessions, only IDs + +# Window +tmux list-windows -F '#I' -t <s> list window IDs for session <s> +tmux selectw -t <s>:<w> select window <w> in session <s> + +# Pane +tmux list-panes -F '#P' -t <s>:<w> list pane IDs for window <w> in session <s> +tmux selectp -t <s>:<w>.<p> select pane <p> in window <w> in session <s> + +# Run commands +tmux send -t <s>:<w>.<p> "ls" C-m send cmds/keys to pane +tmux run -t <p> <sh-cmd> run shell command <sh-cmd> in background and report output on pane -t <p> +``` + +For example cycle through all panes in all windows in all sessions: +```bash +# bash +for s in $(tmux list-sessions -F '#S'); do + for w in $(tmux list-windows -F '#I' -t $s); do + for p in $(tmux list-panes -F '#P' -t $s:$w); do + echo $s:$w.$p + done + done +done +``` + +# Bindings + +```markdown +prefix d detach from current session +prefix c create new window +prefix w open window list +prefix $ rename session +prefix , rename window +prefix . move current window +``` + +Following bindings are specific to my [`tmux.conf`](https://github.com/johannst/dotfiles/blob/master/tmux.conf): +```markdown +C-s prefix + +# Panes +prefix s horizontal split +prefix v vertical split +prefix f toggle maximize/minimize current pane + +# Movement +prefix Tab toggle between window + +prefix h move to pane left +prefix j move to pane down +prefix k move to pane up +prefix l move to pane right + +# Resize +prefix C-h resize pane left +prefix C-j resize pane down +prefix C-k resize pane up +prefix C-l resize pane right + +# Copy/Paste +prefix C-v enter copy mode +prefix C-p paste yanked text +prefix C-b open copy-buffer list + +# In Copy Mode +v enable visual mode +y yank selected text +``` + +# Command mode + +To enter command mode `prefix :`. + +Some useful commands are: +```markdown +setw synchronize-panes on/off enables/disables synchronized input to all panes +list-keys -t vi-copy list keymaps for vi-copy mode +``` diff --git a/src/tools/zsh.md b/src/tools/zsh.md new file mode 100644 index 0000000..ae2a4bc --- /dev/null +++ b/src/tools/zsh.md @@ -0,0 +1,125 @@ +# zsh(1) + +## Keybindings + +Change input mode: +```zsh +bindkey -v change to vi keymap +bindkey -e change to emacs keymap +``` + +Define key-mappings: +```zsh +bindkey list mappings in current keymap +bindkey in-str cmd create mapping for `in-str` to `cmd` +bindkey -r in-str remove binding for `in-str` + +# C-v <key> dump <key> code, which can be used in `in-str` +# zle -l list all functions for keybindings +# man zshzle(1) STANDARD WIDGETS: get description of functions +``` + +## Completion + +### Installation + +Completion functions are provided via files and need to be placed in a location +covered by `$fpath`. By convention the completion files are names as `_<CMD>`. + +A completion skeleton for the command `foo`, stored in `_foo` +```zsh +#compdef _foo foo + +function _foo() { + ... +} +``` + +Alternatively one can install a completion function explicitly by calling `compdef <FUNC> <CMD>`. + +### Completion Variables + +Following variables are available in Completion functions: +```zsh +$words # array with command line in words +$#words # number words +$CURRENT # index into $words for cursor position +$words[CURRENT-1] # previous word (relative to cursor position) +``` + +### Completion Functions +- `_describe` simple completion, just words + description +- `_arguments` sophisticated completion, allow to specify actions + +#### Completion with [`_describe`][zsh-comp-utils] +```zsh +_describe MSG COMP +``` +- `MSG` simple string with header message +- `COMP` array of completions where each entry is `"opt:description"` + +```zsh +function _foo() { + local -a opts + opts=('bla:desc for bla' 'blu:desc for blu') + _describe 'foo-msg' opts +} +compdef _foo foo + +foo <TAB><TAB> + -- foo-msg -- +bla -- desc for bla +blu -- desc for blu +``` + +#### Completion with [`_arguments`][zsh-comp-utils] +```zsh +_arguments SPEC [SPEC...] +``` +where `SPEC` can have one of the following forms: +- `OPT[DESC]:MSG:ACTION` +- `N:MSG:ACTION` + +Available actions +```zsh +(op1 op2) list possible matches +->VAL set $state=VAL and continue, `$state` can be checked later in switch case +FUNC call func to generate matches +{STR} evaluate `STR` to generate matches +``` + +### Example +Skeleton to copy/paste for writing simple completions. + +Assume a program `foo` with the following interface: +```zsh +foo -c green|red|blue -s low|high -f <file> -d <dir> -h +``` + +The completion handler could be implemented as follows in a file called `_foo`: +```zsh +#compdef _foo foo + +function _foo_color() { + local colors=() + colors+=('green:green color') + colors+=('red:red color') + colors+=('blue:blue color') + _describe "color" colors +} + +function _foo() { + _arguments \ + "-c[define color]:color:->s_color" \ + "-s[select sound]:color:(low high)" \ + "-f[select file]:file:_files" \ + "-d[select dir]:fir:_files -/" \ + "-h[help]" + + case $state in + s_color) _foo_color;; + esac +} +``` + +[zsh-comp-utils]: http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-Functions |