switched to dwm bruh

This commit is contained in:
Clay Gomera 2022-12-19 20:15:21 -04:00
parent 5eca67badd
commit 556978c7d0
158 changed files with 11938 additions and 21 deletions

View file

Before

Width:  |  Height:  |  Size: 461 B

After

Width:  |  Height:  |  Size: 461 B

View file

Before

Width:  |  Height:  |  Size: 272 B

After

Width:  |  Height:  |  Size: 272 B

View file

Before

Width:  |  Height:  |  Size: 272 B

After

Width:  |  Height:  |  Size: 272 B

View file

Before

Width:  |  Height:  |  Size: 263 B

After

Width:  |  Height:  |  Size: 263 B

View file

Before

Width:  |  Height:  |  Size: 264 B

After

Width:  |  Height:  |  Size: 264 B

View file

Before

Width:  |  Height:  |  Size: 264 B

After

Width:  |  Height:  |  Size: 264 B

View file

Before

Width:  |  Height:  |  Size: 264 B

After

Width:  |  Height:  |  Size: 264 B

View file

Before

Width:  |  Height:  |  Size: 263 B

After

Width:  |  Height:  |  Size: 263 B

View file

Before

Width:  |  Height:  |  Size: 264 B

After

Width:  |  Height:  |  Size: 264 B

View file

Before

Width:  |  Height:  |  Size: 320 B

After

Width:  |  Height:  |  Size: 320 B

View file

Before

Width:  |  Height:  |  Size: 320 B

After

Width:  |  Height:  |  Size: 320 B

View file

Before

Width:  |  Height:  |  Size: 245 B

After

Width:  |  Height:  |  Size: 245 B

View file

Before

Width:  |  Height:  |  Size: 245 B

After

Width:  |  Height:  |  Size: 245 B

View file

Before

Width:  |  Height:  |  Size: 246 B

After

Width:  |  Height:  |  Size: 246 B

View file

Before

Width:  |  Height:  |  Size: 246 B

After

Width:  |  Height:  |  Size: 246 B

View file

Before

Width:  |  Height:  |  Size: 282 B

After

Width:  |  Height:  |  Size: 282 B

View file

Before

Width:  |  Height:  |  Size: 282 B

After

Width:  |  Height:  |  Size: 282 B

View file

Before

Width:  |  Height:  |  Size: 866 B

After

Width:  |  Height:  |  Size: 866 B

View file

Before

Width:  |  Height:  |  Size: 865 B

After

Width:  |  Height:  |  Size: 865 B

View file

Before

Width:  |  Height:  |  Size: 345 B

After

Width:  |  Height:  |  Size: 345 B

View file

Before

Width:  |  Height:  |  Size: 345 B

After

Width:  |  Height:  |  Size: 345 B

View file

Before

Width:  |  Height:  |  Size: 574 B

After

Width:  |  Height:  |  Size: 574 B

View file

Before

Width:  |  Height:  |  Size: 581 B

After

Width:  |  Height:  |  Size: 581 B

View file

Before

Width:  |  Height:  |  Size: 328 B

After

Width:  |  Height:  |  Size: 328 B

View file

Before

Width:  |  Height:  |  Size: 328 B

After

Width:  |  Height:  |  Size: 328 B

View file

Before

Width:  |  Height:  |  Size: 265 B

After

Width:  |  Height:  |  Size: 265 B

View file

Before

Width:  |  Height:  |  Size: 264 B

After

Width:  |  Height:  |  Size: 264 B

View file

Before

Width:  |  Height:  |  Size: 264 B

After

Width:  |  Height:  |  Size: 264 B

View file

Before

Width:  |  Height:  |  Size: 266 B

After

Width:  |  Height:  |  Size: 266 B

View file

Before

Width:  |  Height:  |  Size: 266 B

After

Width:  |  Height:  |  Size: 266 B

View file

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View file

Before

Width:  |  Height:  |  Size: 265 B

After

Width:  |  Height:  |  Size: 265 B

View file

Before

Width:  |  Height:  |  Size: 265 B

After

Width:  |  Height:  |  Size: 265 B

View file

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View file

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View file

@ -16,10 +16,6 @@ fi
### ENVIRONMENT VARIABLES ### ENVIRONMENT VARIABLES
export EDITOR="emacsclient -t -a ''" # $EDITOR use Emacs in terminal export EDITOR="emacsclient -t -a ''" # $EDITOR use Emacs in terminal
export VISUAL="emacsclient -c -a emacs" # $VISUAL use Emacs in GUI mode export VISUAL="emacsclient -c -a emacs" # $VISUAL use Emacs in GUI mode
export READER="zathura" # Zathura as the pdf viewer
export TERMINAL="alacritty" # Alacritty as the default terminal emulator
export BROWSER="firefox" # Firefox as the default web browser
export WM="awesome" # Awesomewm as the default Window Manager
export XDG_DATA_HOME="${XDG_DATA_HOME:="$HOME/.local/share"}" export XDG_DATA_HOME="${XDG_DATA_HOME:="$HOME/.local/share"}"
export XDG_CACHE_HOME="${XDG_CACHE_HOME:="$HOME/.cache"}" export XDG_CACHE_HOME="${XDG_CACHE_HOME:="$HOME/.cache"}"
export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:="$HOME/.config"}" export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:="$HOME/.config"}"

View file

@ -2,14 +2,14 @@
gtk-theme-name=gruvbox-dark-gtk gtk-theme-name=gruvbox-dark-gtk
gtk-icon-theme-name=gruvbox-dark-icons-gtk gtk-icon-theme-name=gruvbox-dark-icons-gtk
gtk-font-name=mononoki Nerd Font 10 gtk-font-name=mononoki Nerd Font 10
gtk-cursor-theme-name=Simp1e-Gruvbox-Dark gtk-cursor-theme-name=volantes_cursors
gtk-cursor-theme-size=0 gtk-cursor-theme-size=0
gtk-toolbar-style=GTK_TOOLBAR_BOTH_HORIZ gtk-toolbar-style=GTK_TOOLBAR_BOTH
gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR
gtk-button-images=0 gtk-button-images=1
gtk-menu-images=0 gtk-menu-images=1
gtk-enable-event-sounds=1 gtk-enable-event-sounds=1
gtk-enable-input-feedback-sounds=1 gtk-enable-input-feedback-sounds=1
gtk-xft-antialias=1 gtk-xft-antialias=1
gtk-xft-hinting=1 gtk-xft-hinting=1
gtk-xft-hintstyle=hintmedium gtk-xft-hintstyle=hintfull

View file

@ -0,0 +1,64 @@
# dmenu - dynamic menu
# See LICENSE file for copyright and license details.
include config.mk
SRC = drw.c dmenu.c stest.c util.c
OBJ = $(SRC:.c=.o)
all: options dmenu stest
options:
@echo dmenu build options:
@echo "CFLAGS = $(CFLAGS)"
@echo "LDFLAGS = $(LDFLAGS)"
@echo "CC = $(CC)"
.c.o:
$(CC) -c $(CFLAGS) $<
config.h:
cp config.def.h $@
$(OBJ): arg.h config.h config.mk drw.h
dmenu: dmenu.o drw.o util.o
$(CC) -o $@ dmenu.o drw.o util.o $(LDFLAGS)
stest: stest.o
$(CC) -o $@ stest.o $(LDFLAGS)
clean:
rm -f dmenu stest $(OBJ) dmenu-$(VERSION).tar.gz
dist: clean
mkdir -p dmenu-$(VERSION)
cp LICENSE Makefile README arg.h config.def.h config.mk dmenu.1\
drw.h util.h dmenu_path dmenu_run stest.1 $(SRC)\
dmenu-$(VERSION)
tar -cf dmenu-$(VERSION).tar dmenu-$(VERSION)
gzip dmenu-$(VERSION).tar
rm -rf dmenu-$(VERSION)
install: all
mkdir -p $(DESTDIR)$(PREFIX)/bin
cp -f dmenu dmenu_path dmenu_run stest $(DESTDIR)$(PREFIX)/bin
chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu
chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_path
chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_run
chmod 755 $(DESTDIR)$(PREFIX)/bin/stest
mkdir -p $(DESTDIR)$(MANPREFIX)/man1
sed "s/VERSION/$(VERSION)/g" < dmenu.1 > $(DESTDIR)$(MANPREFIX)/man1/dmenu.1
sed "s/VERSION/$(VERSION)/g" < stest.1 > $(DESTDIR)$(MANPREFIX)/man1/stest.1
chmod 644 $(DESTDIR)$(MANPREFIX)/man1/dmenu.1
chmod 644 $(DESTDIR)$(MANPREFIX)/man1/stest.1
uninstall:
rm -f $(DESTDIR)$(PREFIX)/bin/dmenu\
$(DESTDIR)$(PREFIX)/bin/dmenu_path\
$(DESTDIR)$(PREFIX)/bin/dmenu_run\
$(DESTDIR)$(PREFIX)/bin/stest\
$(DESTDIR)$(MANPREFIX)/man1/dmenu.1\
$(DESTDIR)$(MANPREFIX)/man1/stest.1
.PHONY: all options clean dist install uninstall

View file

@ -0,0 +1,49 @@
/*
* Copy me if you can.
* by 20h
*/
#ifndef ARG_H__
#define ARG_H__
extern char *argv0;
/* use main(int argc, char *argv[]) */
#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\
argv[0] && argv[0][0] == '-'\
&& argv[0][1];\
argc--, argv++) {\
char argc_;\
char **argv_;\
int brk_;\
if (argv[0][1] == '-' && argv[0][2] == '\0') {\
argv++;\
argc--;\
break;\
}\
for (brk_ = 0, argv[0]++, argv_ = argv;\
argv[0][0] && !brk_;\
argv[0]++) {\
if (argv_ != argv)\
break;\
argc_ = argv[0][0];\
switch (argc_)
#define ARGEND }\
}
#define ARGC() argc_
#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\
((x), abort(), (char *)0) :\
(brk_ = 1, (argv[0][1] != '\0')?\
(&argv[0][1]) :\
(argc--, argv++, argv[0])))
#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\
(char *)0 :\
(brk_ = 1, (argv[0][1] != '\0')?\
(&argv[0][1]) :\
(argc--, argv++, argv[0])))
#endif

View file

@ -0,0 +1,27 @@
/* See LICENSE file for copyright and license details. */
/* Default settings; can be overriden by command line. */
static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
static int fuzzy = 1; /* -F option; if 0, dmenu doesn't use fuzzy matching */
/* -fn option overrides fonts[0]; default X11 font or font set */
static const char *fonts[] = {
"mononoki Nerd Font Mono:size=10"
};
static const char *prompt = NULL; /* -p option; prompt to the left of input field */
static const char *colors[SchemeLast][2] = {
/* fg bg */
[SchemeNorm] = { "#ebdbb2", "#1d2021" },
[SchemeSel] = { "#ebdbb2", "#cc241d" },
[SchemeSelHighlight] = { "#fbf1c7", "#282828" },
[SchemeNormHighlight] = { "#fbf1c7", "#282828" },
[SchemeOut] = { "#ebdbb2", "#8ec07c" },
[SchemeOutHighlight] = { "#fabd2f", "#83a598" },
};
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
static unsigned int lines = 0;
/*
* Characters not considered part of a word while deleting words
* for example: " /?\"&[]"
*/
static const char worddelimiters[] = " ";

View file

@ -0,0 +1,32 @@
# dmenu version
VERSION = 5.2
# paths
PREFIX = /usr/local
MANPREFIX = $(PREFIX)/share/man
X11INC = /usr/X11R6/include
X11LIB = /usr/X11R6/lib
# Xinerama, comment if you don't want it
XINERAMALIBS = -lXinerama
XINERAMAFLAGS = -DXINERAMA
# freetype
FREETYPELIBS = -lfontconfig -lXft
FREETYPEINC = /usr/include/freetype2
# OpenBSD (uncomment)
#FREETYPEINC = $(X11INC)/freetype2
#MANPREFIX = ${PREFIX}/man
# includes and libs
INCS = -I$(X11INC) -I$(FREETYPEINC)
LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) -lm
# flags
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS)
CFLAGS = -std=c99 -pedantic -Wall -Os $(INCS) $(CPPFLAGS)
LDFLAGS = $(LIBS)
# compiler and linker
CC = cc

View file

@ -0,0 +1,197 @@
.TH DMENU 1 dmenu\-VERSION
.SH NAME
dmenu \- dynamic menu
.SH SYNOPSIS
.B dmenu
.RB [ \-bfivP ]
.RB [ \-l
.IR lines ]
.RB [ \-m
.IR monitor ]
.RB [ \-p
.IR prompt ]
.RB [ \-fn
.IR font ]
.RB [ \-nb
.IR color ]
.RB [ \-nf
.IR color ]
.RB [ \-sb
.IR color ]
.RB [ \-sf
.IR color ]
.RB [ \-w
.IR windowid ]
.P
.BR dmenu_run " ..."
.SH DESCRIPTION
.B dmenu
is a dynamic menu for X, which reads a list of newline\-separated items from
stdin. When the user selects an item and presses Return, their choice is printed
to stdout and dmenu terminates. Entering text will narrow the items to those
matching the tokens in the input.
.P
.B dmenu_run
is a script used by
.IR dwm (1)
which lists programs in the user's $PATH and runs the result in their $SHELL.
.SH OPTIONS
.TP
.B \-b
dmenu appears at the bottom of the screen.
.TP
.B \-f
dmenu grabs the keyboard before reading stdin if not reading from a tty. This
is faster, but will lock up X until stdin reaches end\-of\-file.
.TP
.B \-i
dmenu matches menu items case insensitively.
.TP
.B \-P
dmenu will not directly display the keyboard input, but instead replace it with dots. All data from stdin will be ignored.
.TP
.BI \-l " lines"
dmenu lists items vertically, with the given number of lines.
.TP
.BI \-m " monitor"
dmenu is displayed on the monitor number supplied. Monitor numbers are starting
from 0.
.TP
.BI \-p " prompt"
defines the prompt to be displayed to the left of the input field.
.TP
.BI \-fn " font"
defines the font or font set used.
.TP
.BI \-nb " color"
defines the normal background color.
.IR #RGB ,
.IR #RRGGBB ,
and X color names are supported.
.TP
.BI \-nf " color"
defines the normal foreground color.
.TP
.BI \-sb " color"
defines the selected background color.
.TP
.BI \-sf " color"
defines the selected foreground color.
.TP
.B \-v
prints version information to stdout, then exits.
.TP
.BI \-w " windowid"
embed into windowid.
.SH USAGE
dmenu is completely controlled by the keyboard. Items are selected using the
arrow keys, page up, page down, home, and end.
.TP
.B Tab
Copy the selected item to the input field.
.TP
.B Return
Confirm selection. Prints the selected item to stdout and exits, returning
success.
.TP
.B Ctrl-Return
Confirm selection. Prints the selected item to stdout and continues.
.TP
.B Shift\-Return
Confirm input. Prints the input text to stdout and exits, returning success.
.TP
.B Escape
Exit without selecting an item, returning failure.
.TP
.B Ctrl-Left
Move cursor to the start of the current word
.TP
.B Ctrl-Right
Move cursor to the end of the current word
.TP
.B C\-a
Home
.TP
.B C\-b
Left
.TP
.B C\-c
Escape
.TP
.B C\-d
Delete
.TP
.B C\-e
End
.TP
.B C\-f
Right
.TP
.B C\-g
Escape
.TP
.B C\-h
Backspace
.TP
.B C\-i
Tab
.TP
.B C\-j
Return
.TP
.B C\-J
Shift-Return
.TP
.B C\-k
Delete line right
.TP
.B C\-m
Return
.TP
.B C\-M
Shift-Return
.TP
.B C\-n
Down
.TP
.B C\-p
Up
.TP
.B C\-u
Delete line left
.TP
.B C\-w
Delete word left
.TP
.B C\-y
Paste from primary X selection
.TP
.B C\-Y
Paste from X clipboard
.TP
.B M\-b
Move cursor to the start of the current word
.TP
.B M\-f
Move cursor to the end of the current word
.TP
.B M\-g
Home
.TP
.B M\-G
End
.TP
.B M\-h
Up
.TP
.B M\-j
Page down
.TP
.B M\-k
Page up
.TP
.B M\-l
Down
.SH SEE ALSO
.IR dwm (1),
.IR stest (1)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,13 @@
#!/bin/sh
cachedir="${XDG_CACHE_HOME:-"$HOME/.cache"}"
cache="$cachedir/dmenu_run"
[ ! -e "$cachedir" ] && mkdir -p "$cachedir"
IFS=:
if stest -dqr -n "$cache" $PATH; then
stest -flx $PATH | sort -u | tee "$cache"
else
cat "$cache"
fi

View file

@ -0,0 +1,2 @@
#!/bin/sh
dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} &

View file

@ -0,0 +1,450 @@
/* See LICENSE file for copyright and license details. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xft/Xft.h>
#include "drw.h"
#include "util.h"
#define UTF_INVALID 0xFFFD
#define UTF_SIZ 4
static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
static long
utf8decodebyte(const char c, size_t *i)
{
for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])
return (unsigned char)c & ~utfmask[*i];
return 0;
}
static size_t
utf8validate(long *u, size_t i)
{
if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
*u = UTF_INVALID;
for (i = 1; *u > utfmax[i]; ++i)
;
return i;
}
static size_t
utf8decode(const char *c, long *u, size_t clen)
{
size_t i, j, len, type;
long udecoded;
*u = UTF_INVALID;
if (!clen)
return 0;
udecoded = utf8decodebyte(c[0], &len);
if (!BETWEEN(len, 1, UTF_SIZ))
return 1;
for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
if (type)
return j;
}
if (j < len)
return 0;
*u = udecoded;
utf8validate(u, len);
return len;
}
Drw *
drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
{
Drw *drw = ecalloc(1, sizeof(Drw));
drw->dpy = dpy;
drw->screen = screen;
drw->root = root;
drw->w = w;
drw->h = h;
drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
drw->gc = XCreateGC(dpy, root, 0, NULL);
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
return drw;
}
void
drw_resize(Drw *drw, unsigned int w, unsigned int h)
{
if (!drw)
return;
drw->w = w;
drw->h = h;
if (drw->drawable)
XFreePixmap(drw->dpy, drw->drawable);
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
}
void
drw_free(Drw *drw)
{
XFreePixmap(drw->dpy, drw->drawable);
XFreeGC(drw->dpy, drw->gc);
drw_fontset_free(drw->fonts);
free(drw);
}
/* This function is an implementation detail. Library users should use
* drw_fontset_create instead.
*/
static Fnt *
xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
{
Fnt *font;
XftFont *xfont = NULL;
FcPattern *pattern = NULL;
if (fontname) {
/* Using the pattern found at font->xfont->pattern does not yield the
* same substitution results as using the pattern returned by
* FcNameParse; using the latter results in the desired fallback
* behaviour whereas the former just results in missing-character
* rectangles being drawn, at least with some fonts. */
if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
return NULL;
}
if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
XftFontClose(drw->dpy, xfont);
return NULL;
}
} else if (fontpattern) {
if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
fprintf(stderr, "error, cannot load font from pattern.\n");
return NULL;
}
} else {
die("no font specified.");
}
font = ecalloc(1, sizeof(Fnt));
font->xfont = xfont;
font->pattern = pattern;
font->h = xfont->ascent + xfont->descent;
font->dpy = drw->dpy;
return font;
}
static void
xfont_free(Fnt *font)
{
if (!font)
return;
if (font->pattern)
FcPatternDestroy(font->pattern);
XftFontClose(font->dpy, font->xfont);
free(font);
}
Fnt*
drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
{
Fnt *cur, *ret = NULL;
size_t i;
if (!drw || !fonts)
return NULL;
for (i = 1; i <= fontcount; i++) {
if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
cur->next = ret;
ret = cur;
}
}
return (drw->fonts = ret);
}
void
drw_fontset_free(Fnt *font)
{
if (font) {
drw_fontset_free(font->next);
xfont_free(font);
}
}
void
drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
{
if (!drw || !dest || !clrname)
return;
if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen),
clrname, dest))
die("error, cannot allocate color '%s'", clrname);
}
/* Wrapper to create color schemes. The caller has to call free(3) on the
* returned color scheme when done using it. */
Clr *
drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
{
size_t i;
Clr *ret;
/* need at least two colors for a scheme */
if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
return NULL;
for (i = 0; i < clrcount; i++)
drw_clr_create(drw, &ret[i], clrnames[i]);
return ret;
}
void
drw_setfontset(Drw *drw, Fnt *set)
{
if (drw)
drw->fonts = set;
}
void
drw_setscheme(Drw *drw, Clr *scm)
{
if (drw)
drw->scheme = scm;
}
void
drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
{
if (!drw || !drw->scheme)
return;
XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
if (filled)
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
else
XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
}
int
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
{
int i, ty, ellipsis_x = 0;
unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len;
XftDraw *d = NULL;
Fnt *usedfont, *curfont, *nextfont;
int utf8strlen, utf8charlen, render = x || y || w || h;
long utf8codepoint = 0;
const char *utf8str;
FcCharSet *fccharset;
FcPattern *fcpattern;
FcPattern *match;
XftResult result;
int charexists = 0, overflow = 0;
/* keep track of a couple codepoints for which we have no match. */
enum { nomatches_len = 64 };
static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches;
static unsigned int ellipsis_width = 0;
if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
return 0;
if (!render) {
w = invert ? invert : ~invert;
} else {
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
d = XftDrawCreate(drw->dpy, drw->drawable,
DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen));
x += lpad;
w -= lpad;
}
usedfont = drw->fonts;
if (!ellipsis_width && render)
ellipsis_width = drw_fontset_getwidth(drw, "...");
while (1) {
ew = ellipsis_len = utf8strlen = 0;
utf8str = text;
nextfont = NULL;
while (*text) {
utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
for (curfont = drw->fonts; curfont; curfont = curfont->next) {
charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
if (charexists) {
drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL);
if (ew + ellipsis_width <= w) {
/* keep track where the ellipsis still fits */
ellipsis_x = x + ew;
ellipsis_w = w - ew;
ellipsis_len = utf8strlen;
}
if (ew + tmpw > w) {
overflow = 1;
/* called from drw_fontset_getwidth_clamp():
* it wants the width AFTER the overflow
*/
if (!render)
x += tmpw;
else
utf8strlen = ellipsis_len;
} else if (curfont == usedfont) {
utf8strlen += utf8charlen;
text += utf8charlen;
ew += tmpw;
} else {
nextfont = curfont;
}
break;
}
}
if (overflow || !charexists || nextfont)
break;
else
charexists = 0;
}
if (utf8strlen) {
if (render) {
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen);
}
x += ew;
w -= ew;
}
if (render && overflow)
drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert);
if (!*text || overflow) {
break;
} else if (nextfont) {
charexists = 0;
usedfont = nextfont;
} else {
/* Regardless of whether or not a fallback font is found, the
* character must be drawn. */
charexists = 1;
for (i = 0; i < nomatches_len; ++i) {
/* avoid calling XftFontMatch if we know we won't find a match */
if (utf8codepoint == nomatches.codepoint[i])
goto no_match;
}
fccharset = FcCharSetCreate();
FcCharSetAddChar(fccharset, utf8codepoint);
if (!drw->fonts->pattern) {
/* Refer to the comment in xfont_create for more information. */
die("the first font in the cache must be loaded from a font string.");
}
fcpattern = FcPatternDuplicate(drw->fonts->pattern);
FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
FcDefaultSubstitute(fcpattern);
match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
FcCharSetDestroy(fccharset);
FcPatternDestroy(fcpattern);
if (match) {
usedfont = xfont_create(drw, NULL, match);
if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
; /* NOP */
curfont->next = usedfont;
} else {
xfont_free(usedfont);
nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint;
no_match:
usedfont = drw->fonts;
}
}
}
}
if (d)
XftDrawDestroy(d);
return x + (render ? w : 0);
}
void
drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
{
if (!drw)
return;
XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
XSync(drw->dpy, False);
}
unsigned int
drw_fontset_getwidth(Drw *drw, const char *text)
{
if (!drw || !drw->fonts || !text)
return 0;
return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
}
unsigned int
drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n)
{
unsigned int tmp = 0;
if (drw && drw->fonts && text && n)
tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n);
return MIN(n, tmp);
}
void
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
{
XGlyphInfo ext;
if (!font || !text)
return;
XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
if (w)
*w = ext.xOff;
if (h)
*h = font->h;
}
Cur *
drw_cur_create(Drw *drw, int shape)
{
Cur *cur;
if (!drw || !(cur = ecalloc(1, sizeof(Cur))))
return NULL;
cur->cursor = XCreateFontCursor(drw->dpy, shape);
return cur;
}
void
drw_cur_free(Drw *drw, Cur *cursor)
{
if (!cursor)
return;
XFreeCursor(drw->dpy, cursor->cursor);
free(cursor);
}

View file

@ -0,0 +1,58 @@
/* See LICENSE file for copyright and license details. */
typedef struct {
Cursor cursor;
} Cur;
typedef struct Fnt {
Display *dpy;
unsigned int h;
XftFont *xfont;
FcPattern *pattern;
struct Fnt *next;
} Fnt;
enum { ColFg, ColBg }; /* Clr scheme index */
typedef XftColor Clr;
typedef struct {
unsigned int w, h;
Display *dpy;
int screen;
Window root;
Drawable drawable;
GC gc;
Clr *scheme;
Fnt *fonts;
} Drw;
/* Drawable abstraction */
Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
void drw_resize(Drw *drw, unsigned int w, unsigned int h);
void drw_free(Drw *drw);
/* Fnt abstraction */
Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
void drw_fontset_free(Fnt* set);
unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n);
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
/* Colorscheme abstraction */
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
/* Cursor abstraction */
Cur *drw_cur_create(Drw *drw, int shape);
void drw_cur_free(Drw *drw, Cur *cursor);
/* Drawing context manipulation */
void drw_setfontset(Drw *drw, Fnt *set);
void drw_setscheme(Drw *drw, Clr *scm);
/* Drawing functions */
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
/* Map functions */
void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);

View file

@ -0,0 +1,163 @@
From 94353eb52055927d9079f3d9e33da1c954abf386 Mon Sep 17 00:00:00 2001
From: aleks <aleks.stier@icloud.com>
Date: Wed, 26 Jun 2019 13:25:10 +0200
Subject: [PATCH] Add support for fuzzy-matching
---
config.def.h | 1 +
config.mk | 2 +-
dmenu.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 91 insertions(+), 1 deletion(-)
diff --git a/config.def.h b/config.def.h
index 1edb647..51612b9 100644
--- a/config.def.h
+++ b/config.def.h
@@ -2,6 +2,7 @@
/* Default settings; can be overriden by command line. */
static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
+static int fuzzy = 1; /* -F option; if 0, dmenu doesn't use fuzzy matching */
/* -fn option overrides fonts[0]; default X11 font or font set */
static const char *fonts[] = {
"monospace:size=10"
diff --git a/config.mk b/config.mk
index 0929b4a..d14309a 100644
--- a/config.mk
+++ b/config.mk
@@ -20,7 +20,7 @@ FREETYPEINC = /usr/include/freetype2
# includes and libs
INCS = -I$(X11INC) -I$(FREETYPEINC)
-LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS)
+LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) -lm
# flags
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS)
diff --git a/dmenu.c b/dmenu.c
index 6b8f51b..96ddc98 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -1,6 +1,7 @@
/* See LICENSE file for copyright and license details. */
#include <ctype.h>
#include <locale.h>
+#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -32,6 +33,7 @@ struct item {
char *text;
struct item *left, *right;
int out;
+ double distance;
};
static char text[BUFSIZ] = "";
@@ -210,9 +212,94 @@ grabkeyboard(void)
die("cannot grab keyboard");
}
+int
+compare_distance(const void *a, const void *b)
+{
+ struct item *da = *(struct item **) a;
+ struct item *db = *(struct item **) b;
+
+ if (!db)
+ return 1;
+ if (!da)
+ return -1;
+
+ return da->distance == db->distance ? 0 : da->distance < db->distance ? -1 : 1;
+}
+
+void
+fuzzymatch(void)
+{
+ /* bang - we have so much memory */
+ struct item *it;
+ struct item **fuzzymatches = NULL;
+ char c;
+ int number_of_matches = 0, i, pidx, sidx, eidx;
+ int text_len = strlen(text), itext_len;
+
+ matches = matchend = NULL;
+
+ /* walk through all items */
+ for (it = items; it && it->text; it++) {
+ if (text_len) {
+ itext_len = strlen(it->text);
+ pidx = 0; /* pointer */
+ sidx = eidx = -1; /* start of match, end of match */
+ /* walk through item text */
+ for (i = 0; i < itext_len && (c = it->text[i]); i++) {
+ /* fuzzy match pattern */
+ if (!fstrncmp(&text[pidx], &c, 1)) {
+ if(sidx == -1)
+ sidx = i;
+ pidx++;
+ if (pidx == text_len) {
+ eidx = i;
+ break;
+ }
+ }
+ }
+ /* build list of matches */
+ if (eidx != -1) {
+ /* compute distance */
+ /* add penalty if match starts late (log(sidx+2))
+ * add penalty for long a match without many matching characters */
+ it->distance = log(sidx + 2) + (double)(eidx - sidx - text_len);
+ /* fprintf(stderr, "distance %s %f\n", it->text, it->distance); */
+ appenditem(it, &matches, &matchend);
+ number_of_matches++;
+ }
+ } else {
+ appenditem(it, &matches, &matchend);
+ }
+ }
+
+ if (number_of_matches) {
+ /* initialize array with matches */
+ if (!(fuzzymatches = realloc(fuzzymatches, number_of_matches * sizeof(struct item*))))
+ die("cannot realloc %u bytes:", number_of_matches * sizeof(struct item*));
+ for (i = 0, it = matches; it && i < number_of_matches; i++, it = it->right) {
+ fuzzymatches[i] = it;
+ }
+ /* sort matches according to distance */
+ qsort(fuzzymatches, number_of_matches, sizeof(struct item*), compare_distance);
+ /* rebuild list of matches */
+ matches = matchend = NULL;
+ for (i = 0, it = fuzzymatches[i]; i < number_of_matches && it && \
+ it->text; i++, it = fuzzymatches[i]) {
+ appenditem(it, &matches, &matchend);
+ }
+ free(fuzzymatches);
+ }
+ curr = sel = matches;
+ calcoffsets();
+}
+
static void
match(void)
{
+ if (fuzzy) {
+ fuzzymatch();
+ return;
+ }
static char **tokv = NULL;
static int tokn = 0;
@@ -702,6 +789,8 @@ main(int argc, char *argv[])
topbar = 0;
else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */
fast = 1;
+ else if (!strcmp(argv[i], "-F")) /* grabs keyboard before reading stdin */
+ fuzzy = 0;
else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
fstrncmp = strncasecmp;
fstrstr = cistrstr;
--
2.22.0

View file

@ -0,0 +1,97 @@
From fcdc1593ed418166f20b7e691a49b1e6eefc116e Mon Sep 17 00:00:00 2001
From: Nathaniel Evan <nathanielevan@zohomail.com>
Date: Fri, 11 Dec 2020 11:08:12 +0700
Subject: [PATCH] Highlight matched text in a different color scheme
---
config.def.h | 3 +++
dmenu.c | 44 +++++++++++++++++++++++++++++++++++++++++---
2 files changed, 44 insertions(+), 3 deletions(-)
diff --git a/config.def.h b/config.def.h
index 1edb647..79be73a 100644
--- a/config.def.h
+++ b/config.def.h
@@ -11,7 +11,10 @@ static const char *colors[SchemeLast][2] = {
/* fg bg */
[SchemeNorm] = { "#bbbbbb", "#222222" },
[SchemeSel] = { "#eeeeee", "#005577" },
+ [SchemeSelHighlight] = { "#ffc978", "#005577" },
+ [SchemeNormHighlight] = { "#ffc978", "#222222" },
[SchemeOut] = { "#000000", "#00ffff" },
+ [SchemeOutHighlight] = { "#ffc978", "#00ffff" },
};
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
static unsigned int lines = 0;
diff --git a/dmenu.c b/dmenu.c
index 65f25ce..cce1ad1 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -26,8 +26,7 @@
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
/* enums */
-enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
-
+enum { SchemeNorm, SchemeSel, SchemeOut, SchemeNormHighlight, SchemeSelHighlight, SchemeOutHighlight, SchemeLast }; /* color schemes */
struct item {
char *text;
struct item *left, *right;
@@ -113,6 +112,43 @@ cistrstr(const char *s, const char *sub)
return NULL;
}
+static void
+drawhighlights(struct item *item, int x, int y, int maxw)
+{
+ char restorechar, tokens[sizeof text], *highlight, *token;
+ int indentx, highlightlen;
+
+ drw_setscheme(drw, scheme[item == sel ? SchemeSelHighlight : item->out ? SchemeOutHighlight : SchemeNormHighlight]);
+ strcpy(tokens, text);
+ for (token = strtok(tokens, " "); token; token = strtok(NULL, " ")) {
+ highlight = fstrstr(item->text, token);
+ while (highlight) {
+ // Move item str end, calc width for highlight indent, & restore
+ highlightlen = highlight - item->text;
+ restorechar = *highlight;
+ item->text[highlightlen] = '\0';
+ indentx = TEXTW(item->text);
+ item->text[highlightlen] = restorechar;
+
+ // Move highlight str end, draw highlight, & restore
+ restorechar = highlight[strlen(token)];
+ highlight[strlen(token)] = '\0';
+ if (indentx - (lrpad / 2) - 1 < maxw)
+ drw_text(
+ drw,
+ x + indentx - (lrpad / 2) - 1,
+ y,
+ MIN(maxw - indentx, TEXTW(highlight) - lrpad),
+ bh, 0, highlight, 0
+ );
+ highlight[strlen(token)] = restorechar;
+
+ if (strlen(highlight) - strlen(token) < strlen(token)) break;
+ highlight = fstrstr(highlight + strlen(token), token);
+ }
+ }
+}
+
static int
drawitem(struct item *item, int x, int y, int w)
{
@@ -123,7 +159,9 @@ drawitem(struct item *item, int x, int y, int w)
else
drw_setscheme(drw, scheme[SchemeNorm]);
- return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0);
+ int r = drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0);
+ drawhighlights(item, x, y, w);
+ return r;
}
static void
--
2.29.2

View file

@ -0,0 +1,144 @@
diff --git a/dmenu.c b/dmenu.c
index 7cf253b..d276a94 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -528,6 +528,119 @@ draw:
drawmenu();
}
+static void
+buttonpress(XEvent *e)
+{
+ struct item *item;
+ XButtonPressedEvent *ev = &e->xbutton;
+ int x = 0, y = 0, h = bh, w;
+
+ if (ev->window != win)
+ return;
+
+ /* right-click: exit */
+ if (ev->button == Button3)
+ exit(1);
+
+ if (prompt && *prompt)
+ x += promptw;
+
+ /* input field */
+ w = (lines > 0 || !matches) ? mw - x : inputw;
+
+ /* left-click on input: clear input,
+ * NOTE: if there is no left-arrow the space for < is reserved so
+ * add that to the input width */
+ if (ev->button == Button1 &&
+ ((lines <= 0 && ev->x >= 0 && ev->x <= x + w +
+ ((!prev || !curr->left) ? TEXTW("<") : 0)) ||
+ (lines > 0 && ev->y >= y && ev->y <= y + h))) {
+ insert(NULL, -cursor);
+ drawmenu();
+ return;
+ }
+ /* middle-mouse click: paste selection */
+ if (ev->button == Button2) {
+ XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
+ utf8, utf8, win, CurrentTime);
+ drawmenu();
+ return;
+ }
+ /* scroll up */
+ if (ev->button == Button4 && prev) {
+ sel = curr = prev;
+ calcoffsets();
+ drawmenu();
+ return;
+ }
+ /* scroll down */
+ if (ev->button == Button5 && next) {
+ sel = curr = next;
+ calcoffsets();
+ drawmenu();
+ return;
+ }
+ if (ev->button != Button1)
+ return;
+ if (ev->state & ~ControlMask)
+ return;
+ if (lines > 0) {
+ /* vertical list: (ctrl)left-click on item */
+ w = mw - x;
+ for (item = curr; item != next; item = item->right) {
+ y += h;
+ if (ev->y >= y && ev->y <= (y + h)) {
+ puts(item->text);
+ if (!(ev->state & ControlMask))
+ exit(0);
+ sel = item;
+ if (sel) {
+ sel->out = 1;
+ drawmenu();
+ }
+ return;
+ }
+ }
+ } else if (matches) {
+ /* left-click on left arrow */
+ x += inputw;
+ w = TEXTW("<");
+ if (prev && curr->left) {
+ if (ev->x >= x && ev->x <= x + w) {
+ sel = curr = prev;
+ calcoffsets();
+ drawmenu();
+ return;
+ }
+ }
+ /* horizontal list: (ctrl)left-click on item */
+ for (item = curr; item != next; item = item->right) {
+ x += w;
+ w = MIN(TEXTW(item->text), mw - x - TEXTW(">"));
+ if (ev->x >= x && ev->x <= x + w) {
+ puts(item->text);
+ if (!(ev->state & ControlMask))
+ exit(0);
+ sel = item;
+ if (sel) {
+ sel->out = 1;
+ drawmenu();
+ }
+ return;
+ }
+ }
+ /* left-click on right arrow */
+ w = TEXTW(">");
+ x = mw - w;
+ if (next && ev->x >= x && ev->x <= x + w) {
+ sel = curr = next;
+ calcoffsets();
+ drawmenu();
+ return;
+ }
+ }
+}
+
static void
paste(void)
{
@@ -582,6 +695,9 @@ run(void)
break;
cleanup();
exit(1);
+ case ButtonPress:
+ buttonpress(&ev);
+ break;
case Expose:
if (ev.xexpose.count == 0)
drw_map(drw, win, 0, 0, mw, mh);
@@ -679,7 +795,8 @@ setup(void)
/* create menu window */
swa.override_redirect = True;
swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
- swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
+ swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask |
+ ButtonPressMask;
win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
CopyFromParent, CopyFromParent, CopyFromParent,
CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);

View file

@ -0,0 +1,53 @@
diff --git a/dmenu.c b/dmenu.c
index 48d4980..7677401 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -641,6 +641,29 @@ buttonpress(XEvent *e)
}
}
+static void
+motionevent(XButtonEvent *ev)
+{
+ struct item *it;
+ int xy, ev_xy;
+
+ if (ev->window != win || matches == 0)
+ return;
+
+ xy = lines > 0 ? bh : inputw + promptw + TEXTW("<");
+ ev_xy = lines > 0 ? ev->y : ev->x;
+ for (it = curr; it && it != next; it = it->right) {
+ int wh = lines > 0 ? bh : textw_clamp(it->text, mw - xy - TEXTW(">"));
+ if (ev_xy >= xy && ev_xy < (xy + wh)) {
+ sel = it;
+ calcoffsets();
+ drawmenu();
+ break;
+ }
+ xy += wh;
+ }
+}
+
static void
paste(void)
{
@@ -702,6 +725,9 @@ run(void)
case ButtonPress:
buttonpress(&ev);
break;
+ case MotionNotify:
+ motionevent(&ev.xbutton);
+ break;
case Expose:
if (ev.xexpose.count == 0)
drw_map(drw, win, 0, 0, mw, mh);
@@ -800,7 +826,7 @@ setup(void)
swa.override_redirect = True;
swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask |
- ButtonPressMask;
+ ButtonPressMask | PointerMotionMask;
win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
CopyFromParent, CopyFromParent, CopyFromParent,
CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);

View file

@ -0,0 +1,103 @@
From c4de1032bd4c247bc20b6ab92a10a8d778966679 Mon Sep 17 00:00:00 2001
From: Mehrad Mahmoudian <m.mahmoudian@gmail.com>
Date: Tue, 4 May 2021 12:05:09 +0300
Subject: [PATCH] patched with password patch
---
dmenu.1 | 5 ++++-
dmenu.c | 21 +++++++++++++++++----
2 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/dmenu.1 b/dmenu.1
index 323f93c..762f707 100644
--- a/dmenu.1
+++ b/dmenu.1
@@ -3,7 +3,7 @@
dmenu \- dynamic menu
.SH SYNOPSIS
.B dmenu
-.RB [ \-bfiv ]
+.RB [ \-bfivP ]
.RB [ \-l
.IR lines ]
.RB [ \-m
@@ -47,6 +47,9 @@ is faster, but will lock up X until stdin reaches end\-of\-file.
.B \-i
dmenu matches menu items case insensitively.
.TP
+.B \-P
+dmenu will not directly display the keyboard input, but instead replace it with dots. All data from stdin will be ignored.
+.TP
.BI \-l " lines"
dmenu lists items vertically, with the given number of lines.
.TP
diff --git a/dmenu.c b/dmenu.c
index 65f25ce..ad8f63b 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -37,7 +37,7 @@ struct item {
static char text[BUFSIZ] = "";
static char *embed;
static int bh, mw, mh;
-static int inputw = 0, promptw;
+static int inputw = 0, promptw, passwd = 0;
static int lrpad; /* sum of left and right padding */
static size_t cursor;
static struct item *items = NULL;
@@ -132,6 +132,7 @@ drawmenu(void)
unsigned int curpos;
struct item *item;
int x = 0, y = 0, w;
+ char *censort;
drw_setscheme(drw, scheme[SchemeNorm]);
drw_rect(drw, 0, 0, mw, mh, 1, 1);
@@ -143,7 +144,12 @@ drawmenu(void)
/* draw input field */
w = (lines > 0 || !matches) ? mw - x : inputw;
drw_setscheme(drw, scheme[SchemeNorm]);
- drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0);
+ if (passwd) {
+ censort = ecalloc(1, sizeof(text));
+ memset(censort, '.', strlen(text));
+ drw_text(drw, x, 0, w, bh, lrpad / 2, censort, 0);
+ free(censort);
+ } else drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0);
curpos = TEXTW(text) - TEXTW(&text[cursor]);
if ((curpos += lrpad / 2 - 1) < w) {
@@ -524,6 +530,11 @@ readstdin(void)
char buf[sizeof text], *p;
size_t i, imax = 0, size = 0;
unsigned int tmpmax = 0;
+ if(passwd){
+ inputw = lines = 0;
+ return;
+ }
+
/* read each line from stdin and add it to the item list */
for (i = 0; fgets(buf, sizeof buf, stdin); i++) {
@@ -689,7 +700,7 @@ setup(void)
static void
usage(void)
{
- fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
+ fputs("usage: dmenu [-bfivP] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
" [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
exit(1);
}
@@ -712,7 +723,9 @@ main(int argc, char *argv[])
else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
fstrncmp = strncasecmp;
fstrstr = cistrstr;
- } else if (i + 1 == argc)
+ } else if (!strcmp(argv[i], "-P")) /* is the input a password */
+ passwd = 1;
+ else if (i + 1 == argc)
usage();
/* these options take one argument */
else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */
--
2.31.1

View file

@ -0,0 +1,317 @@
#!/usr/bin/env bash
# _ _ _ _ _ _
# __| |_ __ ___ ___ _ __ _ _ | |__ | |_ _ ___| |_ ___ ___ | |_ | |__
# / _` | '_ ` _ \ / _ \ '_ \| | | |_____| '_ \| | | | |/ _ \ __/ _ \ / _ \| __|| '_ \
# | (_| | | | | | | __/ | | | |_| |_____| |_) | | |_| | __/ || (_) | (_) | |_ | | | |
# \__,_|_| |_| |_|\___|_| |_|\__,_| |_.__/|_|\__,_|\___|\__\___/ \___/ \__||_| |_|
#
# Author: Nick Clyde (clydedroid)
# dmenu support by: Layerex
#
# A script that generates a dmenu menu that uses bluetoothctl to
# connect to bluetooth devices and display status info.
#
# Inspired by networkmanager-dmenu (https://github.com/firecat53/networkmanager-dmenu)
# Thanks to x70b1 (https://github.com/polybar/polybar-scripts/tree/master/polybar-scripts/system-bluetooth-bluetoothctl)
#
# Depends on:
# Arch repositories: dmenu, bluez-utils (contains bluetoothctl)
# Constants
divider="---------"
goback="Back"
# Checks if bluetooth controller is powered on
power_on() {
if bluetoothctl show | grep -F -q "Powered: yes"; then
return 0
else
return 1
fi
}
# Toggles power state
toggle_power() {
if power_on; then
bluetoothctl power off
show_menu
else
if rfkill list bluetooth | grep -F -q 'blocked: yes'; then
rfkill unblock bluetooth && sleep 3
fi
bluetoothctl power on
show_menu
fi
}
# Checks if controller is scanning for new devices
scan_on() {
if bluetoothctl show | grep -F -q "Discovering: yes"; then
echo "Scan: on"
return 0
else
echo "Scan: off"
return 1
fi
}
# Toggles scanning state
toggle_scan() {
if scan_on; then
kill "$(pgrep -F -f "bluetoothctl scan on")"
bluetoothctl scan off
show_menu
else
bluetoothctl scan on &
echo "Scanning..."
sleep 5
show_menu
fi
}
# Checks if controller is able to pair to devices
pairable_on() {
if bluetoothctl show | grep -F -q "Pairable: yes"; then
echo "Pairable: on"
return 0
else
echo "Pairable: off"
return 1
fi
}
# Toggles pairable state
toggle_pairable() {
if pairable_on; then
bluetoothctl pairable off
show_menu
else
bluetoothctl pairable on
show_menu
fi
}
# Checks if controller is discoverable by other devices
discoverable_on() {
if bluetoothctl show | grep -F -q "Discoverable: yes"; then
echo "Discoverable: on"
return 0
else
echo "Discoverable: off"
return 1
fi
}
# Toggles discoverable state
toggle_discoverable() {
if discoverable_on; then
bluetoothctl discoverable off
show_menu
else
bluetoothctl discoverable on
show_menu
fi
}
# Checks if a device is connected
device_connected() {
device_info=$(bluetoothctl info "$1")
if echo "$device_info" | grep -F -q "Connected: yes"; then
return 0
else
return 1
fi
}
# Toggles device connection
toggle_connection() {
if device_connected "$1"; then
bluetoothctl disconnect "$1"
# device_menu "$device"
else
bluetoothctl connect "$1"
# device_menu "$device"
fi
}
# Checks if a device is paired
device_paired() {
device_info=$(bluetoothctl info "$1")
if echo "$device_info" | grep -F -q "Paired: yes"; then
echo "Paired: yes"
return 0
else
echo "Paired: no"
return 1
fi
}
# Toggles device paired state
toggle_paired() {
if device_paired "$1"; then
bluetoothctl remove "$1"
device_menu "$device"
else
bluetoothctl pair "$1"
device_menu "$device"
fi
}
# Checks if a device is trusted
device_trusted() {
device_info=$(bluetoothctl info "$1")
if echo "$device_info" | grep -F -q "Trusted: yes"; then
echo "Trusted: yes"
return 0
else
echo "Trusted: no"
return 1
fi
}
# Toggles device connection
toggle_trust() {
if device_trusted "$1"; then
bluetoothctl untrust "$1"
device_menu "$device"
else
bluetoothctl trust "$1"
device_menu "$device"
fi
}
# Prints a short string with the current bluetooth status
# Useful for status bars like polybar, etc.
print_status() {
if power_on; then
printf ''
mapfile -t paired_devices < <(bluetoothctl paired-devices | grep -F Device | cut -d ' ' -f 2)
counter=0
for device in "${paired_devices[@]}"; do
if device_connected "$device"; then
device_alias="$(bluetoothctl info "$device" | grep -F "Alias" | cut -d ' ' -f 2-)"
if [ $counter -gt 0 ]; then
printf ", %s" "$device_alias"
else
printf " %s" "$device_alias"
fi
((counter++))
fi
done
printf "\n"
else
echo ""
fi
}
# A submenu for a specific device that allows connecting, pairing, and trusting
device_menu() {
device=$1
# Get device name and mac address
device_name="$(echo "$device" | cut -d ' ' -f 3-)"
mac="$(echo "$device" | cut -d ' ' -f 2)"
# Build options
if device_connected "$mac"; then
connected="Connected: yes"
else
connected="Connected: no"
fi
paired=$(device_paired "$mac")
trusted=$(device_trusted "$mac")
options="$connected\n$paired\n$trusted\n$divider\n$goback\nExit"
# Open dmenu menu, read chosen option
chosen="$(echo -e "$options" | run_dmenu "$device_name")"
# Match chosen option to command
case $chosen in
"" | "$divider")
echo "No option chosen."
;;
"$connected")
toggle_connection "$mac"
;;
"$paired")
toggle_paired "$mac"
;;
"$trusted")
toggle_trust "$mac"
;;
"$goback")
show_menu
;;
esac
}
# Opens a dmenu menu with current bluetooth status and options to connect
show_menu() {
# Get menu options
if power_on; then
power="Power: on"
# Human-readable names of devices, one per line
# If scan is off, will only list paired devices
devices=$(bluetoothctl devices | grep -F Device | cut -d ' ' -f 3-)
# Get controller flags
scan=$(scan_on)
pairable=$(pairable_on)
discoverable=$(discoverable_on)
# Options passed to dmenu
options="$devices\n$divider\n$power\n$scan\n$pairable\n$discoverable\nExit"
else
power="Power: off"
options="$power\nExit"
fi
# Open dmenu menu, read chosen option
chosen="$(echo -e "$options" | run_dmenu "Bluetooth")"
# Match chosen option to command
case $chosen in
"" | "$divider")
echo "No option chosen."
;;
"$power")
toggle_power
;;
"$scan")
toggle_scan
;;
"$discoverable")
toggle_discoverable
;;
"$pairable")
toggle_pairable
;;
*)
device=$(bluetoothctl devices | grep -F "$chosen")
# Open a submenu if a device is selected
if [[ $device ]]; then device_menu "$device"; fi
;;
esac
}
original_args=("$@")
# dmenu command to pipe into. Extra arguments to dmenu-bluetooth are passed through to dmenu. This
# allows the user to set fonts, sizes, colours, etc.
run_dmenu() {
dmenu "${original_args[@]}" -b -l 5 -i -p "$1"
}
case "$1" in
--status)
print_status
;;
*)
show_menu
;;
esac

View file

@ -0,0 +1,12 @@
#!/usr/bin/env bash
# ***This script was made by Clay Gomera (Drake)***
# - Description: A simple desktop dmenu script
# - Dependencies: dmenu, j4-dmenu-desktop
prompt="-p launch:"
colors="-nb \#1d2021 -nf \#fbf1c7 -sb \#cc241d -sf \#fbf1c7"
font="-fn 'mononoki Nerd Font-10'"
DMENU="dmenu -i -l 10 $font $colors $prompt"
j4-dmenu-desktop --dmenu "$DMENU" --no-generic

View file

@ -0,0 +1,26 @@
#!/usr/bin/env bash
# ***This script was made by Clay Gomera (Drake)***
# - Description: A simple script for file editing in dmenu
# - Dependencies: dmenu (Everything else can be changed)
# Show list of options
EDITOR="emacsclient -c -a emacs"
cd "$HOME" || exit 0
file=1
while [ "$file" ]; do
file=$(fd -LHpd 1 | dmenu -i -l 10 -fn "mononoki Nerd Font-10" -nb \#1d2021 -nf \#fbf1c7 -sb \#cc241d -sf \#fbf1c7 -p "file to edit: $(basename "$(pwd)")")
if [ -e "$file" ]; then
owd=$(pwd)
if [ -d "$file" ]; then
cd "$file" || exit 0
else [ -f "$file" ]
if [ "$file" ]; then
$EDITOR "$owd/$file" &
exit 0
else
exit 0
fi
fi
fi
done

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,56 @@
#!/usr/bin/env bash
# ***This script was made by Clay Gomera (Drake)***
# - Description: A simple power menu dmenu script
# - Dependencies: dmenu, power-profiles-daemon
## OPTIONS ##
option1="logout"
option2="reboot"
option3="power off"
option4="suspend"
option5="lock"
option6="change power profile"
option7="cancel"
## OPTIONS ARRAY ##
options="$option1\n$option2\n$option3\n$option4\n$option5\n$option6\n$option7"
## POWER PROFILE OPTIONS ##
pwr1="performance"
pwr2="balanced"
pwr3="powersaver"
pwr4="cancel"
## POWER PROFILES ARRAY ##
pwrs="$pwr1\n$pwr2\n$pwr3\n$pwr4"
## MAIN ACTION COMMAND ##
action=$(echo -e "$options" | dmenu -i -fn "mononoki Nerd Font-10" -nb \#1d2021 -nf \#fbf1c7 -sb \#cc241d -sf \#fbf1c7 -p "power options:")
case "$action" in
$option1*)
pkill X;;
$option2*)
systemctl reboot;;
$option3*)
systemctl poweroff;;
$option4*)
slock systemctl suspend;;
$option5*)
slock;;
$option6*)
currentpwr=$(powerprofilesctl get)
pwraction=$(echo -e "$pwrs" | dmenu -i -fn "mononoki Nerd Font-10" -nb \#1d2021 -nf \#fbf1c7 -sb \#cc241d -sf \#fbf1c7 -p "current profile is: ${currentpwr} | select profile:")
case "$pwraction" in
$pwr1*)
powerprofilesctl set performance && notify-send "power profile switched to performance";;
$pwr2*)
powerprofilesctl set balanced && notify-send "power profile switched to balanced";;
$pwr3*)
powerprofilesctl set power-saver && notify-send "power profile switched to power saver";;
$pwr4*)
exit 0
esac;;
$option7*)
exit 0
esac

View file

@ -0,0 +1,63 @@
#!/usr/bin/env bash
# ***This script was made by Clay Gomera (Drake)***
# - Description: A simple screenshot dmenu script
# - Dependencies: scrot, dmenu, notify-send
## CREATING SCREENSHOT FOLDER ##
mkdir -p "$HOME/pictures/screenshots"
cd "$HOME/pictures/screenshots" || exit 0
## CHOICES ##
cho1="entire screen"
cho2="entire screen with delay"
cho3="focused window"
cho4="select area"
chos="$cho1\n$cho2\n$cho3\n$cho4"
## DELAY OPTIONS ##
del1="3 sec delay"
del2="5 sec delay"
del3="10 sec delay"
dels="$del1\n$del2\n$del3"
## DELAY FUNCTION ##
delays() {
del=$(echo -e "$dels" | dmenu -i -fn "mononoki Nerd Font-10" -nb \#1d2021 -nf \#fbf1c7 -sb \#cc241d -sf \#fbf1c7 -p "Select: ");
case $del in
$del1)
scrot -d 3 && notify-send "screenshot saved";;
$del2)
scrot -d 5 && notify-send "screenshot saved";;
$del3)
scrot -d 10 && notify-send "screenshot saved"
esac
}
## ENTIRE SCREEN FUNCTION ##
screen() {
scrot && notify-send "screenshot saved"
}
## FOCUSED WINDOW FUNCTION
window() {
scrot -u -b && notify-send "screenshot saved."
}
## SELECTED AREA FUNCTION ##
area() {
scrot -s && notify-send "screenshot saved."
}
## MAIN ACTION ##
choice=$(echo -e "$chos" | dmenu -i -fn "mononoki Nerd Font-10" -nb \#1d2021 -nf \#fbf1c7 -sb \#cc241d -sf \#fbf1c7 -p "Select: ")
case $choice in
$cho1*)
screen;;
$cho2*)
delays;;
$cho3*)
window;;
$cho4*)
area
esac

View file

@ -0,0 +1,44 @@
#!/usr/bin/env bash
# ***This script was made by Clay Gomera (Drake)***
# - Description: A simple wallpaper changer script
# - Dependencies: dmenu, fd, feh
## MAIN VARIABLES AND COMMANDS ##
walldir="pictures/wallpapers/" # wallpapers folder, change it to yours, make sure that it ends with a /
cd "$walldir" || exit
## SELECT PICTURE FUNCTION ##
selectpic() {
wallpaper=$(fd -p "$walldir" | dmenu -i -l 10 -fn "mononoki Nerd Font-10" -nb \#1d2021 -nf \#fbf1c7 -sb \#cc241d -sf \#fbf1c7 -p "select a wallpaper:")
if [ "$wallpaper" ]; then
chosenwall=$wallpaper
else
exit 0
fi
}
selectpic
## WALLPAPER SETTING OPTIONS ##
option1="fill"
option2="center"
option3="tile"
option4="max"
option5="scale"
options="$option1\n$option2\n$option3\n$option4\n$option5"
## MAIN ACTION ##
action=$(echo -e "$options" | dmenu -i -l 5 -fn "mononoki Nerd Font-10" -nb \#1d2021 -nf \#fbf1c7 -sb \#cc241d -sf \#fbf1c7 -p "chose the format:")
case "$action" in
$option1*)
feh --bg-fill "$chosenwall";;
$option2*)
feh --bg-center "$chosenwall";;
$option3*)
feh --bg-tile "$chosenwall";;
$option4*)
feh --bg-max "$chosenwall";;
$option5*)
feh --bg-scale "$chosenwall";;
esac
exit 0

View file

@ -0,0 +1,86 @@
#!/usr/bin/env bash
# ***This script was made by Clay Gomera (Drake)***
# - Description: A simple wifi dmenu script
# - Dependencies: dmenu, NetworkManager
## MAIN OPTIONS ##
option1="turn on wifi"
option2="turn off wifi"
option3="disconnect wifi"
option4="connect wifi"
option5="setup captive portal"
option6="exit"
options="$option1\n$option2\n$option3\n$option4\n$option5\n$option6"
wlan=$(nmcli dev | grep wifi | sed 's/ \{2,\}/|/g' | cut -d '|' -f1 | head -1)
## TURN OFF WIFI FUNCTION ##
turnoff() {
nmcli radio wifi off
notify-send "WiFi has been turned off"
}
## TURN ON WIFI FUNCTION ##
turnon() {
nmcli radio wifi on
notify-send "WiFi has been turned on"
}
## DISCONNECT WIFI FUNCTION ##
disconnect() {
nmcli device disconnect "$wlan"
sleep 1
constate=$(nmcli dev | grep wifi | sed 's/ \{2,\}/|/g' | cut -d '|' -f3 | head -1)
if [ "$constate" = "disconnected" ]; then
notify-send "WiFi has been disconnected"
fi
}
## CONNECT FUNCTION ##
connect() {
notify-send "Scannig networks, please wait"
sleep 1
bssid=$(nmcli device wifi list | sed -n '1!p' | cut -b 9- | dmenu -i -l 10 -fn "mononoki Nerd Font-10" -nb \#1d2021 -nf \#fbf1c7 -sb \#cc241d -sf \#fbf1c7 -p "select wifi:" | cut -d' ' -f1)
}
## SELECT PASSWORD FUNCTION ##
password() {
pass=$(echo " " | dmenu -P -i -fn "mononoki Nerd Font-10" -nb \#1d2021 -nf \#fbf1c7 -sb \#cc241d -sf \#fbf1c7 -p "enter password:")
}
## MAIN CONNECTION COMMAND ##
action() {
nmcli device wifi connect "$bssid" password "$pass" || nmcli device wifi connect "$bssid"
}
## CHECKING IF WIFI IS WORKING
check() {
notify-send "Checking if connection was successful"
sleep 1
currentwfi=$(nmcli dev | grep wifi | sed 's/ \{2,\}/|/g' | cut -d '|' -f4 | head -1)
if ping -q -c 2 -W 2 google.com >/dev/null; then
notify-send "You are now connected to $currentwfi and internet is working properly"
else
notify-send "Your internet is not working :("
fi
}
## MAIN ACTION COMMANDS ##
cases=$(echo -e "$options" | dmenu -i -fn "mononoki Nerd Font-10" -nb \#1d2021 -nf \#fbf1c7 -sb \#cc241d -sf \#fbf1c7 -p "wifi options:" )
case "$cases" in
$option1*)
turnon;;
$option2*)
turnoff;;
$option3*)
disconnect;;
$option4*)
connect;
password;
action;
check;;
$option5*)
io.elementary.capnet-assist;;
$option6*)
exit 0
esac

View file

@ -0,0 +1,90 @@
.TH STEST 1 dmenu\-VERSION
.SH NAME
stest \- filter a list of files by properties
.SH SYNOPSIS
.B stest
.RB [ -abcdefghlpqrsuwx ]
.RB [ -n
.IR file ]
.RB [ -o
.IR file ]
.RI [ file ...]
.SH DESCRIPTION
.B stest
takes a list of files and filters by the files' properties, analogous to
.IR test (1).
Files which pass all tests are printed to stdout. If no files are given, stest
reads files from stdin.
.SH OPTIONS
.TP
.B \-a
Test hidden files.
.TP
.B \-b
Test that files are block specials.
.TP
.B \-c
Test that files are character specials.
.TP
.B \-d
Test that files are directories.
.TP
.B \-e
Test that files exist.
.TP
.B \-f
Test that files are regular files.
.TP
.B \-g
Test that files have their set-group-ID flag set.
.TP
.B \-h
Test that files are symbolic links.
.TP
.B \-l
Test the contents of a directory given as an argument.
.TP
.BI \-n " file"
Test that files are newer than
.IR file .
.TP
.BI \-o " file"
Test that files are older than
.IR file .
.TP
.B \-p
Test that files are named pipes.
.TP
.B \-q
No files are printed, only the exit status is returned.
.TP
.B \-r
Test that files are readable.
.TP
.B \-s
Test that files are not empty.
.TP
.B \-u
Test that files have their set-user-ID flag set.
.TP
.B \-v
Invert the sense of tests, only failing files pass.
.TP
.B \-w
Test that files are writable.
.TP
.B \-x
Test that files are executable.
.SH EXIT STATUS
.TP
.B 0
At least one file passed all tests.
.TP
.B 1
No files passed all tests.
.TP
.B 2
An error occurred.
.SH SEE ALSO
.IR dmenu (1),
.IR test (1)

View file

@ -0,0 +1,109 @@
/* See LICENSE file for copyright and license details. */
#include <sys/stat.h>
#include <dirent.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "arg.h"
char *argv0;
#define FLAG(x) (flag[(x)-'a'])
static void test(const char *, const char *);
static void usage(void);
static int match = 0;
static int flag[26];
static struct stat old, new;
static void
test(const char *path, const char *name)
{
struct stat st, ln;
if ((!stat(path, &st) && (FLAG('a') || name[0] != '.') /* hidden files */
&& (!FLAG('b') || S_ISBLK(st.st_mode)) /* block special */
&& (!FLAG('c') || S_ISCHR(st.st_mode)) /* character special */
&& (!FLAG('d') || S_ISDIR(st.st_mode)) /* directory */
&& (!FLAG('e') || access(path, F_OK) == 0) /* exists */
&& (!FLAG('f') || S_ISREG(st.st_mode)) /* regular file */
&& (!FLAG('g') || st.st_mode & S_ISGID) /* set-group-id flag */
&& (!FLAG('h') || (!lstat(path, &ln) && S_ISLNK(ln.st_mode))) /* symbolic link */
&& (!FLAG('n') || st.st_mtime > new.st_mtime) /* newer than file */
&& (!FLAG('o') || st.st_mtime < old.st_mtime) /* older than file */
&& (!FLAG('p') || S_ISFIFO(st.st_mode)) /* named pipe */
&& (!FLAG('r') || access(path, R_OK) == 0) /* readable */
&& (!FLAG('s') || st.st_size > 0) /* not empty */
&& (!FLAG('u') || st.st_mode & S_ISUID) /* set-user-id flag */
&& (!FLAG('w') || access(path, W_OK) == 0) /* writable */
&& (!FLAG('x') || access(path, X_OK) == 0)) != FLAG('v')) { /* executable */
if (FLAG('q'))
exit(0);
match = 1;
puts(name);
}
}
static void
usage(void)
{
fprintf(stderr, "usage: %s [-abcdefghlpqrsuvwx] "
"[-n file] [-o file] [file...]\n", argv0);
exit(2); /* like test(1) return > 1 on error */
}
int
main(int argc, char *argv[])
{
struct dirent *d;
char path[PATH_MAX], *line = NULL, *file;
size_t linesiz = 0;
ssize_t n;
DIR *dir;
int r;
ARGBEGIN {
case 'n': /* newer than file */
case 'o': /* older than file */
file = EARGF(usage());
if (!(FLAG(ARGC()) = !stat(file, (ARGC() == 'n' ? &new : &old))))
perror(file);
break;
default:
/* miscellaneous operators */
if (strchr("abcdefghlpqrsuvwx", ARGC()))
FLAG(ARGC()) = 1;
else
usage(); /* unknown flag */
} ARGEND;
if (!argc) {
/* read list from stdin */
while ((n = getline(&line, &linesiz, stdin)) > 0) {
if (line[n - 1] == '\n')
line[n - 1] = '\0';
test(line, line);
}
free(line);
} else {
for (; argc; argc--, argv++) {
if (FLAG('l') && (dir = opendir(*argv))) {
/* test directory contents */
while ((d = readdir(dir))) {
r = snprintf(path, sizeof path, "%s/%s",
*argv, d->d_name);
if (r >= 0 && (size_t)r < sizeof path)
test(path, d->d_name);
}
closedir(dir);
} else {
test(*argv, *argv);
}
}
}
return match ? 0 : 1;
}

Some files were not shown because too many files have changed in this diff Show more