Archived
0
0
Fork 0

did some stuff

This commit is contained in:
Daryl Ronningen 2022-01-08 21:28:34 -08:00
parent 07e93d26c9
commit 2effb6196f
20 changed files with 58 additions and 1259 deletions

View file

@ -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

View file

@ -3,6 +3,9 @@
# Autostart
xrandr --display 0 144 &
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 &
sxhkd &
xrdb $HOME/.Xresources
@ -15,10 +18,11 @@ pgrep -x pasystray > /dev/null || pasystray &
pgrep -x xscreensaver > /dev/null || xscreensaver -no-splash &
pgrep -x picom > /dev/null || picom --config $HOME/.config/picom/picom.conf &
pgrep -x wmname > /dev/null || wmname LG3D &
gnome-keyring-daemon --start &
# Set workspaces
bspc monitor DP-2 1 2 3 4 5
bspc monitor HDMI-0 6 7 8 9 0
bspc monitor DP-2 -d 1 2 3 4 5
bspc monitor HDMI-0 -d 6 7 8 9 0
# BSPWM config
bspc config border_width 1

42
.config/starship.toml Normal file
View 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)"

View file

@ -1,6 +1,6 @@
# Terminal
super + Return
tabbed -r 2 st -w ''
tabbed -c -r 2 st -w ''
# Rofi
super + space

View file

@ -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")

View file

@ -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

View file

@ -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

8
.zshrc
View file

@ -10,7 +10,7 @@ export PATH=$HOME/flutter/bin:$HOME/.cargo/bin:$HOME/.local/bin:$HOME/.dotnet/to
export ZSH="$HOME/.oh-my-zsh"
# omz configs
ZSH_THEME="powerlevel10k/powerlevel10k"
# ZSH_THEME="powerlevel10k/powerlevel10k"
# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" )
# CASE_SENSITIVE="true"
HYPHEN_INSENSITIVE="true"
@ -24,7 +24,7 @@ ENABLE_CORRECTION="true"
COMPLETION_WAITING_DOTS="true"
# 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
export NVM_AUTOLOAD=1
@ -53,7 +53,6 @@ alias cat="bat"
alias parrot="curl parrot.live"
alias neofetch="neofetch | lolcat"
alias grep="batgrep"
alias pacman="paru"
alias man="batman"
alias gitdiff="batdiff"
@ -145,5 +144,8 @@ export QT_QPA_PLATFORMTHEME=qt5ct
# Load nvm
source /usr/share/nvm/init-nvm.sh
# Set starship Prompt
eval "$(starship init zsh)"
# Neofetch cuz its cool
neofetch | lolcat

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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 */
};

View file

@ -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 */
};

View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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 .

View file

@ -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);
}

View file

@ -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