diff --git a/app-misc/nnn/nnn-2.8.1.recipe b/app-misc/nnn/nnn-2.8.1.recipe new file mode 100644 index 000000000..dde912eb5 --- /dev/null +++ b/app-misc/nnn/nnn-2.8.1.recipe @@ -0,0 +1,58 @@ +SUMMARY="The missing terminal file manager for X" +DESCRIPTION="nnn is a full-featured terminal file manager. It's tiny and \ +nearly 0-config with an incredible performance. + +nnn is also a du analyzer, an app launcher, a batch renamer and a file picker. \ +The plugin repository has tons of plugins and documentation to extend the \ +capabilities further. You can plug new functionality and play with a \ +custom keybind instantly. There's an independent (neo)vim plugin. + +It runs smoothly on the Raspberry Pi, Termux on Android, Linux, macOS, BSD, \ +Cygwin, WSL and works seamlessly with DEs and GUI utilities. + +Visit the Wiki for concepts, program usage, how-tos and troubleshooting." +HOMEPAGE="https://github.com/jarun/nnn" +COPYRIGHT="2016-2019 Arun Prakash Jana" +LICENSE="BSD (2-clause)" +REVISION="1" +SOURCE_URI="https://github.com/jarun/nnn/archive/v$portVersion.tar.gz" +CHECKSUM_SHA256="cadf9cf8038433aeeb50a777180ad4b309ac7d2fec81c7da177ddca515812f06" +PATCHES="nnn-$portVersion.patchset" + +ARCHITECTURES="x86_64" +SECONDARY_ARCHITECTURES="x86" + +PROVIDES=" + nnn$secondaryArchSuffix = $portVersion + cmd:nnn = $portVersion + " +REQUIRES=" + haiku$secondaryArchSuffix + file$secondaryArchSuffix + lib:libncurses$secondaryArchSuffix + lib:libreadline$secondaryArchSuffix + " + +BUILD_REQUIRES=" + haiku${secondaryArchSuffix}_devel + devel:libncurses$secondaryArchSuffix + devel:libreadline$secondaryArchSuffix + " +BUILD_PREREQUIRES=" + cmd:g++$secondaryArchSuffix + cmd:gcc$secondaryArchSuffix + cmd:install + cmd:ld$secondaryArchSuffix + cmd:make + cmd:pkg_config$secondaryArchSuffix + " + +BUILD() +{ + make $jobArgs +} + +INSTALL() +{ + make PREFIX=$prefix MANPREFIX=$manDir install +} diff --git a/app-misc/nnn/patches/nnn-2.8.1.patchset b/app-misc/nnn/patches/nnn-2.8.1.patchset new file mode 100644 index 000000000..8a1e9208e --- /dev/null +++ b/app-misc/nnn/patches/nnn-2.8.1.patchset @@ -0,0 +1,262 @@ +From 078ec9f81f00006eb7f50cbbb76e1a085432bdcd Mon Sep 17 00:00:00 2001 +From: Anna Arad +Date: Tue, 17 Dec 2019 08:04:17 +0200 +Subject: [PATCH] Haiku against v2.8.1 + + +diff --git a/Makefile b/Makefile +index 43287f8..c52d43f 100644 +--- a/Makefile ++++ b/Makefile +@@ -53,2 +53,8 @@ endif + ++ifeq ($(shell uname -s), Haiku) ++ LDLIBS_HAIKU ?= -lstdc++ -lbe ++ SRC_HAIKU ?= src/haiku/nm.cpp ++ OBJS_HAIKU ?= src/haiku/nm.o ++endif ++ + CFLAGS += -Wall -Wextra +@@ -57,3 +63,3 @@ CFLAGS += $(CFLAGS_CURSES) + +-LDLIBS += $(LDLIBS_CURSES) ++LDLIBS += $(LDLIBS_CURSES) $(LDLIBS_HAIKU) + +@@ -63,2 +69,3 @@ HEADERS = src/nnn.h + BIN = nnn ++OBJS := nnn.o $(OBJS_HAIKU) + +@@ -66,4 +73,12 @@ all: $(BIN) + +-$(BIN): $(SRC) $(HEADERS) +- $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LDLIBS) ++ifeq ($(shell uname -s), Haiku) ++$(OBJS_HAIKU): $(SRC_HAIKU) ++ $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $< ++endif ++ ++nnn.o: $(SRC) $(HEADERS) ++ $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $< ++ ++$(BIN): $(OBJS) ++ $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) + +@@ -95,3 +110,3 @@ dist: + clean: +- $(RM) -f $(BIN) nnn-$(VERSION).tar.gz ++ $(RM) -f $(BIN) $(OBJS) nnn-$(VERSION).tar.gz + +diff --git a/src/haiku/haiku_interop.h b/src/haiku/haiku_interop.h +new file mode 100644 +index 0000000..b422412 +--- /dev/null ++++ b/src/haiku/haiku_interop.h +@@ -0,0 +1,14 @@ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++typedef struct haiku_nm_t *haiku_nm_h; ++haiku_nm_h haiku_init_nm(); ++void haiku_close_nm(haiku_nm_h hnd); ++int haiku_watch_dir(haiku_nm_h hnd, const char *path); ++int haiku_stop_watch(haiku_nm_h hnd); ++int haiku_is_update_needed(haiku_nm_h hnd); ++ ++#ifdef __cplusplus ++} ++#endif +diff --git a/src/haiku/nm.cpp b/src/haiku/nm.cpp +new file mode 100644 +index 0000000..ede1d37 +--- /dev/null ++++ b/src/haiku/nm.cpp +@@ -0,0 +1,83 @@ ++#include ++#include ++#include ++#include ++ ++#include "haiku_interop.h" ++ ++filter_result dir_mon_flt(BMessage *message, BHandler **hnd, BMessageFilter *fltr) { ++ (void) hnd; ++ (void) fltr; ++ ++ if (message->what == B_NODE_MONITOR) { ++ int32 val; ++ message->FindInt32("opcode", &val); ++ ++ switch (val) { ++ case B_ENTRY_CREATED: ++ case B_ENTRY_MOVED: ++ case B_ENTRY_REMOVED: ++ return B_DISPATCH_MESSAGE; ++ } ++ } ++ ++ return B_SKIP_MESSAGE; ++} ++ ++class DirectoryListener : public BLooper { ++public: ++ bool recv_reset() { ++ Lock(); ++ bool val = _ev_on; ++ _ev_on = false; ++ Unlock(); ++ ++ return val; ++ } ++private: ++ void MessageReceived(BMessage * message) override { ++ Lock(); ++ _ev_on = true; ++ Unlock(); ++ BLooper::MessageReceived(message); ++ } ++ ++ bool _ev_on = false; ++}; ++ ++struct haiku_nm_t { ++ haiku_nm_t() { ++ dl = new DirectoryListener(); ++ flt = new BMessageFilter(B_PROGRAMMED_DELIVERY, B_LOCAL_SOURCE, dir_mon_flt); ++ dl->AddCommonFilter(flt); ++ dl->Run(); ++ } ++ ++ DirectoryListener *dl; ++ BMessageFilter *flt; ++ node_ref nr; ++}; ++ ++haiku_nm_h haiku_init_nm() { ++ return new haiku_nm_t(); ++} ++ ++void haiku_close_nm(haiku_nm_h hnd) { ++ delete hnd->flt; ++ // This is the way of deleting a BLooper ++ hnd->dl->PostMessage(B_QUIT_REQUESTED); ++ delete hnd; ++} ++int haiku_watch_dir(haiku_nm_h hnd, const char *path) { ++ BDirectory dir(path); ++ dir.GetNodeRef(&(hnd->nr)); ++ ++ return watch_node(&(hnd->nr), B_WATCH_DIRECTORY, nullptr, hnd->dl); ++} ++int haiku_stop_watch(haiku_nm_h hnd) { ++ return watch_node(&(hnd->nr), B_STOP_WATCHING, nullptr, hnd->dl); ++} ++ ++int haiku_is_update_needed(haiku_nm_h hnd) { ++ return hnd->dl->recv_reset(); ++} +diff --git a/src/nnn.c b/src/nnn.c +index f751c6f..44acf45 100644 +--- a/src/nnn.c ++++ b/src/nnn.c +@@ -51,2 +51,5 @@ + #define BSD_KQUEUE ++#elif defined(__HAIKU__) ++#include "haiku/haiku_interop.h" ++#define HAIKU_NM + #else +@@ -386,2 +389,4 @@ static char * const utils[] = { + "cygstart", ++#elif defined __HAIKU__ ++ "open", + #else +@@ -564,2 +569,5 @@ static uint KQUEUE_FFLAGS = NOTE_DELETE | NOTE_EXTEND | NOTE_LINK + static struct timespec gtimeout; ++#elif defined(HAIKU_NM) ++static bool haiku_nm_active = FALSE; ++static haiku_nm_h haiku_hnd = NULL; + #endif +@@ -1881,2 +1889,4 @@ static int nextsel(int presel) + memset((void *)event_data, 0x0, sizeof(struct kevent) * NUM_EVENT_SLOTS); ++#elif defined(HAIKU_NM) ++// TODO: Do some Haiku declarations + #endif +@@ -1932,2 +1942,5 @@ static int nextsel(int presel) + c = CONTROL('L'); ++#elif defined(HAIKU_NM) ++ if (!cfg.selmode && !cfg.blkorder && haiku_nm_active && idle & 1 && haiku_is_update_needed(haiku_hnd)) ++ c = CONTROL('L'); + #endif +@@ -3253,2 +3266,12 @@ static bool xmktree(char* path, bool dir) + if (mkdir(path, 0777) == -1 && errno != EEXIST) { ++#ifdef __HAIKU__ ++ // XDG_CONFIG_HOME contains a directory ++ // that is read-only, but the full path ++ // is writeable. ++ // Try to continue and see what happens. ++ // TODO: Find a more robust solution. ++ if (errno == B_READ_ONLY_DEVICE) { ++ goto next; ++ } ++#endif + DPRINTF_S("mkdir1!"); +@@ -3259,2 +3282,5 @@ static bool xmktree(char* path, bool dir) + ++#ifdef __HAIKU__ ++next: ++#endif + /* Restore path */ +@@ -3688,3 +3714,3 @@ static int dentfill(char *path, struct entry **dents) + +-#ifdef __sun ++#if defined(__sun) || defined(__HAIKU__) + if (cfg.blkorder) { /* no d_type */ +@@ -3806,3 +3832,3 @@ static int dentfill(char *path, struct entry **dents) + dentp->t = cfg.mtime ? sb.st_mtime : sb.st_atime; +-#ifndef __sun ++#if !(defined(__sun) || defined(__HAIKU__)) + if (!flags && dp->d_type == DT_LNK) { +@@ -3862,3 +3888,3 @@ static int dentfill(char *path, struct entry **dents) + dentp->flags |= DIR_OR_LINK_TO_DIR; +-#ifndef __sun /* no d_type */ ++#if !(defined(__sun) || defined(__HAIKU__)) /* no d_type */ + } else if (dp->d_type == DT_DIR || (dp->d_type == DT_LNK && S_ISDIR(sb.st_mode))) { +@@ -4210,2 +4236,8 @@ begin: + } ++#elif defined(HAIKU_NM) ++ if ((presel == FILTER || dir_changed) && haiku_hnd != NULL) { ++ haiku_stop_watch(haiku_hnd); ++ haiku_nm_active = FALSE; ++ dir_changed = FALSE; ++ } + #endif +@@ -4241,2 +4273,4 @@ begin: + } ++#elif defined(HAIKU_NM) ++ haiku_nm_active = haiku_watch_dir(haiku_hnd, path) == _SUCCESS; + #endif +@@ -4654,2 +4688,7 @@ nochange: + } ++#elif defined(HAIKU_NM) ++ if (haiku_nm_active) { ++ haiku_stop_watch(haiku_hnd); ++ haiku_nm_active = FALSE; ++ } + #endif +@@ -5773,2 +5812,8 @@ int main(int argc, char *argv[]) + } ++#elif defined(HAIKU_NM) ++ haiku_hnd = haiku_init_nm(); ++ if (!haiku_hnd) { ++ xerror(); ++ return _FAILURE; ++ } + #endif +@@ -5874,2 +5919,4 @@ int main(int argc, char *argv[]) + close(kq); ++#elif defined(HAIKU_NM) ++ haiku_close_nm(haiku_hnd); + #endif +-- +2.24.1 +