~kaction/dvtm

04ecc6eb9663fd1c4879605f047ca3f833251696 — Dmitry Bogatov 7 months ago 311a8c0 + 343e8b3
Merge branch 'next'

* next:
  Configure continous integration
  Makefile: fix variable substitution syntax
  Ensure compatibility with v0.15 config
  vt_forkpty: check for success of chdir(2)
  Display control keys, when typed, next to Layout icon
  copymode: Set cwd so paths make sense in editor
  Added the package for Void Linux, and fixed some distro names.
  When updating the title, mark the window as dirty
  Don't ignore SIGPIPE in children
  Fix minor memory leak in command line parsing
  README: Add Guix System
  Add support for "smam" and "rmam" capabilities
10 files changed, 119 insertions(+), 32 deletions(-)

A .builds/alpine.yml
A .builds/nixos.yml
A .builds/openbsd.yml
M Makefile
M README.md
M config.def.h
M config.mk
M dvtm.c
M dvtm.info
M vt.c
A .builds/alpine.yml => .builds/alpine.yml +10 -0
@@ 0,0 1,10 @@
image: alpine/latest
packages:
  - ncurses-dev
  - make
sources:
  - https://git.sr.ht/~kaction/dvtm
tasks:
  - build: |
      cd dvtm
      make

A .builds/nixos.yml => .builds/nixos.yml +7 -0
@@ 0,0 1,7 @@
image: nixos/latest
sources:
  - https://git.sr.ht/~kaction/dvtm
tasks:
  - build: |
      cd dvtm
      nix-shell -p ncurses -p gnumake --run make

A .builds/openbsd.yml => .builds/openbsd.yml +10 -0
@@ 0,0 1,10 @@
image: openbsd/latest
packages:
  - ncurses
  - gmake
sources:
  - https://git.sr.ht/~kaction/dvtm
tasks:
  - build: |
      cd dvtm
      gmake CPPFLAGS=

M Makefile => Makefile +23 -23
@@ 5,8 5,8 @@ BIN = dvtm dvtm-status dvtm-editor dvtm-pager
MANUALS = dvtm.1 dvtm-editor.1 dvtm-pager.1

VERSION = $(shell git describe --always --dirty 2>/dev/null || echo "0.15-git")
CFLAGS += -DVERSION=\"${VERSION}\"
DEBUG_CFLAGS = ${CFLAGS} -UNDEBUG -O0 -g -ggdb -Wall -Wextra -Wno-unused-parameter
CFLAGS += -DVERSION=\"$(VERSION)\"
DEBUG_CFLAGS = $(CFLAGS) -UNDEBUG -O0 -g -ggdb -Wall -Wextra -Wno-unused-parameter

all: dvtm dvtm-editor



@@ 14,19 14,19 @@ config.h:
	cp config.def.h config.h

dvtm: config.h config.mk *.c *.h
	${CC} ${CFLAGS} ${SRC} ${LDFLAGS} ${LIBS} -o $@
	$(CC) $(CFLAGS) $(SRC) $(LDFLAGS) $(LIBS) -o $@

dvtm-editor: dvtm-editor.c
	${CC} ${CFLAGS} $^ ${LDFLAGS} -o $@
	$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@

man:
	@for m in ${MANUALS}; do \
	@for m in $(MANUALS); do \
		echo "Generating $$m"; \
		sed -e "s/VERSION/${VERSION}/" "$$m" | mandoc -W warning -T utf8 -T xhtml -O man=%N.%S.html -O style=mandoc.css 1> "$$m.html" || true; \
	done

debug: clean
	@$(MAKE) CFLAGS='${DEBUG_CFLAGS}'
	@$(MAKE) CFLAGS='$(DEBUG_CFLAGS)'

clean:
	@echo cleaning


@@ 35,30 35,30 @@ clean:

dist: clean
	@echo creating dist tarball
	@git archive --prefix=dvtm-${VERSION}/ -o dvtm-${VERSION}.tar.gz HEAD
	@git archive --prefix=dvtm-$(VERSION)/ -o dvtm-$(VERSION).tar.gz HEAD

install: all
	@mkdir -p ${DESTDIR}${PREFIX}/bin
	@for b in ${BIN}; do \
		echo "installing ${DESTDIR}${PREFIX}/bin/$$b"; \
		cp -f "$$b" "${DESTDIR}${PREFIX}/bin" && \
		chmod 755 "${DESTDIR}${PREFIX}/bin/$$b"; \
	@mkdir -p $(DESTDIR)$(PREFIX)/bin
	@for b in $(BIN); do \
		echo "installing $(DESTDIR)$(PREFIX)/bin/$$b"; \
		cp -f "$$b" "$(DESTDIR)$(PREFIX)/bin" && \
		chmod 755 "$(DESTDIR)$(PREFIX)/bin/$$b"; \
	done
	@echo installing manual page to ${DESTDIR}${MANPREFIX}/man1
	@mkdir -p ${DESTDIR}${MANPREFIX}/man1
	@for m in ${MANUALS}; do \
		sed -e "s/VERSION/${VERSION}/" < "$$m" >  "${DESTDIR}${MANPREFIX}/man1/$$m" && \
		chmod 644 "${DESTDIR}${MANPREFIX}/man1/$$m"; \
	@echo installing manual page to $(DESTDIR)$(MANPREFIX)/man1
	@mkdir -p $(DESTDIR)$(MANPREFIX)/man1
	@for m in $(MANUALS); do \
		sed -e "s/VERSION/$(VERSION)/" < "$$m" >  "$(DESTDIR)$(MANPREFIX)/man1/$$m" && \
		chmod 644 "$(DESTDIR)$(MANPREFIX)/man1/$$m"; \
	done
	@echo installing terminfo description
	@TERMINFO=${TERMINFO} tic -s dvtm.info
	@TERMINFO=$(TERMINFO) tic -s dvtm.info

uninstall:
	@for b in ${BIN}; do \
		echo "removing ${DESTDIR}${PREFIX}/bin/$$b"; \
		rm -f "${DESTDIR}${PREFIX}/bin/$$b"; \
	@for b in $(BIN); do \
		echo "removing $(DESTDIR)$(PREFIX)/bin/$$b"; \
		rm -f "$(DESTDIR)$(PREFIX)/bin/$$b"; \
	done
	@echo removing manual page from ${DESTDIR}${MANPREFIX}/man1
	@rm -f ${DESTDIR}${MANPREFIX}/man1/dvtm.1
	@echo removing manual page from $(DESTDIR)$(MANPREFIX)/man1
	@rm -f $(DESTDIR)$(MANPREFIX)/man1/dvtm.1

.PHONY: all clean dist install uninstall debug

M README.md => README.md +3 -1
@@ 67,8 67,10 @@ or use one of the distribution provided packages:
 * [Ubuntu](http://packages.ubuntu.com/dvtm)
 * [Fedora](https://admin.fedoraproject.org/pkgdb/package/dvtm/)
 * [openSUSE](http://software.opensuse.org/package/dvtm?search_term=dvtm)
 * [ArchLinux](http://www.archlinux.org/packages/?q=dvtm)
 * [Arch Linux](http://www.archlinux.org/packages/?q=dvtm)
 * [Void Linux](https://github.com/voidlinux/void-packages/tree/master/srcpkgs/dvtm)
 * [Gentoo](http://packages.gentoo.org/package/app-misc/dvtm)
 * [Guix System](http://guix.gnu.org/en/packages/dvtm-0.15/)
 * [Slackware](http://slackbuilds.org/result/?search=dvtm)
 * [FreeBSD](http://www.freshports.org/sysutils/dvtm/)
 * [NetBSD](http://www.pkgsrc.se/misc/dvtm/)

M config.def.h => config.def.h +8 -0
@@ 207,3 207,11 @@ static Action actions[] = {
static char const * const keytable[] = {
	/* add your custom key escape sequences */
};

/* Print dvtm's control sequence as it is typed in status bar, similar
 * to :showcmd in vim.
 *
 * Change 0 to 1 to enable.
 */
#define FEATURE_PRINT_KEYS
static const int config_print_keys = 0;

M config.mk => config.mk +3 -3
@@ 1,14 1,14 @@
# Customize below to fit your system

PREFIX ?= /usr/local
MANPREFIX = ${PREFIX}/share/man
MANPREFIX = $(PREFIX)/share/man
# specify your systems terminfo directory
# leave empty to install into your home folder
TERMINFO := ${DESTDIR}${PREFIX}/share/terminfo
TERMINFO := $(DESTDIR)$(PREFIX)/share/terminfo

INCS = -I.
LIBS = -lc -lutil -lncursesw
CPPFLAGS = -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -D_XOPEN_SOURCE_EXTENDED
CFLAGS += -std=c99 ${INCS} -DNDEBUG ${CPPFLAGS}
CFLAGS += -std=c99 $(INCS) -DNDEBUG $(CPPFLAGS)

CC ?= cc

M dvtm.c => dvtm.c +30 -3
@@ 46,6 46,17 @@ int ESCDELAY;
# define set_escdelay(d) (ESCDELAY = (d))
#endif

/*
 * This feature was introduced in 0.15.1, and this code makes sure that
 * it config file from 0.15 will continue compile as work as before.
 */

#ifndef FEATURE_PRINT_KEYS
static const int compat_print_keys = 0;
#else
static const int compat_print_keys = config_print_keys;
#endif

typedef struct {
	float mfact;
	unsigned int nmaster;


@@ 228,6 239,7 @@ extern Screen screen;
static unsigned int waw, wah, wax, way;
static Client *clients = NULL;
static char *title;
static KeyCombo keys;

#include "config.h"



@@ 354,6 366,16 @@ drawbar(void) {
	addstr(layout->symbol);
	attrset(TAG_NORMAL);

	if (compat_print_keys && keys) {
		unsigned int keycount = 0;
		while (keycount < MAX_KEYS && keys[keycount]) {
			if (keys[keycount] < ' ')
				printw("^%c", 'A' - 1 + keys[keycount++]);
			else
				printw("%c", keys[keycount++]);
		}
	}

	getyx(stdscr, y, x);
	(void)y;
	int maxwidth = screen.w - x - 2;


@@ 558,6 580,7 @@ settitle(Client *c) {
	if (t && (term = getenv("TERM")) && !strstr(term, "linux")) {
		printf("\033]0;%s\007", t);
		fflush(stdout);
		wnoutrefresh(c->window);
	}
}



@@ 1116,7 1139,8 @@ copymode(const char *args[]) {
	snprintf(argline, sizeof(argline), "+%d", line);
	argv[1] = argline;

	if (vt_forkpty(sel->editor, args[0], argv, NULL, NULL, to, from) < 0) {
	char *cwd = getcwd_by_pid(sel);
	if (vt_forkpty(sel->editor, args[0], argv, cwd, NULL, to, from) < 0) {
		vt_destroy(sel->editor);
		sel->editor = NULL;
		return;


@@ 1796,11 1820,12 @@ parse_args(int argc, char *argv[]) {
				updatebarpos();
				break;
			case 'c': {
				const char *fifo;
				char *fifo;
				cmdfifo.fd = open_or_create_fifo(argv[++arg], &cmdfifo.file);
				if (!(fifo = realpath(argv[arg], NULL)))
					error("%s\n", strerror(errno));
				setenv("DVTM_CMD_FIFO", fifo, 1);
				free(fifo);
				break;
			}
			default:


@@ 1812,7 1837,6 @@ parse_args(int argc, char *argv[]) {

int
main(int argc, char *argv[]) {
	KeyCombo keys;
	unsigned int key_index = 0;
	memset(keys, 0, sizeof(keys));
	sigset_t emptyset, blockset;


@@ 1898,6 1922,9 @@ main(int argc, char *argv[]) {
					memset(keys, 0, sizeof(keys));
					keypress(code);
				}
				drawbar();
				if (is_content_visible(sel))
					wnoutrefresh(sel->window);
			}
			if (r == 1) /* no data available on pty's */
				continue;

M dvtm.info => dvtm.info +2 -0
@@ 106,6 106,7 @@ dvtm|dynamic virtual terminal manager,
	ri=\EM,
	ritm=\E[23m,
	rmacs=^O,
	rmam=\E[?7l,
	rmcup=\E[2J\E[?47l\E8,
	rmir=\E[4l,
	rmso=\E[27m,


@@ 121,6 122,7 @@ dvtm|dynamic virtual terminal manager,
	sgr0=\E[m\017,
	sitm=\E[3m,
	smacs=^N,
	smam=\E[?7h,
	smcup=\E7\E[?47h,
	smir=\E[4h,
	smso=\E[7m,

M vt.c => vt.c +23 -2
@@ 184,6 184,7 @@ struct Vt {
	unsigned mousetrack:1;
	unsigned graphmode:1;
	unsigned savgraphmode:1;
	unsigned truncate:1;
	bool charsets[2];
	/* buffers and parsing state */
	char rbuf[BUFSIZ];


@@ 962,6 963,9 @@ static void interpret_csi_priv_mode(Vt *t, int param[], int pcount, bool set)
		case 6: /* set origin to relative/absolute (DECOM) */
			t->relposmode = set;
			break;
		case 7:
			t->truncate = !set;
			break;
		case 25: /* make cursor visible/invisible (DECCM) */
			t->curshid = !set;
			break;


@@ 1379,6 1383,10 @@ static void put_wc(Vt *t, wchar_t wc)
		}

		if (b->curs_col >= b->cols) {
			if (t->truncate && wc != '\n') {
				b->curs_col++;
				return;
			}
			b->curs_col = 0;
			cursor_line_down(t);
		}


@@ 1632,8 1640,21 @@ pid_t vt_forkpty(Vt *t, const char *p, const char *argv[], const char *cwd, cons
			setenv(envp[0], envp[1], 1);
		setenv("TERM", vt_term, 1);

		if (cwd)
			chdir(cwd);
		if (cwd) {
			int err = chdir(cwd);
			if (err) {
				fprintf(stderr, "\nchdir() failed. ");
				perror(cwd);
				exit(1);
			}
		}

		struct sigaction sa;
		memset(&sa, 0, sizeof sa);
		sa.sa_flags = 0;
		sigemptyset(&sa.sa_mask);
		sa.sa_handler = SIG_DFL;
		sigaction(SIGPIPE, &sa, NULL);

		execvp(p, (char *const *)argv);
		fprintf(stderr, "\nexecv() failed.\nCommand: '%s'\n", argv[0]);