did some stuff
This commit is contained in:
parent
07e93d26c9
commit
2effb6196f
20 changed files with 58 additions and 1259 deletions
|
@ -1,153 +0,0 @@
|
||||||
#? Config file for bpytop v. 1.0.67
|
|
||||||
|
|
||||||
#* Color theme, looks for a .theme file in "/usr/[local/]share/bpytop/themes" and "~/.config/bpytop/themes", "Default" for builtin default theme.
|
|
||||||
#* Prefix name by a plus sign (+) for a theme located in user themes folder, i.e. color_theme="+monokai"
|
|
||||||
color_theme="Default"
|
|
||||||
|
|
||||||
#* If the theme set background should be shown, set to False if you want terminal background transparency
|
|
||||||
theme_background=True
|
|
||||||
|
|
||||||
#* Sets if 24-bit truecolor should be used, will convert 24-bit colors to 256 color (6x6x6 color cube) if false.
|
|
||||||
truecolor=True
|
|
||||||
|
|
||||||
#* Manually set which boxes to show. Available values are "cpu mem net proc", separate values with whitespace.
|
|
||||||
shown_boxes="cpu mem net proc"
|
|
||||||
|
|
||||||
#* Update time in milliseconds, increases automatically if set below internal loops processing time, recommended 2000 ms or above for better sample times for graphs.
|
|
||||||
update_ms=1000
|
|
||||||
|
|
||||||
#* Processes update multiplier, sets how often the process list is updated as a multiplier of "update_ms".
|
|
||||||
#* Set to 2 or higher to greatly decrease bpytop cpu usage. (Only integers)
|
|
||||||
proc_update_mult=2
|
|
||||||
|
|
||||||
#* Processes sorting, "pid" "program" "arguments" "threads" "user" "memory" "cpu lazy" "cpu responsive",
|
|
||||||
#* "cpu lazy" updates top process over time, "cpu responsive" updates top process directly.
|
|
||||||
proc_sorting="memory"
|
|
||||||
|
|
||||||
#* Reverse sorting order, True or False.
|
|
||||||
proc_reversed=False
|
|
||||||
|
|
||||||
#* Show processes as a tree
|
|
||||||
proc_tree=False
|
|
||||||
|
|
||||||
#* Which depth the tree view should auto collapse processes at
|
|
||||||
tree_depth=3
|
|
||||||
|
|
||||||
#* Use the cpu graph colors in the process list.
|
|
||||||
proc_colors=True
|
|
||||||
|
|
||||||
#* Use a darkening gradient in the process list.
|
|
||||||
proc_gradient=True
|
|
||||||
|
|
||||||
#* If process cpu usage should be of the core it's running on or usage of the total available cpu power.
|
|
||||||
proc_per_core=False
|
|
||||||
|
|
||||||
#* Show process memory as bytes instead of percent
|
|
||||||
proc_mem_bytes=True
|
|
||||||
|
|
||||||
#* Sets the CPU stat shown in upper half of the CPU graph, "total" is always available, see:
|
|
||||||
#* https://psutil.readthedocs.io/en/latest/#psutil.cpu_times for attributes available on specific platforms.
|
|
||||||
#* Select from a list of detected attributes from the options menu
|
|
||||||
cpu_graph_upper="total"
|
|
||||||
|
|
||||||
#* Sets the CPU stat shown in lower half of the CPU graph, "total" is always available, see:
|
|
||||||
#* https://psutil.readthedocs.io/en/latest/#psutil.cpu_times for attributes available on specific platforms.
|
|
||||||
#* Select from a list of detected attributes from the options menu
|
|
||||||
cpu_graph_lower="total"
|
|
||||||
|
|
||||||
#* Toggles if the lower CPU graph should be inverted.
|
|
||||||
cpu_invert_lower=True
|
|
||||||
|
|
||||||
#* Set to True to completely disable the lower CPU graph.
|
|
||||||
cpu_single_graph=False
|
|
||||||
|
|
||||||
#* Shows the system uptime in the CPU box.
|
|
||||||
show_uptime=True
|
|
||||||
|
|
||||||
#* Check cpu temperature, needs "osx-cpu-temp" on MacOS X.
|
|
||||||
check_temp=True
|
|
||||||
|
|
||||||
#* Which sensor to use for cpu temperature, use options menu to select from list of available sensors.
|
|
||||||
cpu_sensor=Auto
|
|
||||||
|
|
||||||
#* Show temperatures for cpu cores also if check_temp is True and sensors has been found
|
|
||||||
show_coretemp=True
|
|
||||||
|
|
||||||
#* Which temperature scale to use, available values: "celsius", "fahrenheit", "kelvin" and "rankine"
|
|
||||||
temp_scale="celsius"
|
|
||||||
|
|
||||||
#* Show CPU frequency, can cause slowdowns on certain systems with some versions of psutil
|
|
||||||
show_cpu_freq=True
|
|
||||||
|
|
||||||
#* Draw a clock at top of screen, formatting according to strftime, empty string to disable.
|
|
||||||
draw_clock="%X"
|
|
||||||
|
|
||||||
#* Update main ui in background when menus are showing, set this to false if the menus is flickering too much for comfort.
|
|
||||||
background_update=True
|
|
||||||
|
|
||||||
#* Custom cpu model name, empty string to disable.
|
|
||||||
custom_cpu_name=""
|
|
||||||
|
|
||||||
#* Optional filter for shown disks, should be full path of a mountpoint, separate multiple values with a comma ",".
|
|
||||||
#* Begin line with "exclude=" to change to exclude filter, otherwise defaults to "most include" filter. Example: disks_filter="exclude=/boot, /home/user"
|
|
||||||
disks_filter=""
|
|
||||||
|
|
||||||
#* Show graphs instead of meters for memory values.
|
|
||||||
mem_graphs=True
|
|
||||||
|
|
||||||
#* If swap memory should be shown in memory box.
|
|
||||||
show_swap=True
|
|
||||||
|
|
||||||
#* Show swap as a disk, ignores show_swap value above, inserts itself after first disk.
|
|
||||||
swap_disk=True
|
|
||||||
|
|
||||||
#* If mem box should be split to also show disks info.
|
|
||||||
show_disks=True
|
|
||||||
|
|
||||||
#* Filter out non physical disks. Set this to False to include network disks, RAM disks and similar.
|
|
||||||
only_physical=True
|
|
||||||
|
|
||||||
#* Read disks list from /etc/fstab. This also disables only_physical.
|
|
||||||
use_fstab=False
|
|
||||||
|
|
||||||
#* Toggles if io stats should be shown in regular disk usage view
|
|
||||||
show_io_stat=True
|
|
||||||
|
|
||||||
#* Toggles io mode for disks, showing only big graphs for disk read/write speeds.
|
|
||||||
io_mode=False
|
|
||||||
|
|
||||||
#* Set to True to show combined read/write io graphs in io mode.
|
|
||||||
io_graph_combined=False
|
|
||||||
|
|
||||||
#* Set the top speed for the io graphs in MiB/s (10 by default), use format "device:speed" separate disks with a comma ",".
|
|
||||||
#* Example: "/dev/sda:100, /dev/sdb:20"
|
|
||||||
io_graph_speeds=""
|
|
||||||
|
|
||||||
#* Set fixed values for network graphs, default "10M" = 10 Mibibytes, possible units "K", "M", "G", append with "bit" for bits instead of bytes, i.e "100mbit"
|
|
||||||
net_download="10M"
|
|
||||||
net_upload="10M"
|
|
||||||
|
|
||||||
#* Start in network graphs auto rescaling mode, ignores any values set above and rescales down to 10 Kibibytes at the lowest.
|
|
||||||
net_auto=True
|
|
||||||
|
|
||||||
#* Sync the scaling for download and upload to whichever currently has the highest scale
|
|
||||||
net_sync=False
|
|
||||||
|
|
||||||
#* If the network graphs color gradient should scale to bandwidth usage or auto scale, bandwidth usage is based on "net_download" and "net_upload" values
|
|
||||||
net_color_fixed=False
|
|
||||||
|
|
||||||
#* Starts with the Network Interface specified here.
|
|
||||||
net_iface=""
|
|
||||||
|
|
||||||
#* Show battery stats in top right if battery is present
|
|
||||||
show_battery=True
|
|
||||||
|
|
||||||
#* Show init screen at startup, the init screen is purely cosmetical
|
|
||||||
show_init=False
|
|
||||||
|
|
||||||
#* Enable check for new version from github.com/aristocratos/bpytop at start.
|
|
||||||
update_check=True
|
|
||||||
|
|
||||||
#* Set loglevel for "~/.config/bpytop/error.log" levels are: "ERROR" "WARNING" "INFO" "DEBUG".
|
|
||||||
#* The level set includes all lower levels, i.e. "DEBUG" will show all logging info.
|
|
||||||
log_level=WARNING
|
|
|
@ -3,6 +3,9 @@
|
||||||
# Autostart
|
# Autostart
|
||||||
xrandr --display 0 144 &
|
xrandr --display 0 144 &
|
||||||
xrandr --display 1 60 &
|
xrandr --display 1 60 &
|
||||||
|
pgrep -x pipewire > /dev/null || pipewire &
|
||||||
|
pgrep -x pipewire-pulse > /dev/null || pipewire-pulse &
|
||||||
|
pgrep -x pipewire-media-session > /dev/null || pipewire-media-session &
|
||||||
pgrep -x dunst > /dev/null || dunst -conf $HOME/.config/dunst/dunstrc &
|
pgrep -x dunst > /dev/null || dunst -conf $HOME/.config/dunst/dunstrc &
|
||||||
sxhkd &
|
sxhkd &
|
||||||
xrdb $HOME/.Xresources
|
xrdb $HOME/.Xresources
|
||||||
|
@ -15,10 +18,11 @@ pgrep -x pasystray > /dev/null || pasystray &
|
||||||
pgrep -x xscreensaver > /dev/null || xscreensaver -no-splash &
|
pgrep -x xscreensaver > /dev/null || xscreensaver -no-splash &
|
||||||
pgrep -x picom > /dev/null || picom --config $HOME/.config/picom/picom.conf &
|
pgrep -x picom > /dev/null || picom --config $HOME/.config/picom/picom.conf &
|
||||||
pgrep -x wmname > /dev/null || wmname LG3D &
|
pgrep -x wmname > /dev/null || wmname LG3D &
|
||||||
|
gnome-keyring-daemon --start &
|
||||||
|
|
||||||
# Set workspaces
|
# Set workspaces
|
||||||
bspc monitor DP-2 1 2 3 4 5
|
bspc monitor DP-2 -d 1 2 3 4 5
|
||||||
bspc monitor HDMI-0 6 7 8 9 0
|
bspc monitor HDMI-0 -d 6 7 8 9 0
|
||||||
|
|
||||||
# BSPWM config
|
# BSPWM config
|
||||||
bspc config border_width 1
|
bspc config border_width 1
|
||||||
|
|
42
.config/starship.toml
Normal file
42
.config/starship.toml
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
add_newline = true
|
||||||
|
|
||||||
|
format = """
|
||||||
|
$username@$hostname $directory $git_branch $git_status $git_state $git_metrics $git_commit
|
||||||
|
$character"""
|
||||||
|
|
||||||
|
right_format = "$cmd_duration"
|
||||||
|
|
||||||
|
[character]
|
||||||
|
error_symbol = "[✗](bold red)"
|
||||||
|
|
||||||
|
[cmd_duration]
|
||||||
|
format = "took [$duration]($style) "
|
||||||
|
|
||||||
|
[directory]
|
||||||
|
format = "[$path]($style)[$read_only]($read_only_style)"
|
||||||
|
read_only = " 🔒"
|
||||||
|
|
||||||
|
[git_branch]
|
||||||
|
format = "on [$symbol$branch]($style)"
|
||||||
|
|
||||||
|
[git_commit]
|
||||||
|
format = "[\\($hash$tag\\)]($style)"
|
||||||
|
tag_disabled = false
|
||||||
|
|
||||||
|
[git_state]
|
||||||
|
format = '\([$state($progress_current/$progress_total)]($style)\)'
|
||||||
|
|
||||||
|
[git_metrics]
|
||||||
|
disabled = false
|
||||||
|
format = '([+$added]($added_style))([-$deleted]($deleted_style))'
|
||||||
|
|
||||||
|
[git_status]
|
||||||
|
format = '([\[$all_status$ahead_behind\]]($style))'
|
||||||
|
|
||||||
|
[hostname]
|
||||||
|
ssh_only = false
|
||||||
|
format= "[$hostname]($style)"
|
||||||
|
|
||||||
|
[username]
|
||||||
|
show_always = true
|
||||||
|
format = "[$user]($style)"
|
|
@ -1,6 +1,6 @@
|
||||||
# Terminal
|
# Terminal
|
||||||
super + Return
|
super + Return
|
||||||
tabbed -r 2 st -w ''
|
tabbed -c -r 2 st -w ''
|
||||||
|
|
||||||
# Rofi
|
# Rofi
|
||||||
super + space
|
super + space
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
; xfce4-terminal GtkAccelMap rc-file -*- scheme -*-
|
|
||||||
; this file is an automated accelerator map dump
|
|
||||||
;
|
|
||||||
(gtk_accel_path "<Actions>/terminal-window/goto-tab-2" "<Alt>2")
|
|
||||||
(gtk_accel_path "<Actions>/terminal-window/goto-tab-6" "<Alt>6")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/copy-input" "")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/close-other-tabs" "")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/move-tab-right" "<Primary><Shift>Page_Down")
|
|
||||||
(gtk_accel_path "<Actions>/terminal-window/goto-tab-7" "<Alt>7")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/set-title-color" "")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/edit-menu" "")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/zoom-menu" "")
|
|
||||||
(gtk_accel_path "<Actions>/terminal-window/goto-tab-1" "<Alt>1")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/fullscreen" "F11")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/read-only" "")
|
|
||||||
(gtk_accel_path "<Actions>/terminal-window/goto-tab-5" "<Alt>5")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/preferences" "")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/reset-and-clear" "")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/about" "")
|
|
||||||
(gtk_accel_path "<Actions>/terminal-window/goto-tab-4" "<Alt>4")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/close-window" "<Primary><Shift>q")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/reset" "")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/save-contents" "")
|
|
||||||
(gtk_accel_path "<Actions>/terminal-window/toggle-menubar" "F10")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/copy" "<Primary><Shift>c")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/copy-html" "")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/last-active-tab" "")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/show-borders" "")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/view-menu" "")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/detach-tab" "<Primary><Shift>d")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/scroll-on-output" "")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/show-toolbar" "")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/next-tab" "<Primary>Page_Down")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/tabs-menu" "")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/search-next" "")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/search-prev" "")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/undo-close-tab" "")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/set-title" "<Primary><Shift>s")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/contents" "F1")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/zoom-reset" "<Primary>0")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/close-tab" "<Primary><Shift>w")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/new-tab" "<Primary><Shift>t")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/new-window" "<Primary><Shift>n")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/terminal-menu" "")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/show-menubar" "")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/select-all" "<Primary><Shift>a")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/paste" "<Primary><Shift>v")
|
|
||||||
(gtk_accel_path "<Actions>/terminal-window/goto-tab-9" "<Alt>9")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/move-tab-left" "<Primary><Shift>Page_Up")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/search" "<Primary><Shift>f")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/file-menu" "")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/prev-tab" "<Primary>Page_Up")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/paste-selection" "")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/zoom-in" "<Primary>plus")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/zoom-out" "<Primary>minus")
|
|
||||||
(gtk_accel_path "<Actions>/terminal-window/goto-tab-8" "<Alt>8")
|
|
||||||
; (gtk_accel_path "<Actions>/terminal-window/help-menu" "")
|
|
||||||
(gtk_accel_path "<Actions>/terminal-window/goto-tab-3" "<Alt>3")
|
|
|
@ -1,38 +0,0 @@
|
||||||
[Configuration]
|
|
||||||
FontName=FiraCode Nerd Font Mono 9
|
|
||||||
MiscAlwaysShowTabs=FALSE
|
|
||||||
MiscBell=FALSE
|
|
||||||
MiscBellUrgent=FALSE
|
|
||||||
MiscBordersDefault=FALSE
|
|
||||||
MiscCursorBlinks=TRUE
|
|
||||||
MiscCursorShape=TERMINAL_CURSOR_SHAPE_UNDERLINE
|
|
||||||
MiscDefaultGeometry=90x30
|
|
||||||
MiscInheritGeometry=FALSE
|
|
||||||
MiscMenubarDefault=FALSE
|
|
||||||
MiscMouseAutohide=FALSE
|
|
||||||
MiscMouseWheelZoom=TRUE
|
|
||||||
MiscToolbarDefault=FALSE
|
|
||||||
MiscConfirmClose=TRUE
|
|
||||||
MiscCycleTabs=TRUE
|
|
||||||
MiscTabCloseButtons=TRUE
|
|
||||||
MiscTabCloseMiddleClick=TRUE
|
|
||||||
MiscTabPosition=GTK_POS_TOP
|
|
||||||
MiscHighlightUrls=TRUE
|
|
||||||
MiscMiddleClickOpensUri=FALSE
|
|
||||||
MiscCopyOnSelect=FALSE
|
|
||||||
MiscShowRelaunchDialog=TRUE
|
|
||||||
MiscRewrapOnResize=TRUE
|
|
||||||
MiscUseShiftArrowsToScroll=FALSE
|
|
||||||
MiscSlimTabs=FALSE
|
|
||||||
MiscNewTabAdjacent=FALSE
|
|
||||||
MiscSearchDialogOpacity=100
|
|
||||||
MiscShowUnsafePasteDialog=FALSE
|
|
||||||
ScrollingUnlimited=TRUE
|
|
||||||
ScrollingBar=TERMINAL_SCROLLBAR_NONE
|
|
||||||
ColorCursorForeground=#ffffffffffff
|
|
||||||
ColorPalette=rgb(59,66,82);rgb(191,97,106);rgb(163,190,140);rgb(235,203,139);rgb(129,161,193);rgb(180,142,173);rgb(136,192,208);rgb(229,233,240);rgb(76,86,106);rgb(191,97,106);rgb(163,190,140);rgb(235,203,139);rgb(129,161,193);rgb(180,142,173);rgb(143,188,187);rgb(235,203,139)
|
|
||||||
ScrollingOnOutput=FALSE
|
|
||||||
ColorBoldIsBright=FALSE
|
|
||||||
BackgroundDarkness=0.000000
|
|
||||||
BackgroundMode=TERMINAL_BACKGROUND_TRANSPARENT
|
|
||||||
|
|
4
.xinitrc
4
.xinitrc
|
@ -1 +1,5 @@
|
||||||
|
if which dbus-launch >/dev/null && test -z "$DBUS_SESSION_BUS_ADDRESS"; then
|
||||||
|
eval "$(dbus-launch --sh-syntax --exit-with-session)"
|
||||||
|
fi
|
||||||
|
|
||||||
exec bspwm
|
exec bspwm
|
||||||
|
|
8
.zshrc
8
.zshrc
|
@ -10,7 +10,7 @@ export PATH=$HOME/flutter/bin:$HOME/.cargo/bin:$HOME/.local/bin:$HOME/.dotnet/to
|
||||||
export ZSH="$HOME/.oh-my-zsh"
|
export ZSH="$HOME/.oh-my-zsh"
|
||||||
|
|
||||||
# omz configs
|
# omz configs
|
||||||
ZSH_THEME="powerlevel10k/powerlevel10k"
|
# ZSH_THEME="powerlevel10k/powerlevel10k"
|
||||||
# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" )
|
# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" )
|
||||||
# CASE_SENSITIVE="true"
|
# CASE_SENSITIVE="true"
|
||||||
HYPHEN_INSENSITIVE="true"
|
HYPHEN_INSENSITIVE="true"
|
||||||
|
@ -24,7 +24,7 @@ ENABLE_CORRECTION="true"
|
||||||
COMPLETION_WAITING_DOTS="true"
|
COMPLETION_WAITING_DOTS="true"
|
||||||
|
|
||||||
# Plugins
|
# Plugins
|
||||||
plugins=(git yarn command-not-found history-substring-search zsh-autosuggestions nvm rustup rust cargo docker docker-compose dotnet zsh-syntax-highlighting)
|
plugins=(git yarn command-not-found history-substring-search zsh-autosuggestions nvm rust docker docker-compose dotnet zsh-syntax-highlighting)
|
||||||
|
|
||||||
# Plugin Configs
|
# Plugin Configs
|
||||||
export NVM_AUTOLOAD=1
|
export NVM_AUTOLOAD=1
|
||||||
|
@ -53,7 +53,6 @@ alias cat="bat"
|
||||||
alias parrot="curl parrot.live"
|
alias parrot="curl parrot.live"
|
||||||
alias neofetch="neofetch | lolcat"
|
alias neofetch="neofetch | lolcat"
|
||||||
alias grep="batgrep"
|
alias grep="batgrep"
|
||||||
alias pacman="paru"
|
|
||||||
alias man="batman"
|
alias man="batman"
|
||||||
alias gitdiff="batdiff"
|
alias gitdiff="batdiff"
|
||||||
|
|
||||||
|
@ -145,5 +144,8 @@ export QT_QPA_PLATFORMTHEME=qt5ct
|
||||||
# Load nvm
|
# Load nvm
|
||||||
source /usr/share/nvm/init-nvm.sh
|
source /usr/share/nvm/init-nvm.sh
|
||||||
|
|
||||||
|
# Set starship Prompt
|
||||||
|
eval "$(starship init zsh)"
|
||||||
|
|
||||||
# Neofetch cuz its cool
|
# Neofetch cuz its cool
|
||||||
neofetch | lolcat
|
neofetch | lolcat
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
ISC License (ISC)
|
|
||||||
|
|
||||||
Copyright (c) 2020 Jan Klemkow <j.klemkow@wemelug.de>
|
|
||||||
Copyright (c) 2020 Jochen Sprickerhof <git@jochen.sprickerhof.de>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
@ -1,45 +0,0 @@
|
||||||
.POSIX:
|
|
||||||
|
|
||||||
include config.mk
|
|
||||||
|
|
||||||
all: scroll
|
|
||||||
|
|
||||||
config.h:
|
|
||||||
cp config.def.h config.h
|
|
||||||
|
|
||||||
scroll: scroll.c config.h
|
|
||||||
|
|
||||||
install: scroll
|
|
||||||
mkdir -p $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man1
|
|
||||||
cp -f scroll $(DESTDIR)$(BINDIR)
|
|
||||||
cp -f scroll.1 $(DESTDIR)$(MANDIR)/man1
|
|
||||||
|
|
||||||
uninstall:
|
|
||||||
rm -f $(DESTDIR)$(BINDIR)/scroll $(DESTDIR)$(MANDIR)/man1/scroll.1
|
|
||||||
|
|
||||||
test: scroll ptty
|
|
||||||
# check usage
|
|
||||||
if ./ptty ./scroll -h; then exit 1; fi
|
|
||||||
# check exit passthrough of child
|
|
||||||
if ! ./ptty ./scroll true; then exit 1; fi
|
|
||||||
if ./ptty ./scroll false; then exit 1; fi
|
|
||||||
./up.sh
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f scroll ptty
|
|
||||||
|
|
||||||
distclean: clean
|
|
||||||
rm -f config.h scroll-$(VERSION).tar.gz
|
|
||||||
|
|
||||||
dist: clean
|
|
||||||
mkdir -p scroll-$(VERSION)
|
|
||||||
cp -R README scroll.1 TODO Makefile config.mk config.def.h \
|
|
||||||
ptty.c scroll.c up.sh up.log \
|
|
||||||
scroll-$(VERSION)
|
|
||||||
tar -cf - scroll-$(VERSION) | gzip > scroll-$(VERSION).tar.gz
|
|
||||||
rm -rf scroll-$(VERSION)
|
|
||||||
|
|
||||||
.c:
|
|
||||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $< -lutil
|
|
||||||
|
|
||||||
.PHONY: all install test clean distclean dist
|
|
|
@ -1,34 +0,0 @@
|
||||||
This program provides a scroll back buffer for a terminal like st(1). It
|
|
||||||
should run on any Unix-like system.
|
|
||||||
|
|
||||||
At the moment it is in an experimental state. Its not recommended for
|
|
||||||
productive use.
|
|
||||||
|
|
||||||
The initial version of this program is from Roberto E. Vargas Caballero:
|
|
||||||
https://lists.suckless.org/dev/1703/31256.html
|
|
||||||
|
|
||||||
What is the state of scroll?
|
|
||||||
|
|
||||||
The project is faced with some hard facts, that our original plan is not doable
|
|
||||||
as we thought in the first place:
|
|
||||||
|
|
||||||
1. [crtl]+[e] is used in emacs mode (default) on the shell to jump to the end
|
|
||||||
of the line. But, its also used so signal a scroll down mouse event from
|
|
||||||
terminal emulators to the shell an other programs.
|
|
||||||
|
|
||||||
- A workaround is to use vi mode in the shell.
|
|
||||||
- Or to give up mouse support (default behavior)
|
|
||||||
|
|
||||||
2. scroll could not handle backward cursor jumps and editing of old lines
|
|
||||||
properly. We just handle current line editing and switching between
|
|
||||||
alternative screens (curses mode). For a proper end user experience we
|
|
||||||
would need to write a completely new terminal emulator like screen or tmux.
|
|
||||||
|
|
||||||
What is the performance impact of scroll?
|
|
||||||
|
|
||||||
indirect OpenBSD
|
|
||||||
-------------------------------
|
|
||||||
0x 7.53 s
|
|
||||||
1x 10.10 s
|
|
||||||
2x 12.00 s
|
|
||||||
3x 13.73 s
|
|
|
@ -1,3 +0,0 @@
|
||||||
* strlen function which is aware of unicode
|
|
||||||
* handle wrapping lines in scrolling line count correctly
|
|
||||||
* hotkey to dump buffer to file (like screen hardcopy)
|
|
|
@ -1,16 +0,0 @@
|
||||||
/*
|
|
||||||
* Define ESC sequences to use for scroll events.
|
|
||||||
* Use "cat -v" to figure out favorite key combination.
|
|
||||||
*
|
|
||||||
* lines is the number of lines scrolled up or down.
|
|
||||||
* If lines is negative, it's the fraction of the terminal size.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct rule rules[] = {
|
|
||||||
/* sequence event lines */
|
|
||||||
{"\033[5;2~", SCROLL_UP, -1}, /* [Shift] + [PageUP] */
|
|
||||||
{"\033[6;2~", SCROLL_DOWN, -1}, /* [Shift] + [PageDown] */
|
|
||||||
/* mouse binding shadows ^E and ^Y, so it's disabled by default */
|
|
||||||
//{"\031", SCROLL_UP, 1}, /* mouse wheel up */
|
|
||||||
//{"\005", SCROLL_DOWN, 1}, /* mouse wheel Down */
|
|
||||||
};
|
|
|
@ -1,16 +0,0 @@
|
||||||
/*
|
|
||||||
* Define ESC sequences to use for scroll events.
|
|
||||||
* Use "cat -v" to figure out favorite key combination.
|
|
||||||
*
|
|
||||||
* lines is the number of lines scrolled up or down.
|
|
||||||
* If lines is negative, it's the fraction of the terminal size.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct rule rules[] = {
|
|
||||||
/* sequence event lines */
|
|
||||||
{"\033[5;2~", SCROLL_UP, -1}, /* [Shift] + [PageUP] */
|
|
||||||
{"\033[6;2~", SCROLL_DOWN, -1}, /* [Shift] + [PageDown] */
|
|
||||||
/* mouse binding shadows ^E and ^Y, so it's disabled by default */
|
|
||||||
//{"\031", SCROLL_UP, 1}, /* mouse wheel up */
|
|
||||||
//{"\005", SCROLL_DOWN, 1}, /* mouse wheel Down */
|
|
||||||
};
|
|
|
@ -1,12 +0,0 @@
|
||||||
# scroll version
|
|
||||||
VERSION = 0.1
|
|
||||||
|
|
||||||
# paths
|
|
||||||
PREFIX = /usr/local
|
|
||||||
BINDIR = $(PREFIX)/bin
|
|
||||||
MANDIR = $(PREFIX)/share/man
|
|
||||||
|
|
||||||
CPPFLAGS = -DVERSION=\"$(VERSION)\" -D_DEFAULT_SOURCE
|
|
||||||
# if your system is not POSIX, add -std=c99 to CFLAGS
|
|
||||||
CFLAGS = -Os
|
|
||||||
LDFLAGS = -s
|
|
|
@ -1,29 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
export POSIXLY_CORRECT=1
|
|
||||||
num=1000000
|
|
||||||
seq=seq
|
|
||||||
|
|
||||||
if [ -x /usr/bin/jot ]; then
|
|
||||||
seq=jot
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -f perf_*.log
|
|
||||||
|
|
||||||
for i in `$seq 10`; do
|
|
||||||
/usr/bin/time st -e $seq $num 2>>perf_0.log
|
|
||||||
done
|
|
||||||
|
|
||||||
for i in `$seq 10`; do
|
|
||||||
/usr/bin/time st -e ./ptty $seq $num 2>>perf_1.log
|
|
||||||
done
|
|
||||||
|
|
||||||
for i in `$seq 10`; do
|
|
||||||
/usr/bin/time st -e ./ptty ./ptty $seq $num 2>>perf_2.log
|
|
||||||
done
|
|
||||||
|
|
||||||
for i in `$seq 10`; do
|
|
||||||
/usr/bin/time st -e ./ptty ./ptty ./ptty $seq $num 2>>perf_3.log
|
|
||||||
done
|
|
|
@ -1,156 +0,0 @@
|
||||||
#include <sys/wait.h>
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <poll.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#if defined(__linux)
|
|
||||||
#include <pty.h>
|
|
||||||
#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
|
|
||||||
#include <util.h>
|
|
||||||
#elif defined(__FreeBSD__) || defined(__DragonFly__)
|
|
||||||
#include <libutil.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void
|
|
||||||
die(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vfprintf(stderr, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
|
|
||||||
fputc(' ', stderr);
|
|
||||||
perror(NULL);
|
|
||||||
} else {
|
|
||||||
fputc('\n', stderr);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
usage(void)
|
|
||||||
{
|
|
||||||
fputs("ptty [-C] [-c cols] [-r rows] cmd\n", stderr);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
struct winsize ws = {.ws_row = 25, .ws_col = 80, 0, 0};
|
|
||||||
int ch;
|
|
||||||
bool closeflag = false;
|
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv, "c:r:Ch")) != -1) {
|
|
||||||
switch (ch) {
|
|
||||||
case 'c': /* cols */
|
|
||||||
ws.ws_col = strtoimax(optarg, NULL, 10);
|
|
||||||
if (errno != 0)
|
|
||||||
die("strtoimax: %s", optarg);
|
|
||||||
break;
|
|
||||||
case 'r': /* lines */
|
|
||||||
ws.ws_row = strtoimax(optarg, NULL, 10);
|
|
||||||
if (errno != 0)
|
|
||||||
die("strtoimax: %s", optarg);
|
|
||||||
break;
|
|
||||||
case 'C':
|
|
||||||
closeflag = true;
|
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
default:
|
|
||||||
usage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
argc -= optind;
|
|
||||||
argv += optind;
|
|
||||||
|
|
||||||
if (argc < 1)
|
|
||||||
usage();
|
|
||||||
|
|
||||||
int mfd;
|
|
||||||
pid_t child = forkpty(&mfd, NULL, NULL, &ws);
|
|
||||||
switch (child) {
|
|
||||||
case -1:
|
|
||||||
die("forkpty");
|
|
||||||
case 0: /* child */
|
|
||||||
execvp(argv[0], argv);
|
|
||||||
die("exec");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* parent */
|
|
||||||
|
|
||||||
if (closeflag && close(mfd) == -1)
|
|
||||||
die("close:");
|
|
||||||
|
|
||||||
int pfds = 2;
|
|
||||||
struct pollfd pfd[2] = {
|
|
||||||
{ STDIN_FILENO, POLLIN, 0},
|
|
||||||
{ mfd, POLLIN, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
char buf[BUFSIZ];
|
|
||||||
ssize_t n;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if ((r = poll(pfd, pfds, -1)) == -1)
|
|
||||||
die("poll:");
|
|
||||||
|
|
||||||
if (pfd[0].revents & POLLIN) {
|
|
||||||
if ((n = read(STDIN_FILENO, buf, sizeof buf)) == -1)
|
|
||||||
die("read:");
|
|
||||||
if (n == 0) {
|
|
||||||
pfd[0].fd = -1;
|
|
||||||
if (close(mfd) == -1)
|
|
||||||
die("close:");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (write(mfd, buf, n) == -1)
|
|
||||||
die("write:");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pfd[1].revents & POLLIN) {
|
|
||||||
if ((n = read(mfd, buf, sizeof(buf)-1)) == -1)
|
|
||||||
die("read:");
|
|
||||||
|
|
||||||
if (n == 0) break;
|
|
||||||
|
|
||||||
buf[n] = '\0';
|
|
||||||
|
|
||||||
/* handle cursor position request */
|
|
||||||
if (strcmp("\033[6n", buf) == 0) {
|
|
||||||
dprintf(mfd, "\033[25;1R");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (write(STDOUT_FILENO, buf, n) == -1)
|
|
||||||
die("write:");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pfd[0].revents & POLLHUP) {
|
|
||||||
pfd[0].fd = -1;
|
|
||||||
if (close(mfd) == -1)
|
|
||||||
die("close:");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (pfd[1].revents & POLLHUP)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int status;
|
|
||||||
if (waitpid(child, &status, 0) != child)
|
|
||||||
die("waitpid:");
|
|
||||||
|
|
||||||
return WEXITSTATUS(status);
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
.\"
|
|
||||||
.\" Copyright (c) 2020 Jan Klemkow <j.klemkow@wemelug.de>
|
|
||||||
.\"
|
|
||||||
.\" Permission to use, copy, modify, and distribute this software for any
|
|
||||||
.\" purpose with or without fee is hereby granted, provided that the above
|
|
||||||
.\" copyright notice and this permission notice appear in all copies.
|
|
||||||
.\"
|
|
||||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
.\"
|
|
||||||
.Dd April 9, 2020
|
|
||||||
.Dt SCROLL 1
|
|
||||||
.Os
|
|
||||||
.Sh NAME
|
|
||||||
.Nm scroll
|
|
||||||
.Nd scrollback buffer
|
|
||||||
.Sh SYNOPSIS
|
|
||||||
.Nm
|
|
||||||
.Op Fl Mh
|
|
||||||
.Op Fl m Ar size
|
|
||||||
.Op program Op arg ...
|
|
||||||
.Sh DESCRIPTION
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
utility saves output lines from the child
|
|
||||||
.Ar program
|
|
||||||
to use them for scrollback.
|
|
||||||
If
|
|
||||||
.Ar program
|
|
||||||
is not set,
|
|
||||||
.Nm
|
|
||||||
starts the users default shell.
|
|
||||||
.Pp
|
|
||||||
The options are as follows:
|
|
||||||
.Bl -tag -width Ds
|
|
||||||
.It Fl h
|
|
||||||
Shows usage of
|
|
||||||
.Nm .
|
|
||||||
.It Fl M
|
|
||||||
Set memory limit used for scrollbackbuffer to maximum.
|
|
||||||
.It Fl m Ar size
|
|
||||||
Set memory limit used for scrollbackbuffer to
|
|
||||||
.Ar size .
|
|
||||||
.El
|
|
||||||
.Sh EXIT STATUS
|
|
||||||
.Nm
|
|
||||||
exits with the status code of its the child
|
|
||||||
.Ar program .
|
|
||||||
.Sh EXAMPLES
|
|
||||||
.Nm st
|
|
||||||
.Fl e
|
|
||||||
.Nm scroll
|
|
||||||
.Nm /bin/sh
|
|
||||||
.Sh SEE ALSO
|
|
||||||
.Xr screen 1 ,
|
|
||||||
.Xr st 1 ,
|
|
||||||
.Xr tmux 1
|
|
||||||
.Sh AUTHORS
|
|
||||||
.Nm
|
|
||||||
was written by
|
|
||||||
.An Jan Klemkow Aq Mt j.klemkow@wemelug.de
|
|
||||||
and
|
|
||||||
.An Jochen Sprickerhof Aq Mt git@jochen.sprickerhof.de .
|
|
|
@ -1,594 +0,0 @@
|
||||||
/*
|
|
||||||
* Based on an example code from Roberto E. Vargas Caballero.
|
|
||||||
*
|
|
||||||
* See LICENSE file for copyright and license details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <sys/queue.h>
|
|
||||||
#include <sys/resource.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <poll.h>
|
|
||||||
#include <pwd.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#if defined(__linux)
|
|
||||||
#include <pty.h>
|
|
||||||
#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
|
|
||||||
#include <util.h>
|
|
||||||
#elif defined(__FreeBSD__) || defined(__DragonFly__)
|
|
||||||
#include <libutil.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LENGTH(X) (sizeof (X) / sizeof ((X)[0]))
|
|
||||||
|
|
||||||
const char *argv0;
|
|
||||||
|
|
||||||
TAILQ_HEAD(tailhead, line) head;
|
|
||||||
|
|
||||||
struct line {
|
|
||||||
TAILQ_ENTRY(line) entries;
|
|
||||||
size_t size;
|
|
||||||
size_t len;
|
|
||||||
char *buf;
|
|
||||||
} *bottom;
|
|
||||||
|
|
||||||
pid_t child;
|
|
||||||
int mfd;
|
|
||||||
struct termios dfl;
|
|
||||||
struct winsize ws;
|
|
||||||
static bool altscreen = false; /* is alternative screen active */
|
|
||||||
static bool doredraw = false; /* redraw upon sigwinch */
|
|
||||||
|
|
||||||
struct rule {
|
|
||||||
const char *seq;
|
|
||||||
enum {SCROLL_UP, SCROLL_DOWN} event;
|
|
||||||
short lines;
|
|
||||||
};
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
die(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vfprintf(stderr, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
|
|
||||||
fputc(' ', stderr);
|
|
||||||
perror(NULL);
|
|
||||||
} else {
|
|
||||||
fputc('\n', stderr);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
sigwinch(int sig)
|
|
||||||
{
|
|
||||||
assert(sig == SIGWINCH);
|
|
||||||
|
|
||||||
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1)
|
|
||||||
die("ioctl:");
|
|
||||||
if (ioctl(mfd, TIOCSWINSZ, &ws) == -1) {
|
|
||||||
if (errno == EBADF) /* child already exited */
|
|
||||||
return;
|
|
||||||
die("ioctl:");
|
|
||||||
}
|
|
||||||
kill(-child, SIGWINCH);
|
|
||||||
doredraw = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
reset(void)
|
|
||||||
{
|
|
||||||
if (tcsetattr(STDIN_FILENO, TCSANOW, &dfl) == -1)
|
|
||||||
die("tcsetattr:");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* error avoiding remalloc */
|
|
||||||
void *
|
|
||||||
earealloc(void *ptr, size_t size)
|
|
||||||
{
|
|
||||||
void *mem;
|
|
||||||
|
|
||||||
while ((mem = realloc(ptr, size)) == NULL) {
|
|
||||||
struct line *line = TAILQ_LAST(&head, tailhead);
|
|
||||||
|
|
||||||
if (line == NULL)
|
|
||||||
die("realloc:");
|
|
||||||
|
|
||||||
TAILQ_REMOVE(&head, line, entries);
|
|
||||||
free(line->buf);
|
|
||||||
free(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Count string length w/o ansi esc sequences. */
|
|
||||||
size_t
|
|
||||||
strelen(const char *buf, size_t size)
|
|
||||||
{
|
|
||||||
enum {CHAR, BREK, ESC} state = CHAR;
|
|
||||||
size_t len = 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < size; i++) {
|
|
||||||
char c = buf[i];
|
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
case CHAR:
|
|
||||||
if (c == '\033')
|
|
||||||
state = BREK;
|
|
||||||
else
|
|
||||||
len++;
|
|
||||||
break;
|
|
||||||
case BREK:
|
|
||||||
if (c == '[') {
|
|
||||||
state = ESC;
|
|
||||||
} else {
|
|
||||||
state = CHAR;
|
|
||||||
len++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ESC:
|
|
||||||
if (c >= 64 && c <= 126)
|
|
||||||
state = CHAR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* detect alternative screen switching and clear screen */
|
|
||||||
bool
|
|
||||||
skipesc(char c)
|
|
||||||
{
|
|
||||||
static enum {CHAR, BREK, ESC} state = CHAR;
|
|
||||||
static char buf[BUFSIZ];
|
|
||||||
static size_t i = 0;
|
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
case CHAR:
|
|
||||||
if (c == '\033')
|
|
||||||
state = BREK;
|
|
||||||
break;
|
|
||||||
case BREK:
|
|
||||||
if (c == '[')
|
|
||||||
state = ESC;
|
|
||||||
else
|
|
||||||
state = CHAR;
|
|
||||||
break;
|
|
||||||
case ESC:
|
|
||||||
buf[i++] = c;
|
|
||||||
if (i == sizeof buf) {
|
|
||||||
/* TODO: find a better way to handle this situation */
|
|
||||||
state = CHAR;
|
|
||||||
i = 0;
|
|
||||||
} else if (c >= 64 && c <= 126) {
|
|
||||||
state = CHAR;
|
|
||||||
buf[i] = '\0';
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
/* esc seq. enable alternative screen */
|
|
||||||
if (strcmp(buf, "?1049h") == 0 ||
|
|
||||||
strcmp(buf, "?1047h") == 0 ||
|
|
||||||
strcmp(buf, "?47h" ) == 0)
|
|
||||||
altscreen = true;
|
|
||||||
|
|
||||||
/* esc seq. disable alternative screen */
|
|
||||||
if (strcmp(buf, "?1049l") == 0 ||
|
|
||||||
strcmp(buf, "?1047l") == 0 ||
|
|
||||||
strcmp(buf, "?47l" ) == 0)
|
|
||||||
altscreen = false;
|
|
||||||
|
|
||||||
/* don't save cursor move or clear screen */
|
|
||||||
/* esc sequences to log */
|
|
||||||
switch (c) {
|
|
||||||
case 'A':
|
|
||||||
case 'B':
|
|
||||||
case 'C':
|
|
||||||
case 'D':
|
|
||||||
case 'H':
|
|
||||||
case 'J':
|
|
||||||
case 'K':
|
|
||||||
case 'f':
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return altscreen;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
getcursorposition(int *x, int *y)
|
|
||||||
{
|
|
||||||
char input[BUFSIZ];
|
|
||||||
ssize_t n;
|
|
||||||
|
|
||||||
if (write(STDOUT_FILENO, "\033[6n", 4) == -1)
|
|
||||||
die("requesting cursor position");
|
|
||||||
|
|
||||||
do {
|
|
||||||
if ((n = read(STDIN_FILENO, input, sizeof(input)-1)) == -1)
|
|
||||||
die("reading cursor position");
|
|
||||||
input[n] = '\0';
|
|
||||||
} while (sscanf(input, "\033[%d;%dR", y, x) != 2);
|
|
||||||
|
|
||||||
if (*x <= 0 || *y <= 0)
|
|
||||||
die("invalid cursor position: x=%d y=%d", *x, *y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
addline(char *buf, size_t size)
|
|
||||||
{
|
|
||||||
struct line *line = earealloc(NULL, sizeof *line);
|
|
||||||
|
|
||||||
line->size = size;
|
|
||||||
line->len = strelen(buf, size);
|
|
||||||
line->buf = earealloc(NULL, size);
|
|
||||||
memcpy(line->buf, buf, size);
|
|
||||||
|
|
||||||
TAILQ_INSERT_HEAD(&head, line, entries);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
redraw()
|
|
||||||
{
|
|
||||||
int rows = 0, x, y;
|
|
||||||
|
|
||||||
if (bottom == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
getcursorposition(&x, &y);
|
|
||||||
|
|
||||||
if (y < ws.ws_row-1)
|
|
||||||
y--;
|
|
||||||
|
|
||||||
/* wind back bottom pointer by shown history */
|
|
||||||
for (; bottom != NULL && TAILQ_NEXT(bottom, entries) != NULL &&
|
|
||||||
rows < y - 1; rows++)
|
|
||||||
bottom = TAILQ_NEXT(bottom, entries);
|
|
||||||
|
|
||||||
/* clear screen */
|
|
||||||
dprintf(STDOUT_FILENO, "\033[2J");
|
|
||||||
/* set cursor position to upper left corner */
|
|
||||||
write(STDOUT_FILENO, "\033[0;0H", 6);
|
|
||||||
|
|
||||||
/* remove newline of first line as we are at 0,0 already */
|
|
||||||
if (bottom->size > 0 && bottom->buf[0] == '\n')
|
|
||||||
write(STDOUT_FILENO, bottom->buf + 1, bottom->size - 1);
|
|
||||||
else
|
|
||||||
write(STDOUT_FILENO, bottom->buf, bottom->size);
|
|
||||||
|
|
||||||
for (rows = ws.ws_row; rows > 0 &&
|
|
||||||
TAILQ_PREV(bottom, tailhead, entries) != NULL; rows--) {
|
|
||||||
bottom = TAILQ_PREV(bottom, tailhead, entries);
|
|
||||||
write(STDOUT_FILENO, bottom->buf, bottom->size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bottom == TAILQ_FIRST(&head)) {
|
|
||||||
/* add new line in front of the shell prompt */
|
|
||||||
write(STDOUT_FILENO, "\n", 1);
|
|
||||||
write(STDOUT_FILENO, "\033[?25h", 6); /* show cursor */
|
|
||||||
} else
|
|
||||||
bottom = TAILQ_NEXT(bottom, entries);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
scrollup(int n)
|
|
||||||
{
|
|
||||||
int rows = 2, x, y, extra = 0;
|
|
||||||
struct line *scrollend = bottom;
|
|
||||||
|
|
||||||
if (bottom == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
getcursorposition(&x, &y);
|
|
||||||
|
|
||||||
if (n < 0) /* scroll by fraction of ws.ws_row, but at least one line */
|
|
||||||
n = ws.ws_row > (-n) ? ws.ws_row / (-n) : 1;
|
|
||||||
|
|
||||||
/* wind back scrollend pointer by the current screen */
|
|
||||||
while (rows < y && TAILQ_NEXT(scrollend, entries) != NULL) {
|
|
||||||
scrollend = TAILQ_NEXT(scrollend, entries);
|
|
||||||
rows += (scrollend->len - 1) / ws.ws_col + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rows <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* wind back scrollend pointer n lines */
|
|
||||||
for (rows = 0; rows + extra < n &&
|
|
||||||
TAILQ_NEXT(scrollend, entries) != NULL; rows++) {
|
|
||||||
scrollend = TAILQ_NEXT(scrollend, entries);
|
|
||||||
extra += (scrollend->len - 1) / ws.ws_col;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* move the text in terminal rows lines down */
|
|
||||||
dprintf(STDOUT_FILENO, "\033[%dT", n);
|
|
||||||
/* set cursor position to upper left corner */
|
|
||||||
write(STDOUT_FILENO, "\033[0;0H", 6);
|
|
||||||
/* hide cursor */
|
|
||||||
write(STDOUT_FILENO, "\033[?25l", 6);
|
|
||||||
|
|
||||||
/* remove newline of first line as we are at 0,0 already */
|
|
||||||
if (scrollend->size > 0 && scrollend->buf[0] == '\n')
|
|
||||||
write(STDOUT_FILENO, scrollend->buf + 1, scrollend->size - 1);
|
|
||||||
else
|
|
||||||
write(STDOUT_FILENO, scrollend->buf, scrollend->size);
|
|
||||||
if (y + n >= ws.ws_row)
|
|
||||||
bottom = TAILQ_NEXT(bottom, entries);
|
|
||||||
|
|
||||||
/* print rows lines and move bottom forward to the new screen bottom */
|
|
||||||
for (; rows > 1; rows--) {
|
|
||||||
scrollend = TAILQ_PREV(scrollend, tailhead, entries);
|
|
||||||
if (y + n >= ws.ws_row)
|
|
||||||
bottom = TAILQ_NEXT(bottom, entries);
|
|
||||||
write(STDOUT_FILENO, scrollend->buf, scrollend->size);
|
|
||||||
}
|
|
||||||
/* move cursor from line n to the old bottom position */
|
|
||||||
if (y + n < ws.ws_row) {
|
|
||||||
dprintf(STDOUT_FILENO, "\033[%d;%dH", y + n, x);
|
|
||||||
write(STDOUT_FILENO, "\033[?25h", 6); /* show cursor */
|
|
||||||
} else
|
|
||||||
dprintf(STDOUT_FILENO, "\033[%d;0H", ws.ws_row);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
scrolldown(char *buf, size_t size, int n)
|
|
||||||
{
|
|
||||||
if (bottom == NULL || bottom == TAILQ_FIRST(&head))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (n < 0) /* scroll by fraction of ws.ws_row, but at least one line */
|
|
||||||
n = ws.ws_row > (-n) ? ws.ws_row / (-n) : 1;
|
|
||||||
|
|
||||||
bottom = TAILQ_PREV(bottom, tailhead, entries);
|
|
||||||
/* print n lines */
|
|
||||||
while (n > 0 && bottom != NULL && bottom != TAILQ_FIRST(&head)) {
|
|
||||||
bottom = TAILQ_PREV(bottom, tailhead, entries);
|
|
||||||
write(STDOUT_FILENO, bottom->buf, bottom->size);
|
|
||||||
n -= (bottom->len - 1) / ws.ws_col + 1;
|
|
||||||
}
|
|
||||||
if (n > 0 && bottom == TAILQ_FIRST(&head)) {
|
|
||||||
write(STDOUT_FILENO, "\033[?25h", 6); /* show cursor */
|
|
||||||
write(STDOUT_FILENO, buf, size);
|
|
||||||
} else if (bottom != NULL)
|
|
||||||
bottom = TAILQ_NEXT(bottom, entries);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
jumpdown(char *buf, size_t size)
|
|
||||||
{
|
|
||||||
int rows = ws.ws_row;
|
|
||||||
|
|
||||||
/* wind back by one page starting from the latest line */
|
|
||||||
bottom = TAILQ_FIRST(&head);
|
|
||||||
for (; TAILQ_NEXT(bottom, entries) != NULL && rows > 0; rows--)
|
|
||||||
bottom = TAILQ_NEXT(bottom, entries);
|
|
||||||
|
|
||||||
scrolldown(buf, size, ws.ws_row);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
usage(void) {
|
|
||||||
die("usage: %s [-Mvh] [-m mem] [program]", argv0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int ch;
|
|
||||||
struct rlimit rlimit;
|
|
||||||
|
|
||||||
argv0 = argv[0];
|
|
||||||
|
|
||||||
if (getrlimit(RLIMIT_DATA, &rlimit) == -1)
|
|
||||||
die("getrlimit");
|
|
||||||
|
|
||||||
const char *optstring = "Mm:vh";
|
|
||||||
while ((ch = getopt(argc, argv, optstring)) != -1) {
|
|
||||||
switch (ch) {
|
|
||||||
case 'M':
|
|
||||||
rlimit.rlim_cur = rlimit.rlim_max;
|
|
||||||
break;
|
|
||||||
case 'm':
|
|
||||||
rlimit.rlim_cur = strtoull(optarg, NULL, 0);
|
|
||||||
if (errno != 0)
|
|
||||||
die("strtoull: %s", optarg);
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
die("%s " VERSION, argv0);
|
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
default:
|
|
||||||
usage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
argc -= optind;
|
|
||||||
argv += optind;
|
|
||||||
|
|
||||||
TAILQ_INIT(&head);
|
|
||||||
|
|
||||||
if (isatty(STDIN_FILENO) == 0 || isatty(STDOUT_FILENO) == 0)
|
|
||||||
die("parent it not a tty");
|
|
||||||
|
|
||||||
/* save terminal settings for resetting after exit */
|
|
||||||
if (tcgetattr(STDIN_FILENO, &dfl) == -1)
|
|
||||||
die("tcgetattr:");
|
|
||||||
if (atexit(reset))
|
|
||||||
die("atexit:");
|
|
||||||
|
|
||||||
/* get window size of the terminal */
|
|
||||||
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1)
|
|
||||||
die("ioctl:");
|
|
||||||
|
|
||||||
child = forkpty(&mfd, NULL, &dfl, &ws);
|
|
||||||
if (child == -1)
|
|
||||||
die("forkpty:");
|
|
||||||
if (child == 0) { /* child */
|
|
||||||
if (argc >= 1) {
|
|
||||||
execvp(argv[0], argv);
|
|
||||||
} else {
|
|
||||||
struct passwd *passwd = getpwuid(getuid());
|
|
||||||
if (passwd == NULL)
|
|
||||||
die("getpwid:");
|
|
||||||
execlp(passwd->pw_shell, passwd->pw_shell, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
perror("execvp");
|
|
||||||
_exit(127);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set maximum memory size for scrollback buffer */
|
|
||||||
if (setrlimit(RLIMIT_DATA, &rlimit) == -1)
|
|
||||||
die("setrlimit:");
|
|
||||||
|
|
||||||
#ifdef __OpenBSD__
|
|
||||||
if (pledge("stdio tty proc", NULL) == -1)
|
|
||||||
die("pledge:");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (signal(SIGWINCH, sigwinch) == SIG_ERR)
|
|
||||||
die("signal:");
|
|
||||||
|
|
||||||
struct termios new = dfl;
|
|
||||||
cfmakeraw(&new);
|
|
||||||
new.c_cc[VMIN ] = 1; /* return read if at least one byte in buffer */
|
|
||||||
new.c_cc[VTIME] = 0; /* no polling time for read from terminal */
|
|
||||||
if (tcsetattr(STDIN_FILENO, TCSANOW, &new) == -1)
|
|
||||||
die("tcsetattr:");
|
|
||||||
|
|
||||||
size_t size = BUFSIZ, len = 0, pos = 0;
|
|
||||||
char *buf = calloc(size, sizeof *buf);
|
|
||||||
if (buf == NULL)
|
|
||||||
die("calloc:");
|
|
||||||
|
|
||||||
struct pollfd pfd[2] = {
|
|
||||||
{STDIN_FILENO, POLLIN, 0},
|
|
||||||
{mfd, POLLIN, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
char input[BUFSIZ];
|
|
||||||
|
|
||||||
if (poll(pfd, LENGTH(pfd), -1) == -1 && errno != EINTR)
|
|
||||||
die("poll:");
|
|
||||||
|
|
||||||
if (doredraw) {
|
|
||||||
redraw();
|
|
||||||
doredraw = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pfd[0].revents & POLLHUP || pfd[1].revents & POLLHUP)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (pfd[0].revents & POLLIN) {
|
|
||||||
ssize_t n = read(STDIN_FILENO, input, sizeof(input)-1);
|
|
||||||
|
|
||||||
if (n == -1 && errno != EINTR)
|
|
||||||
die("read:");
|
|
||||||
if (n == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
input[n] = '\0';
|
|
||||||
|
|
||||||
if (altscreen)
|
|
||||||
goto noevent;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < LENGTH(rules); i++) {
|
|
||||||
if (strncmp(rules[i].seq, input,
|
|
||||||
strlen(rules[i].seq)) == 0) {
|
|
||||||
if (rules[i].event == SCROLL_UP)
|
|
||||||
scrollup(rules[i].lines);
|
|
||||||
if (rules[i].event == SCROLL_DOWN)
|
|
||||||
scrolldown(buf, len,
|
|
||||||
rules[i].lines);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
noevent:
|
|
||||||
if (write(mfd, input, n) == -1)
|
|
||||||
die("write:");
|
|
||||||
|
|
||||||
if (bottom != TAILQ_FIRST(&head))
|
|
||||||
jumpdown(buf, len);
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
if (pfd[1].revents & POLLIN) {
|
|
||||||
ssize_t n = read(mfd, input, sizeof(input)-1);
|
|
||||||
|
|
||||||
if (n == -1 && errno != EINTR)
|
|
||||||
die("read:");
|
|
||||||
if (n == 0) /* on exit of child we continue here */
|
|
||||||
continue; /* let signal handler catch SIGCHLD */
|
|
||||||
|
|
||||||
input[n] = '\0';
|
|
||||||
|
|
||||||
/* don't print child output while scrolling */
|
|
||||||
if (bottom == TAILQ_FIRST(&head))
|
|
||||||
if (write(STDOUT_FILENO, input, n) == -1)
|
|
||||||
die("write:");
|
|
||||||
|
|
||||||
/* iterate over the input buffer */
|
|
||||||
for (char *c = input; n-- > 0; c++) {
|
|
||||||
/* don't save alternative screen and */
|
|
||||||
/* clear screen esc sequences to scrollback */
|
|
||||||
if (skipesc(*c))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (*c == '\n') {
|
|
||||||
addline(buf, len);
|
|
||||||
/* only advance bottom if scroll is */
|
|
||||||
/* at the end of the scroll back */
|
|
||||||
if (bottom == NULL ||
|
|
||||||
TAILQ_PREV(bottom, tailhead,
|
|
||||||
entries) == TAILQ_FIRST(&head))
|
|
||||||
bottom = TAILQ_FIRST(&head);
|
|
||||||
|
|
||||||
memset(buf, 0, size);
|
|
||||||
len = pos = 0;
|
|
||||||
buf[pos++] = '\r';
|
|
||||||
} else if (*c == '\r') {
|
|
||||||
pos = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
buf[pos++] = *c;
|
|
||||||
if (pos > len)
|
|
||||||
len = pos;
|
|
||||||
if (len == size) {
|
|
||||||
size *= 2;
|
|
||||||
buf = earealloc(buf, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (close(mfd) == -1)
|
|
||||||
die("close:");
|
|
||||||
|
|
||||||
int status;
|
|
||||||
if (waitpid(child, &status, 0) == -1)
|
|
||||||
die("waitpid:");
|
|
||||||
|
|
||||||
return WEXITSTATUS(status);
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
export POSIXLY_CORRECT=1
|
|
||||||
|
|
||||||
i=1
|
|
||||||
while test "$i" -lt 50; do
|
|
||||||
echo "$i"
|
|
||||||
i=$((i + 1))
|
|
||||||
done > tmp.log
|
|
||||||
|
|
||||||
(sleep 1; printf '\033[5;2~'; sleep 1; ) \
|
|
||||||
| ./ptty ./scroll tail -fn 50 tmp.log > out.log
|
|
||||||
|
|
||||||
cmp out.log up.log
|
|
Reference in a new issue