summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.config/env12
-rwxr-xr-x.config/nnn/plugins/joe_preview418
2 files changed, 423 insertions, 7 deletions
diff --git a/.config/env b/.config/env
index b8fc6b6..82f6e23 100644
--- a/.config/env
+++ b/.config/env
@@ -103,18 +103,16 @@ export NNN_OPTS='aAdrRQ'
export NNN_COLORS='4132'
export NNN_FCOLORS='030304020005060801ac0507'
export NNN_ARCHIVE="\\.(7z|a|ace|alz|arc|arj|bz|bz2|cab|cpio|deb|gz|jar|lha|lz|lzh|lzma|lzo|rar|rpm|rz|t7z|tar|tbz|tbz2|tgz|tlz|txz|tZ|tzo|war|xpi|xz|Z|zip)$"
-export NNN_PLUG='t:joe_fzfcd;p:joe_preview'
export NNN_TERMINAL=$TERMINAL
export NNN_PAGER='less'
+export NNN_BATTHEME='gruvbox-dark'
+export NNN_BATSTYLE='plain'
+export NNN_PREVIEWIMGPROG='icat'
+export NNN_ICONLOOKUP=0
+export NNN_PLUG='t:-joe_fzfcd;p:-joe_preview;P:-preview-tui;s:-!du -sh;f:-fzopen'
export RUSTFLAGS='-L /usr/local/lib'
export WWW_HOME='https://start.duckduckgo.com/'
export YTFZF_HIST='0'
-# wayland
-export WLR_DRM_NO_ATOMIC=1
-export XDG_SESSION_TYPE=wayland
-export XDG_CURRENT_DESKTOP=dwl
-export MOZ_ENABLE_WAYLAND=1
-
# PATH
export PATH="$HOME"/.local/bin:"$HOME"/.local/bin/status:/usr/local/llvm13/bin:"$HOME"/.pyenv/bin:"$PATH"
diff --git a/.config/nnn/plugins/joe_preview b/.config/nnn/plugins/joe_preview
new file mode 100755
index 0000000..6620cd3
--- /dev/null
+++ b/.config/nnn/plugins/joe_preview
@@ -0,0 +1,418 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use Cwd qw(cwd);
+use POSIX qw(mkfifo);
+# use POSIX qw(:signal_h);
+use File::Spec;
+use File::Basename;
+use Term::ANSIColor;
+
+
+my $parent = '';
+if ($ENV{'NNN_FIFO'}) {
+ ($parent = $ENV{'NNN_FIFO'}) =~ s/^[^.]*\.//;
+}
+my $tmpdir = '/tmp';
+my $cwd = cwd();
+
+$ENV{'PWD'} = $cwd;
+$ENV{'FIFOPID'} = "$tmpdir/nnn-preview-joe-fifopid.$parent";
+$ENV{'FIFOPATH'} = "$tmpdir/nnn-preview-joe-fifo.$parent";
+$ENV{'PREVIEWPID'} = "$tmpdir/nnn-preview-joe-previewpid.$parent";
+$ENV{'CURSEL'} = "$tmpdir/nnn-preview-joe-selection.$parent";
+$ENV{'POSOFFSET'} = "$tmpdir/nnn-preview-joe-posoffset";
+$ENV{'NNN_PAGER'} ||= 'less';
+$ENV{'NNN_BATSTYLE'} ||= 'numbers';
+$ENV{'NNN_BATTHEME'} ||= 'ansi';
+
+sub image_preview
+{
+ print "IMAGE PREVIEW\n";
+ return;
+}
+
+sub generate_preview
+{
+ print "GENERAL PREVIEW\n";
+ return;
+}
+
+sub fifo_pager
+{
+ my ($cmd, @args) = @_;
+ my $reader_pid;
+ my $writer_pid;
+ my $pager;
+
+ $pager = $ENV{'NNN_PAGER'} // 'less';
+
+ mkfifo($ENV{'FIFOPATH'}, 0700) or return;
+
+ $reader_pid = fork();
+ die $! unless defined $reader_pid;
+ if ($reader_pid == 0) {
+ open(STDIN, '<', $ENV{'FIFOPATH'}) or die $!;
+ exec($pager) or die $!;
+ }
+
+ open(my $pid_fh, '>', $ENV{'PREVIEWPID'}) or die $!;
+ print $pid_fh $reader_pid;
+ close($pid_fh);
+
+ $writer_pid = fork();
+ die $! unless defined $writer_pid;
+ if ($writer_pid == 0) {
+ open(STDOUT, '>', $ENV{'FIFOPATH'}) or die $!;
+ if ($cmd eq 'pager') {
+ my $cols = `tput cols`;
+ chomp $cols;
+ exec("bat",
+ "--terminal-width=$cols",
+ "--decorations=always",
+ "--color=always",
+ "--paging=never",
+ "--style=$ENV{'NNN_BATSTYLE'}",
+ "--theme=$ENV{'NNN_BATTHEME'}",
+ @args
+ ) or die $!;
+ }
+ elsif ($cmd eq 'print_bin_info') {
+ print "-------- ",
+ color('bold red'),
+ "Binary file",
+ color('reset'),
+ " --------\n";
+ exec('mediainfo', @args);
+ }
+ else {
+ exec($cmd, @args) or die $!;
+ }
+ }
+ waitpid($writer_pid, 0);
+ unlink $ENV{'FIFOPATH'} or warn $!;
+ return;
+}
+
+sub handle_ext
+{
+ my ($file, $ext, $type) = @_;
+
+ if ($ext eq 'epub') {
+ generate_preview($file, 'epub');
+ }
+ elsif ($ext eq 'pdf') {
+ generate_preview($file, 'pdf');
+ }
+ elsif (
+ $ext eq 'gz' ||
+ $ext eq 'bz2'
+ ) {
+ fifo_pager('tar', '-tvf', $file);
+ }
+ elsif ($ext eq 'md') {
+ fifo_pager('glow', '-s', 'dark', $file);
+ }
+ elsif (
+ $ext eq 'htm' ||
+ $ext eq 'html' ||
+ $ext eq 'xhtml'
+ ) {
+ fifo_pager('w3m', $file);
+ }
+ elsif (
+ $ext eq '7z' ||
+ $ext eq 'a' ||
+ $ext eq 'ace' ||
+ $ext eq 'alz' ||
+ $ext eq 'arc' ||
+ $ext eq 'arj' ||
+ $ext eq 'bz' ||
+ $ext eq 'cab' ||
+ $ext eq 'cpio' ||
+ $ext eq 'deb' ||
+ $ext eq 'jar' ||
+ $ext eq 'lha' ||
+ $ext eq 'lz' ||
+ $ext eq 'lzh' ||
+ $ext eq 'lzma' ||
+ $ext eq 'lzo' ||
+ $ext eq 'rar' ||
+ $ext eq 'rpm' ||
+ $ext eq 'rz' ||
+ $ext eq 't7z' ||
+ $ext eq 'tar' ||
+ $ext eq 'tbz' ||
+ $ext eq 'tbz2' ||
+ $ext eq 'tgz' ||
+ $ext eq 'tlz' ||
+ $ext eq 'txz' ||
+ $ext eq 'tZ' ||
+ $ext eq 'tzo' ||
+ $ext eq 'war' ||
+ $ext eq 'xpi' ||
+ $ext eq 'xz' ||
+ $ext eq 'xz' ||
+ $ext eq 'zst' ||
+ $ext eq 'Z'
+ ) {
+ fifo_pager('atool', '-l', $file);
+ }
+ elsif ($ext eq 'json') {
+ fifo_pager('jq', '--color-output', '.', $file);
+ }
+ elsif ($type eq 'bin') {
+ fifo_pager('print_bin_info', $file);
+ }
+ else {
+ fifo_pager('pager', $file);
+ }
+ return;
+}
+
+sub handle_mime
+{
+ my ($file, $mimetype, $ext, $type) = @_;
+
+ if ($mimetype eq 'image/jpeg') {
+ image_preview($file);
+ }
+ elsif ($mimetype eq 'image/gif') {
+ generate_preview($file, 'gif');
+ }
+ elsif ($mimetype eq 'image/vnd.djvu') {
+ generate_preview($file, 'djvu');
+ }
+ elsif ($mimetype =~ /^image\//) {
+ generate_preview($file, 'image');
+ }
+ elsif ($mimetype =~ /^video\//) {
+ generate_preview($file, 'video');
+ }
+ elsif ($mimetype =~ /^audio\//) {
+ generate_preview($file, 'audio');
+ }
+ elsif (
+ $mimetype =~ /^application\/font/ ||
+ $mimetype =~ /^application\/.*opentype/ ||
+ $mimetype =~ /^font\//
+ ) {
+ generate_preview($file, 'font');
+ }
+ elsif (
+ $mimetype =~ m{/.+office.+} ||
+ $mimetype =~ m{/.+document.+} ||
+ $mimetype =~ m{/.+msword} ||
+ $mimetype =~ m{/.+ms-excel}
+ ) {
+ generate_preview($file, 'office');
+ }
+ elsif ($mimetype eq 'application/zip') {
+ fifo_pager('unzip', '-l', $file);
+ }
+ elsif ($mimetype eq 'text/troff') {
+ fifo_pager('man', '-Pcat', '-l', $file);
+ }
+ else {
+ handle_ext($file, $ext, $type);
+ }
+ return;
+}
+
+sub preview_file
+{
+ my ($file) = @_;
+ my ($ext) = $file =~ /\.([^.]*)$/;
+ my $encoding;
+ my $mimetype;
+ my $lines;
+ my $cols;
+
+ system('clear');
+ $encoding = `file -bL --mime-encoding -- $file`;
+ $mimetype = `file -bL --mime-type -- $file`;
+ $ext = lc($ext) if length($ext) > 0;
+ $lines = `tput lines`;
+ $cols = `tput cols`;
+
+ if (-d $file) {
+ chdir $file or return;
+ fifo_pager(
+ 'eza',
+ '-T',
+ '--group-directories-first',
+ '--colour=always',
+ '-L',
+ '3'
+ );
+ chdir '..';
+ }
+ elsif ($encoding =~ /\)/) {
+ my ($suffix) = $encoding =~ /\)(.*)/;
+ if (defined $suffix && $suffix eq 'binary') {
+ handle_mime($file, $mimetype, $ext, 'bin');
+ }
+ else {
+ handle_mime($file, $mimetype, $ext);
+ }
+ }
+ return;
+}
+
+sub preview_fifo
+{
+ while (1) {
+ open(my $fh, '<', $ENV{'NNN_FIFO'}) or die $!;
+ while (my $selection = <$fh>) {
+ chomp $selection;
+ if ($selection) {
+ pidkill($ENV{'PREVIEWPID'});
+ last if $selection eq 'close';
+ preview_file($selection);
+ open(my $cursel_fh, '>', $ENV{'CURSEL'}) or die $!;
+ print $cursel_fh $selection;
+ close($cursel_fh);
+ }
+ }
+ close $fh;
+ }
+ return;
+}
+
+sub pidkill {
+ my ($pidfile) = @_;
+ my $pid;
+ my $ret;
+
+ if (-e $pidfile) {
+ $pid = `cat $pidfile 2>/dev/null` or return 1;
+ $ret = system("kill $pid >/dev/null 2>&1");
+ system("wait $pid 2>/dev/null");
+ return $ret;
+ }
+ return 1;
+}
+
+sub winch_handler
+{
+ my $filepath;
+
+ system('clear');
+ pidkill($ENV{'PREVIEWPID'});
+ open(my $fh, '<', $ENV{'CURSEL'}) or die $!;
+ $filepath = <$fh>;
+ chomp $filepath if $filepath;
+ close($fh);
+ preview_file($filepath) if $filepath;
+ return;
+}
+
+sub start_preview
+{
+ my ($file) = @_;
+ my $pid;
+
+ $ENV{'NNN_TERMINAL'} = $ENV{'NNN_TERMINAL'} // 'xterm';
+ $ENV{'PREVIEW_MODE'} = 1;
+ $pid = fork();
+ die $! unless defined $pid;
+ if ($pid == 0) {
+ exec($ENV{'NNN_TERMINAL'}, '-e', $0, $file) or die $!;
+ }
+ return;
+}
+
+sub toggle_preview
+{
+ my ($file) = @_;
+ my $nnn_ppipe;
+
+ $ENV{'PWD'} = cwd();
+ $ENV{'PATH'} = $ENV{'PATH'};
+ $ENV{'NNN_FIFO'} = $ENV{'NNN_FIFO'};
+ $nnn_ppipe = $ENV{'NNN_PPIPE'} // '';
+ if (pidkill($ENV{'FIFOPID'})) {
+ if ($nnn_ppipe && -p $nnn_ppipe) {
+ open(my $fh, '>', $nnn_ppipe) or warn $!;
+ print $fh "0";
+ close($fh);
+ }
+ pidkill($ENV{'PREVIEWPID'});
+ }
+ else {
+ if ($nnn_ppipe && -p $nnn_ppipe) {
+ open(my $fh, '>', $nnn_ppipe) or warn $!;
+ print $fh "1";
+ close($fh);
+ }
+ start_preview($file);
+ }
+ return;
+}
+
+sub joe_preview
+{
+ my $file;
+ my $pid;
+ my $cwd;
+
+ $cwd = cwd();
+
+ $SIG{PIPE} = 'IGNORE';
+
+ $file = $ARGV[0];
+ if (($ENV{'PREVIEW_MODE'} || 0) == 1) {
+ preview_file($cwd . '/' . $file);
+
+ $pid = fork();
+ die $! unless defined $pid;
+ if ($pid == 0) {
+ preview_fifo();
+ return;
+ }
+
+ open(my $pidfh, '>', $ENV{'FIFOPID'}) or die $!;
+ print $pidfh "$pid\n";
+ close($pidfh);
+
+ open(my $curselfh, '>', $ENV{'CURSEL'}) or die $!;
+ print $curselfh "$cwd/$file\n";
+ close($curselfh);
+
+ $SIG{WINCH} = sub {
+ winch_handler();
+ };
+
+ for my $signal (qw(INT HUP EXIT)) {
+ $SIG{$signal} = sub {
+ unlink(
+ $ENV{'PREVIEWPID'},
+ $ENV{'CURSEL'},
+ $ENV{'FIFOPID'},
+ $ENV{'POSOFFSET'}
+ );
+ exit 0;
+ };
+ }
+
+ while (kill 0, $pid) {
+ waitpid($pid, 0);
+ }
+
+ return;
+ }
+ else {
+ # $pid = fork();
+ # die $! unless defined $pid;
+ # if ($pid == 0) {
+ toggle_preview($file);
+ # return;
+ # }
+ }
+ return;
+}
+
+joe_preview();
+
+__END__