diff options
| -rw-r--r-- | aliases | 4 | ||||
| -rwxr-xr-x | bin/log_notifications.sh | 5 | ||||
| -rwxr-xr-x | bin/notify.sh | 23 | ||||
| -rwxr-xr-x | bin/sshot.sh | 31 | ||||
| -rw-r--r-- | dunstrc | 76 | ||||
| -rw-r--r-- | gitconfig | 44 | ||||
| -rw-r--r-- | i3config | 160 | ||||
| -rw-r--r-- | lib/colors.sh | 21 | ||||
| -rw-r--r-- | lib/functions.sh | 18 | ||||
| -rw-r--r-- | rtorrentrc | 118 | ||||
| -rwxr-xr-x | setup.sh | 290 | ||||
| -rw-r--r-- | tmux.conf | 129 | ||||
| -rw-r--r-- | tomorrow_night.vim | 350 | ||||
| -rw-r--r-- | user-dirs.dirs | 4 | ||||
| -rw-r--r-- | vimpwrc | 5 | ||||
| -rw-r--r-- | vimrc | 94 | ||||
| -rw-r--r-- | xinitrc | 19 | ||||
| -rw-r--r-- | zshrc | 35 |
18 files changed, 1426 insertions, 0 deletions
@@ -0,0 +1,4 @@ +alias gitrev='git rev-parse HEAD | GREP_COLORS="ms=34;1" grep $(git rev-parse --short HEAD)' +alias tmuxst='st -e tmux' +alias ls='ls --color' +alias pw='vim -u .vimpwrc' diff --git a/bin/log_notifications.sh b/bin/log_notifications.sh new file mode 100755 index 0000000..2b187db --- /dev/null +++ b/bin/log_notifications.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +echo "${@}" \ + | sed -r 's/IT Message from (\w+)\s*(.+) emblem-important CRITICAL/\1> \2/' \ + >> "/tmp/notifications.log" diff --git a/bin/notify.sh b/bin/notify.sh new file mode 100755 index 0000000..9271b67 --- /dev/null +++ b/bin/notify.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +set -o nounset +set -o errexit +set -o pipefail + +readonly PROGNAME="$(basename "${0}")"; +readonly PROGDIR="$(readlink -m "$(dirname "${0}")")"; +readonly ARGS="${@}"; + +function main() +{ + local username="${1}"; shift; + local message="${@}"; + local userid=$(id -u "${username}"); + sudo -u ${username} \ + DISPLAY=":0" \ + DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${userid}/bus" \ + notify-send -u critical -a IT "Message from tech" "${message}" +} + +main ${ARGS} +exit 0 diff --git a/bin/sshot.sh b/bin/sshot.sh new file mode 100755 index 0000000..426d323 --- /dev/null +++ b/bin/sshot.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +set -o nounset +set -o errexit +set -o pipefail + +readonly PRONAME="$(basename "${0}")"; +readonly PROGDIR="$(readlink -f "$(dirname "${0}")")"; +readonly ARGS="${@}"; + +call_scrot() +{ + local dst_dir="${1}"; shift; + scrot '%Y-%m-%d-%T_$wx$h_scrot.png' -e 'mv $f '"${dst_dir}" ${@} + notify-send "Screenshot saved to ${dst_dir}/$(ls -rt1 "${dst_dir}" | tail -1)" +} + +main() +{ + if [ ${#} -eq 0 ]; + then + >&2 echo "You must at least provide the path of the directory where " + >&2 echo "screenshots will be saved" + exit 1 + fi + + call_scrot ${@}; +} + +main ${ARGS} +exit 0 @@ -0,0 +1,76 @@ +# vim: set et fenc=utf-8 ft=vim sts=4 sw=4 ts=8 tw=80 : +# +# Author: microfracture / https://linuxious.com +# Updated: 2015-03-13 + + +[global] + alignment = left + allow_markup = yes + bounce_freq = 0 + browser = /usr/bin/firefox -new-tab + dmenu = /usr/bin/dmenu -p dunst: + follow = none + font = Terminus (TTF) 12 + format = "<b>%s</b>\n%b" + # geometry [{width}]x{height}][+/-{x}+/-{y}] + geometry = "0-10+10" + history_length = 20 + horizontal_padding = 8 + idle_threshold = 120 + ignore_newline = no + indicate_hidden = yes + line_height = 0 + monitor = 0 + padding = 8 + separator_color = frame + separator_height = 1 + show_age_threshold = 60 + show_indicators = yes + shrink = no + sort = yes + startup_notification = false + sticky_history = yes + transparency = 0 + word_wrap = yes + +[frame] + width = 1 + color = "6092BE" + +[shortcuts] + #close = mod4+x + #close_all = mod4+ctrl+x + history = mod4+agrave + context = ctrl+shift+period + +[urgency_low] + background = "#6092BE" + foreground = "#FFFFFF" + timeout = 10 + +[urgency_normal] + background = "#6092BE" + foreground = "#FFFFFF" + timeout = 20 + +[urgency_critical] + background = "#801515" + foreground = "#D46A6A" + timeout = 0 + +[log] + appname = "IT" + script = "~/.local/bin/log_notifications.sh" + +#[irc] +# appname = "weechat" +# format = "%s: %b" +# urgency = low +# background = "#83c83d" +# foreground = "#000000" +# +#[i3blocks] +# summary = "*" +# script = ~/.bin/notify +# diff --git a/gitconfig b/gitconfig new file mode 100644 index 0000000..6480c71 --- /dev/null +++ b/gitconfig @@ -0,0 +1,44 @@ +[user] + name = Sylvain Herlédan + email = sylvain.herledan@hrafnagud.info + +[alias] + co = checkout + cp = cherry-pick + qlog = log --pretty=oneline --abbrev-commit --graph --decorate + unstage = reset HEAD + headless = "!sh -c 'if [ $# = 1 ]; then git symbolic-ref HEAD refs/heads/$1 && rm .git/index; else echo \"usage: git headless <branchename>\" >&2 && exit 1; fi' -" + origin = remote show origin + wdiff = diff --color-words + wshow = show --color-words + lc = log ORIG_HEAD.. --stat --no-merges + k = !gitk + commit-submodules = "!subs=$(git ls-files --error-unmatch --stage -- $(git ls-files --modified) | grep ^160000 | cut -f2-); msg=$(echo Submodule updates: $subs; echo; git submodule summary); git commit -e -m \"$msg\" --only $(echo $subs)" + mkpatch = diff-tree -p --pretty + pushable = push -n origin "refs/heads/*:refs/heads/*" + unmerged = ls-files --unmerged + whatup = log --stat origin..@{0} + lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit + lgns = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --name-status + +[color] + branch = true + diff = true + pager = true + status = true + +[sendemail] + smtpserver = /usr/bin/msmtp +[push] + default = current +[merge] + tool = vimdiff3 + log = true +[status] + showUntrackedFiles = no +[mergetool "vimdiff3"] + cmd = vim -f -d -c \"wincmd J\" \"$MERGED\" \"$LOCAL\" \"$BASE\" \"$REMOTE\" +[format] + headers = "Content-Type: text/plain; charset=\"utf-8\"" +[core] + editor = vim diff --git a/i3config b/i3config new file mode 100644 index 0000000..94c3018 --- /dev/null +++ b/i3config @@ -0,0 +1,160 @@ +# This file has been auto-generated by i3-config-wizard(1). +# It will not be overwritten, so edit it as you like. +# +# Should you change your keyboard layout some time, delete +# this file and re-run i3-config-wizard(1). +# + +# i3 config file (v4) +# +# Please see http://i3wm.org/docs/userguide.html for a complete reference! + +set $mod Mod4 + +# Font for window titles. Will also be used by the bar unless a different font +# is used in the bar {} block below. +font pango:monospace 8 + +# This font is widely installed, provides lots of unicode glyphs, right-to-left +# text rendering and scalability on retina/hidpi displays (thanks to pango). +#font pango:DejaVu Sans Mono 8 + +# Before i3 v4.8, we used to recommend this one as the default: +# font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 +# The font above is very space-efficient, that is, it looks good, sharp and +# clear in small sizes. However, its unicode glyph coverage is limited, the old +# X core fonts rendering does not support right-to-left and this being a bitmap +# font, it doesn’t scale on retina/hidpi displays. + +# Use Mouse+$mod to drag floating windows to their wanted position +floating_modifier $mod + +# start a terminal +bindsym $mod+Return exec ${HOME}/.local/bin/st -e tmux + +# kill focused window +bindsym $mod+Shift+q kill + +# start dmenu (a program launcher) +bindsym $mod+d exec dmenu_run +# There also is the (new) i3-dmenu-desktop which only displays applications +# shipping a .desktop file. It is a wrapper around dmenu, so you need that +# installed. +# bindsym $mod+d exec --no-startup-id i3-dmenu-desktop + +# change focus +bindsym $mod+j focus left +bindsym $mod+k focus down +bindsym $mod+l focus up +bindsym $mod+m focus right + +# alternatively, you can use the cursor keys: +bindsym $mod+Left focus left +bindsym $mod+Down focus down +bindsym $mod+Up focus up +bindsym $mod+Right focus right + +# move focused window +bindsym $mod+Shift+j move left +bindsym $mod+Shift+k move down +bindsym $mod+Shift+l move up +bindsym $mod+Shift+m move right + +# alternatively, you can use the cursor keys: +bindsym $mod+Shift+Left move left +bindsym $mod+Shift+Down move down +bindsym $mod+Shift+Up move up +bindsym $mod+Shift+Right move right + +# split in horizontal orientation +bindsym $mod+h split h + +# split in vertical orientation +bindsym $mod+v split v + +# enter fullscreen mode for the focused container +bindsym $mod+f fullscreen toggle + +# change container layout (stacked, tabbed, toggle split) +bindsym $mod+s layout stacking +bindsym $mod+w layout tabbed +bindsym $mod+e layout toggle split + +# toggle tiling / floating +bindsym $mod+Shift+space floating toggle + +# change focus between tiling / floating windows +bindsym $mod+space focus mode_toggle + +# focus the parent container +bindsym $mod+a focus parent + +# focus the child container +#bindsym $mod+d focus child + +# switch to workspace +bindsym $mod+1 workspace 1 +bindsym $mod+2 workspace 2 +bindsym $mod+3 workspace 3 +bindsym $mod+4 workspace 4 +bindsym $mod+5 workspace 5 +bindsym $mod+6 workspace 6 +bindsym $mod+7 workspace 7 +bindsym $mod+8 workspace 8 +bindsym $mod+9 workspace 9 +bindsym $mod+0 workspace 10 + +# move focused container to workspace +bindsym $mod+Shift+1 move container to workspace 1 +bindsym $mod+Shift+2 move container to workspace 2 +bindsym $mod+Shift+3 move container to workspace 3 +bindsym $mod+Shift+4 move container to workspace 4 +bindsym $mod+Shift+5 move container to workspace 5 +bindsym $mod+Shift+6 move container to workspace 6 +bindsym $mod+Shift+7 move container to workspace 7 +bindsym $mod+Shift+8 move container to workspace 8 +bindsym $mod+Shift+9 move container to workspace 9 +bindsym $mod+Shift+0 move container to workspace 10 + +# reload the configuration file +bindsym $mod+Shift+c reload +# restart i3 inplace (preserves your layout/session, can be used to upgrade i3) +bindsym $mod+Shift+r restart +# exit i3 (logs you out of your X session) +bindsym $mod+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'" + +# resize window (you can also use the mouse for that) +mode "resize" { + # These bindings trigger as soon as you enter the resize mode + + # Pressing left will shrink the window’s width. + # Pressing right will grow the window’s width. + # Pressing up will shrink the window’s height. + # Pressing down will grow the window’s height. + bindsym j resize shrink width 10 px or 10 ppt + bindsym k resize grow height 10 px or 10 ppt + bindsym l resize shrink height 10 px or 10 ppt + bindsym m resize grow width 10 px or 10 ppt + + # same bindings, but for the arrow keys + bindsym Left resize shrink width 10 px or 10 ppt + bindsym Down resize grow height 10 px or 10 ppt + bindsym Up resize shrink height 10 px or 10 ppt + bindsym Right resize grow width 10 px or 10 ppt + + # back to normal: Enter or Escape + bindsym Return mode "default" + bindsym Escape mode "default" +} + +bindsym $mod+r mode "resize" + +# Start i3bar to display a workspace bar (plus the system information i3status +# finds out, if available) +bar { + status_command i3status +} + +# Screenshot +bindsym Print exec "~/.local/bin/sshot.sh ~/docs/screenshots" +bindsym --release Shift+Print exec "~/.local/bin/sshot.sh ~/docs/screenshots -s" diff --git a/lib/colors.sh b/lib/colors.sh new file mode 100644 index 0000000..a472088 --- /dev/null +++ b/lib/colors.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +readonly BLACK="\033[0;30m"; +readonly DARK_GRAY="\033[1;30m"; +readonly BLUE="\033[0;34m"; +readonly LIGHT_BLUE="\033[1;34m"; +readonly GREEN="\033[0;32m"; +readonly LIGHT_GREEN="\033[1;32m"; +readonly CYAN="\033[0;36m"; +readonly LIGHT_CYAN="\033[1;36m"; +readonly RED="\033[0;31m"; +readonly LIGHT_RED="\033[1;31m"; +readonly PURPLE="\033[0;35m"; +readonly LIGHT_PURPLE="\033[1;35m"; +readonly BROWN="\033[0;33m"; +readonly YELLOW="\033[1;33m"; +readonly LIGHT_GRAY="\033[0;37m"; +readonly WHITE="\033[1;37m"; +readonly BOLD="$(tput bold)"; +readonly NO_COLOR="$(tput sgr0)"; +readonly DEFAULT_COLOR="\033[0m"; diff --git a/lib/functions.sh b/lib/functions.sh new file mode 100644 index 0000000..99a8962 --- /dev/null +++ b/lib/functions.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +function has() +{ + local command_name="${1}"; shift; + + set +o errexit + hash "${command_name}" > /dev/null 2>&1; + if [ 0 -eq ${?} ]; + then + set -o errexit + return 0; + fi + + set -o errexit + return 1; +} + diff --git a/rtorrentrc b/rtorrentrc new file mode 100644 index 0000000..2731033 --- /dev/null +++ b/rtorrentrc @@ -0,0 +1,118 @@ +# https://gist.github.com/bryanjswift/1525912 +# This is an example resource file for rTorrent. Copy to +# ~/.rtorrent.rc and enable/modify the options as needed. Remember to +# uncomment the options you wish to enable. + +# Maximum and minimum number of peers to connect to per torrent. +min_peers = 40 +max_peers = 80 + +# Same as above but for seeding completed torrents (-1 = same as downloading) +min_peers_seed = 40 +max_peers_seed = 80 + +# Maximum number of uploads single torrent may use +max_uploads = 10 + +# Maximum number of simultaneous downloads +max_downloads_global = 10 +# Maximum number of simultaneous uploads +max_uploads_global = 10 + +# Global upload and download rate in KiB. "0" for unlimited. +download_rate = 250 +upload_rate = 70 + +# Default directory to save the downloaded torrents. +directory = ###HOME###/docs/dlz + +# Default session directory. Make sure you don't run multiple instance +# of rtorrent using the same session directory. Perhaps using a +# relative path? +session = ###HOME###/.cache/rtorrent + +# Watch a directory for new torrents, and stop those that have been +# deleted. +#schedule = watch_directory,5,5,load_start=./rtactive/*.torrent +#schedule = tied_directory,6,5,start_tied= +#schedule = untied_directory,7,5,stop_untied= + +# Close torrents when diskspace is low. +schedule = low_diskspace,5,60,close_low_diskspace=500M + +# Periodically save session data +schedule = session_save,240,300,session_save= + +# Enable the default ratio group. +ratio.enable= +# Change the limits, the defaults should be sufficient. +# Upload to a minimum ratio of 4.0 +ratio.min.set=400 +# Upload to a maximum ratio of 20.0 +ratio.max.set=2000 +# Upload a minimum of 250 MB +ratio.upload.set=250M +# When seeding ratio is reached close the torrent +system.method.set = group.seeding.ratio.command, d.close= + +# Move files to ./unsorted when download completes +#system.method.set_key = event.download.finished,move_complete,"execute=mv,-n,$d.get_base_path=,./unsorted/;d.set_directory=./unsorted/" + +# Port range to use for listening. +port_range = 48403-48403 + +# Start opening ports at a random position within the port range. +port_random = no + +# Encryption options, set to none (default) or any combination of the following: +# allow_incoming, try_outgoing, require, require_RC4, enable_retry, prefer_plaintext +# +# The example value allows incoming encrypted connections, starts unencrypted +# outgoing connections but retries with encryption if they fail, preferring +# plaintext to RC4 encryption after the encrypted handshake +# +encryption = allow_incoming,try_outgoing,enable_retry,prefer_plaintext + +# Sort the main view by ratio +view.sort_current = main,greater=d.get_ratio= +view.sort_new = main,less=d.get_ratio= +view.sort = main + +# Sort the seeding view by the upload rate and only show torrents with peers +view.sort_current = seeding,greater=d.get_up_rate= +view.filter = seeding,"and=d.get_complete=,d.get_peers_connected=" +view.sort_new = seeding,less=d.get_up_rate= +view.sort = seeding + +# Sort the leeching view by name +view.sort_current = leeching,greater=d.get_name= +view.sort_new = leeching,greater=d.get_name= +view.sort = leeching + +# Filter the active view by connected peers +view.sort_current = active,less=d.get_name= +view.sort_new = leeching,less=d.get_name= +view.filter = active,d.get_peers_connected= +view.sort = active + +schedule = sort_main,11,5,view.sort=main +schedule = sort_seeding,12,5,view.sort=seeding +schedule = sort_leeching,13,5,view.sort=leeching +schedule = sort_active,14,5,view.sort=active + +# Enable DHT support for trackerless torrents or when all trackers are down. +# May be set to "disable" (completely disable DHT), "off" (do not start DHT), +# "auto" (start and stop DHT as needed), or "on" (start DHT immediately). +# The default is "off". For DHT to work, a session directory must be defined. +# +dht = auto + +# UDP port to use for DHT. +# +dht_port = 44810 + +# Enable peer exchange (for torrents not marked private) +# +peer_exchange = yes + +use_udp_trackers = yes diff --git a/setup.sh b/setup.sh new file mode 100755 index 0000000..4f61e9f --- /dev/null +++ b/setup.sh @@ -0,0 +1,290 @@ +#!/bin/sh +# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 + +# @author: Sylvain Herlédan <sylvain.herledan@hrafnagud.info> +# @date: 2017-06-02 + +set -o nounset +set -o errexit +set -o pipefail + +PROGNAME="$(basename "${0}")"; +PROGDIR="$(readlink -f "$(dirname "${0}")")"; +ARGS="${@}"; + +# Include helpers +. "${PROGDIR}/lib/colors.sh" +. "${PROGDIR}/lib/functions.sh" + +function install_tup() +{ + local tools_dir="${1}"; shift; + local install_dir="${1}"; shift; + + if [ ! -f "${install_dir}/bin/tup" ]; + then + if [ ! -d "${tools_dir}/tup" ]; + then + git clone "git://github.com/gittup/tup.git" "${tools_dir}/tup" + fi + cd "${tools_dir}/tup" + ./bootstrap.sh + mkdir -p "${install_dir}/bin" + cp "${tools_dir}/tup/tup" "${install_dir}/bin/tup" + fi +} + +function install_st() +{ + local tools_dir="${1}"; shift; + local install_dir="${1}"; shift; + local patches_url="http://st.suckless.org/patches"; + + if [ ! -f "${install_dir}/bin/st" ]; + then + if [ ! -d "${tools_dir}/st" ]; + then + git clone "http://git.suckless.org/st" "${tools_dir}/st" + wget \ + "${patches_url}/st-no_bold_colors-20160727-308bfbf.diff" \ + -O "${tools_dir}/st/st-no_bold.diff" + wget \ + "${patches_url}/st-solarized-dark-20160727-308bfbf.diff" \ + -O "${tools_dir}/st/st-solarized.diff" + fi + cd "${tools_dir}/st" + git checkout tags/0.7 + git apply st-no_bold.diff + git apply st-solarized.diff + cp config.def.h config.h + sed -i 's/.*Liberation Mono.*/static char font[] = "Inconsolata:pixelsize=13:antialias=true:hinting=true";/' config.h + sed -i 's/static int borderpx = 2;/static int borderpx = 0;/' config.h + sed -i 's/static char shell\[\] = "\/bin\/sh";/static char shell\[\] = "\/usr\/bin\/zsh";/' config.h + make clean + make + cp "${tools_dir}/st/st" "${install_dir}/bin/st" + fi +} + +# Dein installation ----------------------------------------------------------- +# +# Dein is a manager for vim plugins. +# ----------------------------------------------------------------------------- +install_dein() +{ + local tools_dir="${1}"; shift; + local install_dir="${1}"; shift; + local repo_path="${install_dir}/config/vim/dein/repos/github.com/Shougo"; + local link_path="${repo_path}/dein.vim"; + + if [ ! -h "${link_path}" -o ! -d "${link_path}" ]; + then + if [ ! -d "${tools_dir}/dein" ]; + then + git clone \ + "https://github.com/Shougo/dein.vim.git" \ + "${tools_dir}/dein" + fi + + rm -rf "${install_dir}/config/vim/dein/repos/github.com/Shougo" + mkdir -p "${install_dir}/config/vim/dein/repos/github.com/Shougo" + ln -sf \ + "${tools_dir}/dein" \ + "${install_dir}/config/vim/dein/repos/github.com/Shougo/dein.vim" + fi +} + +# Oh my zsh installation ------------------------------------------------------ +# ----------------------------------------------------------------------------- +install_oh_my_zsh() +{ + local tools_dir="${1}"; shift; + local install_dir="${1}"; shift; + local link_path="${install_dir}/.oh-my-zsh"; + + if [ ! -h "${link_path}" -o ! -d "${link_path}" ]; + then + if [ ! -d "${tools_dir}/oh-my-zsh" ]; + then + git clone \ + "git://github.com/robbyrussell/oh-my-zsh.git" \ + "${tools_dir}/oh-my-zsh" + fi + ln -sf \ + "${tools_dir}/oh-my-zsh" \ + "${install_dir}/config/oh-my-zsh" + fi +} + +# +create_symlinks() +{ + local cfg_dir="${1}"; shift; + local install_dir="${1}"; shift; + + rm -rf "${install_dir}/.config/git" + ln -sfT "${cfg_dir}/git" "${install_dir}/.config/git" + + rm -rf "${install_dir}/.config/i3" + ln -sfT "${cfg_dir}/i3" "${install_dir}/.config/i3" + + rm -rf "${install_dir}/.xinitrc" + ln -sfT "${cfg_dir}/xinitrc" "${install_dir}/.config/xinitrc" + + rm -rf "${install_dir}/.tmux.conf" + ln -sfT "${cfg_dir}/tmux.conf" "${install_dir}/.tmux.conf" + + rm -rf "${install_dir}/.zshrc" + ln -sfT "${cfg_dir}/zshrc" "${install_dir}/.zshrc" + + rm -rf "${install_dir}/.vim" + ln -sfT "${cfg_dir}/vim" "${install_dir}/.vim" + + rm -rf "${install_dir}/.config/dunst" + ln -sfT "${cfg_dir}/dunst" "${install_dir}/.config/dunst" +} + +# Directory creation ---------------------------------------------------------- +# ----------------------------------------------------------------------------- +function create_dirs() +{ + local root_dir="${1}"; shift; + + mkdir -p "${root_dir}/.local/tools" + mkdir -p "${root_dir}/.local/data" + mkdir -p "${root_dir}/.local/config" + mkdir -p "${root_dir}/.local/config/vim/colors" + mkdir -p "${root_dir}/.local/config/dunst" + mkdir -p "${root_dir}/.local/config/i3" + mkdir -p "${root_dir}/.local/config/git" + + mkdir -p "${root_dir}/docs/downloads" + mkdir -p "${root_dir}/docs/screenshots" + + mkdir -p "${root_dir}/.cache/vim/undo" + mkdir -p "${root_dir}/.cache/vim/swap" + mkdir -p "${root_dir}/.cache/vim/backup" + mkdir -p "${root_dir}/.cache/rtorrent" +} + +# Copy configuration files ---------------------------------------------------- +# ----------------------------------------------------------------------------- +function copy_files() +{ + local src_dir="${1}"; shift; + local dst_dir="${1}"; shift; + + cp "${src_dir}/tomorrow_night.vim" \ + "${dst_dir}/.local/config/vim/colors/tomorrow_night.vim" + cp -r "${src_dir}/aliases" \ + "${dst_dir}/.local/config/aliases" + cp -r "${src_dir}/zshrc" \ + "${dst_dir}/.local/config/zshrc" + cp -r "${src_dir}/i3config" \ + "${dst_dir}/.local/config/i3/config" + cp -r "${src_dir}/gitconfig" \ + "${dst_dir}/.local/config/git/config" + cp -r "${src_dir}/tmux.conf" \ + "${dst_dir}/.local/config/tmux.conf" + cp -r "${src_dir}/vimrc" \ + "${dst_dir}/.local/config/vim/vimrc" + cp -r "${src_dir}/xinitrc" \ + "${dst_dir}/.local/config/xinitrc" + cp -r "${src_dir}/dunstrc" \ + "${dst_dir}/.local/config/dunst/dunstrc" + + configure_rtorrent "${src_dir}" "${dst_dir}" +} + +function configure_xdg() +{ + local install_dir="${1}"; shift; + local user_dirs="${install_dir}/.config/user-dirs.dirs"; + + cat > "${user_dirs}" <<EOF +XDG_CONFIG_HOME="${install_dir}/.config" +XDG_CACHE_HOME="${install_dir}/.cache" +XDG_DESKTOP_DIR="${install_dir}/docs" +XDG_DOWNLOAD_DIR="${install_dir}/docs/downloads" +XDG_DOCUMENTS_DIR="${install_dir}/docs" +XDG_MUSIC_DIR="${install_dir}/docs" +XDG_PICTURES_DIR="${install_dir}/docs" +XDG_PUBLICSHARE_DIR="${install_dir}/docs" +XDG_TEMPLATES_DIR="${install_dir}/docs" +XDG_VIDEOS_DIR="${install_dir}/docs" +EOF +} + +configure_rtorrent() +{ + local src_dir="${1}"; shift; + local dst_dir="${1}"; shift; + + sed 's!###HOME###!'"${HOME}"'!g' "${src_dir}/rtorrentrc" \ + > "${dst_dir}/.local/config/rtorrentrc" + +} + +check_requirements() +{ + local requirements="git make wget i3"; + local optional_deps="notify-send dunst pulseaudio scrot sudo redshift numlockx"; + local requirements_not_met=0; + + for cmd in ${optional_deps}; + do + if has "${cmd}"; + then + echo -e " [ ${LIGHT_GREEN}OK${NO_COLOR}] ${cmd}" + else + echo -e " [${LIGHT_CYAN}NOK${NO_COLOR}] ${cmd}" + fi + done + + + for cmd in ${requirements}; + do + if has "${cmd}"; + then + echo -e " [ ${LIGHT_GREEN}OK${NO_COLOR}] ${cmd}" + else + echo -e " [${LIGHT_RED}NOK${NO_COLOR}] ${cmd}" + requirements_not_met=1; + fi + done + + return ${requirements_not_met}; +} + +main() +{ + local local_dir="${HOME}/.local"; + local tools_dir="${local_dir}/tools"; + local cfg_dir="${local_dir}/config"; + + echo -e "\n\t${BOLD}.:| Dotfiles |:.${NO_COLOR}" + + # Check requirements first + echo -e "\n${YELLOW}=>${NO_COLOR}${BOLD} Checking requirements...${NO_COLOR}" + if check_requirements; + then + echo + else + echo -e "\n${YELLOW}=>${NO_COLOR}${BOLD} Abort.${NO_COLOR}" + exit 1 + fi + + create_dirs "${HOME}" + copy_files "${PROGDIR}" "${HOME}" + + install_tup "${tools_dir}" "${local_dir}" + install_st "${tools_dir}" "${local_dir}" + install_dein "${tools_dir}" "${local_dir}" + install_oh_my_zsh "${tools_dir}" "${local_dir}" + + create_symlinks "${cfg_dir}" "${HOME}" + configure_xdg "${HOME}" +} + +main ${ARGS} +exit 0 diff --git a/tmux.conf b/tmux.conf new file mode 100644 index 0000000..5182143 --- /dev/null +++ b/tmux.conf @@ -0,0 +1,129 @@ +# $Id: screen-keys.conf,v 1.7 2010-07-31 11:39:13 nicm Exp $ +# +# By Nicholas Marriott. Public domain. +# +# This configuration file binds many of the common GNU screen key bindings to +# appropriate tmux key bindings. Note that for some key bindings there is no +# tmux analogue and also that this set omits binding some commands available in +# tmux but not in screen. +# +# Note this is only a selection of key bindings and they are in addition to the +# normal tmux key bindings. This is intended as an example not as to be used +# as-is. + +# Set the prefix to ^A. +unbind C-b +set -g prefix ^A +bind a send-prefix + +# Bind appropriate commands similar to screen. +# lockscreen ^X x +unbind ^X +bind ^X lock-server +unbind x +bind x lock-server + +# screen ^C c +unbind ^C +bind ^C new-window +unbind c +bind c new-window + +# detach ^D d +unbind ^D +bind ^D detach + +# displays * +unbind * +bind * list-clients + +# next ^@ ^N sp n +unbind ^@ +bind ^@ next-window +unbind ^N +bind ^N next-window +unbind " " +bind " " next-window +unbind n +bind n next-window + +# title A +unbind A +bind A command-prompt "rename-window %%" + +# other ^A +unbind ^A +bind ^A last-window + +# prev ^H ^P p ^? +unbind ^H +bind ^H previous-window +unbind ^P +bind ^P previous-window +unbind p +bind p previous-window +unbind BSpace +bind BSpace previous-window + +# windows ^W w +unbind ^W +bind ^W list-windows +unbind w +bind w list-windows + +# quit \ +unbind '\' +bind '\' confirm-before "kill-server" + +# kill K k +unbind K +bind K confirm-before "kill-window" +unbind k +bind k confirm-before "kill-window" + +# redisplay ^L l +unbind ^L +bind ^L refresh-client +unbind l +bind l refresh-client + +# split -v | +unbind | +bind | split-window + +# :kB: focus up +unbind Tab +bind Tab select-pane -t:.+ +unbind BTab +bind BTab select-pane -t:.- + +# " windowlist -b +unbind '"' +bind '"' choose-window + + +set -g default-terminal "screen-256color" +set -g history-limit 10000 +# Copy tmux paste buffer to CLIPBOARD +bind C-c run "tmux show-buffer | xsel -i -b" +# Copy CLIPBOARD to tmux paste buffer and paste tmux paste buffer +bind C-v run "tmux set-buffer -- \"$(xsel -o -b)\"; tmux paste-buffer" + +# Reload configuration +bind r source-file ~/.tmux.conf + +# THEME +#set-option -g status-utf8 on +set -g status-bg black +set -g status-fg white +set -g status-interval 60 +set -g status-left-length 30 +set -g status-left '#[fg=green](#S) #(whoami)@#H#[default]' +set -g status-right '#[fg=yellow]#(cut -d " " -f 1-3 /proc/loadavg)#[default] #[fg=blue]%H:%M#[default]' + +# Monitor activity +setw -g monitor-activity off +set -g visual-activity off + +set -g terminal-overrides 'xterm*:smcup@:rmcup@' +set-option -g default-shell /usr/bin/zsh diff --git a/tomorrow_night.vim b/tomorrow_night.vim new file mode 100644 index 0000000..df61b5b --- /dev/null +++ b/tomorrow_night.vim @@ -0,0 +1,350 @@ +" Tomorrow Night - Full Colour and 256 Colour +" http://chriskempson.com +" +" Hex colour conversion functions borrowed from the theme "Desert256"" + +" Default GUI Colours +let s:foreground = "c5c8c6" +let s:background = "1d1f21" +let s:selection = "373b41" +let s:line = "282a2e" +let s:comment = "969896" +let s:red = "cc6666" +let s:orange = "de935f" +let s:yellow = "f0c674" +let s:green = "b5bd68" +let s:aqua = "8abeb7" +let s:blue = "81a2be" +let s:purple = "b294bb" +let s:window = "4d5057" + +" Console 256 Colours +if !has("gui_running") + let s:background = "303030" + let s:window = "5e5e5e" + let s:line = "3a3a3a" + let s:selection = "585858" +end + +set background=dark +hi clear +syntax reset + +let g:colors_name = "tomorrow_night" + +if has("gui_running") || &t_Co == 88 || &t_Co == 256 + " Returns an approximate grey index for the given grey level + fun <SID>grey_number(x) + if &t_Co == 88 + if a:x < 23 + return 0 + elseif a:x < 69 + return 1 + elseif a:x < 103 + return 2 + elseif a:x < 127 + return 3 + elseif a:x < 150 + return 4 + elseif a:x < 173 + return 5 + elseif a:x < 196 + return 6 + elseif a:x < 219 + return 7 + elseif a:x < 243 + return 8 + else + return 9 + endif + else + if a:x < 14 + return 0 + else + let l:n = (a:x - 8) / 10 + let l:m = (a:x - 8) % 10 + if l:m < 5 + return l:n + else + return l:n + 1 + endif + endif + endif + endfun + + " Returns the actual grey level represented by the grey index + fun <SID>grey_level(n) + if &t_Co == 88 + if a:n == 0 + return 0 + elseif a:n == 1 + return 46 + elseif a:n == 2 + return 92 + elseif a:n == 3 + return 115 + elseif a:n == 4 + return 139 + elseif a:n == 5 + return 162 + elseif a:n == 6 + return 185 + elseif a:n == 7 + return 208 + elseif a:n == 8 + return 231 + else + return 255 + endif + else + if a:n == 0 + return 0 + else + return 8 + (a:n * 10) + endif + endif + endfun + + " Returns the palette index for the given grey index + fun <SID>grey_colour(n) + if &t_Co == 88 + if a:n == 0 + return 16 + elseif a:n == 9 + return 79 + else + return 79 + a:n + endif + else + if a:n == 0 + return 16 + elseif a:n == 25 + return 231 + else + return 231 + a:n + endif + endif + endfun + + " Returns an approximate colour index for the given colour level + fun <SID>rgb_number(x) + if &t_Co == 88 + if a:x < 69 + return 0 + elseif a:x < 172 + return 1 + elseif a:x < 230 + return 2 + else + return 3 + endif + else + if a:x < 75 + return 0 + else + let l:n = (a:x - 55) / 40 + let l:m = (a:x - 55) % 40 + if l:m < 20 + return l:n + else + return l:n + 1 + endif + endif + endif + endfun + + " Returns the actual colour level for the given colour index + fun <SID>rgb_level(n) + if &t_Co == 88 + if a:n == 0 + return 0 + elseif a:n == 1 + return 139 + elseif a:n == 2 + return 205 + else + return 255 + endif + else + if a:n == 0 + return 0 + else + return 55 + (a:n * 40) + endif + endif + endfun + + " Returns the palette index for the given R/G/B colour indices + fun <SID>rgb_colour(x, y, z) + if &t_Co == 88 + return 16 + (a:x * 16) + (a:y * 4) + a:z + else + return 16 + (a:x * 36) + (a:y * 6) + a:z + endif + endfun + + " Returns the palette index to approximate the given R/G/B colour levels + fun <SID>colour(r, g, b) + " Get the closest grey + let l:gx = <SID>grey_number(a:r) + let l:gy = <SID>grey_number(a:g) + let l:gz = <SID>grey_number(a:b) + + " Get the closest colour + let l:x = <SID>rgb_number(a:r) + let l:y = <SID>rgb_number(a:g) + let l:z = <SID>rgb_number(a:b) + + if l:gx == l:gy && l:gy == l:gz + " There are two possibilities + let l:dgr = <SID>grey_level(l:gx) - a:r + let l:dgg = <SID>grey_level(l:gy) - a:g + let l:dgb = <SID>grey_level(l:gz) - a:b + let l:dgrey = (l:dgr * l:dgr) + (l:dgg * l:dgg) + (l:dgb * l:dgb) + let l:dr = <SID>rgb_level(l:gx) - a:r + let l:dg = <SID>rgb_level(l:gy) - a:g + let l:db = <SID>rgb_level(l:gz) - a:b + let l:drgb = (l:dr * l:dr) + (l:dg * l:dg) + (l:db * l:db) + if l:dgrey < l:drgb + " Use the grey + return <SID>grey_colour(l:gx) + else + " Use the colour + return <SID>rgb_colour(l:x, l:y, l:z) + endif + else + " Only one possibility + return <SID>rgb_colour(l:x, l:y, l:z) + endif + endfun + + " Returns the palette index to approximate the 'rrggbb' hex string + fun <SID>rgb(rgb) + let l:r = ("0x" . strpart(a:rgb, 0, 2)) + 0 + let l:g = ("0x" . strpart(a:rgb, 2, 2)) + 0 + let l:b = ("0x" . strpart(a:rgb, 4, 2)) + 0 + + return <SID>colour(l:r, l:g, l:b) + endfun + + " Sets the highlighting for the given group + fun <SID>X(group, fg, bg, attr) + if a:fg != "" + exec "hi " . a:group . " guifg=#" . a:fg . " ctermfg=" . <SID>rgb(a:fg) + endif + if a:bg != "" + exec "hi " . a:group . " guibg=#" . a:bg . " ctermbg=" . <SID>rgb(a:bg) + endif + if a:attr != "" + exec "hi " . a:group . " gui=" . a:attr . " cterm=" . a:attr + endif + endfun + + " Vim Highlighting + call <SID>X("Normal", s:foreground, s:background, "") + call <SID>X("LineNr", s:selection, "", "") + call <SID>X("NonText", s:selection, "", "") + call <SID>X("SpecialKey", s:selection, "", "") + call <SID>X("Search", s:background, s:yellow, "") + call <SID>X("TabLine", s:foreground, s:background, "reverse") + call <SID>X("StatusLine", s:window, s:yellow, "reverse") + call <SID>X("StatusLineNC", s:window, s:foreground, "reverse") + call <SID>X("VertSplit", s:window, s:window, "none") + call <SID>X("Visual", "", s:selection, "") + call <SID>X("Directory", s:blue, "", "") + call <SID>X("ModeMsg", s:green, "", "") + call <SID>X("MoreMsg", s:green, "", "") + call <SID>X("Question", s:green, "", "") + call <SID>X("WarningMsg", s:red, "", "") + call <SID>X("MatchParen", "", s:selection, "") + call <SID>X("Folded", s:comment, s:background, "") + call <SID>X("FoldColumn", "", s:background, "") + if version >= 700 + call <SID>X("CursorLine", "", s:line, "none") + call <SID>X("CursorColumn", "", s:line, "none") + call <SID>X("PMenu", s:foreground, s:selection, "none") + call <SID>X("PMenuSel", s:foreground, s:selection, "reverse") + end + if version >= 703 + call <SID>X("ColorColumn", "", s:line, "none") + end + + " Standard Highlighting + call <SID>X("Comment", s:comment, "", "") + call <SID>X("Todo", s:comment, s:background, "") + call <SID>X("Title", s:comment, "", "") + call <SID>X("Identifier", s:red, "", "none") + call <SID>X("Statement", s:purple, "", "") + call <SID>X("Conditional", s:foreground, "", "") + call <SID>X("Repeat", s:foreground, "", "") + call <SID>X("Structure", s:purple, "", "") + call <SID>X("Function", s:blue, "", "") + call <SID>X("Constant", s:orange, "", "") + call <SID>X("String", s:green, "", "") + call <SID>X("Special", s:orange, "", "") + call <SID>X("PreProc", s:purple, "", "") + call <SID>X("Operator", s:aqua, "", "none") + call <SID>X("Type", s:blue, "", "none") + call <SID>X("Define", s:purple, "", "none") + call <SID>X("Include", s:blue, "", "") + "call <SID>X("Ignore", "666666", "", "") + + " Vim Highlighting + call <SID>X("vimCommand", s:red, "", "none") + + " C Highlighting + call <SID>X("cType", s:yellow, "", "") + call <SID>X("cStorageClass", s:purple, "", "") + call <SID>X("cConditional", s:purple, "", "") + call <SID>X("cRepeat", s:purple, "", "") + + " PHP Highlighting + call <SID>X("phpVarSelector", s:red, "", "") + call <SID>X("phpKeyword", s:purple, "", "") + call <SID>X("phpRepeat", s:purple, "", "") + call <SID>X("phpConditional", s:purple, "", "") + call <SID>X("phpStatement", s:purple, "", "") + call <SID>X("phpMemberSelector", s:foreground, "", "") + + " Ruby Highlighting + call <SID>X("rubySymbol", s:green, "", "") + call <SID>X("rubyConstant", s:yellow, "", "") + call <SID>X("rubyAttribute", s:blue, "", "") + call <SID>X("rubyInclude", s:blue, "", "") + call <SID>X("rubyLocalVariableOrMethod", s:orange, "", "") + call <SID>X("rubyCurlyBlock", s:orange, "", "") + call <SID>X("rubyStringDelimiter", s:green, "", "") + call <SID>X("rubyInterpolationDelimiter", s:orange, "", "") + call <SID>X("rubyConditional", s:purple, "", "") + call <SID>X("rubyRepeat", s:purple, "", "") + + " Python Highlighting + call <SID>X("pythonInclude", s:purple, "", "") + call <SID>X("pythonStatement", s:purple, "", "") + call <SID>X("pythonConditional", s:purple, "", "") + call <SID>X("pythonFunction", s:blue, "", "") + call <SID>X("pythonOperator", s:red, "", "") + + " JavaScript Highlighting + call <SID>X("javaScriptBraces", s:foreground, "", "") + call <SID>X("javaScriptFunction", s:purple, "", "") + call <SID>X("javaScriptConditional", s:purple, "", "") + call <SID>X("javaScriptRepeat", s:purple, "", "") + call <SID>X("javaScriptNumber", s:orange, "", "") + call <SID>X("javaScriptMember", s:orange, "", "") + + " Diff Highlighting + call <SID>X("diffAdded", s:green, "", "") + call <SID>X("diffRemoved", s:red, "", "") + + " Delete Functions + delf <SID>X + delf <SID>rgb + delf <SID>colour + delf <SID>rgb_colour + delf <SID>rgb_level + delf <SID>rgb_number + delf <SID>grey_colour + delf <SID>grey_level + delf <SID>grey_number +endif diff --git a/user-dirs.dirs b/user-dirs.dirs new file mode 100644 index 0000000..2b0562f --- /dev/null +++ b/user-dirs.dirs @@ -0,0 +1,4 @@ +XDG_DESKTOP_DIR="${HOME}/docs" +XDG_DOCUMENTS_DIR="${HOME}/docs" +XDG_DOWNLOAD_DIR="${HOME}/docs" + @@ -0,0 +1,5 @@ +set nobackup +set noswapfile +set nowritebackup +set viminfo= +set cm=blowfish @@ -0,0 +1,94 @@ +" vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 + +if &compatible + set nocompatible +endif + +" Paths +set directory=$XDG_CACHE_HOME/vim,~/,/tmp +set backupdir=$XDG_CACHE_HOME/vim,~/,/tmp +set viminfo+=n$XDG_CACHE_HOME/vim/viminfo +set runtimepath=$XDG_CONFIG_HOME/vim,$XDG_CONFIG_HOME/vim/after,$VIM,$VIMRUNTIME +let $MYVIMRC="$XDG_CONFIG_HOME/vim/vimrc" + +" Plugins +" After plugins changes remember to run :call dein#install() +set runtimepath+=~/.vim/dein/repos/github.com/Shougo/dein.vim +call dein#begin(expand('~/.vim/dein')) +call dein#add('Shougo/dein.vim') +call dein#add('majutsushi/tagbar') +call dein#add('scrooloose/nerdtree', + \{'on_cmd': 'NERDTreeToggle'}) +call dein#add('justmao945/vim-clang', + \{'on_ft': ['c', 'cpp']}) +call dein#end() + +filetype plugin indent on +syntax enable + +" Plugins config +let g:clang_c_options = '-std=gnu11' +let g_clang_cpp_options = '-std=c++11 -stdlib=libc++' + +" Encoding +set encoding=utf-8 +set fileencoding=utf-8 +set termencoding=utf-8 + +" Misc +set paste " setting good paste +set colorcolumn=79 " highlight 80 characters limit + +" Whitespace +set nowrap " don't wrap lines +set tabstop=4 shiftwidth=4 " a tab is four spaces +set expandtab " use spaces instead of tabs +set backspace=indent,eol,start " backspace through everything in insert mode + +" Style +colorscheme tomorrow_night " set color scheme +set relativenumber " setting line numbers +set ruler " show column number +set laststatus=2 " always show the status line + +" Searching +set hlsearch " highlight matches +set incsearch " incremental searching +set ignorecase " search are case-insensitive +set smartcase " enable case-sensitivity if the pattern + " contains a capital letter + +" Key bindings +nmap <F2> :NERDTreeToggle<CR> " toggle file browser with F2 +nmap <F8> :TagbarToggle<CR> " toggle tags browser with F8 + +" Highlight extra whitespaces +highlight ExtraWhitespace ctermbg=red +autocmd Syntax * syn match ExtraWhitespace /\s\+$\| \+\ze\t/ + +" Python files +autocmd BufRead,BufNewFile *.py :setlocal + \ tabstop=4 + \ softtabstop=4 + \ shiftwidth=4 + \ textwidth=79 + \ expandtab + \ autoindent + \ fileformat=unix + +" Shell scripts +autocmd BufRead,BufNewFile *.sh,*.ksh,*.csh :setlocal + \ tabstop=2 + \ softtabstop=2 + \ shiftwidth=2 + \ textwidth=79 + \ expandtab + \ autoindent + \ fileformat=unix + +" Web files: JavaScript, HTML and CSS +autocmd BufRead,BufNewFile *.js,*.html,*.css :setlocal + \ tabstop=2 + \ softtabstop=2 + \ shiftwidth=2 + \ expandtab @@ -0,0 +1,19 @@ +if [ -d /etc/X11/xinit/xinitrc.d ]; then + for f in /etc/X11/xinit/xinitrc.d/*; do + [ -x "$f" ] && . "$f" + done + unset f +fi + +# French keyboard layout +setxkbmap -layout "fr" + +# No more "bip" +xset -b + +[ -x "/usr/bin/numlockx" ] && numlockx on +[ -x "/usr/bin/dunst" ] && exec dunst & +[ -x "/usr/bin/pulseaudio" ] && exec pulseaudio --start & +[ -x "/usr/bin/redshift" ] && exec redshift -l 48.390929:-4.487095 & + +exec i3 @@ -0,0 +1,35 @@ +# Oh-my-zsh configuration +# ---------------------------------------------------------------------------- +ZSH="${HOME}/.local/tools/oh-my-zsh" +ZSH_THEME="nanotech" +plugins=(git archlinux gnu-utils pip python ssh-agent) +source $ZSH/oh-my-zsh.sh + +source "${HOME}/.local/config/aliases" +source "${HOME}/.config/user-dirs.dirs" + +# Environment variables +# ---------------------------------------------------------------------------- +TERM=xterm-256color +TERMINAL=tmuxst +EDITOR=vim +PATH="${HOME}/.local/bin:${PATH}" +XINITRC="${XDG_CONFIG_HOME}/xinitrc" +XAUTHORITY="${XDG_RUNTIME_DIR}/Xauthority" +WGETRC="${XDG_CONFIG_HOME}/wgetrc" +TMUX_TMPDIR="${XDG_RUNTIME_DIR}" +GIMP2_DIRECTORY="${XDG_CONFIG_HOME}/gimp" +VIMINIT=":source ${HOME}/.vim/vimrc" + +export TERM TERMINAL EDITOR PATH +export WGETRC TMUX_TMPDIR GIMP2_DIRECTORY VIMINIT +export XINITRC XAUTHORITY + +export XDG_CONFIG_HOME XDG_CACHE_HOME XDG_DESKTOP_DIR XDG_DOWNLOAD_DIR +export XDG_DOCUMENTS_DIR XDG_MUSIC_DIR XDG_PICTURES_DIR XDG_PUBLICSHARE_DIR +export XDG_TEMPLATES_DIR XDG_VIDEOS_DIR + +# Fix key bindings +# ---------------------------------------------------------------------------- +bindkey "${terminfo[khome]}" beginning-of-line +bindkey "${terminfo[kend]}" end-of-line |
