Uploading config dotfiles
This commit is contained in:
parent
dbc8e6cc6d
commit
e9e2f75fa2
Binary file not shown.
|
@ -0,0 +1,91 @@
|
|||
#alias startx
|
||||
|
||||
alias sx='startx'
|
||||
|
||||
# alias doas
|
||||
|
||||
alias ds='doas'
|
||||
|
||||
# alias xbps
|
||||
|
||||
alias xbl='xbps-query -m | column'
|
||||
alias xbup='doas xbps-install -Syu'
|
||||
alias xbins='doas xbps-install -Su'
|
||||
alias xbdel='doas xbps-remove -RcOon'
|
||||
alias xbclean='doas xbps-remove -oO'
|
||||
alias xbser='xbps-query -Rs'
|
||||
alias xbse='xbps-query -s'
|
||||
alias xbd='xbps-query -Rx'
|
||||
alias xbdi='xbps-query -RX'
|
||||
alias xbrc='doas xbps-reconfigure -f'
|
||||
alias xbh='doas xbps-pkgdb -m hold'
|
||||
alias xbuh='doas xbps-pkgdb -m unhold'
|
||||
|
||||
|
||||
# alias xbps-src
|
||||
|
||||
alias srclean='cd $HOME/void-packages/ && ./xbps-src clean-repocache && ./xbps-src clean && ./xbps-src remove-autodeps && rm -rf hostdir/sources/* && xbps-rindex -r ~/void-packages/hostdir/binpkgs && xbps-rindex -c ~/void-packages/hostdir/binpkgs'
|
||||
alias srcins='cd $HOME/void-packages/ && doas xbps-install -R ./hostdir/binpkgs'
|
||||
alias srcinf='cd $HOME/void-packages/ && doas xbps-install -f ./hostdir/binpkgs'
|
||||
alias srcin='doas xbps-install -fR home/diegofcs/void-packages/hostdir/binpkgs/nonfree'
|
||||
alias srcmp='cd $HOME/void-packages/ && ./xbps-src -j $(nproc) pkg'
|
||||
alias srcmf='cd $HOME/void-packages/ && ./xbps-src -j $(nproc) -f pkg'
|
||||
alias srcser='ls $HOME/.config/void-packages/srcpkgs | grep'
|
||||
alias xbo='cd $HOME/void-packages/ && ./xbps-src show-options'
|
||||
alias xboc='cd $HOME/void-packages./xbps-query -R --property=build-options'
|
||||
|
||||
|
||||
# alias status services
|
||||
|
||||
alias svl='ds sv status /var/service/*'
|
||||
|
||||
# alias patch
|
||||
|
||||
alias pt='patch -p1 <'
|
||||
alias cmp='doas make clean install'
|
||||
|
||||
# alias passmenu2
|
||||
|
||||
alias pss='passmenu2'
|
||||
|
||||
# alias varios
|
||||
|
||||
alias v='vis'
|
||||
alias c='cd'
|
||||
alias cl='clear'
|
||||
alias chm='chmod +x'
|
||||
alias chmr='chmod -x'
|
||||
alias sz='du -sh'
|
||||
alias cpr="cp -r"
|
||||
alias rmr='rm -r'
|
||||
alias ls='ls --color -h --group-directories-first -lha'
|
||||
alias ..='cd ..'
|
||||
alias ...='cd ../..'
|
||||
alias ....='cd ../../..'
|
||||
alias .....='cd ../../../..'
|
||||
alias ......='cd ../../../../..'
|
||||
alias top='top -d 1 -u diegofcs'
|
||||
alias sf='scriptfetch'
|
||||
alias gup='xbup && cd void-packages && git pull && ./xbps-src bootstrap-update && xbclean && srclean'
|
||||
alias n3='nnn'
|
||||
alias vim='echo "Que ahora es vis, idiota... ya que nos mudamos, Ahora debe ser así -> vis"'
|
||||
alias yt='yt-dlp "$(ytfzf -I L "$1")" -o - | ffplay - -autoexit -loglevel quiet'
|
||||
alias mu='yt-dlp "$(ytfzf -I L "$1")" -o - | ffplay - -nodisp -autoexit -loglevel quiet'
|
||||
alias ping='ds ping -c 8 voidlinux.org'
|
||||
|
||||
#alias source shell & alias
|
||||
|
||||
alias kreload='source $HOME/.aliases && source $HOME/.mkshrc'
|
||||
|
||||
#alias wifi
|
||||
|
||||
alias wf='doas wpa_passphrase'
|
||||
alias dt='doas vis /etc/wpa_supplicant/wpa_supplicant.conf'
|
||||
alias ctw='doas wpa_supplicant -B -D wext -i wlp0s29u1u1 -c /etc/wpa_supplicant/wpa_supplicant.conf'
|
||||
alias lwf='wpa_cli list_networks'
|
||||
alias swf='wpa_cli select_networks'
|
||||
|
||||
#alias lugares usados
|
||||
|
||||
alias qt='cd $HOME/.config/qutebrowser'
|
||||
alias vs='cd $HOME/.config/vis && vis visrc.lua'
|
|
@ -0,0 +1,5 @@
|
|||
pcm.!default {
|
||||
type asym
|
||||
playback.pcm "plug:dmix"
|
||||
capture.pcm "plug:dsnoop"
|
||||
}
|
|
@ -0,0 +1,351 @@
|
|||
state.PCH {
|
||||
control.1 {
|
||||
iface MIXER
|
||||
name 'Headphone Playback Volume'
|
||||
value.0 87
|
||||
value.1 87
|
||||
comment {
|
||||
access 'read write'
|
||||
type INTEGER
|
||||
count 2
|
||||
range '0 - 87'
|
||||
dbmin -6525
|
||||
dbmax 0
|
||||
dbvalue.0 0
|
||||
dbvalue.1 0
|
||||
}
|
||||
}
|
||||
control.2 {
|
||||
iface MIXER
|
||||
name 'Headphone Playback Switch'
|
||||
value.0 true
|
||||
value.1 true
|
||||
comment {
|
||||
access 'read write'
|
||||
type BOOLEAN
|
||||
count 2
|
||||
}
|
||||
}
|
||||
control.3 {
|
||||
iface MIXER
|
||||
name 'Speaker Playback Volume'
|
||||
value.0 87
|
||||
value.1 87
|
||||
comment {
|
||||
access 'read write'
|
||||
type INTEGER
|
||||
count 2
|
||||
range '0 - 87'
|
||||
dbmin -6525
|
||||
dbmax 0
|
||||
dbvalue.0 0
|
||||
dbvalue.1 0
|
||||
}
|
||||
}
|
||||
control.4 {
|
||||
iface MIXER
|
||||
name 'Speaker Playback Switch'
|
||||
value.0 false
|
||||
value.1 false
|
||||
comment {
|
||||
access 'read write'
|
||||
type BOOLEAN
|
||||
count 2
|
||||
}
|
||||
}
|
||||
control.5 {
|
||||
iface MIXER
|
||||
name 'Loopback Mixing'
|
||||
value Enabled
|
||||
comment {
|
||||
access 'read write'
|
||||
type ENUMERATED
|
||||
count 1
|
||||
item.0 Disabled
|
||||
item.1 Enabled
|
||||
}
|
||||
}
|
||||
control.6 {
|
||||
iface MIXER
|
||||
name 'Mic Playback Volume'
|
||||
value.0 31
|
||||
value.1 31
|
||||
comment {
|
||||
access 'read write'
|
||||
type INTEGER
|
||||
count 2
|
||||
range '0 - 31'
|
||||
dbmin -3450
|
||||
dbmax 1200
|
||||
dbvalue.0 1200
|
||||
dbvalue.1 1200
|
||||
}
|
||||
}
|
||||
control.7 {
|
||||
iface MIXER
|
||||
name 'Mic Playback Switch'
|
||||
value.0 false
|
||||
value.1 false
|
||||
comment {
|
||||
access 'read write'
|
||||
type BOOLEAN
|
||||
count 2
|
||||
}
|
||||
}
|
||||
control.8 {
|
||||
iface MIXER
|
||||
name 'Auto-Mute Mode'
|
||||
value Enabled
|
||||
comment {
|
||||
access 'read write'
|
||||
type ENUMERATED
|
||||
count 1
|
||||
item.0 Disabled
|
||||
item.1 Enabled
|
||||
}
|
||||
}
|
||||
control.9 {
|
||||
iface MIXER
|
||||
name 'Capture Volume'
|
||||
value.0 39
|
||||
value.1 39
|
||||
comment {
|
||||
access 'read write'
|
||||
type INTEGER
|
||||
count 2
|
||||
range '0 - 63'
|
||||
dbmin -1725
|
||||
dbmax 3000
|
||||
dbvalue.0 1200
|
||||
dbvalue.1 1200
|
||||
}
|
||||
}
|
||||
control.10 {
|
||||
iface MIXER
|
||||
name 'Capture Switch'
|
||||
value.0 true
|
||||
value.1 true
|
||||
comment {
|
||||
access 'read write'
|
||||
type BOOLEAN
|
||||
count 2
|
||||
}
|
||||
}
|
||||
control.11 {
|
||||
iface MIXER
|
||||
name 'Mic Boost Volume'
|
||||
value.0 3
|
||||
value.1 3
|
||||
comment {
|
||||
access 'read write'
|
||||
type INTEGER
|
||||
count 2
|
||||
range '0 - 3'
|
||||
dbmin 0
|
||||
dbmax 3000
|
||||
dbvalue.0 3000
|
||||
dbvalue.1 3000
|
||||
}
|
||||
}
|
||||
control.12 {
|
||||
iface MIXER
|
||||
name 'Internal Mic Boost Volume'
|
||||
value.0 3
|
||||
value.1 3
|
||||
comment {
|
||||
access 'read write'
|
||||
type INTEGER
|
||||
count 2
|
||||
range '0 - 3'
|
||||
dbmin 0
|
||||
dbmax 3000
|
||||
dbvalue.0 3000
|
||||
dbvalue.1 3000
|
||||
}
|
||||
}
|
||||
control.13 {
|
||||
iface MIXER
|
||||
name 'Master Playback Volume'
|
||||
value 87
|
||||
comment {
|
||||
access 'read write'
|
||||
type INTEGER
|
||||
count 1
|
||||
range '0 - 87'
|
||||
dbmin -6525
|
||||
dbmax 0
|
||||
dbvalue.0 0
|
||||
}
|
||||
}
|
||||
control.14 {
|
||||
iface MIXER
|
||||
name 'Master Playback Switch'
|
||||
value true
|
||||
comment {
|
||||
access 'read write'
|
||||
type BOOLEAN
|
||||
count 1
|
||||
}
|
||||
}
|
||||
control.15 {
|
||||
iface CARD
|
||||
name 'Mic Jack'
|
||||
value false
|
||||
comment {
|
||||
access read
|
||||
type BOOLEAN
|
||||
count 1
|
||||
}
|
||||
}
|
||||
control.16 {
|
||||
iface CARD
|
||||
name 'Internal Mic Phantom Jack'
|
||||
value true
|
||||
comment {
|
||||
access read
|
||||
type BOOLEAN
|
||||
count 1
|
||||
}
|
||||
}
|
||||
control.17 {
|
||||
iface CARD
|
||||
name 'Headphone Jack'
|
||||
value true
|
||||
comment {
|
||||
access read
|
||||
type BOOLEAN
|
||||
count 1
|
||||
}
|
||||
}
|
||||
control.18 {
|
||||
iface CARD
|
||||
name 'Speaker Phantom Jack'
|
||||
value true
|
||||
comment {
|
||||
access read
|
||||
type BOOLEAN
|
||||
count 1
|
||||
}
|
||||
}
|
||||
control.19 {
|
||||
iface PCM
|
||||
name 'Playback Channel Map'
|
||||
value.0 3
|
||||
value.1 4
|
||||
comment {
|
||||
access read
|
||||
type INTEGER
|
||||
count 2
|
||||
range '0 - 36'
|
||||
}
|
||||
}
|
||||
control.20 {
|
||||
iface PCM
|
||||
name 'Capture Channel Map'
|
||||
value.0 0
|
||||
value.1 0
|
||||
comment {
|
||||
access read
|
||||
type INTEGER
|
||||
count 2
|
||||
range '0 - 36'
|
||||
}
|
||||
}
|
||||
control.21 {
|
||||
iface CARD
|
||||
name 'HDMI/DP,pcm=3 Jack'
|
||||
value false
|
||||
comment {
|
||||
access read
|
||||
type BOOLEAN
|
||||
count 1
|
||||
}
|
||||
}
|
||||
control.22 {
|
||||
iface MIXER
|
||||
name 'IEC958 Playback Con Mask'
|
||||
value '0fff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
|
||||
comment {
|
||||
access read
|
||||
type IEC958
|
||||
count 1
|
||||
}
|
||||
}
|
||||
control.23 {
|
||||
iface MIXER
|
||||
name 'IEC958 Playback Pro Mask'
|
||||
value '0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
|
||||
comment {
|
||||
access read
|
||||
type IEC958
|
||||
count 1
|
||||
}
|
||||
}
|
||||
control.24 {
|
||||
iface MIXER
|
||||
name 'IEC958 Playback Default'
|
||||
value '0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
|
||||
comment {
|
||||
access 'read write'
|
||||
type IEC958
|
||||
count 1
|
||||
}
|
||||
}
|
||||
control.25 {
|
||||
iface MIXER
|
||||
name 'IEC958 Playback Switch'
|
||||
value true
|
||||
comment {
|
||||
access 'read write'
|
||||
type BOOLEAN
|
||||
count 1
|
||||
}
|
||||
}
|
||||
control.26 {
|
||||
iface PCM
|
||||
device 3
|
||||
name ELD
|
||||
value ''
|
||||
comment {
|
||||
access 'read volatile'
|
||||
type BYTES
|
||||
count 0
|
||||
}
|
||||
}
|
||||
control.27 {
|
||||
iface PCM
|
||||
device 3
|
||||
name 'Playback Channel Map'
|
||||
value.0 0
|
||||
value.1 0
|
||||
value.2 0
|
||||
value.3 0
|
||||
value.4 0
|
||||
value.5 0
|
||||
value.6 0
|
||||
value.7 0
|
||||
comment {
|
||||
access 'read write'
|
||||
type INTEGER
|
||||
count 8
|
||||
range '0 - 36'
|
||||
}
|
||||
}
|
||||
control.28 {
|
||||
iface MIXER
|
||||
name 'PCM Playback Volume'
|
||||
value.0 255
|
||||
value.1 255
|
||||
comment {
|
||||
access 'read write user'
|
||||
type INTEGER
|
||||
count 2
|
||||
range '0 - 255'
|
||||
tlv '0000000100000008ffffec1400000014'
|
||||
dbmin -5100
|
||||
dbmax 0
|
||||
dbvalue.0 0
|
||||
dbvalue.1 0
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Copy selection to system clipboard as newline-separated entries
|
||||
# Dependencies:
|
||||
# - tr
|
||||
# - xclip/xsel (Linux)
|
||||
# - pbcopy (macOS)
|
||||
# - termux-clipboard-set (Termux)
|
||||
# - clip.exe (WSL)
|
||||
# - clip (Cygwin)
|
||||
# - wl-copy (Wayland)
|
||||
# - clipboard (Haiku)
|
||||
#
|
||||
# Limitation: breaks if a filename has newline in it
|
||||
#
|
||||
# Note: For a space-separated list:
|
||||
# xargs -0 < "$SELECTION"
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Arun Prakash Jana
|
||||
|
||||
IFS="$(printf '%b_' '\n')"; IFS="${IFS%_}" # protect trailing \n
|
||||
|
||||
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
|
||||
[ -s "$selection" ] || { echo "plugin .cbcp error: empty selection" >&2 ; exit 1; }
|
||||
|
||||
if type xsel >/dev/null 2>&1; then
|
||||
# Linux
|
||||
tr '\0' '\n' < "$selection" | xsel -bi
|
||||
elif type xclip >/dev/null 2>&1; then
|
||||
# Linux
|
||||
tr '\0' '\n' < "$selection" | xclip -sel clip
|
||||
elif type pbcopy >/dev/null 2>&1; then
|
||||
# macOS
|
||||
tr '\0' '\n' < "$selection" | pbcopy
|
||||
elif type termux-clipboard-set >/dev/null 2>&1; then
|
||||
# Termux
|
||||
tr '\0' '\n' < "$selection" | termux-clipboard-set
|
||||
elif type clip.exe >/dev/null 2>&1; then
|
||||
# WSL
|
||||
tr '\0' '\n' < "$selection" | clip.exe
|
||||
elif type clip >/dev/null 2>&1; then
|
||||
# Cygwin
|
||||
tr '\0' '\n' < "$selection" | clip
|
||||
elif type wl-copy >/dev/null 2>&1; then
|
||||
# Wayland
|
||||
tr '\0' '\n' < "$selection" | wl-copy
|
||||
elif type clipboard >/dev/null 2>&1; then
|
||||
# Haiku
|
||||
tr '\0' '\n' < "$selection" | clipboard --stdin
|
||||
fi
|
|
@ -0,0 +1,428 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Print icons in front of list of directories/files
|
||||
|
||||
# Dependencies: awk
|
||||
|
||||
# Usage
|
||||
# 1. Set colors and/or icons to your liking
|
||||
# 2. Pipe any directory listing to iconlookup and it will output prepended icons
|
||||
# 3. preview-tui uses the script to prepend icon to directory listings
|
||||
# 4. Aditionally you can consider adding it to your PATH and/or FZF_DEFAULT_COMMAND to
|
||||
# make it work with various fzf plugins (make sure you also add --ansi to your FZF_DEFAULT_OPTS)
|
||||
|
||||
# Shell: POSIX compliant
|
||||
|
||||
# Author: Luuk van Baal (https://github.com/luukvbaal/iconlookup)
|
||||
|
||||
icon_lookup() {
|
||||
awk 'BEGIN {
|
||||
# Set your ANSI colorscheme below (https://en.wikipedia.org/wiki/ANSI_escape_code#Colors).
|
||||
# Default uses standard nnn icon colors, 8 and 24-bit nord themes are commented out.
|
||||
colordepth=8 #colordepth=8 #colordepth=24
|
||||
color_dirtxt=39 #color_dirtxt=111 #color_dirtxt="129;161;193"
|
||||
color_filetxt=15 #color_filetxt=111 #color_filetxt="129;161;193"
|
||||
color_default=39 #color_default=111 #color_default="129;161;193"
|
||||
color_video=93 #color_video=110 #color_video="136;192;208"
|
||||
color_audio=220 #color_audio=150 #color_audio="163;190;140"
|
||||
color_image=82 #color_image=150 #color_image="163;190;140"
|
||||
color_docs=202 #color_docs=173 #color_docs="208;135;112"
|
||||
color_archive=209 #color_archive=179 #color_archive="235;203;139"
|
||||
color_c=81 #color_c=150 #color_c="163;190;140"
|
||||
color_java=32 #color_java=139 #color_java="180;142;173"
|
||||
color_js=47 #color_js=109 #color_js="143;188;187"
|
||||
color_react=39 #color_react=111 #color_react="129;161;193"
|
||||
color_css=199 #color_css=110 #color_css="136;192;208"
|
||||
color_python=227 #color_python=68 #color_python="94;129;172"
|
||||
color_lua=19 #color_lua=167 #color_lua="191;97;106"
|
||||
color_document=15 #color_document=173 #color_document="208;135;112"
|
||||
color_fsharp=31 #color_fsharp=179 #color_fsharp="180;142;173"
|
||||
color_ruby=160 #color_ruby=150 #color_ruby="163;190;140"
|
||||
color_scala=196 #color_scala=139 #color_scala="143;188;187"
|
||||
color_shell=47 #color_shell=109 #color_shell="143;188;187"
|
||||
color_vim=28 #color_vim=109 #color_vim="143;188;187"
|
||||
|
||||
# icons[][1] contains icon and icons[][2] contains color
|
||||
icons["directory"][1] = ""; icons["directory"][2] = color_default
|
||||
icons["file"][1] = ""; icons["file"][2] = color_default
|
||||
icons["exec"][1] = ""; icons["exec"][2] = color_default
|
||||
icons["manual"][1] = ""; icons["manual"][2] = color_docs
|
||||
icons["pipe"][1] = "ﳣ"; icons["pipe"][2] = color_default
|
||||
icons["socket"][1] = "ﳧ"; icons["socket"][2] = color_default
|
||||
icons["door"][1] = "➡"; icons["door"][2] = color_default
|
||||
|
||||
# top level and common icons
|
||||
icons[".git"][1] = ""; icons[".git"][2] = color_default
|
||||
icons["desktop"][1] = "ﲾ"; icons["desktop"][2] = color_default
|
||||
icons["briefcase"][1] = ""; icons["briefcase"][2] = color_default
|
||||
icons["document"][1] = ""; icons["document"][2] = color_default
|
||||
icons["downloads"][1] = ""; icons["downloads"][2] = color_default
|
||||
icons["music"][1] = ""; icons["music"][2] = color_default
|
||||
icons["musicfile"][1] = ""; icons["musicfile"][2] = color_audio
|
||||
icons["pictures"][1] = ""; icons["pictures"][2] = color_default
|
||||
icons["picturefile"][1] = ""; icons["picturefile"][2] = color_image
|
||||
icons["public"][1] = ""; icons["public"][2] = color_default
|
||||
icons["templates"][1] = "陼"; icons["templates"][2] = color_default
|
||||
icons["videos"][1] = ""; icons["videos"][2] = color_default
|
||||
icons["videofile"][1] = "ﳜ"; icons["videofile"][2] = color_video
|
||||
icons["changelog"][1] = ""; icons["changelog"][2] = color_docs
|
||||
icons["configure"][1] = ""; icons["configure"][2] = color_default
|
||||
icons["license"][1] = ""; icons["license"][2] = color_docs
|
||||
icons["makefile"][1] = ""; icons["makefile"][2] = color_default
|
||||
icons["archive"][1] = ""; icons["archive"][2] = color_archive
|
||||
icons["script"][1] = ""; icons["script"][2] = color_shell
|
||||
icons["cplusplus"][1] = ""; icons["cplusplus"][2] = color_c
|
||||
icons["java"][1] = ""; icons["java"][2] = color_java
|
||||
icons["clojure"][1] = ""; icons["clojure"][2] = color_default
|
||||
icons["js"][1] = ""; icons["js"][2] = color_js
|
||||
icons["linux"][1] = ""; icons["linux"][2] = color_default
|
||||
icons["fsharp"][1] = ""; icons["fsharp"][2] = color_fsharp
|
||||
icons["ruby"][1] = ""; icons["ruby"][2] = color_ruby
|
||||
icons["c"][1] = ""; icons["c"][2] = color_c
|
||||
icons["chess"][1] = ""; icons["chess"][2] = color_default
|
||||
icons["haskell"][1] = ""; icons["haskell"][2] = color_vim
|
||||
icons["html"][1] = ""; icons["html"][2] = color_default
|
||||
icons["react"][1] = ""; icons["react"][2] = color_react
|
||||
icons["python"][1] = ""; icons["python"][2] = color_python
|
||||
icons["database"][1] = ""; icons["database"][2] = color_default
|
||||
icons["worddoc"][1] = ""; icons["worddoc"][2] = color_document
|
||||
icons["playlist"][1] = "蘿"; icons["playlist"][2] = color_audio
|
||||
icons["opticaldisk"][1] = ""; icons["opticaldisk"][2] = color_archive
|
||||
|
||||
# numbers
|
||||
icons["1"][1] = icons["manual"][1]; icons["1"][2] = icons["manual"][2]
|
||||
icons["7z"][1] = icons["archive"][1]; icons["7z"][2] = icons["archive"][2]
|
||||
|
||||
# a
|
||||
icons["a"][1] = icons["manual"][1]; icons["a"][2] = icons["manual"][2]
|
||||
icons["apk"][1] = icons["archive"][1]; icons["apk"][2] = icons["archive"][2]
|
||||
icons["asm"][1] = icons["file"][1]; icons["asm"][2] = icons["file"][2]
|
||||
icons["aup"][1] = icons["musicfile"][1]; icons["aup"][2] = icons["musicfile"][2]
|
||||
icons["avi"][1] = icons["videofile"][1]; icons["avi"][2] = icons["videofile"][2]
|
||||
|
||||
# b
|
||||
icons["bat"][1] = icons["script"][1]; icons["bat"][2] = icons["script"][2]
|
||||
icons["bin"][1] = ""; icons["bin"][2] = color_default
|
||||
icons["bmp"][1] = icons["picturefile"][1]; icons["bmp"][2] = icons["picturefile"][2]
|
||||
icons["bz2"][1] = icons["archive"][1]; icons["bz2"][2] = icons["archive"][2]
|
||||
|
||||
# c
|
||||
icons["cplusplus"][1] = icons["cplusplus"][1]; icons["cplusplus"][2] = icons["cplusplus"][2]
|
||||
icons["cabal"][1] = icons["haskell"][1]; icons["cab"][2] = icons["haskell"][2]
|
||||
icons["cab"][1] = icons["archive"][1]; icons["cab"][2] = icons["archive"][2]
|
||||
icons["cbr"][1] = icons["archive"][1]; icons["cbr"][2] = icons["archive"][2]
|
||||
icons["cbz"][1] = icons["archive"][1]; icons["cbz"][2] = icons["archive"][2]
|
||||
icons["cc"][1] = icons["cplusplus"][1]; icons["cc"][2] = icons["cplusplus"][2]
|
||||
icons["class"][1] = icons["java"][1]; icons["class"][2] = icons["java"][2]
|
||||
icons["clj"][1] = icons["clojure"][1]; icons["clj"][2] = icons["clojure"][2]
|
||||
icons["cljc"][1] = icons["clojure"][1]; icons["cljc"][2] = icons["clojure"][2]
|
||||
icons["cljs"][1] = icons["clojure"][1]; icons["cljs"][2] = icons["clojure"][2]
|
||||
icons["cmake"][1] = icons["makefile"][1]; icons["cmake"][2] = icons["makefile"][2]
|
||||
icons["coffee"][1] = ""; icons["coffee"][2] = color_default
|
||||
icons["conf"][1] = icons["configure"][1]; icons["conf"][2] = icons["configure"][2]
|
||||
icons["cpio"][1] = icons["archive"][1]; icons["cpio"][2] = icons["archive"][2]
|
||||
icons["cpp"][1] = icons["cplusplus"][1]; icons["cpp"][2] = icons["cplusplus"][2]
|
||||
icons["css"][1] = ""; icons["css"][2] = color_css
|
||||
icons["cue"][1] = icons["playlist"][1]; icons["cue"][2] = icons["playlist"][2]
|
||||
icons["cvs"][1] = icons["configure"][1]; icons["cvs"][2] = icons["configure"][2]
|
||||
icons["cxx"][1] = icons["cplusplus"][1]; icons["cxx"][2] = icons["cplusplus"][2]
|
||||
|
||||
# d
|
||||
icons["db"][1] = icons["database"][1]; icons["db"][2] = icons["database"][2]
|
||||
icons["deb"][1] = ""; icons["deb"][2] = color_archive
|
||||
icons["diff"][1] = ""; icons["diff"][2] = color_default
|
||||
icons["dll"][1] = icons["script"][1]; icons["dll"][2] = icons["script"][2]
|
||||
icons["doc"][1] = icons["worddoc"][1]; icons["doc"][2] = icons["worddoc"][2]
|
||||
icons["docx"][1] = icons["worddoc"][1]; icons["docx"][2] = icons["worddoc"][2]
|
||||
|
||||
# e
|
||||
icons["ejs"][1] = icons["js"][1]; icons["ejs"][2] = icons["js"][2]
|
||||
icons["elf"][1] = icons["linux"][1]; icons["elf"][2] = icons["linux"][2]
|
||||
icons["epub"][1] = icons["manual"][1]; icons["epub"][2] = icons["manual"][2]
|
||||
icons["exe"][1] = icons["exec"][1]; icons["exe"][2] = icons["exec"][2]
|
||||
|
||||
# f
|
||||
icons["fsharp"][1] = icons["fsharp"][1]; icons["fsharp"][2] = icons["fsharp"][2]
|
||||
icons["flac"][1] = icons["musicfile"][1]; icons["flac"][2] = icons["musicfile"][2]
|
||||
icons["fen"][1] = icons["chess"][1]; icons["fen"][2] = icons["chess"][2]
|
||||
icons["flv"][1] = icons["videofile"][1]; icons["flv"][2] = icons["videofile"][2]
|
||||
icons["fs"][1] = icons["fsharp"][1]; icons["fs"][2] = icons["fsharp"][2]
|
||||
icons["fsi"][1] = icons["fsharp"][1]; icons["fsi"][2] = icons["fsharp"][2]
|
||||
icons["fsscript"][1] = icons["fsharp"][1]; icons["fsscript"][2] = icons["fsharp"][2]
|
||||
icons["fsx"][1] = icons["fsharp"][1]; icons["fsx"][2] = icons["fsharp"][2]
|
||||
|
||||
# g
|
||||
icons["gem"][1] = icons["ruby"][1]; icons["gem"][2] = icons["ruby"][2]
|
||||
icons["gif"][1] = icons["picturefile"][1]; icons["gif"][2] = icons["picturefile"][2]
|
||||
icons["go"][1] = "ﳑ"; icons["go"][2] = color_default
|
||||
icons["gz"][1] = icons["archive"][1]; icons["gz"][2] = icons["archive"][2]
|
||||
icons["gzip"][1] = icons["archive"][1]; icons["gzip"][2] = icons["archive"][2]
|
||||
|
||||
# h
|
||||
icons["h"][1] = icons["c"][1]; icons["h"][2] = icons["c"][2]
|
||||
icons["hh"][1] = icons["cplusplus"][1]; icons["hh"][2] = icons["cplusplus"][2]
|
||||
icons["hpp"][1] = icons["cplusplus"][1]; icons["hpp"][2] = icons["cplusplus"][2]
|
||||
icons["hs"][1] = icons["haskell"][1]; icons["hs"][2] = icons["haskell"][2]
|
||||
icons["htaccess"][1] = icons["configure"][1]; icons["htaccess"][2] = icons["configure"][2]
|
||||
icons["htpasswd"][1] = icons["configure"][1]; icons["htpasswd"][2] = icons["configure"][2]
|
||||
icons["htm"][1] = icons["html"][1]; icons["htm"][2] = icons["html"][2]
|
||||
icons["hxx"][1] = icons["cplusplus"][1]; icons["hxx"][2] = icons["cplusplus"][2]
|
||||
|
||||
# i
|
||||
icons["ico"][1] = icons["picturefile"][1]; icons["ico"][2] = icons["picturefile"][2]
|
||||
icons["img"][1] = icons["opticaldisk"][1]; icons["img"][2] = icons["opticaldisk"][2]
|
||||
icons["ini"][1] = icons["configure"][1]; icons["ini"][2] = icons["configure"][2]
|
||||
icons["iso"][1] = icons["opticaldisk"][1]; icons["iso"][2] = icons["opticaldisk"][2]
|
||||
|
||||
# j
|
||||
icons["jar"][1] = icons["java"][1]; icons["jar"][2] = icons["java"][2]
|
||||
icons["java"][1] = icons["java"][1]; icons["java"][2] = icons["java"][2]
|
||||
icons["jl"][1] = icons["configure"][1]; icons["jl"][2] = icons["configure"][2]
|
||||
icons["jpeg"][1] = icons["picturefile"][1]; icons["jpeg"][2] = icons["picturefile"][2]
|
||||
icons["jpg"][1] = icons["picturefile"][1]; icons["jpg"][2] = icons["picturefile"][2]
|
||||
icons["json"][1] = "ﬥ"; icons["json"][2] = color_js
|
||||
icons["jsx"][1] = icons["react"][1]; icons["jsx"][2] = icons["react"][2]
|
||||
|
||||
# k
|
||||
|
||||
# l
|
||||
icons["lha"][1] = icons["archive"][1]; icons["lha"][2] = icons["archive"][2]
|
||||
icons["lhs"][1] = icons["haskell"][1]; icons["lhs"][2] = icons["haskell"][2]
|
||||
icons["ilog"][1] = icons["document"][1]; icons["ilog"][2] = icons["document"][2]
|
||||
icons["lua"][1] = ""; icons["lua"][2] = color_lua
|
||||
icons["lzh"][1] = icons["archive"][1]; icons["lzh"][2] = icons["archive"][2]
|
||||
icons["lzma"][1] = icons["archive"][1]; icons["lzma"][2] = icons["archive"][2]
|
||||
|
||||
# m
|
||||
icons["m"][1] = "ﴜ"; icons["mat"][2] = color_c
|
||||
icons["m4a"][1] = icons["musicfile"][1]; icons["m4a"][2] = icons["musicfile"][2]
|
||||
icons["m4v"][1] = icons["videofile"][1]; icons["m4v"][2] = icons["videofile"][2]
|
||||
icons["mat"][1] = ""; icons["mat"][2] = color_c
|
||||
icons["markdown"][1] = ""; icons["markdown"][2] = color_docs
|
||||
icons["md"][1] = ""; icons["md"][2] = color_docs
|
||||
icons["mk"][1] = icons["makefile"][1]; icons["mk"][2] = icons["makefile"][2]
|
||||
icons["mkv"][1] = icons["videofile"][1]; icons["mkv"][2] = icons["videofile"][2]
|
||||
icons["mov"][1] = icons["videofile"][1]; icons["mov"][2] = icons["videofile"][2]
|
||||
icons["mp3"][1] = icons["musicfile"][1]; icons["mp3"][2] = icons["musicfile"][2]
|
||||
icons["mp4"][1] = icons["videofile"][1]; icons["mp4"][2] = icons["videofile"][2]
|
||||
icons["mpeg"][1] = icons["videofile"][1]; icons["mpeg"][2] = icons["videofile"][2]
|
||||
icons["mpg"][1] = icons["videofile"][1]; icons["mpg"][2] = icons["videofile"][2]
|
||||
icons["msi"][1] = ""; icons["msi"][2] = color_default
|
||||
|
||||
# n
|
||||
icons["nix"][1] = ""; icons["nix"][2] = color_fsharp
|
||||
|
||||
# o
|
||||
icons["o"][1] = icons["manual"][1]; icons["o"][2] = icons["manual"][2]
|
||||
icons["ogg"][1] = icons["musicfile"][1]; icons["ogg"][2] = icons["musicfile"][2]
|
||||
icons["odownload"][1] = icons["download"][1]; icons["odownload"][2] = icons["download"][2]
|
||||
icons["out"][1] = icons["linux"][1]; icons["out"][2] = icons["linux"][2]
|
||||
|
||||
# p
|
||||
icons["part"][1] = icons["download"][1]; icons["part"][2] = icons["download"][2]
|
||||
icons["patch"][1] = icons["diff"][1]; icons["patch"][2] = icons["diff"][2]
|
||||
icons["pdf"][1] = ""; icons["pdf"][2] = color_docs
|
||||
icons["pgn"][1] = icons["chess"][1]; icons["pgn"][2] = icons["chess"][2]
|
||||
icons["php"][1] = ""; icons["php"][2] = color_default
|
||||
icons["png"][1] = icons["picturefile"][1]; icons["png"][2] = icons["picturefile"][2]
|
||||
icons["ppt"][1] = ""; icons["ppt"][2] = color_default
|
||||
icons["pptx"][1] = ""; icons["pptx"][2] = color_default
|
||||
icons["psb"][1] = ""; icons["psb"][2] = color_default
|
||||
icons["psd"][1] = ""; icons["psd"][2] = color_default
|
||||
icons["py"][1] = icons["python"][1]; icons["py"][2] = icons["python"][2]
|
||||
icons["pyc"][1] = icons["python"][1]; icons["pyc"][2] = icons["python"][2]
|
||||
icons["pyd"][1] = icons["python"][1]; icons["pyd"][2] = icons["python"][2]
|
||||
icons["pyo"][1] = icons["python"][1]; icons["pyo"][2] = icons["python"][2]
|
||||
|
||||
# q
|
||||
|
||||
# r
|
||||
icons["rar"][1] = icons["archive"][1]; icons["rar"][2] = icons["archive"][2]
|
||||
icons["rc"][1] = icons["configure"][1]; icons["rc"][2] = icons["configure"][2]
|
||||
icons["rom"][1] = ""; icons["rom"][2] = color_default
|
||||
icons["rpm"][1] = icons["archive"][1]; icons["rpm"][2] = icons["archive"][2]
|
||||
icons["rss"][1] = "參"; icons["rss"][2] = color_default
|
||||
icons["rtf"][1] = ""; icons["rtf"][2] = color_default
|
||||
|
||||
# s
|
||||
icons["sass"][1] = ""; icons["sass"][2] = color_css
|
||||
icons["scss"][1] = ""; icons["scss"][2] = color_css
|
||||
icons["so"][1] = icons["manual"][1]; icons["so"][2] = icons["manual"][2]
|
||||
icons["scala"][1] = ""; icons["scala"][2] = color_scala
|
||||
icons["sh"][1] = icons["script"][1]; icons["sh"][2] = icons["script"][2]
|
||||
icons["slim"][1] = icons["script"][1]; icons["slim"][2] = icons["script"][2]
|
||||
icons["sln"][1] = ""; icons["sln"][2] = color_default
|
||||
icons["sql"][1] = icons["database"][1]; icons["sql"][2] = icons["database"][2]
|
||||
icons["srt"][1] = ""; icons["srt"][2] = color_default
|
||||
icons["isub"][1] = ""; icons["isub"][2] = color_default
|
||||
icons["svg"][1] = icons["picturefile"][1]; icons["svg"][2] = icons["picturefile"][2]
|
||||
|
||||
# t
|
||||
icons["tar"][1] = icons["archive"][1]; icons["tar"][2] = icons["archive"][2]
|
||||
icons["tex"][1] = ""; icons["tex"][2] = color_default
|
||||
icons["tgz"][1] = icons["archive"][1]; icons["tgz"][2] = icons["archive"][2]
|
||||
icons["ts"][1] = ""; icons["ts"][2] = color_js
|
||||
icons["tsx"][1] = icons["react"][1]; icons["tsx"][2] = icons["react"][2]
|
||||
icons["txt"][1] = icons["document"][1]; icons["txt"][2] = icons["document"][2]
|
||||
icons["txz"][1] = icons["archive"][1]; icons["txz"][2] = icons["archive"][2]
|
||||
|
||||
# u
|
||||
|
||||
# v
|
||||
icons["vid"][1] = icons["videofile"][1]; icons["vid"][2] = icons["videofile"][2]
|
||||
icons["vim"][1] = ""; icons["vim"][2] = color_vim
|
||||
icons["vimrc"][1] = ""; icons["vimrc"][2] = color_vim
|
||||
icons["vtt"][1] = ""; icons["vtt"][2] = color_default
|
||||
# w
|
||||
icons["wav"][1] = icons["musicfile"][1]; icons["wav"][2] = icons["musicfile"][2]
|
||||
icons["webm"][1] = icons["videofile"][1]; icons["webm"][2] = icons["videofile"][2]
|
||||
icons["wma"][1] = icons["videofile"][1]; icons["wma"][2] = icons["videofile"][2]
|
||||
icons["wmv"][1] = icons["videofile"][1]; icons["wmv"][2] = icons["videofile"][2]
|
||||
|
||||
# x
|
||||
icons["xbps"][1] = icons["archive"][1]; icons["xbps"][2] = color_archive
|
||||
icons["xcf"][1] = icons["picturefile"][1]; icons["xcf"][2] = color_image
|
||||
icons["xhtml"][1] = icons["html"][1]; icons["xhtml"][2] = icons["html"][2]
|
||||
icons["xls"][1] = ""; icons["xls"][2] = color_default
|
||||
icons["xlsx"][1] = ""; icons["xlsx"][2] = color_default
|
||||
icons["xml"][1] = icons["html"][1]; icons["xml"][2] = icons["html"][2]
|
||||
icons["xz"][1] = icons["archive"][1]; icons["xz"][2] = icons["archive"][2]
|
||||
|
||||
# y
|
||||
icons["yaml"][1] = icons["configure"][1]; icons["yaml"][2] = icons["configure"][2]
|
||||
icons["yml"][1] = icons["configure"][1]; icons["yml"][2] = icons["configure"][2]
|
||||
# z
|
||||
icons["zip"][1] = icons["archive"][1]; icons["zip"][2] = icons["archive"][2]
|
||||
icons["zsh"][1] = icons["script"][1]; icons["zsh"][2] = icons["script"][2]
|
||||
icons["zst"][1] = icons["archive"][1]; icons["zst"][2] = icons["archive"][2]
|
||||
|
||||
FS = "."
|
||||
limit = ENVIRON["limit"]
|
||||
switch (colordepth) {
|
||||
case "4":
|
||||
escape="\033["
|
||||
break;
|
||||
case "8":
|
||||
escape="\033[38;5;"
|
||||
break;
|
||||
case "24":
|
||||
escape="\033[38;2;"
|
||||
break;
|
||||
}
|
||||
bstr = ENVIRON["beforestr"]
|
||||
}
|
||||
{
|
||||
# dont print cwd . and leading ./ from tree -f
|
||||
if ($0 ~/^\.$/)
|
||||
next
|
||||
ent = ($0 ~/^\.\//) ? substr($0, 3, length($0) - 2) : $0
|
||||
ext = $NF
|
||||
|
||||
# Print icons, set color and bold directories by using ansi escape codes
|
||||
if (ext in icons)
|
||||
printcolor(icons[ext][1], icons[ext][2], color_filetxt, ent, "10")
|
||||
else
|
||||
switch (substr(ent, length(ent), 1)) {
|
||||
case "/":
|
||||
printcolor(icons["directory"][1], color_default, color_dirtxt, ent, "1")
|
||||
break;
|
||||
case "*":
|
||||
printcolor(icons["exe"][1], color_default, color_filetxt, ent, "10")
|
||||
break;
|
||||
case "|":
|
||||
printcolor(icons["pipe"][1], color_default, color_filetxt, ent, "10")
|
||||
break;
|
||||
case "=":
|
||||
printcolor(icons["socket"][1], color_default, color_filetxt, ent, "10")
|
||||
break;
|
||||
case ">":
|
||||
printcolor(icons["door"][1], color_default, color_filetxt, ent, "10")
|
||||
break;
|
||||
default:
|
||||
printcolor(icons["file"][1], color_default, color_filetxt, ent, "10")
|
||||
}
|
||||
}
|
||||
function printcolor(i, c, d, n, b) {
|
||||
if (limit != "" && length(n) + 2 > limit)
|
||||
n = substr(n, 1, limit - 2)
|
||||
printf "\033[0m"
|
||||
printf "%s%s%s;%sm%s %s%sm%s\n", bstr, escape, c, b, i, escape, d, n
|
||||
}'
|
||||
printf '\033[0m'
|
||||
}
|
||||
|
||||
print_begin() {
|
||||
printf '%s\n' "$1" | sed 's/\\n/\n/g'
|
||||
}
|
||||
|
||||
print_end() {
|
||||
printf '%s\n' "$1" | sed 's/\\n/\n/g'
|
||||
}
|
||||
|
||||
print_help() {
|
||||
printf 'Icon Lookup\n
|
||||
Usage:
|
||||
iconlookup [options]
|
||||
iconlookup [-bBe] [string]
|
||||
iconlookup -l [number]
|
||||
iconlookup (-h | --help)
|
||||
|
||||
Prepend icons to list of files based on extension or appended indicator by ls/tree "-F" flag ("/" for directory, "*" for executable etc.)
|
||||
|
||||
Options:
|
||||
-h --help -? Show this screen.
|
||||
-b --before Prepend str before icon.
|
||||
-B --begin Prepend str before output.
|
||||
-e --end Append str after output.
|
||||
-l --limit Limit line length to [number] characters.'
|
||||
}
|
||||
|
||||
while :; do
|
||||
case $1 in
|
||||
-h|-\?|--help)
|
||||
print_help
|
||||
exit ;;
|
||||
-B|--begin)
|
||||
if [ -n "$2" ]; then
|
||||
print_begin "$2"
|
||||
fi
|
||||
shift ;;
|
||||
-e|--end)
|
||||
if [ -n "$2" ]; then
|
||||
end=1
|
||||
endstr="$2"
|
||||
fi
|
||||
shift ;;
|
||||
-b|--before)
|
||||
if [ -n "$2" ]; then
|
||||
export beforestr="$2"
|
||||
fi
|
||||
shift ;;
|
||||
-l|--limit)
|
||||
if [ -n "$2" ]; then
|
||||
export limit="$2"
|
||||
shift
|
||||
else
|
||||
printf 'ERROR: "--limit" requires a non-empty option argument.\n'
|
||||
exit
|
||||
fi ;;
|
||||
--)
|
||||
shift
|
||||
break ;;
|
||||
-?*)
|
||||
printf 'WARNING: Unknown option ignored: %s\n' "$1" ;;
|
||||
*) break ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [ ! -t 0 ]; then
|
||||
[ -n "$beforestr" ] && limit="$((limit - ${#beforestr}))"
|
||||
icon_lookup
|
||||
else
|
||||
printf 'ERROR: no data provided...\nExpecting a directory listing in stdin\n'
|
||||
fi
|
||||
|
||||
if [ -n "$end" ]; then
|
||||
print_end "$endstr"
|
||||
fi
|
|
@ -0,0 +1,180 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Description: An almost fully POSIX compliant batch file renamer
|
||||
#
|
||||
# Note: nnn auto-detects and invokes this plugin if available
|
||||
# Whitespace is used as delimiter for read.
|
||||
# The plugin doesn't support filenames with leading or trailing whitespace
|
||||
# To use NNN_LIST your shell must support readlink(1)
|
||||
#
|
||||
# Capabilities:
|
||||
# 1. Basic file rename
|
||||
# 2. Detects order change
|
||||
# 3. Can move files
|
||||
# 4. Can remove files
|
||||
# 5. Switch number pairs to swap filenames
|
||||
#
|
||||
# Shell: bash
|
||||
# Author: KlzXS
|
||||
|
||||
EDITOR="${EDITOR:-vi}"
|
||||
TMPDIR="${TMPDIR:-/tmp}"
|
||||
NNN_INCLUDE_HIDDEN="${NNN_INCLUDE_HIDDEN:-0}"
|
||||
VERBOSE="${VERBOSE:-0}"
|
||||
RECURSIVE="${RECURSIVE:-0}"
|
||||
|
||||
case "$NNN_TRASH" in
|
||||
1)
|
||||
RM_UTIL="trash-put" ;;
|
||||
2)
|
||||
RM_UTIL="gio trash" ;;
|
||||
*)
|
||||
RM_UTIL="rm -ri" ;;
|
||||
esac
|
||||
|
||||
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
|
||||
exit_status=0
|
||||
|
||||
dst_file=$(mktemp "$TMPDIR/.nnnXXXXXX")
|
||||
|
||||
if [ -s "$selection" ]; then
|
||||
printf "Rename 'c'urrent / 's'election? "
|
||||
read -r resp
|
||||
|
||||
if ! [ "$resp" = "c" ] && ! [ "$resp" = "s" ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$resp" = "s" ]; then
|
||||
arr=$(tr '\0' '\n' < "$selection")
|
||||
else
|
||||
findcmd="find . ! -name ."
|
||||
|
||||
if [ "$RECURSIVE" -eq 0 ]; then
|
||||
findcmd="$findcmd -prune"
|
||||
fi
|
||||
|
||||
if [ "$NNN_INCLUDE_HIDDEN" -eq 0 ]; then
|
||||
findcmd="$findcmd ! -name \".*\""
|
||||
fi
|
||||
|
||||
if [ -z "$NNN_LIST" ]; then
|
||||
findcmd="$findcmd -print"
|
||||
else
|
||||
findcmd="$findcmd -printf "'"'"$NNN_LIST/%P\n"'"'
|
||||
fi
|
||||
|
||||
arr=$(eval "$findcmd" | sort)
|
||||
fi
|
||||
|
||||
lines=$(printf "%s\n" "$arr" | wc -l)
|
||||
width=${#lines}
|
||||
|
||||
printf "%s" "$arr" | awk '{printf("%'"${width}"'d %s\n", NR, $0)}' > "$dst_file"
|
||||
|
||||
items=("~")
|
||||
while IFS='' read -r line; do
|
||||
if [ -n "$NNN_LIST" ]; then
|
||||
line=$(readlink "$line" || printf "%s" "$line")
|
||||
fi
|
||||
|
||||
items+=("$line");
|
||||
done < <(printf "%s\n" "$arr")
|
||||
|
||||
$EDITOR "$dst_file"
|
||||
|
||||
while read -r num name; do
|
||||
if [ -z "$name" ]; then
|
||||
if [ -z "$num" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
printf "%s: unable to parse line, aborting\n" "$0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check if $num is an integer
|
||||
if [ ! "$num" -eq "$num" ] 2> /dev/null; then
|
||||
printf "%s: unable to parse line, aborting\n" "$0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
src=${items[$num]}
|
||||
|
||||
if [ -z "$src" ]; then
|
||||
printf "%s: unknown item number %s\n" "$0" "$num" > /dev/stderr
|
||||
continue
|
||||
elif [ "$name" != "$src" ]; then
|
||||
if [ -z "$name" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ ! -e "$src" ] && [ ! -L "$src" ]; then
|
||||
printf "%s: %s does not exit\n" "$0" "$src" > /dev/stderr
|
||||
|
||||
unset "items[$num]"
|
||||
continue
|
||||
fi
|
||||
|
||||
# handle swaps
|
||||
if [ -e "$name" ] || [ -L "$name" ]; then
|
||||
tmp="$name~"
|
||||
c=0
|
||||
|
||||
while [ -e "$tmp" ] || [ -L "$tmp" ]; do
|
||||
c=$((c+1))
|
||||
tmp="$tmp~$c"
|
||||
done
|
||||
|
||||
if mv "$name" "$tmp"; then
|
||||
if [ "$VERBOSE" -ne 0 ]; then
|
||||
printf "'%s' -> '%s'\n" "$name" "$tmp"
|
||||
fi
|
||||
else
|
||||
printf "%s: failed to rename %s to %s: %s\n" "$0" "$name" "$tmp" "$!" > /dev/stderr
|
||||
exit_status=1
|
||||
fi
|
||||
|
||||
for key in "${!items[@]}"; do
|
||||
if [ "${items[$key]}" = "$name" ]; then
|
||||
items[$key]="$tmp"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
dir=$(dirname "$name")
|
||||
if [ ! -d "$dir" ] && ! mkdir -p "$dir"; then
|
||||
printf "%s: failed to create directory tree %s\n" "$0" "$dir" > /dev/stderr
|
||||
exit_status=1
|
||||
elif ! mv -i "$src" "$name"; then
|
||||
printf "%s: failed to rename %s to %s: %s\n" "$0" "$name" "$tmp" "$!" > /dev/stderr
|
||||
exit_status=1
|
||||
else
|
||||
if [ -d "$name" ]; then
|
||||
for key in "${!items[@]}"; do
|
||||
items[$key]=$(printf "%s" "${items[$key]}" | sed "s|^$src\(\$\|\/\)|$name\1|")
|
||||
done
|
||||
|
||||
if [ "$VERBOSE" -ne 0 ]; then
|
||||
printf "'%s' => '%s'\n" "$src" "$name"
|
||||
fi
|
||||
else
|
||||
true
|
||||
if [ "$VERBOSE" -ne 0 ]; then
|
||||
printf "'%s' -> '%s'\n" "$src" "$name"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
unset "items[$num]"
|
||||
done <"$dst_file"
|
||||
|
||||
unset "items[0]"
|
||||
for item in "${items[@]}"; do
|
||||
$RM_UTIL "$item"
|
||||
done
|
||||
|
||||
rm "$dst_file"
|
||||
exit $exit_status
|
|
@ -0,0 +1,38 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Helper script for plugins
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Anna Arad
|
||||
|
||||
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
|
||||
export selection
|
||||
|
||||
## Set CUR_CTX to 1 to open directory in current context
|
||||
CUR_CTX=0
|
||||
export CUR_CTX
|
||||
|
||||
## Ask nnn to switch to directory $1 in context $2.
|
||||
## If $2 is not provided, the function asks explicitly.
|
||||
nnn_cd () {
|
||||
dir="$1"
|
||||
|
||||
if [ -z "$NNN_PIPE" ]; then
|
||||
echo "No pipe file found" 1>&2
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -n "$2" ]; then
|
||||
context=$2
|
||||
elif [ $CUR_CTX -ne 1 ]; then
|
||||
printf "Choose context 1-4 (blank for current): "
|
||||
read -r context
|
||||
fi
|
||||
|
||||
printf "%s" "${context:-0}c$dir" > "$NNN_PIPE"
|
||||
}
|
||||
|
||||
cmd_exists () {
|
||||
type "$1" > /dev/null 2>&1
|
||||
echo $?
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Show a notification
|
||||
#
|
||||
# Details: nnn invokes this plugin to show notification when a cp/mv/rm operation is complete.
|
||||
#
|
||||
# Dependencies: notify-send (Ubuntu)/ntfy (https://github.com/dschep/ntfy)/osascript (macOS)/notify (Haiku)
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Anna Arad
|
||||
|
||||
OS="$(uname)"
|
||||
|
||||
if type notify-send >/dev/null 2>&1; then
|
||||
notify-send nnn "Done!"
|
||||
elif [ "$OS" = "Darwin" ]; then
|
||||
osascript -e 'display notification "Done!" with title "nnn"'
|
||||
elif type ntfy >/dev/null 2>&1; then
|
||||
ntfy -t nnn send "Done!"
|
||||
elif [ "$OS" = "Haiku" ]; then
|
||||
notify --title "nnn" "Done!"
|
||||
fi
|
|
@ -0,0 +1,74 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Navigate to directory using jump/autojump/zoxide/z
|
||||
#
|
||||
# Dependencies:
|
||||
# - jump - https://github.com/gsamokovarov/jump
|
||||
# - OR autojump - https://github.com/wting/autojump
|
||||
# - OR zoxide - https://github.com/ajeetdsouza/zoxide
|
||||
# - OR z - https://github.com/rupa/z (z requires fzf)
|
||||
# - OR z (fish) - https://github.com/jethrokuan/z (z requires fzf)
|
||||
# - OR z.lua - https://github.com/skywind3000/z.lua (z.lua can enhanced with fzf)
|
||||
#
|
||||
# Note: The dependencies STORE NAVIGATION PATTERNS
|
||||
#
|
||||
# to make z.lua work, you need to set $NNN_ZLUA to the path of script z.lua
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Authors: Marty Buchaus, Dave Snider, Tim Adler, Nick Waywood
|
||||
|
||||
if [ ! -p "$NNN_PIPE" ]; then
|
||||
printf 'ERROR: NNN_PIPE is not set!'
|
||||
read -r _
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if type jump >/dev/null 2>&1; then
|
||||
printf "jump to : "
|
||||
IFS= read -r line
|
||||
# shellcheck disable=SC2086
|
||||
odir="$(jump cd ${line})"
|
||||
printf "%s" "0c$odir" > "$NNN_PIPE"
|
||||
elif type autojump >/dev/null 2>&1; then
|
||||
printf "jump to : "
|
||||
read -r dir
|
||||
odir="$(autojump "$dir")"
|
||||
printf "%s" "0c$odir" > "$NNN_PIPE"
|
||||
elif type zoxide >/dev/null 2>&1; then
|
||||
if type fzf >/dev/null 2>&1; then
|
||||
odir="$(zoxide query -i --)"
|
||||
printf "%s" "0c$odir" > "$NNN_PIPE"
|
||||
else
|
||||
printf "jump to : "
|
||||
read -r dir
|
||||
odir="$(zoxide query -- "$dir")"
|
||||
printf "%s" "0c$odir" > "$NNN_PIPE"
|
||||
fi
|
||||
elif type lua >/dev/null 2>&1 && [ -n "$NNN_ZLUA" ]; then
|
||||
printf "jump to : "
|
||||
read -r line
|
||||
if type fzf >/dev/null 2>&1; then
|
||||
odir="$(lua "$NNN_ZLUA" -l "$line" | fzf --nth 2.. --reverse --inline-info --tac +s -e --height 35%)"
|
||||
printf "%s" "0c$(echo "$odir" | awk '{print $2}')" > "$NNN_PIPE"
|
||||
else
|
||||
odir="$(lua "$NNN_ZLUA" -e "$line")"
|
||||
printf "%s" "0c$odir" > "$NNN_PIPE"
|
||||
fi
|
||||
else
|
||||
# rupa/z uses $_Z_DATA, jethrokuan/z (=port of z for fish) uses $Z_DATA
|
||||
datafile="${_Z_DATA:-${Z_DATA:-$HOME/.z}}"
|
||||
if type fzf >/dev/null 2>&1 && [ -f "$datafile" ]; then
|
||||
# Read the data from z's file instead of calling
|
||||
# z so the data doesn't need to be processed twice
|
||||
sel=$(awk -F "|" '{print $1}' "$datafile" | fzf | awk '{$1=$1};1')
|
||||
|
||||
# NOTE: Uncomment this line and comment out the line above if
|
||||
# you want to see the weightings of the dir's in the fzf pane
|
||||
# sel=$(awk -F "|" '{printf "%s %s\n", $2, $1}' "$datafile" | fzf | sed 's/^[0-9,.]* *//' | awk '{$1=$1};1')
|
||||
|
||||
printf "%s" "0c$sel" > "$NNN_PIPE"
|
||||
else
|
||||
printf "No supported autojump script [jump/autojump/zoxide/z (needs fzf)] found"
|
||||
read -r _
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,50 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Play random music (MP3, FLAC, M4A, WEBM, WMA) from current dir.
|
||||
#
|
||||
# Dependencies: mocp (or custom)
|
||||
#
|
||||
# Note: You may want to set GUIPLAYER.
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Arun Prakash Jana
|
||||
|
||||
GUIPLAYER="${GUIPLAYER:-""}"
|
||||
NUMTRACKS="${NUMTRACKS:-100}"
|
||||
|
||||
if [ -n "$GUIPLAYER" ]; then
|
||||
find . -type f \( -iname "*.mp3" -o -iname "*.flac" -o -iname "*.m4a" -o -iname "*.webm" -o -iname "*.wma" \) | shuf -n "$NUMTRACKS" | xargs -d "\n" "$GUIPLAYER" > /dev/null 2>&1 &
|
||||
|
||||
# detach the player
|
||||
sleep 1
|
||||
elif type mocp >/dev/null 2>&1; then
|
||||
cmd=$(pgrep -x mocp 2>/dev/null)
|
||||
ret=$cmd
|
||||
|
||||
if [ -z "$ret" ]; then
|
||||
# start MOC server
|
||||
mocp -S
|
||||
mocp -o shuffle
|
||||
else
|
||||
# mocp running, check if it's playing
|
||||
state=$(mocp -i | grep "State:" | cut -d' ' -f2)
|
||||
if [ "$state" = 'PLAY' ]; then
|
||||
# add up to 100 random audio files
|
||||
find . -type f \( -iname "*.mp3" -o -iname "*.flac" -o -iname "*.m4a" -o -iname "*.webm" -o -iname "*.wma" \) | head -n "$NUMTRACKS" | xargs -d "\n" mocp -a
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
|
||||
# clear MOC playlist
|
||||
mocp -c
|
||||
mocp -o shuffle
|
||||
|
||||
# add up to 100 random audio files
|
||||
find . -type f \( -iname "*.mp3" -o -iname "*.flac" -o -iname "*.m4a" -o -iname "*.webm" -o -iname "*.wma" \) | head -n "$NUMTRACKS" | xargs -d "\n" mocp -a
|
||||
|
||||
# start playing
|
||||
mocp -p
|
||||
else
|
||||
printf "moc missing"
|
||||
read -r _
|
||||
fi
|
|
@ -0,0 +1,32 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Allows for creation of multiple files/dirs simultaneously
|
||||
# Creates a tmp file to write each entry in a separate line
|
||||
#
|
||||
# Note: Only relative paths are supported. Absolute paths are ignored
|
||||
# Leading and trailing whitespace in path names is also ignored
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: KlzXS
|
||||
|
||||
EDITOR="${EDITOR:-vi}"
|
||||
TMPDIR="${TMPDIR:-/tmp}"
|
||||
|
||||
printf "'f'ile / 'd'ir? "
|
||||
read -r resp
|
||||
|
||||
if [ "$resp" = "f" ]; then
|
||||
#shellcheck disable=SC2016
|
||||
cmd='mkdir -p "$(dirname "{}")" && touch "{}"'
|
||||
elif [ "$resp" = "d" ]; then
|
||||
cmd='mkdir -p {}'
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tmpfile=$(mktemp "$TMPDIR/.nnnXXXXXX")
|
||||
$EDITOR "$tmpfile"
|
||||
|
||||
sed "/^\//d" "$tmpfile" | xargs -n1 -I{} sh -c "$cmd"
|
||||
|
||||
rm "$tmpfile"
|
|
@ -0,0 +1,56 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: 'cd' to the directory from CDPATH
|
||||
#
|
||||
# Details: If the CDPATH environmet variable is not set, the default value of
|
||||
# ${XDG_CONFIG_HOME:-$HOME/.config}/nnn/bookmarks will be used.
|
||||
# You can create this directory and fill it with symbolic links to your
|
||||
# favorite directories. It's a good idea to add it to CDPATH so that it
|
||||
# could also be used from the command line outside of nnn.
|
||||
# The fzf search is done on the directory basename (the first column).
|
||||
#
|
||||
# This plugin is an extended version of the bookmarks plugin.
|
||||
# If you set your CDPATH to ${XDG_CACHE_HOME:-$HOME/.cache}/nnn/bookmarks
|
||||
# or to the value of BOOKMARKS_DIR, you can use it as a bookmarks replacement.
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Yuri Kloubakov
|
||||
|
||||
# shellcheck disable=SC1090,SC1091
|
||||
. "$(dirname "$0")"/.nnn-plugin-helper
|
||||
|
||||
# Get a list of (symbolic links to) directories for every element of CDPATH
|
||||
get_dirs() {
|
||||
IFS=':'
|
||||
for path in $CDPATH; do
|
||||
for entry in "$path"/*; do
|
||||
if [ -d "$entry" ]; then
|
||||
name=$(basename "$entry" | grep -o '^.\{1,24\}')
|
||||
if [ -h "$entry" ]; then
|
||||
slink=$(ls -dl -- "$entry")
|
||||
entry=${slink#*" $entry -> "}
|
||||
fi
|
||||
printf "%-24s :%s\n" "${name}" "$entry"
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
abort() {
|
||||
echo "$1"
|
||||
read -r _
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ -z "$CDPATH" ]; then
|
||||
CDPATH="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/bookmarks"
|
||||
[ -d "$CDPATH" ] || abort "CDPATH is not set and there is no \"$CDPATH\" directory"
|
||||
fi
|
||||
|
||||
dir_list=$(get_dirs)
|
||||
[ -n "$dir_list" ] || abort "There are no directories to choose from. Check your \"$CDPATH\"."
|
||||
|
||||
dir=$(echo "$dir_list" | fzf --nth=1 --delimiter=':' | awk -F: 'END { print $2 }')
|
||||
if [ -n "$dir" ]; then
|
||||
nnn_cd "$dir" 0
|
||||
fi
|
|
@ -0,0 +1,72 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Create and verify checksums
|
||||
#
|
||||
# Details:
|
||||
# - selection: it will generate one file with the checksums and filenames
|
||||
# (and with paths if they are in another directory)
|
||||
# output checksum filename format: checksum_timestamp.checksum_type
|
||||
# - file: if the file is a checksum, the plugin does the verification
|
||||
# if the file is not a checksum, checksum will be generated for it
|
||||
# the output checksum filename will be filename.checksum_type
|
||||
# - directory: recursively calculates checksum for all the files in the dir
|
||||
# the output checksum filename will be directory.checksum_type
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Authors: ath3, Arun Prakash Jana
|
||||
|
||||
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
|
||||
resp=f
|
||||
chsum=md5
|
||||
|
||||
checksum_type()
|
||||
{
|
||||
echo "possible checksums: md5, sha1, sha224, sha256, sha384, sha512"
|
||||
printf "create md5 (m), sha256 (s), sha512 (S) (or type one of the above checksums) [default=m]: "
|
||||
read -r chsum_resp
|
||||
for chks in md5 sha1 sha224 sha256 sha384 sha512
|
||||
do
|
||||
if [ "$chsum_resp" = "$chks" ]; then
|
||||
chsum=$chsum_resp
|
||||
return
|
||||
fi
|
||||
done
|
||||
if [ "$chsum_resp" = "s" ]; then
|
||||
chsum=sha256
|
||||
elif [ "$chsum_resp" = "S" ]; then
|
||||
chsum=sha512
|
||||
fi
|
||||
}
|
||||
|
||||
if [ -s "$selection" ]; then
|
||||
printf "work with selection (s) or current file (f) [default=f]: "
|
||||
read -r resp
|
||||
fi
|
||||
|
||||
if [ "$resp" = "s" ]; then
|
||||
checksum_type
|
||||
sed 's|'"$PWD/"'||g' < "$selection" | xargs -0 -I{} ${chsum}sum {} > "checksum_$(date '+%Y%m%d%H%M').$chsum"
|
||||
|
||||
# Clear selection
|
||||
if [ -p "$NNN_PIPE" ]; then
|
||||
printf "-" > "$NNN_PIPE"
|
||||
fi
|
||||
elif [ -n "$1" ]; then
|
||||
if [ -f "$1" ]; then
|
||||
for chks in md5 sha1 sha224 sha256 sha384 sha512
|
||||
do
|
||||
if echo "$1" | grep -q \.${chks}$; then
|
||||
${chks}sum -c < "$1"
|
||||
read -r _
|
||||
return
|
||||
fi
|
||||
done
|
||||
checksum_type
|
||||
file=$(basename "$1").$chsum
|
||||
${chsum}sum "$1" > "$file"
|
||||
elif [ -d "$1" ]; then
|
||||
checksum_type
|
||||
file=$(basename "$1").$chsum
|
||||
find "$1" -type f -exec ${chsum}sum "{}" + > "$file"
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,80 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Add selection or hovered file/directory to cmus queue
|
||||
#
|
||||
# Dependencies: cmus, pgrep, xdotool (optional)
|
||||
#
|
||||
# Notes:
|
||||
# 1. If adding selection, files/dirs are added in the same order they were selected in nnn
|
||||
# 2. A new window will be opened if cmus is not running already, playback will start immediately
|
||||
# 3. If cmus is already running, files will be appended to the queue with no forced playback
|
||||
#
|
||||
# TODO:
|
||||
# 1. Add cava and cmus-lyrics as optional dependencies
|
||||
# 2. Start cava and/or cmus-lyrics in tmux or kitty panes next to cmus
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Kabouik
|
||||
|
||||
# (Optional) Set preferred terminal emulator for cmus if not set in your env,
|
||||
# or leave commented out to use OS default
|
||||
#TERMINAL="kitty"
|
||||
|
||||
if ! type cmus >/dev/null; then
|
||||
printf "cmus missing"
|
||||
read -r _
|
||||
exit 1
|
||||
fi
|
||||
|
||||
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
|
||||
|
||||
start_cmus() {
|
||||
type xdotool >/dev/null && nnnwindow="$(xdotool getactivewindow)"
|
||||
case "$TERMINAL" in
|
||||
kitty | gnome-terminal | st)
|
||||
nohup "$TERMINAL" -- cmus & ;;
|
||||
havoc)
|
||||
nohup "$TERMINAL" cmus & ;;
|
||||
"")
|
||||
nohup x-terminal-emulator -e cmus & ;;
|
||||
*)
|
||||
nohup "$TERMINAL" -e cmus & ;;
|
||||
esac
|
||||
# Give the new terminal some time to open
|
||||
until cmus-remote -C; do sleep 0.1; done
|
||||
[ -n "$nnnwindow" ] && xdotool windowactivate "$nnnwindow"
|
||||
} >/dev/null 2>&1
|
||||
|
||||
fill_queue() {
|
||||
if [ "$REPLY" = "s" ]; then
|
||||
xargs < "$selection" -0 cmus-remote -q
|
||||
elif [ -n "$1" ]; then
|
||||
cmus-remote -q "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
# If active selection,then ask what to do
|
||||
if [ -s "$selection" ]; then
|
||||
printf "Queue [s]election or [c]urrently hovered? [default=c]: "
|
||||
read -r REPLY
|
||||
fi
|
||||
|
||||
# If cmus is not running, start and play queue
|
||||
if ! pgrep cmus >/dev/null; then
|
||||
printf "cmus is not running, starting it in a new %s window.\n" "$TERMINAL"
|
||||
start_cmus
|
||||
fill_queue "$1"
|
||||
cmus-remote -p
|
||||
printf "Files added to cmus queue.\n"
|
||||
else # Append to existing queue if cmus is already running
|
||||
fill_queue "$1"
|
||||
printf "Files appended to current cmus queue.\n"
|
||||
fi
|
||||
|
||||
# Change view
|
||||
cmus-remote -C "view 4"
|
||||
|
||||
# Clear selection
|
||||
if [ -p "$NNN_PIPE" ]; then
|
||||
printf "-" > "$NNN_PIPE"
|
||||
fi
|
|
@ -0,0 +1,79 @@
|
|||
#! /bin/sh
|
||||
|
||||
FALLBACK_OPENER=xdg-open
|
||||
entry="$1"
|
||||
#mime="$(file -ibL "$entry" )"
|
||||
FNAME=$(basename "$entry")
|
||||
ext="${FNAME##*.}"
|
||||
if [ -n "$ext" ]; then
|
||||
ext="$(printf "%s" "${ext}" | tr '[:upper:]' '[:lower:]')"
|
||||
fi
|
||||
|
||||
case "${ext}" in
|
||||
## Archive
|
||||
a|ace|alz|arc|arj|bz|bz2|cab|cpio|deb|gz|jar|lha|lz|lzh|lzma|lzo|\
|
||||
rpm|rz|t7z|tar|tbz|tbz2|tgz|tlz|txz|tZ|tzo|war|xpi|xz|Z|zst|zip|rar|7z)
|
||||
extract "$entry"
|
||||
exit 0;;
|
||||
|
||||
## PDF
|
||||
pdf)
|
||||
zathura "$entry"
|
||||
exit 1;;
|
||||
|
||||
## Audio
|
||||
aac|flac|m4a|mid|midi|mpa|mp2|mp3|ogg|wav|wma)
|
||||
mpv --no-video --quiet "$entry"
|
||||
exit 1;;
|
||||
|
||||
## Video
|
||||
avi|mkv|mp4|gif)
|
||||
devour mpv "$entry"
|
||||
exit 1;;
|
||||
|
||||
## Image
|
||||
png|jpg|jpeg|PNG|JPG|JPEG|svg)
|
||||
"$IMAGEVIEWER" "$entry"
|
||||
exit 1;;
|
||||
|
||||
## Log files
|
||||
log)
|
||||
"$EDITOR" "$entry"
|
||||
exit 0;;
|
||||
|
||||
## BitTorrent
|
||||
torrenti|magnet)
|
||||
aria2c -i "$entry"
|
||||
exit 0;;
|
||||
|
||||
## OpenDocument
|
||||
odt|ods|odp|sxw)
|
||||
"$BROWSER" "$entry"
|
||||
exit 0;;
|
||||
|
||||
## Markdown
|
||||
md)
|
||||
"$EDITOR" "$entry"
|
||||
exit 0;;
|
||||
|
||||
## HTML
|
||||
htm|html|xhtml)
|
||||
## Preview as text conversion
|
||||
"$BROWSER" "$entry"
|
||||
exit 0;;
|
||||
|
||||
## JSON
|
||||
json)
|
||||
jq --color-output . "$entry"
|
||||
exit 0 ;;
|
||||
|
||||
esac
|
||||
|
||||
|
||||
case "$mime" in
|
||||
*text*)
|
||||
"$EDITOR" "$entry"
|
||||
exit 0 ;;
|
||||
esac
|
||||
|
||||
$FALLBACK_OPENER "$entry"
|
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Show diff of 2 directories or multiple files in vimdiff
|
||||
#
|
||||
# Notes:
|
||||
# 1. vim may show the warning: 'Vim: Warning: Input is not from a terminal'
|
||||
# press 'Enter' to ignore and proceed.
|
||||
# 2. if only one file is in selection, the hovered file is considered as the
|
||||
# second file to diff with
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Authors: Arun Prakash Jana, ath3
|
||||
|
||||
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
|
||||
|
||||
if type nvim >/dev/null 2>&1; then
|
||||
diffcmd="nvim -d"
|
||||
else
|
||||
diffcmd="vimdiff +0"
|
||||
fi
|
||||
|
||||
dirdiff() {
|
||||
dir1=$(mktemp "${TMPDIR:-/tmp}"/nnn-"$(basename "$1")".XXXXXXXX)
|
||||
dir2=$(mktemp "${TMPDIR:-/tmp}"/nnn-"$(basename "$2")".XXXXXXXX)
|
||||
ls -A1 "$1" > "$dir1"
|
||||
ls -A1 "$2" > "$dir2"
|
||||
$diffcmd "$dir1" "$dir2"
|
||||
rm "$dir1" "$dir2"
|
||||
}
|
||||
|
||||
if [ -s "$selection" ]; then
|
||||
arr=$(tr '\0' '\n' < "$selection")
|
||||
if [ "$(echo "$arr" | wc -l)" -gt 1 ]; then
|
||||
f1="$(echo "$arr" | sed -n '1p')"
|
||||
f2="$(echo "$arr" | sed -n '2p')"
|
||||
if [ -d "$f1" ] && [ -d "$f2" ]; then
|
||||
dirdiff "$f1" "$f2"
|
||||
else
|
||||
# If xargs supports the -o option, use it to get rid of:
|
||||
# Vim: Warning: Input is not from a terminal
|
||||
# xargs -0 -o vimdiff < $selection
|
||||
|
||||
eval xargs -0 "$diffcmd" < "$selection"
|
||||
fi
|
||||
elif [ -n "$1" ]; then
|
||||
f1="$(echo "$arr" | sed -n '1p')"
|
||||
if [ -d "$f1" ] && [ -d "$1" ]; then
|
||||
dirdiff "$f1" "$1"
|
||||
elif [ -f "$f1" ] && [ -f "$1" ]; then
|
||||
$diffcmd "$f1" "$1"
|
||||
else
|
||||
echo "cannot compare file with directory"
|
||||
fi
|
||||
else
|
||||
echo "needs at least 2 files or directories selected for comparison"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Clear selection
|
||||
if [ -p "$NNN_PIPE" ]; then
|
||||
printf "-" > "$NNN_PIPE"
|
||||
fi
|
|
@ -0,0 +1,77 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Open a Drag and drop window, to drop files onto other programs.
|
||||
# Also provides drag and drop window for files.
|
||||
#
|
||||
# Dependencies: dragon - https://github.com/mwh/dragon
|
||||
#
|
||||
# Notes:
|
||||
# 1. Files that are dropped will be added to nnn's selection
|
||||
# Some web-based files will be downloaded to current dir
|
||||
# with curl and it may overwrite some existing files
|
||||
# 2. The user has to mm to clear nnn's selection first
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: 0xACE
|
||||
|
||||
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
|
||||
resp=f
|
||||
all=
|
||||
if type dragon-drag-and-drop >/dev/null 2>&1; then
|
||||
dnd="dragon-drag-and-drop"
|
||||
elif type dragon-drop >/dev/null 2>&1; then
|
||||
dnd="dragon-drop"
|
||||
else
|
||||
dnd="dragon"
|
||||
fi
|
||||
|
||||
add_file ()
|
||||
{
|
||||
printf '%s\0' "$@" >> "$selection"
|
||||
}
|
||||
|
||||
use_all ()
|
||||
{
|
||||
printf "mark --all (a) [default=none]: "
|
||||
read -r resp
|
||||
if [ "$resp" = "a" ]; then
|
||||
all="--all"
|
||||
else
|
||||
all=""
|
||||
fi
|
||||
}
|
||||
|
||||
if [ -s "$selection" ]; then
|
||||
printf "Drop file (r). Drag selection (s), Drag current directory (d) or drag current file (f) [default=f]: "
|
||||
read -r resp
|
||||
else
|
||||
printf "Drop file (r). Drag current directory (d) or drag current file (f) [default=f]: "
|
||||
read -r resp
|
||||
if [ "$resp" = "s" ]; then
|
||||
resp=f
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$resp" = "s" ]; then
|
||||
use_all
|
||||
sed -z 's|'"$PWD/"'||g' < "$selection" | xargs -0 "$dnd" "$all" &
|
||||
elif [ "$resp" = "d" ]; then
|
||||
use_all
|
||||
"$dnd" "$all" "$PWD/"* &
|
||||
elif [ "$resp" = "r" ]; then
|
||||
true > "$selection"
|
||||
"$dnd" --print-path --target | while read -r f
|
||||
do
|
||||
if printf "%s" "$f" | grep '^\(https\?\|ftps\?\|s\?ftp\):\/\/' ; then
|
||||
curl -LJO "$f"
|
||||
add_file "$PWD/$(basename "$f")"
|
||||
elif [ -e "$f" ]; then
|
||||
add_file "$f"
|
||||
fi
|
||||
done &
|
||||
else
|
||||
if [ -n "$1" ] && [ -e "$1" ]; then
|
||||
"$dnd" "$1" &
|
||||
fi
|
||||
fi
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: List non-empty duplicates in the current dir (based on size followed by MD5)
|
||||
#
|
||||
# Source: https://www.commandlinefu.com/commands/view/3555/find-duplicate-files-based-on-size-first-then-md5-hash
|
||||
#
|
||||
# Dependencies: find md5sum sort uniq xargs gsed
|
||||
#
|
||||
# Notes:
|
||||
# 1. If the file size exceeds $size_digits digits the file will be misplaced
|
||||
# 12 digits fit files up to 931GiB
|
||||
# 2. Bash compatible required for mktemp
|
||||
#
|
||||
# Shell: Bash
|
||||
# Authors: syssyphus, KlzXS
|
||||
|
||||
EDITOR="${EDITOR:-vi}"
|
||||
TMPDIR="${TMPDIR:-/tmp}"
|
||||
|
||||
size_digits=12
|
||||
tmpfile=$(mktemp "$TMPDIR/.nnnXXXXXX")
|
||||
|
||||
printf "\
|
||||
## This is an overview of all duplicate files found.
|
||||
## Comment out the files you wish to remove. You will be given an option to cancel.
|
||||
## Lines with double comments (##) are ignored.
|
||||
## You will have the option to remove the files with force or interactively.\n
|
||||
" > "$tmpfile"
|
||||
|
||||
# shellcheck disable=SC2016
|
||||
find . -size +0 -type f -printf "%${size_digits}s %p\n" | sort -rn | uniq -w"${size_digits}" -D | sed -e '
|
||||
s/^ \{0,12\}\([0-9]\{0,12\}\) \(.*\)$/printf "%s %s\\n" "$(md5sum "\2")" "d\1"/
|
||||
' | tr '\n' '\0' | xargs -0 -n1 sh -c | sort | { uniq -w32 --all-repeated=separate; echo; } | sed -ne '
|
||||
h
|
||||
s/^\(.\{32\}\).* d\([0-9]*\)$/## md5sum: \1 size: \2 bytes/p
|
||||
g
|
||||
|
||||
:loop
|
||||
N
|
||||
/.*\n$/!b loop
|
||||
p' | sed -e 's/^.\{32\} \(.*\) d[0-9]*$/\1/' >> "$tmpfile"
|
||||
|
||||
"$EDITOR" "$tmpfile"
|
||||
|
||||
printf "Remove commented files? (yes/no) [default=n]: "
|
||||
read -r commented
|
||||
|
||||
if [ "$commented" = "y" ]; then
|
||||
sedcmd="/^##.*/d; /^[^#].*/d; /^$/d; s/^# *\(.*\)$/\1/"
|
||||
else
|
||||
printf "Press any key to exit"
|
||||
read -r _
|
||||
exit
|
||||
fi
|
||||
|
||||
printf "Remove with force or interactive? (f/i) [default=i]: "
|
||||
read -r force
|
||||
|
||||
if [ "$force" = "f" ]; then
|
||||
#shellcheck disable=SC2016
|
||||
sed -e "$sedcmd" "$tmpfile" | tr '\n' '\0' | xargs -0 -r sh -c 'rm -f "$0" "$@" </dev/tty'
|
||||
else
|
||||
#shellcheck disable=SC2016
|
||||
sed -e "$sedcmd" "$tmpfile" | tr '\n' '\0' | xargs -0 -r sh -c 'rm -i "$0" "$@" </dev/tty'
|
||||
fi
|
||||
|
||||
rm "$tmpfile"
|
||||
|
||||
printf "Press any key to exit"
|
||||
read -r _
|
|
@ -0,0 +1,89 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Description: Run custom search and list results in smart context
|
||||
#
|
||||
# Note: This plugin retains search history
|
||||
#
|
||||
# Usage:
|
||||
# Run plugin and enter e.g. "-size +10M" to list files in current
|
||||
# directory larger than 10M. By default entered expressions are
|
||||
# interpreted as arguments to find. Results have to be NUL
|
||||
# terminated which is done by default for find. Alternatively one
|
||||
# can prepend a '$' to run a custom search program such as fd or
|
||||
# ripgrep. Entered expressions will be saved in history file to
|
||||
# be listed as bookmarks and and can be entered by index and edited.
|
||||
#
|
||||
# Shell: Bash
|
||||
# Author: Arun Prakash Jana, Luuk van Baal
|
||||
TMPDIR="${TMPDIR:-/tmp}"
|
||||
NNN_FINDHIST="${NNN_FINDHIST:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/finderbms}"
|
||||
NNN_FINDHISTLEN="${NNN_FINDHISTLEN:-10000}"
|
||||
|
||||
printexamples() {
|
||||
printf -- "-maxdepth 1 -name pattern
|
||||
-maxdepth 1 -size +100M
|
||||
\$fd -0 pattern
|
||||
\$fd -0 -d 2 -S +100M
|
||||
\$grep -rlZ pattern
|
||||
\$rg -l0 pattern
|
||||
\$fzf -m | tr '\\\n' '\\\0'\n"
|
||||
}
|
||||
|
||||
printexprs() {
|
||||
for ((i = "$1"; i < ${#fexprs[@]}; i++)); do
|
||||
printf '%s\t%s\n' "$((i + 1))" "${fexprs[$i]}"
|
||||
done
|
||||
}
|
||||
|
||||
mapexpr() {
|
||||
if [ "$fexpr" -eq "$fexpr" ] 2>/dev/null; then
|
||||
fexpr=${fexprs[$((fexpr - 1))]}
|
||||
read -r -e -p "Search expression: " -i "$fexpr" fexpr
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
readexpr() {
|
||||
case "$fexpr" in
|
||||
h) clear
|
||||
printf "Examples:\n"
|
||||
mapfile -t fexprs < <(printexamples)
|
||||
printexprs 0
|
||||
read -r -p "Search expression or index: " fexpr
|
||||
mapexpr
|
||||
[ -n "$fexpr" ] && readexpr ;;
|
||||
\$*) cmd="${fexpr:1}" ;;
|
||||
*) mapexpr && readexpr
|
||||
cmd="find $fexpr -print0" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
clear
|
||||
[ -f "$NNN_FINDHIST" ] || printexamples > "$NNN_FINDHIST"
|
||||
|
||||
mapfile -t fexprs < <(sort "$NNN_FINDHIST" | uniq -c | sort -nr | head -n5 |\
|
||||
awk '{for (i=2; i<NF; i++) printf $i " "; print $NF}')
|
||||
printf "Most used search expressions:\n"
|
||||
printexprs 0
|
||||
|
||||
mapfile -t -O"$i" fexprs < <(tac "$NNN_FINDHIST" | awk '!a[$0]++' | head -n5)
|
||||
printf "Most recently used search expressions:\n"
|
||||
printexprs "$i"
|
||||
read -r -p "Search expression or index (h for help): " fexpr
|
||||
|
||||
mapexpr
|
||||
|
||||
if [ -n "$fexpr" ]; then
|
||||
printf "+l" > "$NNN_PIPE"
|
||||
while :; do
|
||||
readexpr
|
||||
eval "$cmd" > "$NNN_PIPE" && break
|
||||
read -r -e -p "Search expression: " -i "$fexpr" fexpr
|
||||
done
|
||||
if [ -n "$fexpr" ]; then
|
||||
tail -n"$NNN_FINDHISTLEN" "$NNN_FINDHIST" > "$TMPDIR/finderbms"
|
||||
printf "%s\n" "$fexpr" >> "$TMPDIR/finderbms"
|
||||
mv "$TMPDIR/finderbms" "$NNN_FINDHIST"
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,75 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Description: Clean filename or dirname (either hovered or selections)
|
||||
# to be more shell-friendly. This script cleans
|
||||
# non A-Za-z0-9._- characters.
|
||||
# and replaces it with underscore (_).
|
||||
#
|
||||
# It supports cleaning single/double quote, newline,
|
||||
# leading, trailing spaces.
|
||||
#
|
||||
# eg.
|
||||
# to be continued (つづく).mp4 -> to_be_continued______.mp4
|
||||
# [work] stuff.txt -> _work__stuff.txt
|
||||
# home's server -> home_s_server
|
||||
# qwe\trty -> __qwe_rty
|
||||
#
|
||||
# And if there are two almost similar filenames
|
||||
# like: 'asd]f' and 'asd f' both will be renamed to 'asd_f',
|
||||
# to avoid overwriting, the last file will be prepended by _.
|
||||
# So they will be: 'asd_f' and '_asd_f'
|
||||
#
|
||||
# Dependencies: sed
|
||||
#
|
||||
# Shell: Bash
|
||||
# Author: Benawi Adha
|
||||
|
||||
prompt=true
|
||||
sel=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
|
||||
|
||||
cleanup() {
|
||||
# printf "%s" "$1" | sed -e 's/[^A-Za-z0-9._-]/_/g'
|
||||
printf "%s" "$1" | sed 's/[^A-Za-z0-9._-]/_/g' | sed ':a;N;$!ba;s/\n/_/g'
|
||||
}
|
||||
|
||||
if [ -s "$sel" ]; then
|
||||
targets=()
|
||||
while IFS= read -r -d '' i || [ -n "$i" ]; do
|
||||
targets+=( "$(basename "$i")" )
|
||||
done < "$sel"
|
||||
else
|
||||
targets=("$1")
|
||||
fi
|
||||
|
||||
for i in "${targets[@]}"; do
|
||||
printf "%s -> %s\n" "$i" "$(cleanup "$i")";
|
||||
done
|
||||
|
||||
if $prompt; then
|
||||
echo
|
||||
printf "Proceed [Yn]? "
|
||||
read -r input
|
||||
case "$input" in
|
||||
y|Y|'')
|
||||
;;
|
||||
*)
|
||||
echo "Canceled"
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
for i in "${targets[@]}"; do
|
||||
if [ "$i" != "$(cleanup "$i")" ]; then
|
||||
tmp=''
|
||||
if [ -e "$(cleanup "$i")" ]; then
|
||||
tmp='_'
|
||||
fi
|
||||
mv "$i" "$tmp$(cleanup "$i")";
|
||||
fi
|
||||
done
|
||||
|
||||
# Clear selection
|
||||
if [ -s "$sel" ] && [ -p "$NNN_PIPE" ]; then
|
||||
printf "-" > "$NNN_PIPE"
|
||||
fi
|
|
@ -0,0 +1,89 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Fuzzy search multiple locations read-in from a path-list file
|
||||
# (or $PWD) and open the selected file's dir in a smart context.
|
||||
# Dependencies: fzf, find (only for multi-location search)
|
||||
#
|
||||
# Details: Paths in list file should be newline-separated absolute paths.
|
||||
# Paths can be file paths; the script will scan the parent dirs.
|
||||
#
|
||||
# The path-list file precedence is:
|
||||
# - "$1" (the hovered file) if it exists, is plain-text and the
|
||||
# first line points to an existing file
|
||||
# - "$LIST" if set below
|
||||
# - "$2" (the current directory) [mimics plugin fzcd behaviour]
|
||||
#
|
||||
# The path-list file can be generated easily:
|
||||
# - pick the (file)paths in picker mode to path-list file
|
||||
# - OR, edit selection in nnn and save as path-list file
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Anna Arad, Arun Prakash Jana, KlzXS
|
||||
|
||||
IFS="$(printf '\n\r')"
|
||||
|
||||
# shellcheck disable=SC1090,SC1091
|
||||
. "$(dirname "$0")"/.nnn-plugin-helper
|
||||
|
||||
CTX=+
|
||||
LIST="${LIST:-""}"
|
||||
|
||||
if ! type fzf >/dev/null 2>&1; then
|
||||
printf "fzf missing"
|
||||
read -r _
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "$1" ] && [ "$(file -b --mime-type "$1")" = 'text/plain' ] && [ -e "$(head -1 "$1")" ]; then
|
||||
LIST="$1"
|
||||
elif ! [ -s "$LIST" ]; then
|
||||
sel=$(fzf)
|
||||
# Show only the file and parent dir
|
||||
# sel=$(fzf --delimiter / --with-nth=-2,-1 --tiebreak=begin --info=hidden)
|
||||
|
||||
LIST=''
|
||||
fi
|
||||
|
||||
if [ -n "$LIST" ]; then
|
||||
if type find >/dev/null 2>&1; then
|
||||
tmpfile=$(mktemp /tmp/abc-script.XXXXXX)
|
||||
|
||||
while IFS= read -r path; do
|
||||
if [ -d "$path" ]; then
|
||||
printf "%s\n" "$path" >> "$tmpfile"
|
||||
elif [ -f "$path" ]; then
|
||||
printf "%s\n" "$(dirname "$path")" >> "$tmpfile"
|
||||
fi
|
||||
done < "$LIST"
|
||||
|
||||
sel=$(xargs -d '\n' < "$tmpfile" -I{} find {} -type f -printf "%H//%P\n" | sed '/.*\/\/\(\..*\|.*\/\..*\)/d; s:/\+:/:g' | fzf --delimiter / --tiebreak=begin --info=hidden)
|
||||
# Alternative for 'fd'
|
||||
# sel=$(xargs -d '\n' < "$tmpfile" fd . | fzf --delimiter / --tiebreak=begin --info=hidden)
|
||||
|
||||
rm "$tmpfile"
|
||||
else
|
||||
printf "find missing"
|
||||
read -r _
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$sel" ]; then
|
||||
if [ "$sel" = "." ] || { ! [ -d "$sel" ] && ! [ -f "$sel" ]; }; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Check if the selected path returned by fzf command is absolute
|
||||
case $sel in
|
||||
/*) nnn_cd "$sel" "$CTX" ;;
|
||||
*)
|
||||
# Remove "./" prefix if it exists
|
||||
sel="${sel#./}"
|
||||
|
||||
if [ "$PWD" = "/" ]; then
|
||||
nnn_cd "/$sel" "$CTX"
|
||||
else
|
||||
nnn_cd "$PWD/$sel" "$CTX"
|
||||
fi;;
|
||||
esac
|
||||
fi
|
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Fuzzy find a command from history,
|
||||
# edit in $EDITOR and run as a command
|
||||
#
|
||||
# Note: Supports only bash and fish history
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Arun Prakash Jana
|
||||
|
||||
if type fzf >/dev/null 2>&1; then
|
||||
fuzzy=fzf
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
shellname="$(basename "$SHELL")"
|
||||
|
||||
if [ "$shellname" = "bash" ]; then
|
||||
hist_file="$HOME/.bash_history"
|
||||
entry="$("$fuzzy" < "$hist_file")"
|
||||
elif [ "$shellname" = "fish" ]; then
|
||||
hist_file="$HOME/.local/share/fish/fish_history"
|
||||
entry="$(grep "\- cmd: " "$hist_file" | cut -c 8- | "$fuzzy")"
|
||||
fi
|
||||
|
||||
if [ -n "$entry" ]; then
|
||||
tmpfile=$(mktemp)
|
||||
echo "$entry" >> "$tmpfile"
|
||||
$EDITOR "$tmpfile"
|
||||
|
||||
if [ -s "$tmpfile" ]; then
|
||||
$SHELL -c "$(cat "$tmpfile")"
|
||||
fi
|
||||
|
||||
rm "$tmpfile"
|
||||
|
||||
printf "Press any key to exit"
|
||||
read -r _
|
||||
fi
|
|
@ -0,0 +1,83 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Regular mode:
|
||||
# Fuzzy find a file in directory subtree.
|
||||
# Opens in $VISUAL or $EDITOR if text.
|
||||
# Opens other type of files with xdg-open.
|
||||
# Work only with a single file selected.
|
||||
#
|
||||
# Picker mode:
|
||||
# If picker mode output file is passed, it
|
||||
# will be overwritten with any picked files.
|
||||
# Leaves untouched if no file is picked.
|
||||
# Works with single/multiple files selected.
|
||||
#
|
||||
# Dependencies: fd/find, fzf/skim, xdg-open/open (on macOS)
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Arun Prakash Jana
|
||||
|
||||
NUKE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins/nuke"
|
||||
USE_NUKE=0
|
||||
|
||||
# shellcheck disable=SC1090,SC1091
|
||||
. "$(dirname "$0")"/.nnn-plugin-helper
|
||||
|
||||
if type fzf >/dev/null 2>&1; then
|
||||
cmd="$FZF_DEFAULT_COMMAND"
|
||||
if type fd >/dev/null 2>&1; then
|
||||
[ -z "$cmd" ] && cmd="fd -t f 2>/dev/null"
|
||||
else
|
||||
[ -z "$cmd" ] && cmd="find . -type f 2>/dev/null"
|
||||
fi
|
||||
entry="$(eval "$cmd" | fzf -m)"
|
||||
# To show only the file name
|
||||
# entry=$(find . -type f 2>/dev/null | fzf --delimiter / --with-nth=-1 --tiebreak=begin --info=hidden)
|
||||
elif type sk >/dev/null 2>&1; then
|
||||
entry=$(find . -type f 2>/dev/null | sk)
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for picker mode
|
||||
if [ "$3" ]; then
|
||||
if [ "$entry" ]; then
|
||||
case "$entry" in
|
||||
/*) fullpath="$entry" ;;
|
||||
*) fullpath="$PWD/$entry" ;;
|
||||
esac
|
||||
if [ "-" = "$3" ]; then
|
||||
printf "%s\n" "$fullpath"
|
||||
else
|
||||
printf "%s\n" "$fullpath" > "$3"
|
||||
fi
|
||||
|
||||
# Tell `nnn` to clear its internal selection
|
||||
printf "%s" "0p" > "$NNN_PIPE"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$USE_NUKE" -ne 0 ]; then
|
||||
"$NUKE" "$entry"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Open the file (works for a single file only)
|
||||
cmd_file=""
|
||||
cmd_open=""
|
||||
if uname | grep -q "Darwin"; then
|
||||
cmd_file="file -bIL"
|
||||
cmd_open="open"
|
||||
else
|
||||
cmd_file="file -biL"
|
||||
cmd_open="xdg-open"
|
||||
fi
|
||||
|
||||
case "$($cmd_file "$entry")" in
|
||||
*text*)
|
||||
"${VISUAL:-$EDITOR}" "$entry" ;;
|
||||
*)
|
||||
$cmd_open "$entry" >/dev/null 2>&1 ;;
|
||||
esac
|
|
@ -0,0 +1,59 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Fuzzy find and execute nnn plugins (and optionally,
|
||||
# custom scripts located elsewhere).
|
||||
# Description and details of plugins can be previewed
|
||||
# from the fzf interface. Use `?` to toggle preview
|
||||
# pane on and off, ^Up/^Dn to scroll.
|
||||
#
|
||||
# Dependencies: find, fzf, cat (or bat, if installed)
|
||||
#
|
||||
# Note: For better compatibility with as many nnn plugins as possible,
|
||||
# fzplug will first execute the chosen script on the file hovered
|
||||
# in nnn, and upon failure, try to run it with no target (i.e on
|
||||
# an active selection, if present).
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Kabouik
|
||||
|
||||
# Optional scripts sources
|
||||
|
||||
# Leave blank or fill with the absolute path of a folder containing executable
|
||||
# scripts other than nnn plugins (e.g., "$HOME/.local/share/nautilus/scripts",
|
||||
# since there are numerous Nautilus script git repositories).
|
||||
# Add extra variables if needed, make sure you call them in the find command.
|
||||
|
||||
#CUSTOMDIR1="$HOME/.local/share/nautilus/scripts"
|
||||
CUSTOMDIR1=""
|
||||
CUSTOMDIR2=""
|
||||
|
||||
nnnpluginsdir="$HOME/.config/nnn/plugins"
|
||||
|
||||
# Preview with bat if installed
|
||||
if type bat >/dev/null; then
|
||||
BAT="bat --terminal-width='$(tput cols)' --decorations=always --color=always --style='${BAT_STYLE:-header,numbers}'"
|
||||
fi
|
||||
|
||||
plugin=$(find "$nnnpluginsdir" "$CUSTOMDIR1" "$CUSTOMDIR2" \
|
||||
-maxdepth 3 -perm -111 -type f 2>/dev/null | fzf --ansi --preview \
|
||||
"${BAT:-cat} {}" --preview-window="right:66%:wrap" --delimiter / \
|
||||
--with-nth -1 --bind="?:toggle-preview")
|
||||
|
||||
# Try running the script on the hovered file, and abort
|
||||
# abort if no plugin was selected (ESC or ^C pressed).
|
||||
err=0
|
||||
if ! [ "$plugin" = "" ]; then
|
||||
"$plugin" "$1" || err=1
|
||||
fi
|
||||
|
||||
# If attempt with hovered file fails, try without any target
|
||||
# (nnn selections should still be passed to the script in that case)
|
||||
if [ "$err" -eq "1" ]; then
|
||||
clear && "$plugin" || err=2
|
||||
fi
|
||||
|
||||
# Abort and show error if both fail
|
||||
if [ "$err" -eq "2" ]; then
|
||||
sep="\n---\n"
|
||||
printf "$sep""Failed to execute '%s'. See error above or try without fzfplug. Press return to continue. " "$plugin" && read -r _ && clear
|
||||
fi
|
|
@ -0,0 +1,70 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Update nnn plugins to installed nnn version
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Authors: Arun Prakash Jana, KlzXS
|
||||
|
||||
CONFIG_DIR=${XDG_CONFIG_HOME:-$HOME/.config}/nnn/
|
||||
PLUGIN_DIR=${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins
|
||||
|
||||
merge () {
|
||||
if type nvim >/dev/null 2>&1; then
|
||||
nvim -d "$1" "$2"
|
||||
else
|
||||
vimdiff +0 "$1" "$2"
|
||||
fi
|
||||
}
|
||||
|
||||
prompt () {
|
||||
printf "%s\n" "Plugin $1 already exists and is different."
|
||||
printf "Keep (k), merge (m), overwrite (o) [default: k]? "
|
||||
read -r operation
|
||||
|
||||
if [ "$operation" = "m" ]; then
|
||||
op="merge"
|
||||
elif [ "$operation" = "o" ]; then
|
||||
op="cp -vRf"
|
||||
else
|
||||
op="true"
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "$1" = "master" ] ; then
|
||||
VER="master"
|
||||
ARCHIVE_URL=https://github.com/jarun/nnn/archive/master.tar.gz
|
||||
elif type nnn >/dev/null 2>&1; then
|
||||
VER=$(nnn -V)
|
||||
ARCHIVE_URL=https://github.com/jarun/nnn/releases/download/v"$VER"/nnn-v"$VER".tar.gz
|
||||
else
|
||||
echo "nnn is not installed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# backup any earlier plugins
|
||||
if [ -d "$PLUGIN_DIR" ]; then
|
||||
tar -C "$CONFIG_DIR" -czf "$CONFIG_DIR""plugins-$(date '+%Y%m%d%H%M').tar.gz" plugins/
|
||||
fi
|
||||
|
||||
mkdir -p "$PLUGIN_DIR"
|
||||
cd "$CONFIG_DIR" || exit 1
|
||||
curl -Ls "$ARCHIVE_URL" -o nnn-"$VER".tar.gz
|
||||
tar -zxf nnn-"$VER".tar.gz
|
||||
|
||||
cd nnn-"$VER"/plugins || exit 1
|
||||
|
||||
# shellcheck disable=SC2044
|
||||
# We do not use obnoxious names for plugins
|
||||
for f in $(find . -maxdepth 1 \( ! -iname "." ! -iname "*.md" \)); do
|
||||
if [ -f ../../plugins/"$f" ]; then
|
||||
if [ "$(diff --brief "$f" ../../plugins/"$f")" ]; then
|
||||
prompt "$f"
|
||||
$op "$f" ../../plugins/
|
||||
fi
|
||||
else
|
||||
cp -vRf "$f" ../../plugins/
|
||||
fi
|
||||
done
|
||||
cd ../.. || exit 1
|
||||
|
||||
rm -rf nnn-"$VER"/ nnn-"$VER".tar.gz
|
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: cd to the top level of the current git repository in the current context
|
||||
# Dependencies: git
|
||||
# Shell: sh
|
||||
# Author: https://github.com/PatrickF1
|
||||
|
||||
root="$(git rev-parse --show-toplevel 2>/dev/null)"
|
||||
if [ -n "$root" ]; then
|
||||
printf "%s" "0c$root" > "$NNN_PIPE"
|
||||
else
|
||||
printf "Not in a git repository"
|
||||
read -r _
|
||||
exit 1
|
||||
fi
|
|
@ -0,0 +1,28 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Decrypts selected files using gpg. The contents of the
|
||||
# decrypted file are stored in a file with extension .dec
|
||||
#
|
||||
# Note: If an appropriate private key cannot be found gpg silently
|
||||
# prints a message in the background and no files are written.
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: KlzXS
|
||||
|
||||
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
|
||||
|
||||
printf "(s)election/(c)urrent? [default=c] "
|
||||
read -r resp
|
||||
|
||||
if [ "$resp" = "s" ]; then
|
||||
files=$(tr '\0' '\n' < "$selection")
|
||||
else
|
||||
files=$1
|
||||
fi
|
||||
|
||||
printf "%s" "$files" | xargs -n1 -I{} gpg --decrypt --output "{}.dec" {}
|
||||
|
||||
# Clear selection
|
||||
if [ "$resp" = "s" ] && [ -p "$NNN_PIPE" ]; then
|
||||
printf "-" > "$NNN_PIPE"
|
||||
fi
|
|
@ -0,0 +1,44 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Encrypts selected files using gpg. Can encrypt
|
||||
# asymmetrically (key) or symmetrically (passphrase).
|
||||
# If asymmetric encryption is chosen a key can be
|
||||
# chosen from the list of capable public keys using fzf.
|
||||
#
|
||||
# Note: Symmetric encryption only works for a single (current) file as per gpg limitations
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: KlzXS
|
||||
|
||||
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
|
||||
|
||||
printf "(s)ymmetric, (a)symmetric? [default=a] "
|
||||
read -r symmetry
|
||||
|
||||
if [ "$symmetry" = "s" ]; then
|
||||
gpg --symmetric "$1"
|
||||
else
|
||||
printf "(s)election/(c)urrent? [default=c] "
|
||||
read -r resp
|
||||
|
||||
if [ "$resp" = "s" ]; then
|
||||
files=$(tr '\0' '\n' < "$selection")
|
||||
else
|
||||
files=$1
|
||||
fi
|
||||
|
||||
keyids=$(gpg --list-public-keys --with-colons | grep -E "pub:(.*:){10}.*[eE].*:" | awk -F ":" '{print $5}')
|
||||
|
||||
#awk needs literal $10
|
||||
#shellcheck disable=SC2016
|
||||
keyuids=$(printf "%s" "$keyids" | xargs -n1 -I{} sh -c 'gpg --list-key --with-colons "{}" | grep "uid" | awk -F ":" '\''{printf "%s %s\n", "{}", $10}'\''')
|
||||
|
||||
recipient=$(printf "%s" "$keyuids" | fzf | awk '{print $1}')
|
||||
|
||||
printf "%s" "$files" | xargs -n1 gpg --encrypt --recipient "$recipient"
|
||||
|
||||
# Clear selection
|
||||
if [ "$resp" = "s" ] && [ -p "$NNN_PIPE" ]; then
|
||||
printf "-" > "$NNN_PIPE"
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
#set -x
|
||||
# Description: Send the selected (or hovered) files to your Android device using gsconnect daemon.js.
|
||||
# GSConnect must be configured on the Android device and the PC.
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Darukutsu
|
||||
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
|
||||
gsconnect=$HOME/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/daemon.js
|
||||
ids=$($gsconnect -l)
|
||||
|
||||
for id in $ids; do
|
||||
if [ -s "$selection" ]; then
|
||||
xargs -0 < "$selection" -I{} "$gsconnect" -d "$id" --share-file="{}"
|
||||
# Clear selection
|
||||
printf "-" > "$NNN_PIPE"
|
||||
else
|
||||
"$gsconnect" -d "$id" --share-file="$2/$1"
|
||||
fi
|
||||
done
|
|
@ -0,0 +1,49 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Browse Project Gutenberg catalogue by popularity, then download
|
||||
# and read a book of your choice.
|
||||
#
|
||||
# Details: Set the variable EBOOK_ID to download in html format and read in w3m.
|
||||
# Clear EBOOK_ID to browse available ebooks by popularity and set it to
|
||||
# the ID once you find an interesting one.
|
||||
# To download and read in epub format set READER to an epub reader like
|
||||
# epr: https://github.com/wustho/epr
|
||||
#
|
||||
# More on EBOOK_ID:
|
||||
# Wuthering Heights by Emily Brontë is at https://www.gutenberg.org/ebooks/768
|
||||
# So EBOOK_ID would be 768
|
||||
#
|
||||
# Downloaded ebooks are at ${XDG_CACHE_HOME:-$HOME/.cache}/nnn/gutenbooks/
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Arun Prakash Jana
|
||||
|
||||
EBOOK_ID="${EBOOK_ID:-""}"
|
||||
DIR="${XDG_CACHE_HOME:-$HOME/.cache}/nnn/gutenbooks/$EBOOK_ID"
|
||||
BROWSE_LINK="https://www.gutenberg.org/ebooks/search/?sort_order=downloads"
|
||||
BROWSER="${BROWSER:-w3m}"
|
||||
READER="${READER:-""}"
|
||||
|
||||
if [ -n "$EBOOK_ID" ]; then
|
||||
if [ ! -e "$DIR" ]; then
|
||||
mkdir -p "$DIR"
|
||||
cd "$DIR" || exit 1
|
||||
|
||||
if [ -z "$READER" ]; then
|
||||
curl -L -O "https://www.gutenberg.org/files/$EBOOK_ID/$EBOOK_ID-h.zip"
|
||||
unzip "$EBOOK_ID"-h.zip
|
||||
else
|
||||
curl -L -o "$EBOOK_ID".epub "https://www.gutenberg.org/ebooks/$EBOOK_ID.epub.noimages"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d "$DIR" ]; then
|
||||
if [ -z "$READER" ]; then
|
||||
"$BROWSER" "$DIR/$EBOOK_ID-h/$EBOOK_ID-h.htm"
|
||||
else
|
||||
"$READER" "$DIR/$EBOOK_ID.epub"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
"$BROWSER" "$BROWSE_LINK"
|
||||
fi
|
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Resize images in a directory to screen resolution with imgp
|
||||
#
|
||||
# Dependencipes: imgp - https://github.com/jarun/imgp
|
||||
#
|
||||
# Notes:
|
||||
# 1. Set res to avoid the desktop resolution prompt each time
|
||||
# 2. MINSIZE is set to 1MB by default, adjust it if you want
|
||||
# 3. imgp options used:
|
||||
# a - adaptive mode
|
||||
# c - convert PNG to JPG
|
||||
# k - skip images matching specified hres/vres
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Arun Prakash Jana
|
||||
|
||||
# set resolution (e.g. 1920x1080)
|
||||
res="${RESOLUTION}"
|
||||
|
||||
# set minimum image size (in bytes) to resize (default: 1MB)
|
||||
MINSIZE="${MINSIZE:-1048576}"
|
||||
|
||||
if [ -z "$res" ]; then
|
||||
printf "desktop resolution (hxv): "
|
||||
read -r res
|
||||
fi
|
||||
|
||||
if [ -n "$res" ] && [ -n "$MINSIZE" ]; then
|
||||
imgp -ackx "$res" -s "$MINSIZE"
|
||||
fi
|
|
@ -0,0 +1,597 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
##########################################################################
|
||||
# The MIT License
|
||||
#
|
||||
# Copyright (c) jomo
|
||||
#
|
||||
# Permission is hereby granted, free of charge,
|
||||
# to any person obtaining a copy of this software and
|
||||
# associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify,
|
||||
# merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom
|
||||
# the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice
|
||||
# shall be included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
##########################################################################
|
||||
|
||||
# https://github.com/jomo/imgur-screenshot
|
||||
# https://help.imgur.com/hc/en-us/articles/209592766-Tools-for-Imgur
|
||||
#
|
||||
# Slightly modified for `nnn` integration
|
||||
#
|
||||
# Shell: Bash
|
||||
# Description: Upload an image file to imgur
|
||||
|
||||
if [ "${1}" = "--debug" ]; then
|
||||
echo "########################################"
|
||||
echo "Enabling debug mode"
|
||||
echo "Please remove credentials before pasting"
|
||||
echo "########################################"
|
||||
echo ""
|
||||
uname -a
|
||||
for arg in ${0} "${@}"; do
|
||||
echo -n "'${arg}' "
|
||||
done
|
||||
echo -e "\n"
|
||||
shift
|
||||
set -x
|
||||
fi
|
||||
|
||||
current_version="v1.7.4"
|
||||
|
||||
function is_mac() {
|
||||
uname | grep -q "Darwin"
|
||||
}
|
||||
|
||||
### IMGUR-SCREENSHOT DEFAULT CONFIG ####
|
||||
|
||||
# You can override the config in ~/.config/imgur-screenshot/settings.conf
|
||||
|
||||
imgur_anon_id="ea6c0ef2987808e"
|
||||
imgur_icon_path="${HOME}/Pictures/imgur.png"
|
||||
|
||||
imgur_acct_key=""
|
||||
imgur_secret=""
|
||||
login="false"
|
||||
album_title=""
|
||||
album_id=""
|
||||
credentials_file="${HOME}/.config/imgur-screenshot/credentials.conf"
|
||||
|
||||
file_name_format="imgur-%Y_%m_%d-%H:%M:%S.png" # when using scrot, must end with .png!
|
||||
file_dir="${HOME}/Pictures"
|
||||
|
||||
upload_connect_timeout="5"
|
||||
upload_timeout="120"
|
||||
upload_retries="1"
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
if is_mac; then
|
||||
screenshot_select_command="screencapture -i %img"
|
||||
screenshot_window_command="screencapture -iWa %img"
|
||||
screenshot_full_command="screencapture %img"
|
||||
open_command="open %url"
|
||||
else
|
||||
screenshot_select_command="scrot -s %img"
|
||||
screenshot_window_command="scrot %img"
|
||||
screenshot_full_command="scrot %img"
|
||||
open_command="xdg-open %url"
|
||||
fi
|
||||
open="true"
|
||||
|
||||
mode="select"
|
||||
edit_command="gimp %img"
|
||||
edit="false"
|
||||
exit_on_album_creation_fail="true"
|
||||
|
||||
log_file="${HOME}/.imgur-screenshot.log"
|
||||
|
||||
auto_delete=""
|
||||
copy_url="true"
|
||||
keep_file="true"
|
||||
check_update="true"
|
||||
|
||||
# NOTICE: if you make changes here, also edit the docs at
|
||||
# https://github.com/jomo/imgur-screenshot/wiki/Config
|
||||
|
||||
# You can override the config in ~/.config/imgur-screenshot/settings.conf
|
||||
|
||||
############## END CONFIG ##############
|
||||
|
||||
settings_path="${HOME}/.config/imgur-screenshot/settings.conf"
|
||||
if [ -f "${settings_path}" ]; then
|
||||
# shellcheck disable=SC1090
|
||||
source "${settings_path}"
|
||||
fi
|
||||
|
||||
# dependency check
|
||||
if [ "${1}" = "--check" ]; then
|
||||
(type grep &>/dev/null && echo "OK: found grep") || echo "ERROR: grep not found"
|
||||
if is_mac; then
|
||||
if type growlnotify &>/dev/null; then
|
||||
echo "OK: found growlnotify"
|
||||
elif type terminal-notifier &>/dev/null; then
|
||||
echo "OK: found terminal-notifier"
|
||||
else
|
||||
echo "ERROR: growlnotify nor terminal-notifier found"
|
||||
fi
|
||||
(type screencapture &>/dev/null && echo "OK: found screencapture") || echo "ERROR: screencapture not found"
|
||||
(type pbcopy &>/dev/null && echo "OK: found pbcopy") || echo "ERROR: pbcopy not found"
|
||||
else
|
||||
(type notify-send &>/dev/null && echo "OK: found notify-send") || echo "ERROR: notify-send (from libnotify-bin) not found"
|
||||
(type scrot &>/dev/null && echo "OK: found scrot") || echo "ERROR: scrot not found"
|
||||
(type xclip &>/dev/null && echo "OK: found xclip") || echo "ERROR: xclip not found"
|
||||
fi
|
||||
(type curl &>/dev/null && echo "OK: found curl") || echo "ERROR: curl not found"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
# notify <'ok'|'error'> <title> <text>
|
||||
function notify() {
|
||||
if is_mac; then
|
||||
if type growlnotify &>/dev/null; then
|
||||
growlnotify --icon "${imgur_icon_path}" --iconpath "${imgur_icon_path}" --title "${2}" --message "${3}"
|
||||
else
|
||||
terminal-notifier -appIcon "${imgur_icon_path}" -contentImage "${imgur_icon_path}" -title "imgur: ${2}" -message "${3}"
|
||||
fi
|
||||
else
|
||||
if [ "${1}" = "error" ]; then
|
||||
notify-send -a ImgurScreenshot -u critical -c "im.error" -i "${imgur_icon_path}" -t 500 "imgur: ${2}" "${3}"
|
||||
else
|
||||
notify-send -a ImgurScreenshot -u low -c "transfer.complete" -i "${imgur_icon_path}" -t 500 "imgur: ${2}" "${3}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function take_screenshot() {
|
||||
echo "Please select area"
|
||||
is_mac || sleep 0.1 # https://bbs.archlinux.org/viewtopic.php?pid=1246173#p1246173
|
||||
|
||||
cmd="screenshot_${mode}_command"
|
||||
cmd=${!cmd//\%img/${1}}
|
||||
|
||||
if ! shot_err="$(${cmd} &>/dev/null)"; then #takes a screenshot with selection
|
||||
echo "Failed to take screenshot '${1}': '${shot_err}'. For more information visit https://github.com/jomo/imgur-screenshot/wiki/Troubleshooting" | tee -a "${log_file}"
|
||||
notify error "Something went wrong :(" "Information has been logged"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function check_for_update() {
|
||||
# exit non-zero on HTTP error, output only the body (no stats) but output errors, follow redirects, output everything to stdout
|
||||
remote_version="$(curl --compressed -fsSL --stderr - "https://api.github.com/repos/jomo/imgur-screenshot/releases" | grep -Em 1 --color 'tag_name":\s*".*"' | cut -d '"' -f 4)"
|
||||
if [ -n "$remote_version" ]; then
|
||||
if [ ! "${current_version}" = "${remote_version}" ] && [ -n "${current_version}" ] && [ -n "${remote_version}" ]; then
|
||||
echo "Update found!"
|
||||
echo "Version ${remote_version} is available (You have ${current_version})"
|
||||
notify ok "Update found" "Version ${remote_version} is available (You have ${current_version}). https://github.com/jomo/imgur-screenshot"
|
||||
echo "Check https://github.com/jomo/imgur-screenshot/releases/${remote_version} for more info."
|
||||
elif [ -z "${current_version}" ] || [ -z "${remote_version}" ]; then
|
||||
echo "Invalid empty version string"
|
||||
echo "Current (local) version: '${current_version}'"
|
||||
echo "Latest (remote) version: '${remote_version}'"
|
||||
else
|
||||
echo "Version ${current_version} is up to date."
|
||||
fi
|
||||
else
|
||||
echo "Failed to check for latest version: ${remote_version}"
|
||||
fi
|
||||
}
|
||||
|
||||
function check_oauth2_client_secrets() {
|
||||
if [ -z "${imgur_acct_key}" ] || [ -z "${imgur_secret}" ]; then
|
||||
echo "In order to upload to your account, register a new application at:"
|
||||
echo "https://api.imgur.com/oauth2/addclient"
|
||||
echo "Select 'OAuth 2 authorization without a callback URL'"
|
||||
echo "Then, set the imgur_acct_key (Client ID) and imgur_secret in your config."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function load_access_token() {
|
||||
token_expire_time=0
|
||||
# check for saved access_token and its expiration date
|
||||
if [ -f "${credentials_file}" ]; then
|
||||
# shellcheck disable=SC1090
|
||||
source "${credentials_file}"
|
||||
fi
|
||||
current_time="$(date +%s)"
|
||||
preemptive_refresh_time="$((10*60))"
|
||||
expired="$((current_time > (token_expire_time - preemptive_refresh_time)))"
|
||||
if [ -n "${refresh_token}" ]; then
|
||||
# token already set
|
||||
if [ "${expired}" -eq "0" ]; then
|
||||
# token expired
|
||||
refresh_access_token "${credentials_file}"
|
||||
fi
|
||||
else
|
||||
acquire_access_token "${credentials_file}"
|
||||
fi
|
||||
}
|
||||
|
||||
function acquire_access_token() {
|
||||
check_oauth2_client_secrets
|
||||
# prompt for a PIN
|
||||
authorize_url="https://api.imgur.com/oauth2/authorize?client_id=${imgur_acct_key}&response_type=pin"
|
||||
echo "Go to"
|
||||
echo "${authorize_url}"
|
||||
echo "and grant access to this application."
|
||||
read -rp "Enter the PIN: " imgur_pin
|
||||
|
||||
if [ -z "${imgur_pin}" ]; then
|
||||
echo "PIN not entered, exiting"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# exchange the PIN for access token and refresh token
|
||||
response="$(curl --compressed -fsSL --stderr - \
|
||||
-F "client_id=${imgur_acct_key}" \
|
||||
-F "client_secret=${imgur_secret}" \
|
||||
-F "grant_type=pin" \
|
||||
-F "pin=${imgur_pin}" \
|
||||
https://api.imgur.com/oauth2/token)"
|
||||
save_access_token "${response}" "${1}"
|
||||
}
|
||||
|
||||
function refresh_access_token() {
|
||||
check_oauth2_client_secrets
|
||||
token_url="https://api.imgur.com/oauth2/token"
|
||||
# exchange the refresh token for access_token and refresh_token
|
||||
if ! response="$(curl --compressed -fsSL --stderr - \
|
||||
-F "client_id=${imgur_acct_key}" \
|
||||
-F "client_secret=${imgur_secret}" \
|
||||
-F "grant_type=refresh_token" \
|
||||
-F "refresh_token=${refresh_token}" \
|
||||
"${token_url}"
|
||||
)"; then
|
||||
# curl failed
|
||||
handle_upload_error "${response}" "${token_url}"
|
||||
exit 1
|
||||
fi
|
||||
save_access_token "${response}" "${1}"
|
||||
}
|
||||
|
||||
function save_access_token() {
|
||||
if ! grep -q "access_token" <<<"${1}"; then
|
||||
# server did not send access_token
|
||||
echo "Error: Something is wrong with your credentials:"
|
||||
echo "${1}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
access_token="$(grep -Eo 'access_token":".*"' <<<"${1}" | cut -d '"' -f 3)"
|
||||
refresh_token="$(grep -Eo 'refresh_token":".*"' <<<"${1}" | cut -d '"' -f 3)"
|
||||
expires_in="$(grep -Eo 'expires_in":[0-9]*' <<<"${1}" | cut -d ':' -f 2)"
|
||||
token_expire_time="$(( $(date +%s) + expires_in ))"
|
||||
|
||||
# create dir if not exist
|
||||
mkdir -p "$(dirname "${2}")" 2>/dev/null
|
||||
touch "${2}" && chmod 600 "${2}"
|
||||
cat <<EOF > "${2}"
|
||||
access_token="${access_token}"
|
||||
refresh_token="${refresh_token}"
|
||||
token_expire_time="${token_expire_time}"
|
||||
EOF
|
||||
}
|
||||
|
||||
function fetch_account_info() {
|
||||
response="$(curl --compressed --connect-timeout "${upload_connect_timeout}" -m "${upload_timeout}" --retry "${upload_retries}" -fsSL --stderr - -H "Authorization: Bearer ${access_token}" https://api.imgur.com/3/account/me)"
|
||||
if grep -Eq '"success":\s*true' <<<"${response}"; then
|
||||
username="$(grep -Eo '"url":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4)"
|
||||
echo "Logged in as ${username}."
|
||||
echo "https://${username}.imgur.com"
|
||||
else
|
||||
echo "Failed to fetch info: ${response}"
|
||||
fi
|
||||
}
|
||||
|
||||
function delete_image() {
|
||||
response="$(curl --compressed -X DELETE -fsSL --stderr - -H "Authorization: Client-ID ${1}" "https://api.imgur.com/3/image/${2}")"
|
||||
if grep -Eq '"success":\s*true' <<<"${response}"; then
|
||||
echo "Image successfully deleted (delete hash: ${2})." >> "${3}"
|
||||
else
|
||||
echo "The Image could not be deleted: ${response}." >> "${3}"
|
||||
fi
|
||||
}
|
||||
|
||||
function upload_authenticated_image() {
|
||||
echo "Uploading '${1}'..."
|
||||
title="$(echo "${1}" | rev | cut -d "/" -f 1 | cut -d "." -f 2- | rev)"
|
||||
if [ -n "${album_id}" ]; then
|
||||
response="$(curl --compressed --connect-timeout "${upload_connect_timeout}" -m "${upload_timeout}" --retry "${upload_retries}" -fsSL --stderr - -F "title=${title}" -F "image=@\"${1}\"" -F "album=${album_id}" -H "Authorization: Bearer ${access_token}" https://api.imgur.com/3/image)"
|
||||
else
|
||||
response="$(curl --compressed --connect-timeout "${upload_connect_timeout}" -m "${upload_timeout}" --retry "${upload_retries}" -fsSL --stderr - -F "title=${title}" -F "image=@\"${1}\"" -H "Authorization: Bearer ${access_token}" https://api.imgur.com/3/image)"
|
||||
fi
|
||||
|
||||
# JSON parser premium edition (not really)
|
||||
if grep -Eq '"success":\s*true' <<<"${response}"; then
|
||||
img_id="$(grep -Eo '"id":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4)"
|
||||
img_ext="$(grep -Eo '"link":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4 | rev | cut -d "." -f 1 | rev)" # "link" itself has ugly '\/' escaping and no https!
|
||||
del_id="$(grep -Eo '"deletehash":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4)"
|
||||
|
||||
if [ -n "${auto_delete}" ]; then
|
||||
export -f delete_image
|
||||
echo "Deleting image in ${auto_delete} seconds."
|
||||
nohup /bin/bash -c "sleep ${auto_delete} && delete_image ${imgur_anon_id} ${del_id} ${log_file}" &
|
||||
fi
|
||||
|
||||
handle_upload_success "https://i.imgur.com/${img_id}.${img_ext}" "https://imgur.com/delete/${del_id}" "${1}"
|
||||
else # upload failed
|
||||
err_msg="$(grep -Eo '"error":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4)"
|
||||
test -z "${err_msg}" && err_msg="${response}"
|
||||
handle_upload_error "${err_msg}" "${1}"
|
||||
fi
|
||||
}
|
||||
|
||||
function upload_anonymous_image() {
|
||||
echo "Uploading '${1}'..."
|
||||
title="$(echo "${1}" | rev | cut -d "/" -f 1 | cut -d "." -f 2- | rev)"
|
||||
if [ -n "${album_id}" ]; then
|
||||
response="$(curl --compressed --connect-timeout "${upload_connect_timeout}" -m "${upload_timeout}" --retry "${upload_retries}" -fsSL --stderr - -H "Authorization: Client-ID ${imgur_anon_id}" -F "title=${title}" -F "image=@\"${1}\"" -F "album=${album_id}" https://api.imgur.com/3/image)"
|
||||
else
|
||||
response="$(curl --compressed --connect-timeout "${upload_connect_timeout}" -m "${upload_timeout}" --retry "${upload_retries}" -fsSL --stderr - -H "Authorization: Client-ID ${imgur_anon_id}" -F "title=${title}" -F "image=@\"${1}\"" https://api.imgur.com/3/image)"
|
||||
fi
|
||||
# JSON parser premium edition (not really)
|
||||
if grep -Eq '"success":\s*true' <<<"${response}"; then
|
||||
img_id="$(grep -Eo '"id":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4)"
|
||||
img_ext="$(grep -Eo '"link":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4 | rev | cut -d "." -f 1 | rev)" # "link" itself has ugly '\/' escaping and no https!
|
||||
del_id="$(grep -Eo '"deletehash":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4)"
|
||||
|
||||
if [ -n "${auto_delete}" ]; then
|
||||
export -f delete_image
|
||||
echo "Deleting image in ${auto_delete} seconds."
|
||||
nohup /bin/bash -c "sleep ${auto_delete} && delete_image ${imgur_anon_id} ${del_id} ${log_file}" &
|
||||
fi
|
||||
|
||||
handle_upload_success "https://i.imgur.com/${img_id}.${img_ext}" "https://imgur.com/delete/${del_id}" "${1}"
|
||||
else # upload failed
|
||||
err_msg="$(grep -Eo '"error":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4)"
|
||||
test -z "${err_msg}" && err_msg="${response}"
|
||||
handle_upload_error "${err_msg}" "${1}"
|
||||
fi
|
||||
}
|
||||
|
||||
function handle_upload_success() {
|
||||
echo ""
|
||||
echo "image link: ${1}"
|
||||
echo "delete link: ${2}"
|
||||
|
||||
if [ "${copy_url}" = "true" ] && [ -z "${album_title}" ]; then
|
||||
if is_mac; then
|
||||
echo -n "${1}" | pbcopy
|
||||
else
|
||||
echo -n "${1}" | xclip -selection clipboard
|
||||
fi
|
||||
echo "URL copied to clipboard"
|
||||
fi
|
||||
|
||||
# print to log file: image link, image location, delete link
|
||||
echo -e "${1}\t${3}\t${2}" >> "${log_file}"
|
||||
|
||||
notify ok "Upload done!" "${1}"
|
||||
|
||||
# if [ ! -z "${open_command}" ] && [ "${open}" = "true" ]; then
|
||||
# open_cmd=${open_command//\%url/${1}}
|
||||
# open_cmd=${open_cmd//\%img/${2}}
|
||||
# echo "Opening '${open_cmd}'"
|
||||
# eval "${open_cmd}"
|
||||
# fi
|
||||
}
|
||||
|
||||
function handle_upload_error() {
|
||||
error="Upload failed: \"${1}\""
|
||||
echo "${error}"
|
||||
echo -e "Error\t${2}\t${error}" >> "${log_file}"
|
||||
notify error "Upload failed :(" "${1}"
|
||||
}
|
||||
|
||||
function handle_album_creation_success() {
|
||||
echo ""
|
||||
echo "Album link: ${1}"
|
||||
echo "Delete hash: ${2}"
|
||||
echo ""
|
||||
|
||||
notify ok "Album created!" "${1}"
|
||||
|
||||
if [ "${copy_url}" = "true" ]; then
|
||||
if is_mac; then
|
||||
echo -n "${1}" | pbcopy
|
||||
else
|
||||
echo -n "${1}" | xclip -selection clipboard
|
||||
fi
|
||||
echo "URL copied to clipboard"
|
||||
fi
|
||||
|
||||
# print to log file: album link, album title, delete hash
|
||||
echo -e "${1}\t\"${3}\"\t${2}" >> "${log_file}"
|
||||
}
|
||||
|
||||
function handle_album_creation_error() {
|
||||
error="Album creation failed: \"${1}\""
|
||||
echo -e "Error\t${2}\t${error}" >> "${log_file}"
|
||||
notify error "Album creation failed :(" "${1}"
|
||||
if [ ${exit_on_album_creation_fail} ]; then
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
while [ ${#} != 0 ]; do
|
||||
case "${1}" in
|
||||
-h | --help)
|
||||
echo "usage: ${0} [--debug] [-c | --check | -v | -h | -u]"
|
||||
echo " ${0} [--debug] [option]... [file]..."
|
||||
echo ""
|
||||
echo " --debug Enable debugging, must be first option"
|
||||
echo " -h, --help Show this help, exit"
|
||||
echo " -v, --version Show current version, exit"
|
||||
echo " --check Check if all dependencies are installed, exit"
|
||||
echo " -c, --connect Show connected imgur account, exit"
|
||||
echo " -o, --open <true|false> Override 'open' config"
|
||||
echo " -e, --edit <true|false> Override 'edit' config"
|
||||
echo " -i, --edit-command <command> Override 'edit_command' config (include '%img'), sets --edit 'true'"
|
||||
echo " -l, --login <true|false> Override 'login' config"
|
||||
echo " -a, --album <album_title> Create new album and upload there"
|
||||
echo " -A, --album-id <album_id> Override 'album_id' config"
|
||||
echo " -k, --keep-file <true|false> Override 'keep_file' config"
|
||||
echo " -d, --auto-delete <s> Automatically delete image after <s> seconds"
|
||||
echo " -u, --update Check for updates, exit"
|
||||
echo " file Upload file instead of taking a screenshot"
|
||||
exit 0;;
|
||||
-v | --version)
|
||||
echo "${current_version}"
|
||||
exit 0;;
|
||||
-s | --select)
|
||||
mode="select"
|
||||
shift;;
|
||||
-w | --window)
|
||||
mode="window"
|
||||
shift;;
|
||||
-f | --full)
|
||||
mode="full"
|
||||
shift;;
|
||||
-o | --open)
|
||||
# shellcheck disable=SC2034
|
||||
open="${2}"
|
||||
shift 2;;
|
||||
-e | --edit)
|
||||
edit="${2}"
|
||||
shift 2;;
|
||||
-i | --edit-command)
|
||||
edit_command="${2}"
|
||||
edit="true"
|
||||
shift 2;;
|
||||
-l | --login)
|
||||
login="${2}"
|
||||
shift 2;;
|
||||
-c | --connect)
|
||||
load_access_token
|
||||
fetch_account_info
|
||||
exit 0;;
|
||||
-a | --album)
|
||||
album_title="${2}"
|
||||
shift 2;;
|
||||
-A | --album-id)
|
||||
album_id="${2}"
|
||||
shift 2;;
|
||||
-k | --keep-file)
|
||||
keep_file="${2}"
|
||||
shift 2;;
|
||||
-d | --auto-delete)
|
||||
auto_delete="${2}"
|
||||
shift 2;;
|
||||
-u | --update)
|
||||
check_for_update
|
||||
exit 0;;
|
||||
*)
|
||||
upload_files=("${@}")
|
||||
break;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "${login}" = "true" ]; then
|
||||
# load before changing directory
|
||||
load_access_token
|
||||
fi
|
||||
|
||||
|
||||
if [ -n "${album_title}" ]; then
|
||||
if [ "${login}" = "true" ]; then
|
||||
response="$(curl -fsSL --stderr - \
|
||||
-F "title=${album_title}" \
|
||||
-H "Authorization: Bearer ${access_token}" \
|
||||
https://api.imgur.com/3/album)"
|
||||
else
|
||||
response="$(curl -fsSL --stderr - \
|
||||
-F "title=${album_title}" \
|
||||
-H "Authorization: Client-ID ${imgur_anon_id}" \
|
||||
https://api.imgur.com/3/album)"
|
||||
fi
|
||||
if grep -Eq '"success":\s*true' <<<"${response}"; then # Album creation successful
|
||||
echo "Album '${album_title}' successfully created"
|
||||
album_id="$(grep -Eo '"id":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4)"
|
||||
del_id="$(grep -Eo '"deletehash":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4)"
|
||||
handle_album_creation_success "https://imgur.com/a/${album_id}" "${del_id}" "${album_title}"
|
||||
|
||||
if [ "${login}" = "false" ]; then
|
||||
album_id="${del_id}"
|
||||
fi
|
||||
else # Album creation failed
|
||||
err_msg="$(grep -Eo '"error":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4)"
|
||||
test -z "${err_msg}" && err_msg="${response}"
|
||||
handle_album_creation_error "${err_msg}" "${album_title}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "${upload_files[*]}" ]; then
|
||||
upload_files[0]=""
|
||||
fi
|
||||
|
||||
for upload_file in "${upload_files[@]}"; do
|
||||
|
||||
if [ -z "${upload_file}" ]; then
|
||||
cd "${file_dir}" || exit 1
|
||||
|
||||
# new filename with date
|
||||
img_file="$(date +"${file_name_format}")"
|
||||
take_screenshot "${img_file}"
|
||||
else
|
||||
# upload file instead of screenshot
|
||||
img_file="${upload_file}"
|
||||
fi
|
||||
|
||||
# get full path
|
||||
#cd "$(dirname "$(realpath "${img_file}")")"
|
||||
#img_file="$(realpath "${img_file}")"
|
||||
|
||||
# check if file exists
|
||||
if ! [ -f "${img_file}" ]; then
|
||||
echo "file '${img_file}' doesn't exist !"
|
||||
read -r _
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# open image in editor if configured
|
||||
if [ "${edit}" = "true" ]; then
|
||||
edit_cmd=${edit_command//\%img/${img_file}}
|
||||
echo "Opening editor '${edit_cmd}'"
|
||||
if ! (eval "${edit_cmd}"); then
|
||||
echo "Error for image '${img_file}': command '${edit_cmd}' failed, not uploading. For more information visit https://github.com/jomo/imgur-screenshot/wiki/Troubleshooting" | tee -a "${log_file}"
|
||||
notify error "Something went wrong :(" "Information has been logged"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${login}" = "true" ]; then
|
||||
upload_authenticated_image "${img_file}"
|
||||
else
|
||||
upload_anonymous_image "${img_file}"
|
||||
fi
|
||||
|
||||
# delete file if configured
|
||||
if [ "${keep_file}" = "false" ] && [ -z "${1}" ]; then
|
||||
echo "Deleting temp file ${file_dir}/${img_file}"
|
||||
rm -rf "${img_file}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
done
|
||||
|
||||
|
||||
if [ "${check_update}" = "true" ]; then
|
||||
check_for_update
|
||||
fi
|
||||
|
||||
read -r _
|
|
@ -0,0 +1,111 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Open hovered or current directory in image viewer.
|
||||
# Generates media thumbnails with optional dependencies.
|
||||
#
|
||||
# Dependencies:
|
||||
# - imv (https://github.com/eXeC64/imv) or,
|
||||
# - sxiv (https://github.com/muennich/sxiv) or,
|
||||
# - nsxiv (https://github.com/nsxiv/nsxiv) or,
|
||||
# - ucollage (https://github.com/ckardaris/ucollage) or,
|
||||
# - lsix (https://github.com/hackerb9/lsix), or
|
||||
# - viu (https://github.com/atanunq/viu), or
|
||||
# - catimg (https://github.com/posva/catimg), or
|
||||
# - optional: ffmpeg for audio thumbnails (album art)
|
||||
# - optional: ffmpegthumbnailer for video thumbnails
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Arun Prakash Jana, Luuk van Baal
|
||||
#
|
||||
# Consider setting NNN_PREVIEWDIR to $XDG_CACHE_HOME/nnn/previews
|
||||
# if you want to keep media thumbnails on disk between reboots.
|
||||
NNN_PREVIEWDIR="${NNN_PREVIEWDIR:-${TMPDIR:-/tmp}/nnn/previews}"
|
||||
|
||||
exit_prompt() {
|
||||
[ -n "$1" ] && printf "%s\n" "$1"
|
||||
printf "%s" "Press any key to exit..."
|
||||
cfg=$(stty -g); stty raw -echo; head -c 1; stty "$cfg"
|
||||
clear
|
||||
exit
|
||||
}
|
||||
|
||||
make_thumbs() {
|
||||
mkdir -p "$NNN_PREVIEWDIR$dir" || return
|
||||
if [ "$1" -eq 3 ]; then
|
||||
[ -d "$target" ] && exit_prompt "$2 can only display a single image"
|
||||
mime="$(file -bL --mime-type -- "$target")"
|
||||
case "$mime" in
|
||||
audio/*) ffmpeg -i "$target" "$NNN_PREVIEWDIR$target.jpg" -y >/dev/null 2>&1
|
||||
ret="$NNN_PREVIEWDIR/$target.jpg" ;;
|
||||
video/*) ffmpegthumbnailer -i "$target" -o "$NNN_PREVIEWDIR$target.jpg" 2> /dev/null
|
||||
ret="$NNN_PREVIEWDIR/$target.jpg" ;;
|
||||
*) ret="$target" ;;
|
||||
esac
|
||||
fi
|
||||
for file in "$dir"/*; do
|
||||
if [ ! -f "$NNN_PREVIEWDIR$file.jpg" ]; then
|
||||
case "$(file -bL --mime-type -- "$file")" in
|
||||
audio/*) [ "$1" -ne 0 ] && ffmpeg -i "$file" "$NNN_PREVIEWDIR$file.jpg" -y >/dev/null 2>&1 ;;
|
||||
video/*) [ "$1" -ne 1 ] && ffmpegthumbnailer -i "$file" -o "$NNN_PREVIEWDIR$file.jpg" 2> /dev/null ;;
|
||||
esac
|
||||
fi
|
||||
done
|
||||
for file in "$NNN_PREVIEWDIR$dir"/*; do
|
||||
filename="$(basename "$file" .jpg)"
|
||||
[ ! -e "$dir/$filename" ] && rm "$file" 2>/dev/null
|
||||
done
|
||||
}
|
||||
|
||||
listimages() {
|
||||
find -L "$dir" "$NNN_PREVIEWDIR$dir" -maxdepth 1 -type f -print0 2>/dev/null | sort -z
|
||||
}
|
||||
|
||||
view_files() {
|
||||
[ -f "$target" ] && count="-n $(listimages | grep -a -m 1 -ZznF "$target" | cut -d: -f1)"
|
||||
case "$1" in
|
||||
nsxiv) listimages | xargs -0 nsxiv -a "${count:--t}" -- ;;
|
||||
sxiv) listimages | xargs -0 sxiv -a "${count:--t}" -- ;;
|
||||
imv*) listimages | xargs -0 "$1" "${count:-}" -- ;;
|
||||
esac
|
||||
}
|
||||
|
||||
target="$(readlink -f "$1")"
|
||||
[ -d "$target" ] && dir="$target" || dir="${target%/*}"
|
||||
if uname | grep -q "Darwin"; then
|
||||
[ -f "$1" ] && open "$1" >/dev/null 2>&1 &
|
||||
elif type lsix >/dev/null 2>&1; then
|
||||
if [ -d "$target" ]; then
|
||||
cd "$target" || exit_prompt
|
||||
fi
|
||||
make_thumbs ""
|
||||
clear
|
||||
lsix
|
||||
cd "$NNN_PREVIEWDIR$dir" && lsix
|
||||
exit_prompt
|
||||
elif type ucollage >/dev/null 2>&1; then
|
||||
type ffmpeg >/dev/null 2>&1 && make_thumbs 1
|
||||
UCOLLAGE_EXPAND_DIRS=1 ucollage "$dir" "$NNN_PREVIEWDIR$dir" || exit_prompt
|
||||
elif type sxiv >/dev/null 2>&1; then
|
||||
type ffmpegthumbnailer >/dev/null 2>&1 && make_thumbs 0
|
||||
view_files sxiv >/dev/null 2>&1 &
|
||||
elif type nsxiv >/dev/null 2>&1; then
|
||||
type ffmpegthumbnailer >/dev/null 2>&1 && make_thumbs 0
|
||||
view_files nsxiv >/dev/null 2>&1 &
|
||||
elif type imv >/dev/null 2>&1; then
|
||||
make_thumbs ""
|
||||
view_files imv >/dev/null 2>&1 &
|
||||
elif type imvr >/dev/null 2>&1; then
|
||||
make_thumbs ""
|
||||
view_files imvr >/dev/null 2>&1 &
|
||||
elif type viu >/dev/null 2>&1; then
|
||||
clear
|
||||
make_thumbs 3 viu
|
||||
viu -n "$ret"
|
||||
exit_prompt
|
||||
elif type catimg >/dev/null 2>&1; then
|
||||
make_thumbs 3 catimg
|
||||
catimg "$ret"
|
||||
exit_prompt
|
||||
else
|
||||
exit_prompt "Please install sxiv/nsxiv/imv/viu/catimg/lsix."
|
||||
fi
|
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Shows the external IP address and whois information. Useful over VPNs.
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Arun Prakash Jana
|
||||
|
||||
IP=$(curl -s ifconfig.me)
|
||||
|
||||
whois "$IP"
|
||||
echo your external IP address is "$IP"
|
||||
|
||||
read -r _
|
|
@ -0,0 +1,24 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Send the selected files to your Android device using kdeconnect-cli.
|
||||
# kdeconnect must be configured on the Android device and the PC.
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: juacq97
|
||||
|
||||
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
|
||||
|
||||
id=$(kdeconnect-cli -a --id-only | awk '{print $1}')
|
||||
if [ -s "$selection" ]; then
|
||||
kdeconnect-cli -d "$id" --share "$(cat "$selection")"
|
||||
|
||||
# If you want a system notification, uncomment the next 3 lines.
|
||||
#notify-send -a "Kdeconnect" "Sending $(cat "$selection")"
|
||||
#else
|
||||
#notify-send -a "Kdeconnect" "No file selected"
|
||||
|
||||
# Clear selection
|
||||
if [ -p "$NNN_PIPE" ]; then
|
||||
printf "-" > "$NNN_PIPE"
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Independent POSIX-compliant GUI application launcher.
|
||||
# Fuzzy find executables in $PATH and launch an application.
|
||||
# stdin, stdout, stderr are suppressed so CLI tools exit silently.
|
||||
#
|
||||
# To configure launch as an independent app launcher add a keybind
|
||||
# to open launch in a terminal e.g.,
|
||||
#
|
||||
# xfce4-terminal -e "${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins/launch
|
||||
#
|
||||
# Dependencies: fzf
|
||||
#
|
||||
# Usage: launch [delay]
|
||||
# delay is in seconds, if omitted launch waits for 1 sec
|
||||
#
|
||||
# Integration with nnn: launch is installed with other plugins, nnn picks it up.
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Arun Prakash Jana
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
|
||||
IFS=':'
|
||||
|
||||
get_selection() {
|
||||
if type fzf >/dev/null 2>&1; then
|
||||
{ IFS=':'; ls -H $PATH; } | sort | fzf
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
if selection=$( get_selection ); then
|
||||
setsid "$selection" 2>/dev/null 1>/dev/null &
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
sleep "$1"
|
||||
else
|
||||
sleep 1
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Find and list files by mime type in smart context
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Arun Prakash Jana
|
||||
|
||||
# shellcheck disable=SC1090,SC1091
|
||||
. "$(dirname "$0")"/.nnn-plugin-helper
|
||||
|
||||
printf "mime (e.g., video/audio/image): "
|
||||
read -r mime
|
||||
|
||||
printf "%s" "+l" > "$NNN_PIPE"
|
||||
find . | file -if- | grep "$mime" | awk -F: '{printf "%s\0", $1}' > "$NNN_PIPE"
|
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Fetches the lyrics of the track currently playing in MOC
|
||||
#
|
||||
# Dependencies: ddgr (https://github.com/jarun/ddgr)
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Arun Prakash Jana
|
||||
|
||||
# Check if MOC server is running
|
||||
cmd=$(pgrep -x mocp 2>/dev/null)
|
||||
ret=$cmd
|
||||
if [ -z "$ret" ]; then
|
||||
exit
|
||||
fi
|
||||
|
||||
# Grab the output
|
||||
out="$(mocp -i)"
|
||||
|
||||
# Check if anything is playing
|
||||
state=$(echo "$out" | grep "State:" | cut -d' ' -f2)
|
||||
if ! [ "$state" = 'PLAY' ]; then
|
||||
exit
|
||||
fi
|
||||
|
||||
# Try by Artist and Song Title first
|
||||
ARTIST="$(echo "$out" | grep 'Artist:' | cut -d':' -f2 | sed 's/^[[:blank:]]*//;s/[[:blank:]]*$//')"
|
||||
TITLE="$(echo "$out" | grep 'SongTitle:' | cut -d':' -f2 | sed 's/^[[:blank:]]*//;s/[[:blank:]]*$//')"
|
||||
|
||||
if [ -n "$ARTIST" ] && [ -n "$TITLE" ]; then
|
||||
ddgr -w azlyrics.com --ducky "$ARTIST" "$TITLE"
|
||||
else
|
||||
# Try by file name
|
||||
FILENAME="$(basename "$(echo "$out" | grep 'File:' | cut -d':' -f2)")"
|
||||
FILENAME="$(echo "${FILENAME%%.*}" | tr -d -)"
|
||||
|
||||
if [ -n "$FILENAME" ]; then
|
||||
ddgr -w azlyrics.com --ducky "$FILENAME"
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,89 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Appends and optionally plays music in MOC
|
||||
#
|
||||
# Notes:
|
||||
# - if selection is available, plays it, else plays the current file or directory
|
||||
# - appends tracks and exits is MOC is running, else clears playlist and adds tracks
|
||||
# - to let mocp shuffle tracks, set SHUFFLE=1
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Authors: Arun Prakash Jana, ath3
|
||||
|
||||
IFS="$(printf '\n\r')"
|
||||
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
|
||||
cmd=$(pgrep -x mocp 2>/dev/null)
|
||||
ret=$cmd
|
||||
|
||||
SHUFFLE="${SHUFFLE:-0}"
|
||||
|
||||
mocp_add ()
|
||||
{
|
||||
if [ "$SHUFFLE" = 1 ]; then
|
||||
if [ "$resp" = "y" ]; then
|
||||
arr=$(tr '\0' '\n' < "$selection")
|
||||
elif [ -n "$1" ]; then
|
||||
arr="$1"
|
||||
fi
|
||||
|
||||
for entry in $arr
|
||||
do
|
||||
if [ -d "$entry" ]; then
|
||||
arr2=$arr2$(find "$entry" -type f \( ! -iname "*.m3u" ! -iname "*.pls" \))
|
||||
elif echo "$entry" | grep -qv '\.m3u$\|\.pls$' ; then
|
||||
arr2=$(printf "%s\n%s" "$entry" "$arr2")
|
||||
fi
|
||||
done
|
||||
|
||||
mocp -o shuffle
|
||||
echo "$arr2" | xargs -d "\n" mocp -a
|
||||
else
|
||||
if [ "$resp" = "y" ]; then
|
||||
xargs < "$selection" -0 mocp -a
|
||||
else
|
||||
mocp -a "$1"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
if [ ! -s "$selection" ] && [ -z "$1" ]; then
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ "$2" = "opener" ]; then
|
||||
:
|
||||
elif [ -s "$selection" ]; then
|
||||
printf "Work with selection? Enter 'y' to confirm: "
|
||||
read -r resp
|
||||
fi
|
||||
|
||||
if [ -z "$ret" ]; then
|
||||
# mocp not running
|
||||
mocp -S
|
||||
else
|
||||
# mocp running, check if it's playing
|
||||
state=$(mocp -i | grep "State:" | cut -d' ' -f2)
|
||||
|
||||
if [ "$state" = 'PLAY' ]; then
|
||||
# add to playlist and exit
|
||||
mocp_add "$1"
|
||||
|
||||
# uncomment the line below to show mocp interface after appending
|
||||
# mocp
|
||||
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
|
||||
# clear selection and play
|
||||
mocp -c
|
||||
mocp_add "$1" "$resp"
|
||||
mocp -p
|
||||
|
||||
# uncomment the line below to show mocp interface after appending
|
||||
# mocp
|
||||
|
||||
# Clear selection
|
||||
if [ "$resp" = "y" ] && [ -p "$NNN_PIPE" ]; then
|
||||
printf "-" > "$NNN_PIPE"
|
||||
fi
|
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Extract audio from multimedia files and convert to mp3
|
||||
#
|
||||
# Dependencies: ffmpeg compiled with libmp3lame audio codec support
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Arun Prakash Jana
|
||||
|
||||
outdir=_mp3files
|
||||
|
||||
handle_multimedia() {
|
||||
mime="${1}"
|
||||
file="${2}"
|
||||
|
||||
case "${mime}" in
|
||||
audio/* | video/*)
|
||||
ffmpeg -i "${file}" -vn -codec:a libmp3lame -q:a 2 "${outdir}/${file%.*}.mp3"
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
printf "Process 'a'll in directory or 'c'urrent? "
|
||||
read -r resp
|
||||
|
||||
if [ "$resp" = "a" ]; then
|
||||
if ! [ -e "${outdir}" ]; then
|
||||
mkdir "${outdir}"
|
||||
fi
|
||||
|
||||
for f in *; do
|
||||
if [ -f "${f}" ]; then
|
||||
mimestr="$( file --dereference --brief --mime-type -- "${f}" )"
|
||||
handle_multimedia "${mimestr}" "${f}"
|
||||
fi
|
||||
done
|
||||
elif [ "$resp" = "c" ] && [ -f "$1" ]; then
|
||||
ffmpeg -i "${1}" -vn -codec:a libmp3lame -q:a 2 "${1%.*}.mp3"
|
||||
fi
|
|
@ -0,0 +1,76 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Toggle mount of MTP device (eg. Android device)
|
||||
# 'l' to list mountable devices
|
||||
# 'n' integer associated to device to mount
|
||||
# 'q'/'Return' exit
|
||||
#
|
||||
# Dependencies: gvfs-mtp
|
||||
#
|
||||
# Notes: The MTP device should be mounted at /run/user/$UID/gvfs.
|
||||
# Put /run/user/$UID/gvfs to bookmark entries (NNN_BMS) for faster access.
|
||||
# Make sure the device is unlocked when mounting.
|
||||
#
|
||||
# When doing copy-paste into MTP device, you will get an error like this:
|
||||
# cp: preserving times for './gambar1.png': Operation not supported
|
||||
# That just means the file is copied but timestamp won't be preserved.
|
||||
# It's like doing `cp -p localfile.txt file-to-SMB.txt`.
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Benawi Adha
|
||||
|
||||
prompt="Device number ('l' to list): "
|
||||
|
||||
IFS='
|
||||
'
|
||||
|
||||
lsmtp () {
|
||||
devs=$(gio mount -li | grep -e 'activation_root' | sed 's/\s*activation_root=//g')
|
||||
c=1
|
||||
printf "Devices list:\n"
|
||||
for i in $devs; do
|
||||
printf "%s %s\\n" "$c" "$i"
|
||||
c=$(( c + 1 ))
|
||||
done
|
||||
echo
|
||||
}
|
||||
|
||||
lsmtp
|
||||
printf "%s" "$prompt"
|
||||
read -r input
|
||||
|
||||
while [ -n "$input" ]
|
||||
do
|
||||
if [ "$input" = "l" ]; then
|
||||
lsmtp
|
||||
elif [ "$input" = "q" ] || [ "$input" -eq 0 ]; then
|
||||
exit
|
||||
elif [ "$input" -le "$(printf '%s\n' "${devs}" | grep -c '^')" ]; then
|
||||
# dev=$(printf "%s\n" "$devs" | cut -d$'\n' -f${input})
|
||||
c=1
|
||||
for i in $devs; do
|
||||
dev=$i
|
||||
if [ "$input" -eq $c ]; then
|
||||
break
|
||||
fi
|
||||
c=$(( c + 1 ))
|
||||
done
|
||||
|
||||
if (gio mount -l | grep '^Mount([1-9]).*'"$dev" ) 1>/dev/null; then
|
||||
if gio mount -u "${dev}"; then
|
||||
printf "%s unmounted\n" "$dev"
|
||||
fi
|
||||
else
|
||||
if gio mount "${dev}"; then
|
||||
printf "%s mounted to /run/user/\$UID/gvfs\n" "$dev"
|
||||
fi
|
||||
fi
|
||||
echo
|
||||
else
|
||||
printf "Invalid input\n"
|
||||
fi
|
||||
|
||||
printf "%s" "$prompt"
|
||||
read -r input
|
||||
done
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Backup nnn configuration
|
||||
# - config dir content
|
||||
# - environment config
|
||||
# - shell functions and aliases
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Léo Villeveygoux
|
||||
|
||||
nnn_aliases="n nnn"
|
||||
|
||||
outdir="nnn-$(whoami)@$(hostname)"
|
||||
|
||||
outfile="${outdir}.tar.bz2"
|
||||
|
||||
shellname="$(basename "$SHELL")"
|
||||
|
||||
conffile="config.txt"
|
||||
|
||||
configdir="${XDG_CONFIG_HOME:-$HOME/.config}/nnn"
|
||||
|
||||
workdir="$PWD"
|
||||
|
||||
tempdir="$(mktemp -d)"
|
||||
|
||||
mkdir "$tempdir/$outdir"
|
||||
|
||||
if [ ! -d "$tempdir" ]; then
|
||||
echo "Can't create work directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$tempdir/$outdir" || exit 1
|
||||
|
||||
# Backing up config dir content
|
||||
cp -r "$configdir" . || exit 1
|
||||
|
||||
# Environment config
|
||||
env | sed "s/'/'\\\\''/" |\
|
||||
awk '/^NNN_/{print "export '\''"$0"'\''"}' > "$conffile"
|
||||
|
||||
# Shell functions/aliases
|
||||
case "$shellname" in
|
||||
bash)
|
||||
for name in $nnn_aliases ; do
|
||||
if [ "$(bash -ic "type -t $name")" = "function" ] ; then
|
||||
bash -ic "type $name" | tail -n+2 >> "$conffile"
|
||||
elif bash -ic "alias $name" >/dev/null 2>&1 ; then
|
||||
bash -ic "alias $name" >> "$conffile"
|
||||
fi
|
||||
done
|
||||
;;
|
||||
zsh)
|
||||
for name in $nnn_aliases ; do
|
||||
if zsh -ic "functions $name" ; then
|
||||
zsh -ic "functions $name" >> "$conffile"
|
||||
elif zsh -ic "alias $name" ; then
|
||||
echo alias "$(zsh -ic "alias $name")" >> "$conffile"
|
||||
fi
|
||||
done
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown shell, skipping alias/function checking." >&2
|
||||
;;
|
||||
esac
|
||||
|
||||
cd .. || exit 1
|
||||
|
||||
printf "Saving as '%s' ... " "$workdir/$outfile"
|
||||
|
||||
tar caf "$workdir/$outfile" "$outdir" && echo "Done" || echo "Failed"
|
||||
|
||||
cd "$workdir" && rm -rf "$tempdir"
|
|
@ -0,0 +1,55 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Toggle mount status of a device using pmount
|
||||
# If the device is not mounted, it will be mounted.
|
||||
# If the device is mounted, it will be unmounted and powered down.
|
||||
#
|
||||
# Dependencies: lsblk, pmount
|
||||
#
|
||||
# Usage: Runs `lsblk` on 'l', exits on 'Return`.
|
||||
#
|
||||
# Notes:
|
||||
# - The script uses Linux-specific lsblk to list block devices. Alternatives:
|
||||
# macOS: "diskutil list"
|
||||
# BSD: "geom disk list"
|
||||
# - The script uses udisksctl (from udisks2) to power down devices. This is also Linux-specific.
|
||||
# Users on non-Linux platforms can comment it and use an alterntive to power-down disks.
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Arun Prakash Jana
|
||||
|
||||
prompt="device name [e.g. sdXn] ('l'ist, 'q'uit): "
|
||||
|
||||
lsblk
|
||||
|
||||
printf "\nEnsure you aren't still in the mounted device.\n"
|
||||
printf "%s" "$prompt"
|
||||
read -r dev
|
||||
|
||||
while [ -n "$dev" ]
|
||||
do
|
||||
if [ "$dev" = "l" ]; then
|
||||
lsblk
|
||||
elif [ "$dev" = "q" ]; then
|
||||
exit
|
||||
else
|
||||
if grep -qs "$dev " /proc/mounts; then
|
||||
sync
|
||||
if pumount "$dev"
|
||||
then
|
||||
echo "$dev" unmounted.
|
||||
if udisksctl power-off -b /dev/"$dev"
|
||||
then
|
||||
echo "$dev" ejected.
|
||||
fi
|
||||
fi
|
||||
else
|
||||
pmount "$dev"
|
||||
echo "$dev" mounted to "$(lsblk -n /dev/"$dev" | rev | cut -d' ' -f1 | rev)".
|
||||
fi
|
||||
fi
|
||||
|
||||
echo
|
||||
printf "%s" "$prompt"
|
||||
read -r dev
|
||||
done
|
|
@ -0,0 +1,555 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Sample script to play files in apps by file type or mime
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Usage: nuke filepath
|
||||
#
|
||||
# Integration with nnn:
|
||||
# 1. Export the required config:
|
||||
# export NNN_OPENER=/absolute/path/to/nuke
|
||||
# # Otherwise, if nuke is in $PATH
|
||||
# # export NNN_OPENER=nuke
|
||||
# 2. Run nnn with the program option to indicate a CLI opener
|
||||
# nnn -c
|
||||
# # The -c program option overrides option -e
|
||||
# 3. nuke can use nnn plugins (e.g. mocq is used for audio), $PATH is updated.
|
||||
#
|
||||
# Details:
|
||||
# Inspired by ranger's scope.sh, modified for usage with nnn.
|
||||
#
|
||||
# Guards against accidentally opening mime types like executables, shared libs etc.
|
||||
#
|
||||
# Tries to play 'file' (1st argument) in the following order:
|
||||
# 1. by extension
|
||||
# 2. by mime (image, video, audio, pdf)
|
||||
# 3. by mime (other file types)
|
||||
# 4. by mime (prompt and run executables)
|
||||
#
|
||||
# Modification tips:
|
||||
# 1. Invokes CLI utilities by default. Set GUI to 1 to enable GUI apps.
|
||||
# 2. PAGER is "less -R".
|
||||
# 3. Start GUI apps in bg to unblock. Redirect stdout and strerr if required.
|
||||
# 4. Some CLI utilities are piped to the $PAGER, to wait and quit uniformly.
|
||||
# 5. If the output cannot be paged use "read -r _" to wait for user input.
|
||||
# 6. On a DE, try 'xdg-open' or 'open' in handle_fallback() as last resort.
|
||||
#
|
||||
# Feel free to change the utilities to your favourites and add more mimes.
|
||||
#
|
||||
# Defaults:
|
||||
# By extension (only the enabled ones):
|
||||
# most archives: list with atool, bsdtar
|
||||
# rar: list with unrar
|
||||
# 7-zip: list with 7z
|
||||
# pdf: zathura (GUI), pdftotext, mutool, exiftool
|
||||
# audio: mocq (nnn plugin using MOC), mpv, media_client (Haiku), mediainfo, exiftool
|
||||
# avi|mkv|mp4: smplayer, mpv (GUI), ffmpegthumbnailer, mediainfo, exiftool
|
||||
# log: vi
|
||||
# torrent: rtorrent, transmission-show
|
||||
# odt|ods|odp|sxw: odt2txt
|
||||
# md: glow (https://github.com/charmbracelet/glow), lowdown (https://kristaps.bsd.lv/lowdown)
|
||||
# htm|html|xhtml: w3m, lynx, elinks
|
||||
# json: jq, python (json.tool module)
|
||||
# Multimedia by mime:
|
||||
# image/*: imv/sxiv/nsxiv (GUI), viu (https://github.com/atanunq/viu), img2txt, exiftool
|
||||
# video/*: smplayer, mpv (GUI), ffmpegthumbnailer, mediainfo, exiftool
|
||||
# audio/*: mocq (nnn plugin using MOC), mpv, media_client (Haiku), mediainfo, exiftool
|
||||
# application/pdf: zathura (GUI), pdftotext, mutool, exiftool
|
||||
# Other mimes:
|
||||
# text/troff: man -l
|
||||
# text/* | */xml: vi
|
||||
# image/vnd.djvu): djvutxt, exiftool
|
||||
#
|
||||
# TODO:
|
||||
# 1. Adapt, test and enable all mimes
|
||||
# 2. Clean-up the unnecessary exit codes
|
||||
|
||||
# set to 1 to enable GUI apps and/or BIN execution
|
||||
GUI="${GUI:-0}"
|
||||
BIN="${BIN:-0}"
|
||||
|
||||
set -euf -o noclobber -o noglob -o nounset
|
||||
IFS="$(printf '%b_' '\n')"; IFS="${IFS%_}" # protect trailing \n
|
||||
|
||||
PATH=$PATH:"${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins"
|
||||
IMAGE_CACHE_PATH="$(dirname "$1")"/.thumbs
|
||||
|
||||
FPATH="$1"
|
||||
FNAME=$(basename "$1")
|
||||
EDITOR="${VISUAL:-${EDITOR:-vi}}"
|
||||
PAGER="${PAGER:-less -R}"
|
||||
ext="${FNAME##*.}"
|
||||
if [ -n "$ext" ]; then
|
||||
ext="$(printf "%s" "${ext}" | tr '[:upper:]' '[:lower:]')"
|
||||
fi
|
||||
|
||||
is_mac() {
|
||||
uname | grep -q "Darwin"
|
||||
}
|
||||
|
||||
handle_pdf() {
|
||||
if [ "$GUI" -ne 0 ]; then
|
||||
if is_mac; then
|
||||
nohup open "${FPATH}" >/dev/null 2>&1 &
|
||||
elif type zathura >/dev/null 2>&1; then
|
||||
nohup zathura "${FPATH}" >/dev/null 2>&1 &
|
||||
else
|
||||
return
|
||||
fi
|
||||
elif type pdftotext >/dev/null 2>&1; then
|
||||
## Preview as text conversion
|
||||
pdftotext -l 10 -nopgbrk -q -- "${FPATH}" - | eval "$PAGER"
|
||||
elif type mutool >/dev/null 2>&1; then
|
||||
mutool draw -F txt -i -- "${FPATH}" 1-10 | eval "$PAGER"
|
||||
elif type exiftool >/dev/null 2>&1; then
|
||||
exiftool "${FPATH}" | eval "$PAGER"
|
||||
else
|
||||
return
|
||||
fi
|
||||
exit 0
|
||||
}
|
||||
|
||||
handle_audio() {
|
||||
if type mocp >/dev/null 2>&1 && type mocq >/dev/null 2>&1; then
|
||||
mocq "${FPATH}" "opener" >/dev/null 2>&1
|
||||
elif type mpv >/dev/null 2>&1; then
|
||||
mpv "${FPATH}" >/dev/null 2>&1 &
|
||||
elif type media_client >/dev/null 2>&1; then
|
||||
media_client play "${FPATH}" >/dev/null 2>&1 &
|
||||
elif type mediainfo >/dev/null 2>&1; then
|
||||
mediainfo "${FPATH}" | eval "$PAGER"
|
||||
elif type exiftool >/dev/null 2>&1; then
|
||||
exiftool "${FPATH}"| eval "$PAGER"
|
||||
else
|
||||
return
|
||||
fi
|
||||
exit 0
|
||||
}
|
||||
|
||||
handle_video() {
|
||||
if [ "$GUI" -ne 0 ]; then
|
||||
if is_mac; then
|
||||
nohup open "${FPATH}" >/dev/null 2>&1 &
|
||||
elif type smplayer >/dev/null 2>&1; then
|
||||
nohup smplayer "${FPATH}" >/dev/null 2>&1 &
|
||||
elif type mpv >/dev/null 2>&1; then
|
||||
nohup mpv "${FPATH}" >/dev/null 2>&1 &
|
||||
else
|
||||
return
|
||||
fi
|
||||
elif type ffmpegthumbnailer >/dev/null 2>&1; then
|
||||
# Thumbnail
|
||||
[ -d "${IMAGE_CACHE_PATH}" ] || mkdir "${IMAGE_CACHE_PATH}"
|
||||
ffmpegthumbnailer -i "${FPATH}" -o "${IMAGE_CACHE_PATH}/${FNAME}.jpg" -s 0
|
||||
viu -n "${IMAGE_CACHE_PATH}/${FNAME}.jpg" | eval "$PAGER"
|
||||
elif type mediainfo >/dev/null 2>&1; then
|
||||
mediainfo "${FPATH}" | eval "$PAGER"
|
||||
elif type exiftool >/dev/null 2>&1; then
|
||||
exiftool "${FPATH}"| eval "$PAGER"
|
||||
else
|
||||
return
|
||||
fi
|
||||
exit 0
|
||||
}
|
||||
|
||||
# handle this extension and exit
|
||||
handle_extension() {
|
||||
case "${ext}" in
|
||||
## Archive
|
||||
a|ace|alz|arc|arj|bz|bz2|cab|cpio|deb|gz|jar|lha|lz|lzh|lzma|lzo|\
|
||||
rpm|rz|t7z|tar|tbz|tbz2|tgz|tlz|txz|tZ|tzo|war|xpi|xz|Z|zip)
|
||||
if type atool >/dev/null 2>&1; then
|
||||
atool --list -- "${FPATH}" | eval "$PAGER"
|
||||
exit 0
|
||||
elif type bsdtar >/dev/null 2>&1; then
|
||||
bsdtar --list --file "${FPATH}" | eval "$PAGER"
|
||||
exit 0
|
||||
fi
|
||||
exit 1;;
|
||||
rar)
|
||||
if type unrar >/dev/null 2>&1; then
|
||||
## Avoid password prompt by providing empty password
|
||||
unrar lt -p- -- "${FPATH}" | eval "$PAGER"
|
||||
fi
|
||||
exit 1;;
|
||||
7z)
|
||||
if type 7z >/dev/null 2>&1; then
|
||||
## Avoid password prompt by providing empty password
|
||||
7z l -p -- "${FPATH}" | eval "$PAGER"
|
||||
exit 0
|
||||
fi
|
||||
exit 1;;
|
||||
|
||||
## PDF
|
||||
pdf)
|
||||
handle_pdf
|
||||
exit 1;;
|
||||
|
||||
## Audio
|
||||
aac|flac|m4a|mid|midi|mpa|mp2|mp3|ogg|wav|wma)
|
||||
handle_audio
|
||||
exit 1;;
|
||||
|
||||
## Video
|
||||
avi|mkv|mp4)
|
||||
handle_video
|
||||
exit 1;;
|
||||
|
||||
## Log files
|
||||
log)
|
||||
"$EDITOR" "${FPATH}"
|
||||
exit 0;;
|
||||
|
||||
## BitTorrent
|
||||
torrent)
|
||||
if type rtorrent >/dev/null 2>&1; then
|
||||
rtorrent "${FPATH}"
|
||||
exit 0
|
||||
elif type transmission-show >/dev/null 2>&1; then
|
||||
transmission-show -- "${FPATH}"
|
||||
exit 0
|
||||
fi
|
||||
exit 1;;
|
||||
|
||||
## OpenDocument
|
||||
odt|ods|odp|sxw)
|
||||
if type odt2txt >/dev/null 2>&1; then
|
||||
## Preview as text conversion
|
||||
odt2txt "${FPATH}" | eval "$PAGER"
|
||||
exit 0
|
||||
fi
|
||||
exit 1;;
|
||||
|
||||
## Markdown
|
||||
md)
|
||||
if type glow >/dev/null 2>&1; then
|
||||
glow -sdark "${FPATH}" | eval "$PAGER"
|
||||
exit 0
|
||||
elif type lowdown >/dev/null 2>&1; then
|
||||
lowdown -Tterm "${FPATH}" | eval "$PAGER"
|
||||
exit 0
|
||||
fi
|
||||
;;
|
||||
|
||||
## HTML
|
||||
htm|html|xhtml)
|
||||
## Preview as text conversion
|
||||
if type w3m >/dev/null 2>&1; then
|
||||
w3m -dump "${FPATH}" | eval "$PAGER"
|
||||
exit 0
|
||||
elif type lynx >/dev/null 2>&1; then
|
||||
lynx -dump -- "${FPATH}" | eval "$PAGER"
|
||||
exit 0
|
||||
elif type elinks >/dev/null 2>&1; then
|
||||
elinks -dump "${FPATH}" | eval "$PAGER"
|
||||
exit 0
|
||||
fi
|
||||
;;
|
||||
|
||||
## JSON
|
||||
json)
|
||||
if type jq >/dev/null 2>&1; then
|
||||
jq --color-output . "${FPATH}" | eval "$PAGER"
|
||||
exit 0
|
||||
elif type python >/dev/null 2>&1; then
|
||||
python -m json.tool -- "${FPATH}" | eval "$PAGER"
|
||||
exit 0
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# sets the variable abs_target, this should be faster than calling printf
|
||||
abspath() {
|
||||
case "$1" in
|
||||
/*) abs_target="$1";;
|
||||
*) abs_target="$PWD/$1";;
|
||||
esac
|
||||
}
|
||||
|
||||
# storing the result to a tmp file is faster than calling listimages twice
|
||||
listimages() {
|
||||
find -L "///${1%/*}" -maxdepth 1 -type f -print0 |
|
||||
grep -izZE '\.(jpe?g|png|gif|webp|tiff|bmp|ico|svg)$' |
|
||||
sort -z | tee "$tmp"
|
||||
}
|
||||
|
||||
load_dir() {
|
||||
abspath "$2"
|
||||
tmp="${TMPDIR:-/tmp}/nuke_$$"
|
||||
trap 'rm -f $tmp' EXIT
|
||||
count="$(listimages "$abs_target" | grep -a -m 1 -ZznF "$abs_target" | cut -d: -f1)"
|
||||
|
||||
if [ -n "$count" ]; then
|
||||
if [ "$GUI" -ne 0 ]; then
|
||||
xargs -0 nohup "$1" -n "$count" -- < "$tmp"
|
||||
else
|
||||
xargs -0 "$1" -n "$count" -- < "$tmp"
|
||||
fi
|
||||
else
|
||||
shift
|
||||
"$1" -- "$@" # fallback
|
||||
fi
|
||||
}
|
||||
|
||||
handle_multimedia() {
|
||||
## Size of the preview if there are multiple options or it has to be
|
||||
## rendered from vector graphics. If the conversion program allows
|
||||
## specifying only one dimension while keeping the aspect ratio, the width
|
||||
## will be used.
|
||||
# local DEFAULT_SIZE="1920x1080"
|
||||
|
||||
mimetype="${1}"
|
||||
case "${mimetype}" in
|
||||
## SVG
|
||||
# image/svg+xml|image/svg)
|
||||
# convert -- "${FPATH}" "${IMAGE_CACHE_PATH}" && exit 6
|
||||
# exit 1;;
|
||||
|
||||
## DjVu
|
||||
# image/vnd.djvu)
|
||||
# ddjvu -format=tiff -quality=90 -page=1 -size="${DEFAULT_SIZE}" \
|
||||
# - "${IMAGE_CACHE_PATH}" < "${FPATH}" \
|
||||
# && exit 6 || exit 1;;
|
||||
|
||||
## Image
|
||||
image/*)
|
||||
if [ "$GUI" -ne 0 ]; then
|
||||
if is_mac; then
|
||||
nohup open "${FPATH}" >/dev/null 2>&1 &
|
||||
exit 0
|
||||
elif type imv >/dev/null 2>&1; then
|
||||
load_dir imv "${FPATH}" >/dev/null 2>&1 &
|
||||
exit 0
|
||||
elif type imvr >/dev/null 2>&1; then
|
||||
load_dir imvr "${FPATH}" >/dev/null 2>&1 &
|
||||
exit 0
|
||||
elif type sxiv >/dev/null 2>&1; then
|
||||
load_dir sxiv "${FPATH}" >/dev/null 2>&1 &
|
||||
exit 0
|
||||
elif type nsxiv >/dev/null 2>&1; then
|
||||
load_dir nsxiv "${FPATH}" >/dev/null 2>&1 &
|
||||
exit 0
|
||||
fi
|
||||
elif type viu >/dev/null 2>&1; then
|
||||
viu -n "${FPATH}" | eval "$PAGER"
|
||||
exit 0
|
||||
elif type img2txt >/dev/null 2>&1; then
|
||||
img2txt --gamma=0.6 -- "${FPATH}" | eval "$PAGER"
|
||||
exit 0
|
||||
elif type exiftool >/dev/null 2>&1; then
|
||||
exiftool "${FPATH}" | eval "$PAGER"
|
||||
exit 0
|
||||
fi
|
||||
# local orientation
|
||||
# orientation="$( identify -format '%[EXIF:Orientation]\n' -- "${FPATH}" )"
|
||||
## If orientation data is present and the image actually
|
||||
## needs rotating ("1" means no rotation)...
|
||||
# if [[ -n "$orientation" && "$orientation" != 1 ]]; then
|
||||
## ...auto-rotate the image according to the EXIF data.
|
||||
# convert -- "${FPATH}" -auto-orient "${IMAGE_CACHE_PATH}" && exit 6
|
||||
# fi
|
||||
|
||||
## `w3mimgdisplay` will be called for all images (unless overridden
|
||||
## as above), but might fail for unsupported types.
|
||||
exit 7;;
|
||||
|
||||
## PDF
|
||||
application/pdf)
|
||||
handle_pdf
|
||||
exit 1;;
|
||||
|
||||
## Audio
|
||||
audio/*)
|
||||
handle_audio
|
||||
exit 1;;
|
||||
|
||||
## Video
|
||||
video/*)
|
||||
handle_video
|
||||
exit 1;;
|
||||
|
||||
# pdftoppm -f 1 -l 1 \
|
||||
# -scale-to-x "${DEFAULT_SIZE%x*}" \
|
||||
# -scale-to-y -1 \
|
||||
# -singlefile \
|
||||
# -jpeg -tiffcompression jpeg \
|
||||
# -- "${FPATH}" "${IMAGE_CACHE_PATH%.*}" \
|
||||
# && exit 6 || exit 1;;
|
||||
|
||||
|
||||
## ePub, MOBI, FB2 (using Calibre)
|
||||
# application/epub+zip|application/x-mobipocket-ebook|\
|
||||
# application/x-fictionbook+xml)
|
||||
# # ePub (using https://github.com/marianosimone/epub-thumbnailer)
|
||||
# epub-thumbnailer "${FPATH}" "${IMAGE_CACHE_PATH}" \
|
||||
# "${DEFAULT_SIZE%x*}" && exit 6
|
||||
# ebook-meta --get-cover="${IMAGE_CACHE_PATH}" -- "${FPATH}" \
|
||||
# >/dev/null && exit 6
|
||||
# exit 1;;
|
||||
|
||||
## Font
|
||||
# application/font*|application/*opentype)
|
||||
# preview_png="/tmp/$(basename "${IMAGE_CACHE_PATH%.*}").png"
|
||||
# if fontimage -o "${preview_png}" \
|
||||
# --pixelsize "120" \
|
||||
# --fontname \
|
||||
# --pixelsize "80" \
|
||||
# --text " ABCDEFGHIJKLMNOPQRSTUVWXYZ " \
|
||||
# --text " abcdefghijklmnopqrstuvwxyz " \
|
||||
# --text " 0123456789.:,;(*!?') ff fl fi ffi ffl " \
|
||||
# --text " The quick brown fox jumps over the lazy dog. " \
|
||||
# "${FPATH}";
|
||||
# then
|
||||
# convert -- "${preview_png}" "${IMAGE_CACHE_PATH}" \
|
||||
# && rm "${preview_png}" \
|
||||
# && exit 6
|
||||
# else
|
||||
# exit 1
|
||||
# fi
|
||||
# ;;
|
||||
|
||||
## Preview archives using the first image inside.
|
||||
## (Very useful for comic book collections for example.)
|
||||
# application/zip|application/x-rar|application/x-7z-compressed|\
|
||||
# application/x-xz|application/x-bzip2|application/x-gzip|application/x-tar)
|
||||
# local fn=""; local fe=""
|
||||
# local zip=""; local rar=""; local tar=""; local bsd=""
|
||||
# case "${mimetype}" in
|
||||
# application/zip) zip=1 ;;
|
||||
# application/x-rar) rar=1 ;;
|
||||
# application/x-7z-compressed) ;;
|
||||
# *) tar=1 ;;
|
||||
# esac
|
||||
# { [ "$tar" ] && fn=$(tar --list --file "${FPATH}"); } || \
|
||||
# { fn=$(bsdtar --list --file "${FPATH}") && bsd=1 && tar=""; } || \
|
||||
# { [ "$rar" ] && fn=$(unrar lb -p- -- "${FPATH}"); } || \
|
||||
# { [ "$zip" ] && fn=$(zipinfo -1 -- "${FPATH}"); } || return
|
||||
#
|
||||
# fn=$(echo "$fn" | python -c "import sys; import mimetypes as m; \
|
||||
# [ print(l, end='') for l in sys.stdin if \
|
||||
# (m.guess_type(l[:-1])[0] or '').startswith('image/') ]" |\
|
||||
# sort -V | head -n 1)
|
||||
# [ "$fn" = "" ] && return
|
||||
# [ "$bsd" ] && fn=$(printf '%b' "$fn")
|
||||
#
|
||||
# [ "$tar" ] && tar --extract --to-stdout \
|
||||
# --file "${FPATH}" -- "$fn" > "${IMAGE_CACHE_PATH}" && exit 6
|
||||
# fe=$(echo -n "$fn" | sed 's/[][*?\]/\\\0/g')
|
||||
# [ "$bsd" ] && bsdtar --extract --to-stdout \
|
||||
# --file "${FPATH}" -- "$fe" > "${IMAGE_CACHE_PATH}" && exit 6
|
||||
# [ "$bsd" ] || [ "$tar" ] && rm -- "${IMAGE_CACHE_PATH}"
|
||||
# [ "$rar" ] && unrar p -p- -inul -- "${FPATH}" "$fn" > \
|
||||
# "${IMAGE_CACHE_PATH}" && exit 6
|
||||
# [ "$zip" ] && unzip -pP "" -- "${FPATH}" "$fe" > \
|
||||
# "${IMAGE_CACHE_PATH}" && exit 6
|
||||
# [ "$rar" ] || [ "$zip" ] && rm -- "${IMAGE_CACHE_PATH}"
|
||||
# ;;
|
||||
esac
|
||||
}
|
||||
|
||||
handle_mime() {
|
||||
mimetype="${1}"
|
||||
case "${mimetype}" in
|
||||
## Manpages
|
||||
text/troff)
|
||||
man -l "${FPATH}"
|
||||
exit 0;;
|
||||
|
||||
## Text
|
||||
text/* | */xml)
|
||||
"$EDITOR" "${FPATH}"
|
||||
exit 0;;
|
||||
## Syntax highlight
|
||||
# if [[ "$( stat --printf='%s' -- "${FPATH}" )" -gt "${HIGHLIGHT_SIZE_MAX}" ]]; then
|
||||
# exit 2
|
||||
# fi
|
||||
# if [[ "$( tput colors )" -ge 256 ]]; then
|
||||
# local pygmentize_format='terminal256'
|
||||
# local highlight_format='xterm256'
|
||||
# else
|
||||
# local pygmentize_format='terminal'
|
||||
# local highlight_format='ansi'
|
||||
# fi
|
||||
# env HIGHLIGHT_OPTIONS="${HIGHLIGHT_OPTIONS}" highlight \
|
||||
# --out-format="${highlight_format}" \
|
||||
# --force -- "${FPATH}" && exit 5
|
||||
# pygmentize -f "${pygmentize_format}" -O "style=${PYGMENTIZE_STYLE}"\
|
||||
# -- "${FPATH}" && exit 5
|
||||
# exit 2;;
|
||||
|
||||
## DjVu
|
||||
image/vnd.djvu)
|
||||
if type djvutxt >/dev/null 2>&1; then
|
||||
## Preview as text conversion (requires djvulibre)
|
||||
djvutxt "${FPATH}" | eval "$PAGER"
|
||||
exit 0
|
||||
elif type exiftool >/dev/null 2>&1; then
|
||||
exiftool "${FPATH}" | eval "$PAGER"
|
||||
exit 0
|
||||
fi
|
||||
exit 1;;
|
||||
esac
|
||||
}
|
||||
|
||||
handle_fallback() {
|
||||
if [ "$GUI" -ne 0 ]; then
|
||||
if type xdg-open >/dev/null 2>&1; then
|
||||
nohup xdg-open "${FPATH}" >/dev/null 2>&1 &
|
||||
exit 0
|
||||
elif type open >/dev/null 2>&1; then
|
||||
nohup open "${FPATH}" >/dev/null 2>&1 &
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
echo '----- File details -----' && file --dereference --brief -- "${FPATH}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
handle_blocked() {
|
||||
case "${MIMETYPE}" in
|
||||
application/x-sharedlib)
|
||||
exit 0;;
|
||||
|
||||
application/x-shared-library-la)
|
||||
exit 0;;
|
||||
|
||||
application/x-executable)
|
||||
exit 0;;
|
||||
|
||||
application/x-shellscript)
|
||||
exit 0;;
|
||||
|
||||
application/octet-stream)
|
||||
exit 0;;
|
||||
esac
|
||||
}
|
||||
|
||||
handle_bin() {
|
||||
case "${MIMETYPE}" in
|
||||
application/x-executable|application/x-shellscript)
|
||||
clear
|
||||
echo '-------- Executable File --------' && file --dereference --brief -- "${FPATH}"
|
||||
printf "Run executable (y/N/'a'rgs)? "
|
||||
read -r answer
|
||||
case "$answer" in
|
||||
[Yy]* ) exec "${FPATH}";;
|
||||
[Aa]* )
|
||||
printf "args: "
|
||||
read -r args
|
||||
exec "${FPATH}" "$args";;
|
||||
[Nn]* ) exit;;
|
||||
esac
|
||||
esac
|
||||
}
|
||||
|
||||
MIMETYPE="$( file -bL --mime-type -- "${FPATH}" )"
|
||||
handle_extension
|
||||
handle_multimedia "${MIMETYPE}"
|
||||
handle_mime "${MIMETYPE}"
|
||||
[ "$BIN" -ne 0 ] && [ -x "${FPATH}" ] && handle_bin
|
||||
handle_blocked "${MIMETYPE}"
|
||||
handle_fallback
|
||||
|
||||
exit 1
|
|
@ -0,0 +1,16 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: List files bigger than input size by ascending access date.
|
||||
#
|
||||
# Dependencies: find sort
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Arun Prakash Jana
|
||||
|
||||
printf "Min file size (MB): "
|
||||
read -r size
|
||||
|
||||
find . -size +"$size"M -type f -printf '%A+ %s %p\n' | sort
|
||||
|
||||
echo "Press any key to exit"
|
||||
read -r _
|
|
@ -0,0 +1,49 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Description: Open selected files in nuke one by one or in oneshot
|
||||
#
|
||||
# Notes: 1. Opens the hovered file if the selection is empty
|
||||
# 2. nuke is the default, set OPENER below for custom
|
||||
# 3. Opener is invoked once for each file in a loop
|
||||
# 4. Keep pressing "Enter" to open files one by one
|
||||
#
|
||||
# Shell: bash
|
||||
# Author: Arun Prakash Jana
|
||||
|
||||
sel=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
|
||||
OPENER="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins/nuke"
|
||||
|
||||
if [ -s "$sel" ]; then
|
||||
targets=()
|
||||
while IFS= read -r -d '' entry || [ -n "$entry" ]; do
|
||||
targets+=( "$entry" )
|
||||
done < "$sel"
|
||||
|
||||
elements=${#targets[@]}
|
||||
|
||||
if (( elements == 1 )); then
|
||||
# If there's only one file selected, open without prompts
|
||||
"$OPENER" "${targets[0]}"
|
||||
else
|
||||
printf "open [A]ll? "
|
||||
read -r all
|
||||
|
||||
for ((index=0; index <= ${#targets[@]}; index++)); do
|
||||
"$OPENER" "${targets[index]}"
|
||||
if [ "$all" != "A" ] && (( index+1 < elements )); then
|
||||
printf "press Enter to open '%s'\n" "${targets[index+1]}"
|
||||
read -r -s -n 1 key
|
||||
if [[ $key != "" ]]; then
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Clear selection
|
||||
if [ -s "$sel" ] && [ -p "$NNN_PIPE" ]; then
|
||||
printf "-" > "$NNN_PIPE"
|
||||
fi
|
||||
elif [ -n "$1" ]; then
|
||||
"$OPENER" "$1"
|
||||
fi
|
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Organize files in directories by category
|
||||
#
|
||||
# Note: This plugin clears the selection as it changes the contents of the current dir
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: th3lusive
|
||||
|
||||
sel=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
|
||||
|
||||
organize() {
|
||||
case "$(file -biL "$1")" in
|
||||
*video*)
|
||||
[ ! -d "Videos" ] && mkdir "Videos"
|
||||
mv "$1" "Videos/$1"
|
||||
printf "Moved %s to Videos\n" "$1" ;;
|
||||
|
||||
*audio*) [ ! -d "Audio" ] && mkdir "Audio"
|
||||
mv "$1" "Audio/$1"
|
||||
printf "Moved %s to Audio\n" "$1" ;;
|
||||
|
||||
*image*)
|
||||
[ ! -d "Images" ] && mkdir "Images"
|
||||
mv "$1" "Images/$1"
|
||||
printf "Moved %s to Images\n" "$1" ;;
|
||||
|
||||
*pdf*|*document*|*epub*|*djvu*|*cb*)
|
||||
[ ! -d "Documents" ] && mkdir "Documents"
|
||||
mv "$1" "Documents/$1"
|
||||
printf "Moved %s to Documents\n" "$1" ;;
|
||||
|
||||
*text*)
|
||||
[ ! -d "Plaintext" ] && mkdir "Plaintext"
|
||||
mv "$1" "Plaintext/$1"
|
||||
printf "Moved %s to Plaintext\n" "$1" ;;
|
||||
|
||||
*tar*|*xz*|*compress*|*7z*|*rar*|*zip*)
|
||||
[ ! -d "Archives" ] && mkdir "Archives"
|
||||
mv "$1" "Archives/$1"
|
||||
printf "Moved %s to Archives\n" "$1" ;;
|
||||
|
||||
*binary*)
|
||||
[ ! -d "Binaries" ] && mkdir "Binaries"
|
||||
mv "$1" "Binaries/$1"
|
||||
printf "Moved %s to Binaries\n" "$1" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
main() {
|
||||
for file in *
|
||||
do
|
||||
[ -f "$file" ] && organize "$file"
|
||||
done
|
||||
|
||||
# Clear selection
|
||||
if [ -s "$sel" ] && [ -p "$NNN_PIPE" ]; then
|
||||
printf "-" > "$NNN_PIPE"
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Read a text or PDF file in British English
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Arun Prakash Jana
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
tmpf="$(basename "$1")"
|
||||
tmpf="${TMPDIR:-/tmp}"/"${tmpf%.*}"
|
||||
|
||||
if [ "$(head -c 4 "$1")" = "%PDF" ]; then
|
||||
# Convert using pdftotext
|
||||
pdftotext -nopgbrk -layout "$1" - | sed 's/\xe2\x80\x8b//g' > "$tmpf".txt
|
||||
|
||||
pico2wave -w "$tmpf".wav -l en-GB "$(tr '\n' ' ' < "$tmpf".txt)"
|
||||
|
||||
rm "$tmpf".txt
|
||||
else
|
||||
pico2wave -w "$tmpf".wav -l en-GB "$(tr '\n' ' ' < "$1")"
|
||||
fi
|
||||
|
||||
# to jump around and note the time
|
||||
mpv "$tmpf".wav
|
||||
|
||||
# flat read but better quality
|
||||
# play -qV0 "$tmpf".wav treble 2 gain -l 2
|
||||
|
||||
rm "$tmpf".wav
|
||||
fi
|
|
@ -0,0 +1,211 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Description: tabbed/xembed based file previewer
|
||||
#
|
||||
# Dependencies:
|
||||
# - tabbed (https://tools.suckless.org/tabbed): xembed host
|
||||
# - xterm (or urxvt or st) : xembed client for text-based preview
|
||||
# - mpv (https://mpv.io): xembed client for video/audio
|
||||
# - sxiv (https://github.com/muennich/sxiv) or,
|
||||
# - nsxiv (https://github.com/nsxiv/nsxiv) : xembed client for images
|
||||
# - zathura (https://pwmt.org/projects/zathura): xembed client for PDF
|
||||
# - nnn's nuke plugin for text preview and fallback
|
||||
# nuke is a fallback for 'mpv', 'sxiv'/'nsxiv', and 'zathura', but has its
|
||||
# own dependencies, see the script for more information
|
||||
# - vim (or any editor/pager really)
|
||||
# - file
|
||||
# - mktemp
|
||||
# - xdotool (optional, to keep main window focused)
|
||||
#
|
||||
# Usage:
|
||||
# - Install the dependencies. Then set a NNN_FIFO
|
||||
# and set a key for the plugin, then start `nnn`:
|
||||
# $ NNN_FIFO=/tmp/nnn.fifo nnn
|
||||
# - Launch the plugin with the designated key from nnn
|
||||
#
|
||||
# Notes:
|
||||
# 1. This plugin needs a "NNN_FIFO" to work. See man.
|
||||
# 2. If the same NNN_FIFO is used in multiple nnn instances, there will be one
|
||||
# common preview window. With different FIFO paths, they will be independent.
|
||||
#
|
||||
# How it works:
|
||||
# We use `tabbed` [1] as a xembed [2] host, to have a single window
|
||||
# owning each previewer window. So each previewer must be a xembed client.
|
||||
# For text previewers, this is not an issue, as there are a lot of
|
||||
# xembed-able terminal emulator (we default to `xterm`, but examples are
|
||||
# provided for `urxvt` and `st`). For graphic preview this can be trickier,
|
||||
# but a few popular viewers are xembed-able, we use:
|
||||
# - `mpv`: multimedia player, for video/audio preview
|
||||
# - `sxiv`/`nsxiv`: image viewer
|
||||
# - `zathura`: PDF viewer
|
||||
# - but we always fallback to `nuke` plugin
|
||||
#
|
||||
# [1]: https://tools.suckless.org/tabbed/
|
||||
# [2]: https://specifications.freedesktop.org/xembed-spec/xembed-spec-latest.html
|
||||
#
|
||||
# Shell: Bash (job control is weakly specified in POSIX)
|
||||
# Author: Léo Villeveygoux
|
||||
|
||||
|
||||
XDOTOOL_TIMEOUT=2
|
||||
PAGER=${PAGER:-"vim -R"}
|
||||
NUKE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins/nuke"
|
||||
|
||||
|
||||
if type xterm >/dev/null 2>&1 ; then
|
||||
TERMINAL="xterm -into"
|
||||
elif type urxvt >/dev/null 2>&1 ; then
|
||||
TERMINAL="urxvt -embed"
|
||||
elif type st >/dev/null 2>&1 ; then
|
||||
TERMINAL="st -w"
|
||||
else
|
||||
echo "No xembed term found" >&2
|
||||
fi
|
||||
|
||||
|
||||
term_nuke () {
|
||||
# $1 -> $XID, $2 -> $FILE
|
||||
$TERMINAL "$1" -e "$NUKE" "$2" &
|
||||
}
|
||||
|
||||
start_tabbed () {
|
||||
FIFO="$(mktemp -u)"
|
||||
mkfifo "$FIFO"
|
||||
|
||||
tabbed > "$FIFO" &
|
||||
|
||||
jobs # Get rid of the "Completed" entries
|
||||
|
||||
TABBEDPID="$(jobs -p %%)"
|
||||
|
||||
if [ -z "$TABBEDPID" ] ; then
|
||||
echo "Can't start tabbed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
read -r XID < "$FIFO"
|
||||
|
||||
rm "$FIFO"
|
||||
}
|
||||
|
||||
get_viewer_pid () {
|
||||
VIEWERPID="$(jobs -p %%)"
|
||||
}
|
||||
|
||||
kill_viewer () {
|
||||
if [ -n "$VIEWERPID" ] && jobs -p | grep "$VIEWERPID" ; then
|
||||
kill "$VIEWERPID"
|
||||
fi
|
||||
}
|
||||
|
||||
sigint_kill () {
|
||||
kill_viewer
|
||||
kill "$TABBEDPID"
|
||||
exit 0
|
||||
}
|
||||
|
||||
previewer_loop () {
|
||||
unset -v NNN_FIFO
|
||||
# mute from now
|
||||
exec >/dev/null 2>&1
|
||||
|
||||
MAINWINDOW="$(xdotool getactivewindow)"
|
||||
|
||||
start_tabbed
|
||||
trap sigint_kill SIGINT
|
||||
|
||||
xdotool windowactivate "$MAINWINDOW"
|
||||
|
||||
# Bruteforce focus stealing prevention method,
|
||||
# works well in floating window managers like XFCE
|
||||
# but make interaction with the preview window harder
|
||||
# (uncomment to use):
|
||||
#xdotool behave "$XID" focus windowactivate "$MAINWINDOW" &
|
||||
|
||||
while read -r FILE ; do
|
||||
|
||||
jobs # Get rid of the "Completed" entries
|
||||
|
||||
if ! jobs | grep tabbed ; then
|
||||
break
|
||||
fi
|
||||
|
||||
if [ ! -e "$FILE" ] ; then
|
||||
continue
|
||||
fi
|
||||
|
||||
kill_viewer
|
||||
|
||||
MIME="$(file -bL --mime-type "$FILE")"
|
||||
|
||||
case "$MIME" in
|
||||
video/*)
|
||||
if type mpv >/dev/null 2>&1 ; then
|
||||
mpv --force-window=immediate --loop-file --wid="$XID" "$FILE" &
|
||||
else
|
||||
term_nuke "$XID" "$FILE"
|
||||
fi
|
||||
;;
|
||||
audio/*)
|
||||
if type mpv >/dev/null 2>&1 ; then
|
||||
mpv --force-window=immediate --loop-file --wid="$XID" "$FILE" &
|
||||
else
|
||||
term_nuke "$XID" "$FILE"
|
||||
fi
|
||||
;;
|
||||
image/*)
|
||||
if type sxiv >/dev/null 2>&1 ; then
|
||||
sxiv -ae "$XID" "$FILE" &
|
||||
elif type nsxiv >/dev/null 2>&1 ; then
|
||||
nsxiv -ae "$XID" "$FILE" &
|
||||
else
|
||||
term_nuke "$XID" "$FILE"
|
||||
fi
|
||||
;;
|
||||
application/pdf)
|
||||
if type zathura >/dev/null 2>&1 ; then
|
||||
zathura -e "$XID" "$FILE" &
|
||||
else
|
||||
term_nuke "$XID" "$FILE"
|
||||
fi
|
||||
;;
|
||||
inode/directory)
|
||||
$TERMINAL "$XID" -e nnn "$FILE" &
|
||||
;;
|
||||
text/*)
|
||||
if [ -x "$NUKE" ] ; then
|
||||
term_nuke "$XID" "$FILE"
|
||||
else
|
||||
# shellcheck disable=SC2086
|
||||
$TERMINAL "$XID" -e $PAGER "$FILE" &
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
if [ -x "$NUKE" ] ; then
|
||||
term_nuke "$XID" "$FILE"
|
||||
else
|
||||
$TERMINAL "$XID" -e sh -c "file '$FILE' | $PAGER -" &
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
get_viewer_pid
|
||||
|
||||
# following lines are not needed with the bruteforce xdotool method
|
||||
ACTIVE_XID="$(xdotool getactivewindow)"
|
||||
if [ $((ACTIVE_XID == XID)) -ne 0 ] ; then
|
||||
xdotool windowactivate "$MAINWINDOW"
|
||||
else
|
||||
timeout "$XDOTOOL_TIMEOUT" xdotool behave "$XID" focus windowactivate "$MAINWINDOW" &
|
||||
fi
|
||||
done
|
||||
kill "$TABBEDPID"
|
||||
kill_viewer
|
||||
}
|
||||
|
||||
if [ ! -r "$NNN_FIFO" ] ; then
|
||||
echo "Can't read \$NNN_FIFO ('$NNN_FIFO')"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
previewer_loop < "$NNN_FIFO" &
|
||||
disown
|
|
@ -0,0 +1,481 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Terminal based file previewer
|
||||
#
|
||||
# Note: This plugin needs a "NNN_FIFO" to work. See man.
|
||||
#
|
||||
# Dependencies:
|
||||
# - Supports 5 independent methods to preview with:
|
||||
# - tmux (>=3.0), or
|
||||
# - kitty with allow_remote_control and listen_on set in kitty.conf, or
|
||||
# - QuickLook on WSL (https://github.com/QL-Win/QuickLook), or
|
||||
# - Windows Terminal (https://github.com/Microsoft/Terminal | https://aka.ms/terminal) with WSL, or
|
||||
# - $TERMINAL set to a terminal (it's xterm by default).
|
||||
# - less or $PAGER
|
||||
# - tree or exa or ls
|
||||
# - mediainfo or file
|
||||
# - mktemp
|
||||
# - unzip
|
||||
# - tar
|
||||
# - man
|
||||
# - optional: bsdtar or atool for additional archive preview
|
||||
# - optional: bat for code syntax highlighting
|
||||
# - optional: ueberzug, kitty terminal, viu or catimg for images
|
||||
# - optional: convert(ImageMagick) for playing gif preview (required for kitty image previews)
|
||||
# - optional: ffmpegthumbnailer for video thumbnails (https://github.com/dirkvdb/ffmpegthumbnailer)
|
||||
# - optional: ffmpeg for audio thumbnails
|
||||
# - optional: libreoffce for opendocument/officedocument preview
|
||||
# - optional: pdftoppm(poppler) for pdf thumbnails
|
||||
# - optional: gnome-epub-thumbnailer for epub thumbnails (https://gitlab.gnome.org/GNOME/gnome-epub-thumbnailer)
|
||||
# - optional: fontpreview for font preview (https://github.com/sdushantha/fontpreview)
|
||||
# - optional: djvulibre for djvu
|
||||
# - optional: glow or lowdown for markdown
|
||||
# - optional: w3m or lynx or elinks for html
|
||||
# - optional: set/export ICONLOOKUP as 1 to enable file icons in front of directory previews with .iconlookup
|
||||
# Icons and colors are configureable in .iconlookup
|
||||
# - optional: scope.sh file viewer from ranger.
|
||||
# 1. drop scope.sh executable in $PATH
|
||||
# 2. set/export $USE_SCOPE as 1
|
||||
# - optional: pistol file viewer (https://github.com/doronbehar/pistol).
|
||||
# 1. install pistol
|
||||
# 2. set/export $USE_PISTOL as 1
|
||||
#
|
||||
# Usage:
|
||||
# You need to set a NNN_FIFO path and a key for the plugin with NNN_PLUG,
|
||||
# then start `nnn`:
|
||||
#
|
||||
# $ nnn -a
|
||||
#
|
||||
# or
|
||||
#
|
||||
# $ NNN_FIFO=/tmp/nnn.fifo nnn
|
||||
#
|
||||
# Then launch the `preview-tui` plugin in `nnn`.
|
||||
#
|
||||
# If you provide the same NNN_FIFO to all nnn instances, there will be a
|
||||
# single common preview window. If you provide different FIFO path (e.g.
|
||||
# with -a), they will be independent.
|
||||
#
|
||||
# The previews will be shown in a tmux split. If that isn't possible, it
|
||||
# will try to use a kitty terminal split. And as a final fallback, a
|
||||
# different terminal window will be used ($TERMINAL).
|
||||
#
|
||||
# Tmux and kitty users can configure $SPLIT to either "h" or "v" to set a
|
||||
# 'h'orizontal split or a 'v'ertical split (as in, the line that splits the
|
||||
# windows will be horizontal or vertical).
|
||||
#
|
||||
# Kitty users need something similar to the following in their kitty.conf:
|
||||
# - `allow_remote_control yes`
|
||||
# - `listen_on unix:$TMPDIR/kitty`
|
||||
# - `enabled_layouts splits` (optional)
|
||||
# With ImageMagick installed, this terminal can use the icat kitten to display images.
|
||||
# Refer to kitty documentation for further details.
|
||||
#
|
||||
# Iterm2 users are recommended to use viu to view images without getting pixelated.
|
||||
#
|
||||
# Windows Terminal users can set "Profile termination behavior" under "Profile > Advanced" settings
|
||||
# to automaticaly close pane on quit when exit code is 0.
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Authors: Todd Yamakawa, Léo Villeveygoux, @Recidiviste, Mario Ortiz Manero, Luuk van Baal, @WanderLanz
|
||||
|
||||
#SPLIT="$SPLIT" # you can set a permanent split here
|
||||
#TERMINAL="$TERMINAL" # same goes for the terminal
|
||||
SPLIT_SIZE="${SPLIT_SIZE:-50}" # split size in percentage for supported previewers
|
||||
USE_SCOPE="${USE_SCOPE:-0}"
|
||||
USE_PISTOL="${USE_PISTOL:-0}"
|
||||
ICONLOOKUP="${ICONLOOKUP:-0}"
|
||||
PAGER="${PAGER:-less -P?n -R}"
|
||||
TMPDIR="${TMPDIR:-/tmp}"
|
||||
BAT_STYLE="${BAT_STYLE:-numbers}"
|
||||
BAT_THEME="${BAT_THEME:-ansi}"
|
||||
# Consider setting NNN_PREVIEWDIR to $XDG_CACHE_HOME/nnn/previews if you want to keep previews on disk between reboots
|
||||
NNN_PREVIEWDIR="${NNN_PREVIEWDIR:-$TMPDIR/nnn/previews}"
|
||||
NNN_PREVIEWWIDTH="${NNN_PREVIEWWIDTH:-1920}"
|
||||
NNN_PREVIEWHEIGHT="${NNN_PREVIEWHEIGHT:-1080}"
|
||||
NNN_PARENT="${NNN_FIFO#*.}"
|
||||
[ "$NNN_PARENT" -eq "$NNN_PARENT" ] 2>/dev/null || NNN_PARENT=""
|
||||
FIFOPID="$TMPDIR/nnn-preview-tui-fifopid.$NNN_PARENT"
|
||||
PREVIEWPID="$TMPDIR/nnn-preview-tui-pagerpid.$NNN_PARENT"
|
||||
CURSEL="$TMPDIR/nnn-preview-tui-selection.$NNN_PARENT"
|
||||
FIFO_UEBERZUG="$TMPDIR/nnn-preview-tui-ueberzug-fifo.$NNN_PARENT"
|
||||
POSOFFSET="$TMPDIR/nnn-preview-tui-posoffset"
|
||||
|
||||
exists() { type "$1" >/dev/null 2>&1 ;}
|
||||
pkill() { command pkill "$@" >/dev/null 2>&1 ;}
|
||||
pidkill() { [ -f "$1" ] && kill "$(cat "$1")" >/dev/null 2>&1 ;}
|
||||
prompt() { printf "%b" "$@"; cfg=$(stty -g); stty raw -echo; head -c 1; stty "$cfg" ;}
|
||||
|
||||
start_preview() {
|
||||
[ "$PAGER" = "most" ] && PAGER="less -R"
|
||||
|
||||
if [ -e "${TMUX%%,*}" ] && tmux -V | grep -q '[ -][3456789]\.'; then
|
||||
TERMINAL=tmux
|
||||
elif [ -n "$KITTY_LISTEN_ON" ]; then
|
||||
TERMINAL=kitty
|
||||
elif [ -z "$TERMINAL" ] && [ "$TERM_PROGRAM" = "iTerm.app" ]; then
|
||||
TERMINAL=iterm
|
||||
elif [ -n "$WT_SESSION" ]; then
|
||||
TERMINAL=winterm
|
||||
else
|
||||
TERMINAL="${TERMINAL:-xterm}"
|
||||
fi
|
||||
|
||||
if [ -z "$SPLIT" ] && [ $(($(tput lines) * 2)) -gt "$(tput cols)" ]; then
|
||||
SPLIT='h'
|
||||
elif [ "$SPLIT" != 'h' ]; then
|
||||
SPLIT='v'
|
||||
fi
|
||||
|
||||
case "$TERMINAL" in
|
||||
tmux) # tmux splits are inverted
|
||||
if [ "$SPLIT" = "v" ]; then DSPLIT="h"; else DSPLIT="v"; fi
|
||||
tmux split-window -e "NNN_FIFO=$NNN_FIFO" -e "PREVIEW_MODE=1" -e "CURSEL=$CURSEL" \
|
||||
-e "TMPDIR=$TMPDIR" -e "FIFOPID=$FIFOPID" -e "POSOFFSET=$POSOFFSET" \
|
||||
-e "BAT_STYLE=$BAT_STYLE" -e "BAT_THEME=$BAT_THEME" -e "PREVIEWPID=$PREVIEWPID" \
|
||||
-e "PAGER=$PAGER" -e "ICONLOOKUP=$ICONLOOKUP" -e "NNN_PREVIEWWIDTH=$NNN_PREVIEWWIDTH" \
|
||||
-e "USE_SCOPE=$USE_SCOPE" -e "SPLIT=$SPLIT" -e "USE_PISTOL=$USE_PISTOL" \
|
||||
-e "NNN_PREVIEWDIR=$NNN_PREVIEWDIR" -e "NNN_PREVIEWHEIGHT=$NNN_PREVIEWHEIGHT" \
|
||||
-e "FIFO_UEBERZUG=$FIFO_UEBERZUG" -e "QLPATH=$2" -d"$DSPLIT" -p"$SPLIT_SIZE" "$0" "$1" ;;
|
||||
kitty) # Setting the layout for the new window. It will be restored after the script ends.
|
||||
kitty @ goto-layout splits
|
||||
# Trying to use kitty's integrated window management as the split window. All
|
||||
# environmental variables that will be used in the new window must be explicitly passed.
|
||||
kitty @ launch --no-response --title "nnn preview" --keep-focus \
|
||||
--cwd "$PWD" --env "PATH=$PATH" --env "NNN_FIFO=$NNN_FIFO" \
|
||||
--env "PREVIEW_MODE=1" --env "PAGER=$PAGER" --env "TMPDIR=$TMPDIR" \
|
||||
--env "USE_SCOPE=$USE_SCOPE" --env "SPLIT=$SPLIT" --env "TERMINAL=$TERMINAL"\
|
||||
--env "PREVIEWPID=$PREVIEWPID" --env "FIFO_UEBERZUG=$FIFO_UEBERZUG" \
|
||||
--env "ICONLOOKUP=$ICONLOOKUP" --env "NNN_PREVIEWHEIGHT=$NNN_PREVIEWHEIGHT" \
|
||||
--env "NNN_PREVIEWWIDTH=$NNN_PREVIEWWIDTH" --env "NNN_PREVIEWDIR=$NNN_PREVIEWDIR" \
|
||||
--env "USE_PISTOL=$USE_PISTOL" --env "BAT_STYLE=$BAT_STYLE" \
|
||||
--env "BAT_THEME=$BAT_THEME" --env "FIFOPID=$FIFOPID" \
|
||||
--env "CURSEL=$CURSEL" --location "${SPLIT}split" "$0" "$1" ;;
|
||||
iterm)
|
||||
command="$SHELL -c 'cd $PWD; \
|
||||
PATH=\\\"$PATH\\\" NNN_FIFO=\\\"$NNN_FIFO\\\" PREVIEW_MODE=1 PAGER=\\\"$PAGER\\\" \
|
||||
USE_SCOPE=\\\"$USE_SCOPE\\\" SPLIT=\\\"$SPLIT\\\" TERMINAL=\\\"$TERMINAL\\\" \
|
||||
PREVIEWPID=\\\"$PREVIEWPID\\\" CURSEL=\\\"$CURSEL\\\" TMPDIR=\\\"$TMPDIR\\\" \
|
||||
ICONLOOKUP=\\\"$ICONLOOKUP\\\" NNN_PREVIEWHEIGHT=\\\"$NNN_PREVIEWHEIGHT\\\" \
|
||||
NNN_PREVIEWWIDTH=\\\"$NNN_PREVIEWWIDTH\\\" NNN_PREVIEWDIR=\\\"$NNN_PREVIEWDIR\\\" \
|
||||
USE_PISTOL=\\\"$USE_PISTOL\\\" BAT_STYLE=\\\"$BAT_STYLE\\\" \
|
||||
BAT_THEME=\\\"$BAT_THEME\\\" FIFOPID=\\\"$FIFOPID\\\" \\\"$0\\\" \\\"$1\\\"'"
|
||||
if [ "$SPLIT" = "h" ]; then split="horizontally"; else split="vertically"; fi
|
||||
osascript <<-EOF
|
||||
tell application "iTerm"
|
||||
tell current session of current window
|
||||
split $split with default profile command "$command"
|
||||
end tell
|
||||
end tell
|
||||
EOF
|
||||
;;
|
||||
winterm)
|
||||
if [ "$SPLIT" = "h" ]; then split="H"; else split="V"; fi
|
||||
cmd.exe /c wt -w 0 sp -$split -s$((SPLIT_SIZE / 100)) bash -c "cd $PWD \; \
|
||||
PATH='$PATH' NNN_FIFO=$NNN_FIFO PREVIEW_MODE=1 CURSEL=$CURSEL TMPDIR=$TMPDIR \
|
||||
FIFOPID=$FIFOPID BAT_STYLE=$BAT_STYLE BAT_THEME=$BAT_THEME PREVIEWPID=$PREVIEWPID \
|
||||
PAGER='$PAGER' ICONLOOKUP=$ICONLOOKUP NNN_PREVIEWWIDTH=$NNN_PREVIEWWIDTH \
|
||||
USE_SCOPE=$USE_SCOPE SPLIT=$SPLIT USE_PISTOL=$USE_PISTOL \
|
||||
NNN_PREVIEWDIR=$NNN_PREVIEWDIR NNN_PREVIEWHEIGHT=$NNN_PREVIEWHEIGHT \
|
||||
FIFO_UEBERZUG=$FIFO_UEBERZUG QLPATH=$2 $0 $1" \; -w 0 mf previous
|
||||
;;
|
||||
*) if [ -n "$2" ]; then
|
||||
QUICKLOOK=1 QLPATH="$2" PREVIEW_MODE=1 "$0" "$1" &
|
||||
else
|
||||
PREVIEWPID="$PREVIEWPID" CURSEL="$CURSEL" PREVIEW_MODE=1 \
|
||||
FIFOPID="$FIFOPID" FIFO_UEBERZUG="$FIFO_UEBERZUG" $TERMINAL -e "$0" "$1" &
|
||||
fi ;;
|
||||
esac
|
||||
}
|
||||
|
||||
toggle_preview() {
|
||||
if exists QuickLook.exe; then
|
||||
QLPATH="QuickLook.exe"
|
||||
elif exists Bridge.exe; then
|
||||
QLPATH="Bridge.exe"
|
||||
fi
|
||||
if pidkill "$FIFOPID"; then
|
||||
[ -p "$NNN_PPIPE" ] && printf "0" > "$NNN_PPIPE"
|
||||
pidkill "$PREVIEWPID"
|
||||
pkill -f "tail --follow $FIFO_UEBERZUG"
|
||||
if [ -n "$QLPATH" ] && stat "$1"; then
|
||||
f="$(wslpath -w "$1")" && "$QLPATH" "$f" &
|
||||
fi
|
||||
else
|
||||
[ -p "$NNN_PPIPE" ] && printf "1" > "$NNN_PPIPE"
|
||||
start_preview "$1" "$QLPATH"
|
||||
fi
|
||||
}
|
||||
|
||||
fifo_pager() {
|
||||
cmd="$1"
|
||||
shift
|
||||
|
||||
# We use a FIFO to access $PAGER PID in jobs control
|
||||
tmpfifopath="$TMPDIR/nnn-preview-tui-fifo.$$"
|
||||
mkfifo "$tmpfifopath" || return
|
||||
|
||||
$PAGER < "$tmpfifopath" &
|
||||
printf "%s" "$!" > "$PREVIEWPID"
|
||||
|
||||
(
|
||||
exec > "$tmpfifopath"
|
||||
if [ "$cmd" = "pager" ]; then
|
||||
if exists bat; then
|
||||
bat --terminal-width="$cols" --decorations=always --color=always \
|
||||
--paging=never --style="$BAT_STYLE" --theme="$BAT_THEME" "$@" &
|
||||
else
|
||||
$PAGER "$@" &
|
||||
fi
|
||||
else
|
||||
"$cmd" "$@" &
|
||||
fi
|
||||
)
|
||||
|
||||
rm "$tmpfifopath"
|
||||
}
|
||||
|
||||
# Binary file: show file info inside the pager
|
||||
print_bin_info() {
|
||||
printf -- "-------- \033[1;31mBinary file\033[0m --------\n"
|
||||
if exists mediainfo; then
|
||||
mediainfo "$1"
|
||||
else
|
||||
file -b "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
handle_mime() {
|
||||
case "$2" in
|
||||
image/jpeg) image_preview "$cols" "$lines" "$1" ;;
|
||||
image/gif) generate_preview "$cols" "$lines" "$1" "gif" ;;
|
||||
image/vnd.djvu) generate_preview "$cols" "$lines" "$1" "djvu" ;;
|
||||
image/*) generate_preview "$cols" "$lines" "$1" "image" ;;
|
||||
video/*) generate_preview "$cols" "$lines" "$1" "video" ;;
|
||||
audio/*) generate_preview "$cols" "$lines" "$1" "audio" ;;
|
||||
application/font*|application/*opentype|font/*) generate_preview "$cols" "$lines" "$1" "font" ;;
|
||||
*/*office*|*/*document*) generate_preview "$cols" "$lines" "$1" "office" ;;
|
||||
application/zip) fifo_pager unzip -l "$1" ;;
|
||||
text/troff)
|
||||
if exists man; then
|
||||
fifo_pager man -Pcat -l "$1"
|
||||
else
|
||||
fifo_pager pager "$1"
|
||||
fi ;;
|
||||
*) handle_ext "$1" "$3" "$4" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
handle_ext() {
|
||||
case "$2" in
|
||||
epub) generate_preview "$cols" "$lines" "$1" "epub" ;;
|
||||
pdf) generate_preview "$cols" "$lines" "$1" "pdf" ;;
|
||||
gz|bz2) fifo_pager tar -tvf "$1" ;;
|
||||
md) if exists glow; then
|
||||
fifo_pager glow -s dark "$1"
|
||||
elif exists lowdown; then
|
||||
fifo_pager lowdown -Tterm "$1"
|
||||
else
|
||||
fifo_pager pager "$1"
|
||||
fi ;;
|
||||
htm|html|xhtml)
|
||||
if exists w3m; then
|
||||
fifo_pager w3m "$1"
|
||||
elif exists lynx; then
|
||||
fifo_pager lynx "$1"
|
||||
elif exists elinks; then
|
||||
fifo_pager elinks "$1"
|
||||
else
|
||||
fifo_pager pager "$1"
|
||||
fi ;;
|
||||
7z|a|ace|alz|arc|arj|bz|cab|cpio|deb|jar|lha|lz|lzh|lzma|lzo\
|
||||
|rar|rpm|rz|t7z|tar|tbz|tbz2|tgz|tlz|txz|tZ|tzo|war|xpi|xz|Z)
|
||||
if exists atool; then
|
||||
fifo_pager atool -l "$1"
|
||||
elif exists bsdtar; then
|
||||
fifo_pager bsdtar -tvf "$1"
|
||||
fi ;;
|
||||
*) if [ "$3" = "bin" ]; then
|
||||
fifo_pager print_bin_info "$1"
|
||||
else
|
||||
fifo_pager pager "$1"
|
||||
fi ;;
|
||||
esac
|
||||
}
|
||||
|
||||
preview_file() {
|
||||
clear
|
||||
# Trying to use pistol if it's available.
|
||||
if [ "$USE_PISTOL" -ne 0 ] && exists pistol; then
|
||||
fifo_pager pistol "$1"
|
||||
return
|
||||
fi
|
||||
|
||||
# Trying to use scope.sh if it's available.
|
||||
if [ "$USE_SCOPE" -ne 0 ] && exists scope.sh; then
|
||||
fifo_pager scope.sh "$1" "$cols" "$lines" "$(mktemp -d)" "True"
|
||||
return
|
||||
fi
|
||||
|
||||
# Use QuickLook if it's available.
|
||||
if [ -n "$QUICKLOOK" ]; then
|
||||
stat "$1" && f="$(wslpath -w "$1")" && "$QLPATH" "$f" &
|
||||
return
|
||||
fi
|
||||
|
||||
# Detecting the exact type of the file: the encoding, mime type, and extension in lowercase.
|
||||
encoding="$(file -bL --mime-encoding -- "$1")"
|
||||
mimetype="$(file -bL --mime-type -- "$1")"
|
||||
ext="${1##*.}"
|
||||
[ -n "$ext" ] && ext="$(printf "%s" "${ext}" | tr '[:upper:]' '[:lower:]')"
|
||||
lines=$(tput lines)
|
||||
cols=$(tput cols)
|
||||
|
||||
# Otherwise, falling back to the defaults.
|
||||
if [ -d "$1" ]; then
|
||||
cd "$1" || return
|
||||
if [ "$ICONLOOKUP" -ne 0 ] && [ -f "$(dirname "$0")"/.iconlookup ]; then
|
||||
[ "$SPLIT" = v ] && BSTR="\n"
|
||||
# shellcheck disable=SC2012
|
||||
ls -F --group-directories-first | head -n "$((lines - 3))" | "$(dirname "$0")"/.iconlookup -l "$cols" -B "$BSTR" -b " "
|
||||
elif exists tree; then
|
||||
fifo_pager tree --filelimit "$(find . -maxdepth 1 | wc -l)" -L 3 -C -F --dirsfirst --noreport
|
||||
elif exists exa; then
|
||||
exa -G --group-directories-first --colour=always
|
||||
else
|
||||
fifo_pager ls -F --group-directories-first --color=always
|
||||
fi
|
||||
elif [ "${encoding#*)}" = "binary" ]; then
|
||||
handle_mime "$1" "$mimetype" "$ext" "bin"
|
||||
else
|
||||
handle_mime "$1" "$mimetype" "$ext"
|
||||
fi
|
||||
}
|
||||
|
||||
generate_preview() {
|
||||
if [ -n "$QLPATH" ] && stat "$3"; then
|
||||
f="$(wslpath -w "$3")" && "$QLPATH" "$f" &
|
||||
elif [ ! -f "$NNN_PREVIEWDIR/$3.jpg" ] || [ -n "$(find -L "$3" -newer "$NNN_PREVIEWDIR/$3.jpg")" ]; then
|
||||
mkdir -p "$NNN_PREVIEWDIR/${3%/*}"
|
||||
case $4 in
|
||||
audio) ffmpeg -i "$3" -filter_complex "scale=iw*min(1\,min($NNN_PREVIEWWIDTH/iw\,ih)):-1" "$NNN_PREVIEWDIR/$3.jpg" -y ;;
|
||||
epub) gnome-epub-thumbnailer "$3" "$NNN_PREVIEWDIR/$3.jpg" ;;
|
||||
font) fontpreview -i "$3" -o "$NNN_PREVIEWDIR/$3.jpg" ;;
|
||||
gif) if [ -p "$FIFO_UEBERZUG" ] && exists convert; then
|
||||
frameprefix="$NNN_PREVIEWDIR/$3/${3##*/}"
|
||||
if [ ! -d "$NNN_PREVIEWDIR/$3" ]; then
|
||||
mkdir -p "$NNN_PREVIEWDIR/$3"
|
||||
convert -coalesce -resize "$NNN_PREVIEWWIDTH"x"$NNN_PREVIEWHEIGHT"\> "$3" "$frameprefix.jpg" ||
|
||||
MAGICK_TMPDIR="/tmp" convert -coalesce -resize "$NNN_PREVIEWWIDTH"x"$NNN_PREVIEWHEIGHT"\> "$3" "$frameprefix.jpg"
|
||||
fi
|
||||
frames=$(($(find "$NNN_PREVIEWDIR/$3" | wc -l) - 2))
|
||||
[ $frames -lt 0 ] && return
|
||||
while true; do
|
||||
for i in $(seq 0 $frames); do
|
||||
image_preview "$1" "$2" "$frameprefix-$i.jpg"
|
||||
sleep 0.1
|
||||
done
|
||||
done &
|
||||
printf "%s" "$!" > "$PREVIEWPID"
|
||||
return
|
||||
else
|
||||
exec >/dev/tty
|
||||
image_preview "$1" "$2" "$3"
|
||||
return
|
||||
fi ;;
|
||||
image) if exists convert; then
|
||||
convert "$3" -flatten -resize "$NNN_PREVIEWWIDTH"x"$NNN_PREVIEWHEIGHT"\> "$NNN_PREVIEWDIR/$3.jpg"
|
||||
else
|
||||
image_preview "$1" "$2" "$3" && return
|
||||
fi ;;
|
||||
office) libreoffice --convert-to jpg "$3" --outdir "$NNN_PREVIEWDIR/${3%/*}"
|
||||
filename="$(printf "%s" "${3##*/}" | cut -d. -f1)"
|
||||
mv "$NNN_PREVIEWDIR/${3%/*}/$filename.jpg" "$NNN_PREVIEWDIR/$3.jpg" ;;
|
||||
pdf) pdftoppm -jpeg -f 1 -singlefile "$3" "$NNN_PREVIEWDIR/$3" ;;
|
||||
djvu) ddjvu -format=ppm -page=1 "$3" "$NNN_PREVIEWDIR/$3.jpg" ;;
|
||||
video) ffmpegthumbnailer -s0 -i "$3" -o "$NNN_PREVIEWDIR/$3.jpg" || rm "$NNN_PREVIEWDIR/$3.jpg" ;;
|
||||
esac
|
||||
fi
|
||||
if [ -f "$NNN_PREVIEWDIR/$3.jpg" ]; then
|
||||
image_preview "$1" "$2" "$NNN_PREVIEWDIR/$3.jpg"
|
||||
else
|
||||
fifo_pager print_bin_info "$3"
|
||||
fi
|
||||
} >/dev/null 2>&1
|
||||
|
||||
image_preview() {
|
||||
clear
|
||||
if [ "$TERMINAL" = "kitty" ]; then
|
||||
# Kitty terminal users can use the native image preview method
|
||||
kitty +kitten icat --silent --scale-up --place "$1"x"$2"@0x0 --transfer-mode=stream --stdin=no "$3" &
|
||||
elif exists ueberzug; then
|
||||
ueberzug_layer "$1" "$2" "$3" && return
|
||||
elif exists catimg; then
|
||||
catimg "$3" &
|
||||
elif exists viu; then
|
||||
viu -t "$3" &
|
||||
else
|
||||
fifo_pager print_bin_info "$3" && return
|
||||
fi
|
||||
printf "%s" "$!" > "$PREVIEWPID"
|
||||
}
|
||||
|
||||
ueberzug_layer() {
|
||||
[ -f "$POSOFFSET" ] && read -r x y < "$POSOFFSET"
|
||||
printf '{"action": "add", "identifier": "nnn_ueberzug", "x": %d, "y": %d, "width": "%d", "height": "%d", "scaler": "fit_contain", "path": "%s"}\n'\
|
||||
"${x:-0}" "${y:-0}" "$1" "$2" "$3" > "$FIFO_UEBERZUG"
|
||||
}
|
||||
|
||||
ueberzug_remove() {
|
||||
printf '{"action": "remove", "identifier": "nnn_ueberzug"}\n' > "$FIFO_UEBERZUG"
|
||||
}
|
||||
|
||||
winch_handler() {
|
||||
clear
|
||||
pidkill "$PREVIEWPID"
|
||||
if [ -p "$FIFO_UEBERZUG" ]; then
|
||||
pkill -f "tail --follow $FIFO_UEBERZUG"
|
||||
tail --follow "$FIFO_UEBERZUG" | ueberzug layer --silent --parser json &
|
||||
fi
|
||||
preview_file "$(cat "$CURSEL")"
|
||||
}
|
||||
|
||||
preview_fifo() {
|
||||
while read -r selection; do
|
||||
if [ -n "$selection" ]; then
|
||||
pidkill "$PREVIEWPID"
|
||||
[ -p "$FIFO_UEBERZUG" ] && ueberzug_remove
|
||||
[ "$selection" = "close" ] && break
|
||||
preview_file "$selection"
|
||||
printf "%s" "$selection" > "$CURSEL"
|
||||
fi
|
||||
done < "$NNN_FIFO"
|
||||
sleep 0.1 # make sure potential preview by winch_handler is killed
|
||||
pkill -P "$$"
|
||||
}
|
||||
|
||||
if [ "$PREVIEW_MODE" ]; then
|
||||
if [ "$TERMINAL" != "kitty" ] && exists ueberzug; then
|
||||
mkfifo "$FIFO_UEBERZUG"
|
||||
tail --follow "$FIFO_UEBERZUG" | ueberzug layer --silent --parser json &
|
||||
fi
|
||||
|
||||
preview_file "$PWD/$1"
|
||||
preview_fifo &
|
||||
printf "%s" "$!" > "$FIFOPID"
|
||||
printf "%s" "$PWD/$1" > "$CURSEL"
|
||||
trap 'winch_handler; wait' WINCH
|
||||
trap 'rm "$PREVIEWPID" "$CURSEL" "$FIFO_UEBERZUG" "$FIFOPID" "$POSOFFSET" 2>/dev/null' INT HUP EXIT
|
||||
wait "$!" 2>/dev/null
|
||||
exit 0
|
||||
else
|
||||
if [ ! -r "$NNN_FIFO" ]; then
|
||||
clear
|
||||
prompt "No FIFO available! (\$NNN_FIFO='$NNN_FIFO')\nPlease read Usage in preview-tui."
|
||||
elif [ "$KITTY_WINDOW_ID" ] && [ -z "$TMUX" ] && [ -z "$KITTY_LISTEN_ON" ]; then
|
||||
clear
|
||||
prompt "\$KITTY_LISTEN_ON not set!\nPlease read Usage in preview-tui."
|
||||
else
|
||||
toggle_preview "$1" &
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Fuzzy list and kill a (zombie) process by name
|
||||
#
|
||||
# Dependencies: fzf, ps
|
||||
#
|
||||
# Note: To kill a zombie process enter "zombie"
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Arun Prakash Jana
|
||||
|
||||
printf "Enter process name ['defunct' for zombies]: "
|
||||
read -r psname
|
||||
|
||||
# shellcheck disable=SC2009
|
||||
if [ -n "$psname" ]; then
|
||||
if type sudo >/dev/null 2>&1; then
|
||||
sucmd=sudo
|
||||
elif type doas >/dev/null 2>&1; then
|
||||
sucmd=doas
|
||||
else
|
||||
sucmd=: # noop
|
||||
fi
|
||||
|
||||
if type fzf >/dev/null 2>&1; then
|
||||
fuzzy=fzf
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cmd="$(ps -ax | grep -iw "$psname" | "$fuzzy" | sed -e 's/^[ \t]*//' | cut -d' ' -f1)"
|
||||
if [ -n "$cmd" ]; then
|
||||
$sucmd kill -9 "$cmd"
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,45 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Batch rename selection or current directory with qmv or vidir
|
||||
#
|
||||
# Notes:
|
||||
# - Try to mimic current batch rename functionality but with correct
|
||||
# handling of edge cases by qmv or vidir.
|
||||
# - Qmv opens with hidden files if no selection is used. Selected
|
||||
# directories are shown.
|
||||
# - Vidir don't show directories nor hidden files.
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: José Neder
|
||||
|
||||
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
|
||||
|
||||
if type qmv >/dev/null 2>&1; then
|
||||
batchrenamesel="qmv -fdo -da"
|
||||
batchrename="qmv -fdo -a"
|
||||
elif type vidir >/dev/null 2>&1; then
|
||||
batchrenamesel="vidir"
|
||||
batchrename="vidir"
|
||||
else
|
||||
printf "there is not batchrename program installed."
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ -s "$selection" ]; then
|
||||
printf "rename selection? "
|
||||
read -r resp
|
||||
fi
|
||||
|
||||
if [ "$resp" = "y" ]; then
|
||||
# -o flag is necessary for interactive editors
|
||||
xargs -o -0 $batchrenamesel < "$selection"
|
||||
|
||||
# Clear selection
|
||||
if [ -p "$NNN_PIPE" ]; then
|
||||
printf "-" > "$NNN_PIPE"
|
||||
fi
|
||||
elif [ ! "$(LC_ALL=C ls -a)" = ".
|
||||
.." ]; then
|
||||
# On older systems that don't have ls -A
|
||||
$batchrename
|
||||
fi
|
|
@ -0,0 +1,36 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Create an mp3 ringtone out of an audio file in any format
|
||||
# Needs user to provide start and end where to cut the file
|
||||
# Input file audio.ext results in audio_ringtone.mp3
|
||||
#
|
||||
# Tip: To convert a complete media file, set start as 0 and
|
||||
# the runtime of the file as end.
|
||||
#
|
||||
# Dependencies: date, ffmpeg
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Arun Prakash Jana
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
printf "start (hh:mm:ss): "
|
||||
read -r start
|
||||
st=$(date -d "$start" +%s) || exit 1
|
||||
|
||||
printf "end (hh:mm:ss): "
|
||||
read -r end
|
||||
et=$(date -d "$end" +%s) || exit 1
|
||||
|
||||
if [ "$st" -ge "$et" ]; then
|
||||
printf "error: start >= end "
|
||||
read -r _
|
||||
exit 1
|
||||
fi
|
||||
|
||||
interval=$(( et - st ))
|
||||
|
||||
outfile=$(basename "$1")
|
||||
outfile="${outfile%.*}"_ringtone.mp3
|
||||
|
||||
ffmpeg -i "$1" -ss "$start" -t "$interval" -vn -sn -acodec libmp3lame -q:a 2 "$outfile"
|
||||
fi
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Simple script to give copy-paste a progress percentage
|
||||
# by utilizing rsync.
|
||||
#
|
||||
# LIMITATION: this won't work when pasting to MTP device.
|
||||
#
|
||||
# Dependencies: rsync
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Benawi Adha
|
||||
|
||||
sel=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
|
||||
|
||||
# Choose one of these two schemes by commenting
|
||||
|
||||
# more verbose
|
||||
xargs -0 -I % rsync -ah --progress % "$PWD" < "$sel"
|
||||
|
||||
# less verbose
|
||||
# xargs -0 -I % rsync -ah --info=progress2 % "$PWD" < "$sel"
|
||||
|
||||
# Clear selection
|
||||
if [ -p "$NNN_PIPE" ]; then
|
||||
printf "-" > "$NNN_PIPE"
|
||||
fi
|
|
@ -0,0 +1,52 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Splits the file passed as argument or joins selection
|
||||
#
|
||||
# Note: Adds numeric suffix to split files
|
||||
# Adds '.out suffix to the first file to be joined and saves as output file for join
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Authors: Arun Prakash Jana, ath3
|
||||
|
||||
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
|
||||
resp=s
|
||||
|
||||
if [ -s "$selection" ]; then
|
||||
printf "press 's' (split current file) or 'j' (join selection): "
|
||||
read -r resp
|
||||
fi
|
||||
|
||||
if [ "$resp" = "j" ]; then
|
||||
if [ -s "$selection" ]; then
|
||||
arr=$(tr '\0' '\n' < "$selection")
|
||||
if [ "$(echo "$arr" | wc -l)" -lt 2 ]; then
|
||||
echo "joining needs at least 2 files"
|
||||
exit
|
||||
fi
|
||||
for entry in $arr
|
||||
do
|
||||
if [ -d "$entry" ]; then
|
||||
echo "cant join directories"
|
||||
exit
|
||||
fi
|
||||
done
|
||||
|
||||
file="$(basename "$(echo "$arr" | sed -n '1p' | sed -e 's/[0-9][0-9]$//')")"
|
||||
sort -z < "$selection" | xargs -0 -I{} cat {} > "${file}.out"
|
||||
|
||||
# Clear selection
|
||||
if [ -p "$NNN_PIPE" ]; then
|
||||
printf "-" > "$NNN_PIPE"
|
||||
fi
|
||||
fi
|
||||
elif [ "$resp" = "s" ]; then
|
||||
if [ -n "$1" ] && [ -f "$1" ]; then
|
||||
# a single file is passed
|
||||
printf "split size in MB: "
|
||||
read -r size
|
||||
|
||||
if [ -n "$size" ]; then
|
||||
split -d -b "$size"M "$1" "$1"
|
||||
fi
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,16 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Edit file as superuser
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Anna Arad
|
||||
|
||||
EDITOR="${EDITOR:-vim}"
|
||||
|
||||
if type sudo >/dev/null 2>&1; then
|
||||
sudo -E "$EDITOR" "$1"
|
||||
elif type sudoedit >/dev/null 2>&1; then
|
||||
sudoedit -E "$1"
|
||||
elif type doas >/dev/null 2>&1; then
|
||||
doas "$EDITOR" "$1"
|
||||
fi
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Toggles executable mode for selection
|
||||
#
|
||||
# Dependencies: chmod
|
||||
#
|
||||
# Note: Works _only_ with selection (nnn can toggle the mode for the hovered file)
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Arun Prakash Jana
|
||||
|
||||
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
|
||||
|
||||
if [ -s "$selection" ]; then
|
||||
xargs -0 -I {} sh -c 'if [ -x "{}" ] ; then chmod -x "{}" ; else chmod +x "{}" ; fi' < "$selection"
|
||||
|
||||
# Clear selection
|
||||
if [ -p "$NNN_PIPE" ]; then
|
||||
printf "-" > "$NNN_PIPE"
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,52 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Autodetects a nnn remote mountpoint (mounted with `c`)
|
||||
# from any of its subfolders and allows unmounting it
|
||||
# from the subdir without navigating to the mountppoint
|
||||
# or entering the remote name. Also works when hovering
|
||||
# the mountpoint directly like vanilla `u`.
|
||||
#
|
||||
# Dependencies: fusermount
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Authors: Kabouik & 0xACE
|
||||
#
|
||||
# TODO:
|
||||
# - Avoid lazy unmount by forcing nnn context to leave the subfolder before fusermount.
|
||||
# Tried `printf "%s" "0c$m" > "$NNN_PIPE"` but it breaks the nnn interface, see #854.
|
||||
|
||||
err=0
|
||||
m=$HOME/.config/nnn/mounts
|
||||
if [ "$PWD" = "$m" ]; then
|
||||
# Allow running the script on hovered directory if user is in ~/.config/nnn/mounts
|
||||
d="$1"
|
||||
else
|
||||
d=$(dirname "$(readlink -f "$1")" | grep -oP "^$m\K.*" | cut -d"/" -f2)
|
||||
fi
|
||||
|
||||
# Test if user is within $m or a subdir, abort if not
|
||||
if [ "$d" = "" ]; then
|
||||
clear && printf "You are not in a remote folder mounted with nnn. Press return to continue. " && read -r _
|
||||
else
|
||||
# Test if $m/$d is a mountpoint and try unmounting if it is
|
||||
mountpoint -q -- "$m/$d"
|
||||
if [ "$?" -eq "1" ]; then
|
||||
clear && printf "Parent '%s' is not a mountpoint. Press return to continue. " "$d" && read -r _
|
||||
else
|
||||
cd "$m" && fusermount -uq "$m/$d" || err=1
|
||||
if [ "$err" -eq "0" ]; then
|
||||
rmdir "$m/$d" && clear && printf "Parent '%s' unmounted." "$d"
|
||||
else
|
||||
clear && printf "Failed to unmount. Try lazy unmount? [Yy/Nn] " && read -r
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# If unmount fails, offer lazy unmount
|
||||
if [ "$REPLY" = "y" ] || [ "$REPLY" = "Y" ]; then
|
||||
err=0
|
||||
cd "$m" && fusermount -uqz "$m/$d" || err=1
|
||||
if [ "$err" -eq "0" ]; then
|
||||
rmdir "$m/$d" && clear && printf "Parent '%s' unmounted with lazy unmount. " "$d"
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Upload to Firefox Send if ffsend is found, else
|
||||
# Paste contents of a text a file http://ix.io
|
||||
# Upload a binary file to file.io
|
||||
#
|
||||
# Dependencies: ffsend (https://github.com/timvisee/ffsend), curl, jq, tr
|
||||
#
|
||||
# Note: Binary file set to expire after a week
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Arun Prakash Jana
|
||||
|
||||
if [ -n "$1" ] && [ -s "$1" ]; then
|
||||
if type ffsend >/dev/null 2>&1; then
|
||||
ffsend -fiq u "$1"
|
||||
elif [ "$(mimetype --output-format %m "$1" | awk -F '/' '{print $1}')" = "text" ]; then
|
||||
curl -F "f:1=@$1" ix.io
|
||||
else
|
||||
# Upload the file, show the download link and wait till user presses any key
|
||||
curl -s -F "file=@$1" https://file.io/?expires=1w | jq '.link' | tr -d '"'
|
||||
|
||||
# To write download link to "$1".loc and exit
|
||||
# curl -s -F "file=@$1" https://file.io/?expires=1w -o `basename "$1"`.loc
|
||||
fi
|
||||
else
|
||||
printf "empty file!"
|
||||
fi
|
||||
|
||||
read -r _
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Set the selected image as wallpaper using nitrogen or pywal.
|
||||
#
|
||||
# Usage: Hover on an image and run the script to set it as wallpaper.
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: juacq97
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
if [ "$(file --mime-type "$1" | awk '{print $NF}' | awk -F '/' '{print $1}')" = "image" ]; then
|
||||
if type nitrogen >/dev/null 2>&1; then
|
||||
nitrogen --set-zoom-fill --save "$1"
|
||||
elif type wal >/dev/null 2>&1; then
|
||||
wal -i "$1"
|
||||
else
|
||||
printf "nitrogen or pywal missing"
|
||||
read -r _
|
||||
fi
|
||||
|
||||
# If you want a system notification, uncomment the next 3 lines.
|
||||
# notify-send -a "nnn" "Wallpaper changed!"
|
||||
# else
|
||||
# notify-send -a "nnn" "No image selected"
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Copy system clipboard newline-separated file list to selection
|
||||
#
|
||||
# Dependencies:
|
||||
# - tr
|
||||
# - xclip/xsel (Linux)
|
||||
# - pbpaste (macOS)
|
||||
# - termux-clipboard-get (Termux)
|
||||
# - powershell (WSL)
|
||||
# - cygwim's /dev/clipboard (Cygwin)
|
||||
# - wl-paste (Wayland)
|
||||
# - clipboard (Haiku)
|
||||
#
|
||||
# Note:
|
||||
# - Limitation: breaks if a filename has newline in it
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: Léo Villeveygoux, after Arun Prakash Jana's .cbcp
|
||||
|
||||
IFS="$(printf '%b_' '\n')"; IFS="${IFS%_}" # protect trailing \n
|
||||
|
||||
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
|
||||
|
||||
getclip () {
|
||||
if type xsel >/dev/null 2>&1; then
|
||||
# Linux
|
||||
xsel -bo
|
||||
elif type xclip >/dev/null 2>&1; then
|
||||
# Linux
|
||||
xclip -sel clip -o
|
||||
elif type pbpaste >/dev/null 2>&1; then
|
||||
# macOS
|
||||
pbpaste
|
||||
elif type termux-clipboard-get >/dev/null 2>&1; then
|
||||
# Termux
|
||||
termux-clipboard-get
|
||||
elif type powershell.exe >/dev/null 2>&1; then
|
||||
# WSL
|
||||
powershell.exe Get-Clipboard
|
||||
elif [ -r /dev/clipboard ] ; then
|
||||
# Cygwin
|
||||
cat /dev/clipboard
|
||||
elif type wl-paste >/dev/null 2>&1; then
|
||||
# Wayland
|
||||
wl-paste
|
||||
elif type clipboard >/dev/null 2>&1; then
|
||||
# Haiku
|
||||
clipboard --print
|
||||
fi
|
||||
}
|
||||
|
||||
CLIPBOARD=$(getclip)
|
||||
|
||||
# Check if clipboard actually contains a file list
|
||||
for file in $CLIPBOARD ; do
|
||||
if [ ! -e "$file" ] ; then
|
||||
exit 1;
|
||||
fi
|
||||
done
|
||||
|
||||
printf "%s" "$CLIPBOARD" | tr '\n' '\0' > "$selection"
|
|
@ -0,0 +1,53 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# Description: Sets the xdg-open's default application for the current entry's file
|
||||
# type. ${XDG_DATA_DIRS} and ${XDG_DATA_HOME} are set to the recommended
|
||||
# defaults if unset, as specified in XDG Base Directory Specification
|
||||
# - http://specifications.freedesktop.org/basedir-spec/.
|
||||
#
|
||||
# Dependencies: xdg-utils, fzf or dmenu (GUI)
|
||||
#
|
||||
# Shell: POSIX compliant
|
||||
# Author: lwnctd
|
||||
|
||||
# set to 1 to enable GUI apps
|
||||
GUI="${GUI:-0}"
|
||||
|
||||
if [ "$GUI" -ne 0 ] && command -v dmenu > /dev/null 2>& 1; then
|
||||
menu="dmenu -i -l 7"
|
||||
elif command -v fzf > /dev/null 2>& 1; then
|
||||
menu="fzf -e --tiebreak=begin"
|
||||
fi
|
||||
|
||||
if [ -z "$1" ] || [ -z "$menu" ] > /dev/null 2>& 1; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ftype=$(xdg-mime query filetype "$2/$1")
|
||||
|
||||
if [ -z "$ftype" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dirs=${XDG_DATA_DIRS:-/usr/local/share:/usr/share}
|
||||
dirs=${dirs}:${XDG_DATA_HOME:-$HOME/.local/share}:
|
||||
|
||||
while [ -n "$dirs" ]; do
|
||||
d=${dirs%%:*}
|
||||
if [ -n "$d" ] && [ -d "$d"/applications ]; then
|
||||
set -- "$@" "$d"/applications
|
||||
fi
|
||||
dirs=${dirs#*:}
|
||||
done
|
||||
|
||||
app=$(find "$@" -iname '*.desktop' -exec grep '^Name=' {} + \
|
||||
| sort -u -t ':' -k 1,1 \
|
||||
| sed -e 's;..*/\(..*desktop\):Name=\(..*\);\2:\1;' \
|
||||
| sort -t ':' -k 1,1 \
|
||||
| column -t -s ':' -o "$(printf '\t')" \
|
||||
| $menu \
|
||||
| cut -f 2)
|
||||
|
||||
if [ -n "$app" ]; then
|
||||
xdg-mime default "${app%%[[:blank:]]*}" "$ftype"
|
||||
fi
|
|
@ -0,0 +1,10 @@
|
|||
# If a config.py file exists, this file is ignored unless it's explicitly loaded
|
||||
# via config.load_autoconfig(). For more information, see:
|
||||
# https://github.com/qutebrowser/qutebrowser/blob/master/doc/help/configuring.asciidoc#loading-autoconfigyml
|
||||
# DO NOT edit this file by hand, qutebrowser will overwrite it.
|
||||
# Instead, create a config.py - see :help for details.
|
||||
|
||||
config_version: 2
|
||||
settings:
|
||||
content.media.video_capture:
|
||||
https://meet.google.com: true
|
|
@ -0,0 +1,527 @@
|
|||
# Autogenerated config.py
|
||||
#
|
||||
# NOTE: config.py is intended for advanced users who are comfortable
|
||||
# with manually migrating the config file on qutebrowser upgrades. If
|
||||
# you prefer, you can also configure qutebrowser using the
|
||||
# :set/:bind/:config-* commands without having to write a config.py
|
||||
# file.
|
||||
#
|
||||
# Documentation:
|
||||
# qute://help/configuring.html
|
||||
# qute://help/settings.html
|
||||
|
||||
# Change the argument to True to still load settings configured via autoconfig.yml
|
||||
config.load_autoconfig(False)
|
||||
|
||||
# Which cookies to accept. With QtWebEngine, this setting also controls
|
||||
# other features with tracking capabilities similar to those of cookies;
|
||||
# including IndexedDB, DOM storage, filesystem API, service workers, and
|
||||
# AppCache. Note that with QtWebKit, only `all` and `never` are
|
||||
# supported as per-domain values. Setting `no-3rdparty` or `no-
|
||||
# unknown-3rdparty` per-domain on QtWebKit will have the same effect as
|
||||
# `all`. If this setting is used with URL patterns, the pattern gets
|
||||
# applied to the origin/first party URL of the page making the request,
|
||||
# not the request URL. With QtWebEngine 5.15.0+, paths will be stripped
|
||||
# from URLs, so URL patterns using paths will not match. With
|
||||
# QtWebEngine 5.15.2+, subdomains are additionally stripped as well, so
|
||||
# you will typically need to set this setting for `example.com` when the
|
||||
# cookie is set on `somesubdomain.example.com` for it to work properly.
|
||||
# To debug issues with this setting, start qutebrowser with `--debug
|
||||
# --logfilter network --debug-flag log-cookies` which will show all
|
||||
# cookies being set.
|
||||
# Type: String
|
||||
# Valid values:
|
||||
# - all: Accept all cookies.
|
||||
# - no-3rdparty: Accept cookies from the same origin only. This is known to break some sites, such as GMail.
|
||||
# - no-unknown-3rdparty: Accept cookies from the same origin only, unless a cookie is already set for the domain. On QtWebEngine, this is the same as no-3rdparty.
|
||||
# - never: Don't accept cookies at all.
|
||||
config.set('content.cookies.accept', 'all', 'chrome-devtools://*')
|
||||
|
||||
# Which cookies to accept. With QtWebEngine, this setting also controls
|
||||
# other features with tracking capabilities similar to those of cookies;
|
||||
# including IndexedDB, DOM storage, filesystem API, service workers, and
|
||||
# AppCache. Note that with QtWebKit, only `all` and `never` are
|
||||
# supported as per-domain values. Setting `no-3rdparty` or `no-
|
||||
# unknown-3rdparty` per-domain on QtWebKit will have the same effect as
|
||||
# `all`. If this setting is used with URL patterns, the pattern gets
|
||||
# applied to the origin/first party URL of the page making the request,
|
||||
# not the request URL. With QtWebEngine 5.15.0+, paths will be stripped
|
||||
# from URLs, so URL patterns using paths will not match. With
|
||||
# QtWebEngine 5.15.2+, subdomains are additionally stripped as well, so
|
||||
# you will typically need to set this setting for `example.com` when the
|
||||
# cookie is set on `somesubdomain.example.com` for it to work properly.
|
||||
# To debug issues with this setting, start qutebrowser with `--debug
|
||||
# --logfilter network --debug-flag log-cookies` which will show all
|
||||
# cookies being set.
|
||||
# Type: String
|
||||
# Valid values:
|
||||
# - all: Accept all cookies.
|
||||
# - no-3rdparty: Accept cookies from the same origin only. This is known to break some sites, such as GMail.
|
||||
# - no-unknown-3rdparty: Accept cookies from the same origin only, unless a cookie is already set for the domain. On QtWebEngine, this is the same as no-3rdparty.
|
||||
# - never: Don't accept cookies at all.
|
||||
config.set('content.cookies.accept', 'all', 'devtools://*')
|
||||
|
||||
# Value to send in the `Accept-Language` header. Note that the value
|
||||
# read from JavaScript is always the global value.
|
||||
# Type: String
|
||||
config.set('content.headers.accept_language', '', 'https://matchmaker.krunker.io/*')
|
||||
|
||||
# User agent to send. The following placeholders are defined: *
|
||||
# `{os_info}`: Something like "X11; Linux x86_64". * `{webkit_version}`:
|
||||
# The underlying WebKit version (set to a fixed value with
|
||||
# QtWebEngine). * `{qt_key}`: "Qt" for QtWebKit, "QtWebEngine" for
|
||||
# QtWebEngine. * `{qt_version}`: The underlying Qt version. *
|
||||
# `{upstream_browser_key}`: "Version" for QtWebKit, "Chrome" for
|
||||
# QtWebEngine. * `{upstream_browser_version}`: The corresponding
|
||||
# Safari/Chrome version. * `{qutebrowser_version}`: The currently
|
||||
# running qutebrowser version. The default value is equal to the
|
||||
# unchanged user agent of QtWebKit/QtWebEngine. Note that the value
|
||||
# read from JavaScript is always the global value. With QtWebEngine
|
||||
# between 5.12 and 5.14 (inclusive), changing the value exposed to
|
||||
# JavaScript requires a restart.
|
||||
# Type: FormatString
|
||||
config.set('content.headers.user_agent', 'Mozilla/5.0 ({os_info}) AppleWebKit/{webkit_version} (KHTML, like Gecko) {upstream_browser_key}/{upstream_browser_version} Safari/{webkit_version}', 'https://web.whatsapp.com/')
|
||||
|
||||
# User agent to send. The following placeholders are defined: *
|
||||
# `{os_info}`: Something like "X11; Linux x86_64". * `{webkit_version}`:
|
||||
# The underlying WebKit version (set to a fixed value with
|
||||
# QtWebEngine). * `{qt_key}`: "Qt" for QtWebKit, "QtWebEngine" for
|
||||
# QtWebEngine. * `{qt_version}`: The underlying Qt version. *
|
||||
# `{upstream_browser_key}`: "Version" for QtWebKit, "Chrome" for
|
||||
# QtWebEngine. * `{upstream_browser_version}`: The corresponding
|
||||
# Safari/Chrome version. * `{qutebrowser_version}`: The currently
|
||||
# running qutebrowser version. The default value is equal to the
|
||||
# unchanged user agent of QtWebKit/QtWebEngine. Note that the value
|
||||
# read from JavaScript is always the global value. With QtWebEngine
|
||||
# between 5.12 and 5.14 (inclusive), changing the value exposed to
|
||||
# JavaScript requires a restart.
|
||||
# Type: FormatString
|
||||
config.set('content.headers.user_agent', 'Mozilla/5.0 ({os_info}; rv:90.0) Gecko/20100101 Firefox/90.0', 'https://accounts.google.com/*')
|
||||
|
||||
# User agent to send. The following placeholders are defined: *
|
||||
# `{os_info}`: Something like "X11; Linux x86_64". * `{webkit_version}`:
|
||||
# The underlying WebKit version (set to a fixed value with
|
||||
# QtWebEngine). * `{qt_key}`: "Qt" for QtWebKit, "QtWebEngine" for
|
||||
# QtWebEngine. * `{qt_version}`: The underlying Qt version. *
|
||||
# `{upstream_browser_key}`: "Version" for QtWebKit, "Chrome" for
|
||||
# QtWebEngine. * `{upstream_browser_version}`: The corresponding
|
||||
# Safari/Chrome version. * `{qutebrowser_version}`: The currently
|
||||
# running qutebrowser version. The default value is equal to the
|
||||
# unchanged user agent of QtWebKit/QtWebEngine. Note that the value
|
||||
# read from JavaScript is always the global value. With QtWebEngine
|
||||
# between 5.12 and 5.14 (inclusive), changing the value exposed to
|
||||
# JavaScript requires a restart.
|
||||
# Type: FormatString
|
||||
config.set('content.headers.user_agent', 'Mozilla/5.0 ({os_info}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99 Safari/537.36', 'https://*.slack.com/*')
|
||||
|
||||
# Load images automatically in web pages.
|
||||
# Type: Bool
|
||||
config.set('content.images', True, 'chrome-devtools://*')
|
||||
|
||||
# Load images automatically in web pages.
|
||||
# Type: Bool
|
||||
config.set('content.images', True, 'devtools://*')
|
||||
|
||||
# Enable JavaScript.
|
||||
# Type: Bool
|
||||
config.set('content.javascript.enabled', True, 'chrome-devtools://*')
|
||||
|
||||
# Enable JavaScript.
|
||||
# Type: Bool
|
||||
config.set('content.javascript.enabled', True, 'devtools://*')
|
||||
|
||||
# Enable JavaScript.
|
||||
# Type: Bool
|
||||
config.set('content.javascript.enabled', True, 'chrome://*/*')
|
||||
|
||||
# Enable JavaScript.
|
||||
# Type: Bool
|
||||
config.set('content.javascript.enabled', True, 'qute://*/*')
|
||||
|
||||
#####################################################################################
|
||||
#Configuraciones personales DiegoFcs
|
||||
#####################################################################################
|
||||
|
||||
#Configuraciones de tipos de letra#
|
||||
|
||||
# Default font families to use. Whenever "default_family" is used in a
|
||||
# font setting, it's replaced with the fonts listed here. If set to an
|
||||
# empty value, a system-specific monospace default is used.
|
||||
# Type: List of Font, or Font
|
||||
c.fonts.default_family = '"Hack Nerd Font"'
|
||||
|
||||
# Default font size to use. Whenever "default_size" is used in a font
|
||||
# setting, it's replaced with the size listed here. Valid values are
|
||||
# either a float value with a "pt" suffix, or an integer value with a
|
||||
# "px" suffix.
|
||||
# Type: String
|
||||
c.fonts.default_size = '8pt'
|
||||
|
||||
# Font used in the completion widget.
|
||||
# Type: Font
|
||||
c.fonts.completion.entry = '8pt "Hack Nerd Font"'
|
||||
|
||||
# Font used for the debugging console.
|
||||
# Type: Font
|
||||
c.fonts.debug_console = '8pt "Hack Nerd Font"'
|
||||
|
||||
# Font used for prompts.
|
||||
# Type: Font
|
||||
c.fonts.prompts = '8pt "Hack Nerd Font"'
|
||||
|
||||
# Font used in the statusbar.
|
||||
# Type: Font
|
||||
c.fonts.statusbar = '8pt "Hack Nerd Font"'
|
||||
|
||||
#Configuracion de pagina de inicio#
|
||||
|
||||
# Setting default page for when opening new tabs or new windows with
|
||||
# commands like :open -t and :open -w .
|
||||
c.url.default_page = 'file:///home/diegofcs/.config/startpages/term/index.html'
|
||||
c.url.start_pages = 'file:///home/diegofcs/.config/startpages/term/index.html'
|
||||
|
||||
#Configuracion de la visibilidad de las tabs#
|
||||
|
||||
# When to show the tab bar.
|
||||
# Type: String
|
||||
# Valid values:
|
||||
# - always: Always show the tab bar.
|
||||
# - never: Always hide the tab bar.
|
||||
# - multiple: Hide the tab bar if only one tab is open.
|
||||
# - switching: Show the tab bar when switching tabs.
|
||||
c.tabs.show = 'switching'
|
||||
|
||||
#Configuracion de descargas#
|
||||
|
||||
# Directory to save downloads to. If unset, a sensible OS-specific
|
||||
# default is used.
|
||||
# Type: Directory
|
||||
c.downloads.location.directory = '~/Descargas'
|
||||
c.downloads.location.prompt = False
|
||||
c.downloads.remove_finished = 500
|
||||
|
||||
#Configuracion de color#
|
||||
|
||||
# base16-qutebrowser (https://github.com/theova/base16-qutebrowser)
|
||||
# Base16 qutebrowser template by theova
|
||||
# Grayscale Dark scheme by Alexandre Gavioli (https://github.com/Alexx2/)
|
||||
|
||||
# set qutebrowser colors
|
||||
|
||||
# Text color of the completion widget. May be a single color to use for
|
||||
# all columns or a list of three colors, one for each column.
|
||||
c.colors.completion.fg = "#b9b9b9"
|
||||
|
||||
# Background color of the completion widget for odd rows.
|
||||
c.colors.completion.odd.bg = "#252525"
|
||||
|
||||
# Background color of the completion widget for even rows.
|
||||
c.colors.completion.even.bg = "#101010"
|
||||
|
||||
# Foreground color of completion widget category headers.
|
||||
c.colors.completion.category.fg = "#a0a0a0"
|
||||
|
||||
# Background color of the completion widget category headers.
|
||||
c.colors.completion.category.bg = "#101010"
|
||||
|
||||
# Top border color of the completion widget category headers.
|
||||
c.colors.completion.category.border.top = "#101010"
|
||||
|
||||
# Bottom border color of the completion widget category headers.
|
||||
c.colors.completion.category.border.bottom = "#101010"
|
||||
|
||||
# Foreground color of the selected completion item.
|
||||
c.colors.completion.item.selected.fg = "#b9b9b9"
|
||||
|
||||
# Background color of the selected completion item.
|
||||
c.colors.completion.item.selected.bg = "#464646"
|
||||
|
||||
# Top border color of the selected completion item.
|
||||
c.colors.completion.item.selected.border.top = "#464646"
|
||||
|
||||
# Bottom border color of the selected completion item.
|
||||
c.colors.completion.item.selected.border.bottom = "#464646"
|
||||
|
||||
# Foreground color of the matched text in the selected completion item.
|
||||
c.colors.completion.item.selected.match.fg = "#8e8e8e"
|
||||
|
||||
# Foreground color of the matched text in the completion.
|
||||
c.colors.completion.match.fg = "#8e8e8e"
|
||||
|
||||
# Color of the scrollbar handle in the completion view.
|
||||
c.colors.completion.scrollbar.fg = "#b9b9b9"
|
||||
|
||||
# Color of the scrollbar in the completion view.
|
||||
c.colors.completion.scrollbar.bg = "#101010"
|
||||
|
||||
# Background color of disabled items in the context menu.
|
||||
c.colors.contextmenu.disabled.bg = "#252525"
|
||||
|
||||
# Foreground color of disabled items in the context menu.
|
||||
c.colors.contextmenu.disabled.fg = "#ababab"
|
||||
|
||||
# Background color of the context menu. If set to null, the Qt default is used.
|
||||
c.colors.contextmenu.menu.bg = "#101010"
|
||||
|
||||
# Foreground color of the context menu. If set to null, the Qt default is used.
|
||||
c.colors.contextmenu.menu.fg = "#b9b9b9"
|
||||
|
||||
# Background color of the context menu’s selected item. If set to null, the Qt default is used.
|
||||
c.colors.contextmenu.selected.bg = "#464646"
|
||||
|
||||
#Foreground color of the context menu’s selected item. If set to null, the Qt default is used.
|
||||
c.colors.contextmenu.selected.fg = "#b9b9b9"
|
||||
|
||||
# Background color for the download bar.
|
||||
c.colors.downloads.bar.bg = "#101010"
|
||||
|
||||
# Color gradient start for download text.
|
||||
c.colors.downloads.start.fg = "#101010"
|
||||
|
||||
# Color gradient start for download backgrounds.
|
||||
c.colors.downloads.start.bg = "#686868"
|
||||
|
||||
# Color gradient end for download text.
|
||||
c.colors.downloads.stop.fg = "#101010"
|
||||
|
||||
# Color gradient stop for download backgrounds.
|
||||
c.colors.downloads.stop.bg = "#868686"
|
||||
|
||||
# Foreground color for downloads with errors.
|
||||
c.colors.downloads.error.fg = "#7c7c7c"
|
||||
|
||||
# Font color for hints.
|
||||
c.colors.hints.fg = "#101010"
|
||||
|
||||
# Foreground color of the URL in the statusbar when there's a warning.
|
||||
# Type: QssColor
|
||||
c.colors.statusbar.url.warn.fg = "#7c7c7c"
|
||||
|
||||
#hints.border
|
||||
#CSS border value for hints.
|
||||
#Type: String
|
||||
c.hints.border = "#101010"
|
||||
|
||||
# Background color for hints. Note that you can use a `rgba(...)` value
|
||||
# for transparency.
|
||||
c.colors.hints.bg = "#a0a0a0"
|
||||
|
||||
# Font color for the matched part of hints.
|
||||
c.colors.hints.match.fg = "#b9b9b9"
|
||||
|
||||
# Text color for the keyhint widget.
|
||||
c.colors.keyhint.fg = "#b9b9b9"
|
||||
|
||||
# Highlight color for keys to complete the current keychain.
|
||||
c.colors.keyhint.suffix.fg = "#b9b9b9"
|
||||
|
||||
# Background color of the keyhint widget.
|
||||
c.colors.keyhint.bg = "#101010"
|
||||
|
||||
# Foreground color of an error message.
|
||||
c.colors.messages.error.fg = "#101010"
|
||||
|
||||
# Background color of an error message.
|
||||
c.colors.messages.error.bg = "#7c7c7c"
|
||||
|
||||
# Border color of an error message.
|
||||
c.colors.messages.error.border = "#7c7c7c"
|
||||
|
||||
# Foreground color of a warning message.
|
||||
c.colors.messages.warning.fg = "#101010"
|
||||
|
||||
# Background color of a warning message.
|
||||
c.colors.messages.warning.bg = "#747474"
|
||||
|
||||
# Border color of a warning message.
|
||||
c.colors.messages.warning.border = "#747474"
|
||||
|
||||
# Foreground color of an info message.
|
||||
c.colors.messages.info.fg = "#b9b9b9"
|
||||
|
||||
# Background color of an info message.
|
||||
c.colors.messages.info.bg = "#101010"
|
||||
|
||||
# Border color of an info message.
|
||||
c.colors.messages.info.border = "#101010"
|
||||
|
||||
# Foreground color for prompts.
|
||||
c.colors.prompts.fg = "#b9b9b9"
|
||||
|
||||
# Border used around UI elements in prompts.
|
||||
c.colors.prompts.border = "#101010"
|
||||
|
||||
# Background color for prompts.
|
||||
c.colors.prompts.bg = "#101010"
|
||||
|
||||
# Background color for the selected item in filename prompts.
|
||||
c.colors.prompts.selected.bg = "#464646"
|
||||
|
||||
# Foreground color for the selected item in filename prompts.
|
||||
c.colors.prompts.selected.fg = "#b9b9b9"
|
||||
|
||||
# Foreground color of the statusbar.
|
||||
c.colors.statusbar.normal.fg = "#8e8e8e"
|
||||
|
||||
# Background color of the statusbar.
|
||||
c.colors.statusbar.normal.bg = "#101010"
|
||||
|
||||
# Foreground color of the statusbar in insert mode.
|
||||
c.colors.statusbar.insert.fg = "#101010"
|
||||
|
||||
# Background color of the statusbar in insert mode.
|
||||
c.colors.statusbar.insert.bg = "#686868"
|
||||
|
||||
# Foreground color of the statusbar in passthrough mode.
|
||||
c.colors.statusbar.passthrough.fg = "#101010"
|
||||
|
||||
# Background color of the statusbar in passthrough mode.
|
||||
c.colors.statusbar.passthrough.bg = "#868686"
|
||||
|
||||
# Foreground color of the statusbar in private browsing mode.
|
||||
c.colors.statusbar.private.fg = "#101010"
|
||||
|
||||
# Background color of the statusbar in private browsing mode.
|
||||
c.colors.statusbar.private.bg = "#252525"
|
||||
|
||||
# Foreground color of the statusbar in command mode.
|
||||
c.colors.statusbar.command.fg = "#b9b9b9"
|
||||
|
||||
# Background color of the statusbar in command mode.
|
||||
c.colors.statusbar.command.bg = "#101010"
|
||||
|
||||
# Foreground color of the statusbar in private browsing + command mode.
|
||||
c.colors.statusbar.command.private.fg = "#b9b9b9"
|
||||
|
||||
# Background color of the statusbar in private browsing + command mode.
|
||||
c.colors.statusbar.command.private.bg = "#101010"
|
||||
|
||||
# Foreground color of the statusbar in caret mode.
|
||||
c.colors.statusbar.caret.fg = "#101010"
|
||||
|
||||
# Background color of the statusbar in caret mode.
|
||||
c.colors.statusbar.caret.bg = "#747474"
|
||||
|
||||
# Foreground color of the statusbar in caret mode with a selection.
|
||||
c.colors.statusbar.caret.selection.fg = "#101010"
|
||||
|
||||
# Background color of the statusbar in caret mode with a selection.
|
||||
c.colors.statusbar.caret.selection.bg = "#686868"
|
||||
|
||||
# Background color of the progress bar.
|
||||
c.colors.statusbar.progress.bg = "#686868"
|
||||
|
||||
# Default foreground color of the URL in the statusbar.
|
||||
c.colors.statusbar.url.fg = "#b9b9b9"
|
||||
|
||||
# Foreground color of the URL in the statusbar on error.
|
||||
c.colors.statusbar.url.error.fg = "#7c7c7c"
|
||||
|
||||
# Foreground color of the URL in the statusbar for hovered links.
|
||||
c.colors.statusbar.url.hover.fg = "#b9b9b9"
|
||||
|
||||
# Foreground color of the URL in the statusbar on successful load
|
||||
# (http).
|
||||
c.colors.statusbar.url.success.http.fg = "#868686"
|
||||
|
||||
# Foreground color of the URL in the statusbar on successful load
|
||||
# (https).
|
||||
c.colors.statusbar.url.success.https.fg = "#8e8e8e"
|
||||
|
||||
# Foreground color of the URL in the statusbar when there's a warning.
|
||||
c.colors.statusbar.url.warn.fg = "#747474"
|
||||
|
||||
# Background color of the tab bar.
|
||||
c.colors.tabs.bar.bg = "#101010"
|
||||
|
||||
# Color gradient start for the tab indicator.
|
||||
c.colors.tabs.indicator.start = "#686868"
|
||||
|
||||
# Color gradient end for the tab indicator.
|
||||
c.colors.tabs.indicator.stop = "#868686"
|
||||
|
||||
# Color for the tab indicator on errors.
|
||||
c.colors.tabs.indicator.error = "#7c7c7c"
|
||||
|
||||
# Foreground color of unselected odd tabs.
|
||||
c.colors.tabs.odd.fg = "#b9b9b9"
|
||||
|
||||
# Background color of unselected odd tabs.
|
||||
c.colors.tabs.odd.bg = "#252525"
|
||||
|
||||
# Foreground color of unselected even tabs.
|
||||
c.colors.tabs.even.fg = "#b9b9b9"
|
||||
|
||||
# Background color of unselected even tabs.
|
||||
c.colors.tabs.even.bg = "#101010"
|
||||
|
||||
# Background color of pinned unselected even tabs.
|
||||
c.colors.tabs.pinned.even.bg = "#868686"
|
||||
|
||||
# Foreground color of pinned unselected even tabs.
|
||||
c.colors.tabs.pinned.even.fg = "#f7f7f7"
|
||||
|
||||
# Background color of pinned unselected odd tabs.
|
||||
c.colors.tabs.pinned.odd.bg = "#8e8e8e"
|
||||
|
||||
# Foreground color of pinned unselected odd tabs.
|
||||
c.colors.tabs.pinned.odd.fg = "#f7f7f7"
|
||||
|
||||
# Background color of pinned selected even tabs.
|
||||
c.colors.tabs.pinned.selected.even.bg = "#464646"
|
||||
|
||||
# Foreground color of pinned selected even tabs.
|
||||
c.colors.tabs.pinned.selected.even.fg = "#b9b9b9"
|
||||
|
||||
# Background color of pinned selected odd tabs.
|
||||
c.colors.tabs.pinned.selected.odd.bg = "#464646"
|
||||
|
||||
# Foreground color of pinned selected odd tabs.
|
||||
c.colors.tabs.pinned.selected.odd.fg = "#b9b9b9"
|
||||
|
||||
# Foreground color of selected odd tabs.
|
||||
c.colors.tabs.selected.odd.fg = "#b9b9b9"
|
||||
|
||||
# Background color of selected odd tabs.
|
||||
c.colors.tabs.selected.odd.bg = "#464646"
|
||||
|
||||
# Foreground color of selected even tabs.
|
||||
c.colors.tabs.selected.even.fg = "#b9b9b9"
|
||||
|
||||
# Background color of selected even tabs.
|
||||
c.colors.tabs.selected.even.bg = "#464646"
|
||||
|
||||
# Background color for webpages if unset (or empty to use the theme's
|
||||
# color).
|
||||
c.colors.webpage.bg = "#101010"
|
||||
|
||||
# Text color of the completion widget. May be a single color to use for
|
||||
# all columns or a list of three colors, one for each column.
|
||||
# Type: List of QtColor, or QtColor
|
||||
#c.colors.completion.fg = ['#f7f7f7', 'white', 'white']
|
||||
|
||||
# Background color of the completion widget for odd rows.
|
||||
# Type: QssColor
|
||||
c.colors.completion.odd.bg = '#252525'
|
||||
|
||||
# Background color of the completion widget for even rows.
|
||||
# Type: QssColor
|
||||
c.colors.completion.even.bg = '#464646'
|
||||
|
||||
# Foreground color of completion widget category headers.
|
||||
# Type: QtColor
|
||||
c.colors.completion.category.fg = '#999999'
|
||||
|
||||
##########################################################
|
||||
# Keybinds personalizados
|
||||
##########################################################
|
||||
|
||||
config.bind('Y', 'hint links spawn bash -c "~/.local/bin/qute-dl "$1"" _ {hint-url}')
|
||||
|
||||
#config.bind('M', 'hint links spawn nohup mpv --cache=yes --demuxer-max-bytes=500M --demuxer-max-back-bytes=100M --save-position-on-quit=no -ytdl-format="bv*[height=720][ext=mp4][fps=30]+ba/b" {hint-url}')
|
||||
|
||||
#########################################################
|
||||
#Bangs!
|
||||
########################################################
|
||||
|
||||
c.url.searchengines = {'DEFAULT': 'https://duckduckgo.com/?q={}', 'aw': 'https://wiki.archlinux.org/?search={}', 're': 'https://www.reddit.com/r/{}', 'yt': 'https://www.youtube.com/results?search_query={}'}
|
|
@ -0,0 +1,18 @@
|
|||
// ==UserScript==
|
||||
// @name Auto Skip YouTube Ads
|
||||
// @version 1.0.0
|
||||
// @description Speed up and skip YouTube ads automatically
|
||||
// @author jso8910
|
||||
// @match *://*.youtube.com/*
|
||||
// @exclude *://*.youtube.com/subscribe_embed?*
|
||||
// ==/UserScript==
|
||||
setInterval(() => {
|
||||
const btn = document.querySelector('.videoAdUiSkipButton,.ytp-ad-skip-button')
|
||||
if (btn) {
|
||||
btn.click()
|
||||
}
|
||||
const ad = [...document.querySelectorAll('.ad-showing')][0];
|
||||
if (ad) {
|
||||
document.querySelector('video').playbackRate = 10;
|
||||
}
|
||||
}, 50)
|
|
@ -0,0 +1,8 @@
|
|||
[FileDialog]
|
||||
history=file:///home/diegofcs/Documentos/Trabajo_oficina/Proceso_Oscar, file:///home/diegofcs/Documentos/Trabajo_oficina/Trabajo_SINTRASECOL/Activos/Procesos_Fabiano/Proceso_adtivo, file:///home/diegofcs/Imagenes/Screenshots, file:///home/diegofcs/Descargas, file:///home/diegofcs/Imagenes/Wallpapers
|
||||
lastVisited=file:///home/diegofcs/Imagenes/Wallpapers
|
||||
qtVersion=5.15.5
|
||||
shortcuts=file:, file:///home/diegofcs
|
||||
sidebarWidth=83
|
||||
treeViewHeader=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\x1\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x3#\0\0\0\x4\x1\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\x4\0\0\x1\xec\0\0\0\x1\0\0\0\0\0\0\0K\0\0\0\x1\0\0\0\0\0\0\0\x31\0\0\0\x1\0\0\0\0\0\0\0\xbb\0\0\0\x1\0\0\0\0\0\0\x3\xe8\0\xff\xff\xff\xff)
|
||||
viewMode=List
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 2c2a7f54ab55a022a617e510b6e00c3e2736fabd
|
|
@ -0,0 +1 @@
|
|||
<svg width="32" height="32" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0)"><path d="M19.624 20.664c-.96 0-1.824-.208-2.592-.624-.736-.416-1.44-.88-2.112-1.392-.64-.512-1.28-.976-1.92-1.392-.608-.416-1.248-.624-1.92-.624-.736 0-1.44.272-2.112.816-.64.544-1.232 1.648-1.776 3.312l-2.544-1.104c.832-2.24 1.824-3.792 2.976-4.656 1.152-.896 2.336-1.344 3.552-1.344.96 0 1.808.208 2.544.624.768.416 1.472.88 2.112 1.392.672.512 1.312.976 1.92 1.392.64.416 1.296.624 1.968.624.384 0 .736-.048 1.056-.144a3.089 3.089 0 001.008-.624c.352-.32.672-.752.96-1.296.288-.544.576-1.232.864-2.064l2.544 1.152c-.832 2.24-1.824 3.792-2.976 4.656-1.152.864-2.336 1.296-3.552 1.296z" fill="#B3C9D5"/></g><defs><clipPath id="clip0"><path fill="#fff" d="M0 0h32v32H0z"/></clipPath></defs></svg>
|
After Width: | Height: | Size: 798 B |
|
@ -0,0 +1,113 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" type="text/css" href="style/main.css">
|
||||
<title>diego@void~ $</title>
|
||||
<link rel="icon" href="favicon.svg" type="image/svg+xml" sizes="any">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="flex-container">
|
||||
|
||||
<div class="flex-center">
|
||||
<div class="center-box">
|
||||
<span><span style="color: #7c7c7c">~</span>utilities</span>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://ilovepdf.com">
|
||||
<div class="link" tabindex="2">IlovePDF</div>
|
||||
</a>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://iloveimg.com">
|
||||
<div class="link" tabindex="3">IloveIMG</div>
|
||||
</a>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://canva.com">
|
||||
<div class="link" tabindex="4">Canva</div>
|
||||
</a>
|
||||
<a target="_blank" rel="noopener noreferrer" href="http://online-calculator.com">
|
||||
<div class="link" tabindex="5">Calculator</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="center-box">
|
||||
<span><span style="color: #999999">~</span>other</span>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://centroaseo.com/">
|
||||
<div class="link" tabindex="7">Mom's work</div>
|
||||
</a>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://wallhaven.cc">
|
||||
<div class="link" tabindex="7">Wallhaven</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="center-box">
|
||||
<span><span style="color: #a0a0a0">~</span>tech</span>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://nerdfonts.com/cheat-sheet">
|
||||
<div class="link" tabindex="7">NF-icons</div>
|
||||
</a>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://www.fsf.org">
|
||||
<div class="link" tabindex="7">Fsf</div>
|
||||
</a>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://news.ycombinator.com/">
|
||||
<div class="link" tabindex="7">Hackernews</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="center-box">
|
||||
<span><span style="color: #8e8e8e">~</span>work</span>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://www.ramajudicial.gov.co">
|
||||
<div class="link" tabindex="7">Rama</div>
|
||||
</a> <a target="_blank" rel="noopener noreferrer" href="https://consultaprocesos.ramajudicial.gov.co/procesos/bienvenida">
|
||||
<div class="link" tabindex="7">Consulta</div>
|
||||
</a>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://procesojudicial.ramajudicial.gov.co/Justicia21/">
|
||||
<div class="link" tabindex="7">Tyba XXI</div>
|
||||
</a>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://clientes.e-entrega.co/index.php"/>
|
||||
<div class="link" tabindex="7">E-entrega</div>
|
||||
</a>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://www.ambitojuridico.com"/>
|
||||
<div class="link" tabindex="7">Amb. jurídico</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="center-box">
|
||||
<span><span style="color: #868686">~</span>linux</span>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://suckless.org/">
|
||||
<div class="link" tabindex="7">Suckless</div>
|
||||
</a>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://docs.voidlinux.org/">
|
||||
<div class="link" tabindex="7">VoidHandbook</div>
|
||||
</a>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://voidlinux.org/packages">
|
||||
<div class="link" tabindex="7">VoidPKGS</div>
|
||||
</a>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://voidforums.com">
|
||||
<div class="link" tabindex="7">Void_forums</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="center-box">
|
||||
<span><span style="color: #747474">~</span>personal</span>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://outlook.live.com/owa/">
|
||||
<div class="link" tabindex="7">Outlook</div>
|
||||
</a>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://mail.google.com/mail">
|
||||
<div class="link" tabindex="7">Gmail</div>
|
||||
</a>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://mail.proton.me/u/0/inbox">
|
||||
<div class="link" tabindex="7">Protonmail</div>
|
||||
</a>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://docs.google.com/document/u/0/">
|
||||
<div class="link" tabindex="7">Google docs</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-bottom-bar">
|
||||
<span class="bottom-bar" id="lang"></span>
|
||||
<div class="bottom-bar" id="date"></div>
|
||||
<div class="bottom-bar" id="time"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
<script src="js/script.js" async defer></script>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,65 @@
|
|||
var data = [
|
||||
{
|
||||
AboutDevTypeText: "",
|
||||
},
|
||||
];
|
||||
|
||||
var allElements = document.getElementsByClassName("typing");
|
||||
for (var j = 0; j < allElements.length; j++) {
|
||||
var currentElementId = allElements[j].id;
|
||||
var currentElementIdContent = data[0][currentElementId];
|
||||
var element = document.getElementById(currentElementId);
|
||||
var devTypeText = currentElementIdContent;
|
||||
|
||||
// type code
|
||||
var i = 0,
|
||||
isTag,
|
||||
text;
|
||||
(function type() {
|
||||
text = devTypeText.slice(0, ++i);
|
||||
if (text === devTypeText) return;
|
||||
element.innerHTML = text;
|
||||
var char = text.slice(-1);
|
||||
if (char === "<") isTag = true;
|
||||
if (char === ">") isTag = false;
|
||||
if (isTag) return type();
|
||||
setTimeout(type, 60);
|
||||
})();
|
||||
}
|
||||
|
||||
function updateClock() {
|
||||
var now = new Date();
|
||||
hours = now.getHours();
|
||||
minutes = now.getMinutes();
|
||||
seconds = now.getSeconds();
|
||||
if (seconds < 10) {
|
||||
seconds_ = ":" + "0" + seconds;
|
||||
} else {
|
||||
seconds_ = ":" + seconds;
|
||||
}
|
||||
if (minutes < 10) {
|
||||
time = hours + ":" + "0" + minutes + seconds_;
|
||||
} else {
|
||||
time = hours + ":" + minutes + seconds_;
|
||||
}
|
||||
if (hours < 10) {
|
||||
time = "0" + time;
|
||||
}
|
||||
document.getElementById("time").innerHTML = time;
|
||||
setTimeout(updateClock, 1000);
|
||||
}
|
||||
|
||||
function updateDate() {
|
||||
const d = new Date();
|
||||
document.getElementById("date").innerHTML = d.toDateString();
|
||||
}
|
||||
|
||||
function getLanguage() {
|
||||
var lang = navigator.language;
|
||||
|
||||
document.getElementById("lang").innerHTML = lang;
|
||||
}
|
||||
|
||||
updateClock();
|
||||
updateDate();
|
||||
getLanguage();
|
|
@ -0,0 +1,2 @@
|
|||
User-agent: *
|
||||
Disallow: /
|
|
@ -0,0 +1,111 @@
|
|||
:root {
|
||||
--bgColor: #101010;
|
||||
--textColor: #e3e3e3;
|
||||
--linkColor: var(--textColor);
|
||||
--textColorHover: #f7f7f7;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Hack Nerd Font";
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Hack Nerd Font";
|
||||
font-size: 11px;
|
||||
background: var(--bgColor);
|
||||
color: var(--textColor);
|
||||
border: #f7f7f7;
|
||||
display: flex;
|
||||
/* align-items: center; */
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--linkColor);
|
||||
text-decoration: underline;
|
||||
margin-top: .2rem;
|
||||
}
|
||||
|
||||
a > div:hover {
|
||||
color: var(--textColorHover)
|
||||
}
|
||||
|
||||
.flex-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
width: auto;
|
||||
margin-top: 15rem;
|
||||
outline-style: solid;
|
||||
outline-color: #f7f7f7;
|
||||
outline-width: 1px;
|
||||
}
|
||||
|
||||
.flex-top-bar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.top-bar {
|
||||
margin-left: 0.2rem;
|
||||
margin-bottom: 0.1rem;
|
||||
|
||||
}
|
||||
|
||||
.flex-center {
|
||||
flex-direction: row;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.center-box {
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
margin: .75rem;
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.flex-bottom-bar {
|
||||
flex-direction: row;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: var(--bgColor);
|
||||
background-color: var(--textColor);
|
||||
}
|
||||
|
||||
.botton-bar {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.search-form {
|
||||
width: 10rem;
|
||||
outline: none;
|
||||
border: none;
|
||||
color: var(--textColor);
|
||||
background-color: var(--bgColor);
|
||||
font-family: "Hack Nerd Font";
|
||||
font-size: 11px;
|
||||
padding-left: .4rem;
|
||||
caret-color: var(--textColor);
|
||||
}
|
||||
|
||||
|
||||
.tilde {
|
||||
color: #FF0000;
|
||||
}
|
||||
|
||||
/* .blinker {
|
||||
opacity: 1;
|
||||
margin-bottom: -2px;
|
||||
height: 15px;
|
||||
margin-left: -5px;
|
||||
border-left: 3px solid yellow;
|
||||
animation: blinker 0.9s steps(2, start) infinite;
|
||||
}
|
||||
|
||||
@keyframes blinker {
|
||||
to {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
*/
|
|
@ -0,0 +1,58 @@
|
|||
<!-- Skovati made this -->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title> diego@void~ $</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="prompt"><span>diego</span>@<span>void</span>~ $ tree</div>
|
||||
<div class="tree">
|
||||
<h1>.</h1>
|
||||
<ul>
|
||||
<li>
|
||||
<h1>/usr/</h1>
|
||||
<ul>
|
||||
<li>
|
||||
<h1>/bookmarks/</h1>
|
||||
<ul>
|
||||
<li><a href="https://suckless.org/">suckless</a></li>
|
||||
<li><a href="https://docs.voidlinux.org/">voidhandbook</a></li>
|
||||
<li><a href="https://voidlinux.org/packages">voidpkgs</a></li>
|
||||
<li><a href="https://mail.proton.me/u/0/inbox">protonmail</a></li>
|
||||
<li><a href="https://mail.google.com/mail">gmail</a></li>
|
||||
<li><a href="https://outlook.live.com/owa/">outlook</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<h1>/b/</h1>
|
||||
<li><a href="https://www.centroaseo.com/entrenamiento/">mom</a></li>
|
||||
<li><a href="https://git.disroot.org/d13g0x/">gitea</a></li>
|
||||
<li><a href="http://wallhaven.cc">wallhaven</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<h1>/wks/</h1>
|
||||
<ul>
|
||||
<li><a href="https://consultaprocesos.ramajudicial.gov.co/procesos/bienvenida/">consulta</a></li>
|
||||
<li><a href="https://procesojudicial.ramajudicial.gov.co/Justicia21/">tyba21</a></li>
|
||||
<li><a href="https://www.ramajudicial.gov.co/portal/inicio">rama</a></li>
|
||||
<li><a href="https://clientes.e-entrega.co/">e-service</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<h1>/etc/</h1>
|
||||
<ul>
|
||||
<li><a href="https://drive.google.com/drive/u/1/my-drive?ths=true">drive</a></li>
|
||||
<li><a href="https://www.ilovepdf.com/">ilovepdf</a></li>
|
||||
<li><a href="https://www.iloveimg.com">iloveimg</a></li>
|
||||
<li><a href="https://canva.com">canva</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"name": "My custom new tab page",
|
||||
"description": "Overrides the new tab page",
|
||||
"version": "0.1",
|
||||
"incognito": "split",
|
||||
"chrome_url_overrides": {
|
||||
"newtab": "index.html"
|
||||
},
|
||||
"manifest_version": 2
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
:root {
|
||||
--font: "Hack Nerd Font";
|
||||
--background: #101010;
|
||||
--foreground: #e3e3e3;
|
||||
--green: #f7f7f7;
|
||||
--red: #f7f7f7;
|
||||
--orange: #f7f7f7;
|
||||
--branch: 1px solid #e3e3e3;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--background);
|
||||
}
|
||||
|
||||
.container {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.prompt {
|
||||
font-family: var(--font);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.prompt~.prompt {
|
||||
padding: 1.5rem 0 0.3125rem;
|
||||
}
|
||||
|
||||
span {
|
||||
color: var(--green);
|
||||
}
|
||||
|
||||
h1 {
|
||||
display: inline;
|
||||
font-family: var(--font);
|
||||
font-size: 1rem;
|
||||
font-weight: normal;
|
||||
color: var(--red);
|
||||
}
|
||||
|
||||
.tree > ul {
|
||||
margin: 0;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
padding-left: 2.5rem;
|
||||
}
|
||||
|
||||
li {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
li::before, li::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: -0.75rem;
|
||||
}
|
||||
|
||||
li::before {
|
||||
border-top: var(--branch);
|
||||
top: 0.75rem;
|
||||
width: 0.5rem;
|
||||
}
|
||||
|
||||
li::after {
|
||||
border-left: var(--branch);
|
||||
height: 100%;
|
||||
top: 0.25rem;
|
||||
}
|
||||
|
||||
li:last-child::after {
|
||||
height: 0.5rem;
|
||||
}
|
||||
|
||||
a {
|
||||
font-family: var(--font);
|
||||
font-size: 1rem;
|
||||
color: var(--foreground);
|
||||
text-decoration: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: var(--background);
|
||||
background: var(--orange);
|
||||
}
|
||||
|
||||
form h1 {
|
||||
padding-left: 0.125rem;
|
||||
}
|
||||
|
||||
input {
|
||||
font-family: var(--font);
|
||||
font-size: 1rem;
|
||||
color: var(--foreground);
|
||||
background-color: var(--background);
|
||||
border: none;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
-- complete file path at primary selection location using vis-complete(1)
|
||||
|
||||
vis:map(vis.modes.INSERT, "<C-x><C-f>", function()
|
||||
local win = vis.win
|
||||
local file = win.file
|
||||
local pos = win.selection.pos
|
||||
if not pos then return end
|
||||
-- TODO do something clever here
|
||||
local range = file:text_object_longword(pos > 0 and pos-1 or pos);
|
||||
if not range then return end
|
||||
if range.finish > pos then range.finish = pos end
|
||||
if range.start == range.finish then return end
|
||||
local prefix = file:content(range)
|
||||
if not prefix then return end
|
||||
-- Strip leading delimiters for some languages
|
||||
local _, j = string.find(prefix, "[[(<'\"]+")
|
||||
if j then prefix = prefix:sub(j + 1) end
|
||||
local cmd = string.format("vis-complete --file '%s'", prefix:gsub("'", "'\\''"))
|
||||
local status, out, err = vis:pipe(file, { start = 0, finish = 0 }, cmd)
|
||||
if status ~= 0 or not out then
|
||||
if err then vis:info(err) end
|
||||
return
|
||||
end
|
||||
file:insert(pos, out)
|
||||
win.selection.pos = pos + #out
|
||||
end, "Complete file path")
|
||||
|
||||
-- complete file path at primary selection location using vis-open(1)
|
||||
|
||||
vis:map(vis.modes.INSERT, "<C-x><C-o>", function()
|
||||
local win = vis.win
|
||||
local file = win.file
|
||||
local pos = win.selection.pos
|
||||
if not pos then return end
|
||||
-- TODO do something clever here
|
||||
local range = file:text_object_longword(pos > 0 and pos-1 or pos);
|
||||
if not range then return end
|
||||
if range.finish > pos then range.finish = pos end
|
||||
local prefix = file:content(range)
|
||||
if not prefix then return end
|
||||
if prefix:match("^%s*$") then
|
||||
prefix = ""
|
||||
range.start = pos
|
||||
range.finish = pos
|
||||
end
|
||||
local cmd = string.format("vis-open -- '%s'*", prefix:gsub("'", "'\\''"))
|
||||
local status, out, err = vis:pipe(file, { start = 0, finish = 0 }, cmd)
|
||||
if status ~= 0 or not out then
|
||||
if err then vis:info(err) end
|
||||
return
|
||||
end
|
||||
out = out:gsub("\n$", "")
|
||||
file:delete(range)
|
||||
file:insert(range.start, out)
|
||||
win.selection.pos = range.start + #out
|
||||
end, "Complete file name")
|
|
@ -0,0 +1,22 @@
|
|||
-- complete word at primary selection location using vis-complete(1)
|
||||
|
||||
vis:map(vis.modes.INSERT, "<C-n>", function()
|
||||
local win = vis.win
|
||||
local file = win.file
|
||||
local pos = win.selection.pos
|
||||
if not pos then return end
|
||||
local range = file:text_object_word(pos > 0 and pos-1 or pos);
|
||||
if not range then return end
|
||||
if range.finish > pos then range.finish = pos end
|
||||
if range.start == range.finish then return end
|
||||
local prefix = file:content(range)
|
||||
if not prefix then return end
|
||||
local cmd = string.format("vis-complete --word '%s'", prefix:gsub("'", "'\\''"))
|
||||
local status, out, err = vis:pipe(file, { start = 0, finish = file.size }, cmd)
|
||||
if status ~= 0 or not out then
|
||||
if err then vis:info(err) end
|
||||
return
|
||||
end
|
||||
file:insert(pos, out)
|
||||
win.selection.pos = pos + #out
|
||||
end, "Complete word in file")
|
|
@ -0,0 +1,23 @@
|
|||
-- insert digraphs using vis-digraph(1)
|
||||
|
||||
vis:map(vis.modes.INSERT, "<C-k>", function(keys)
|
||||
if #keys < 2 then
|
||||
return -1 -- need more input
|
||||
end
|
||||
local file = io.popen(string.format("vis-digraph '%s' 2>&1", keys:gsub("'", "'\\''")))
|
||||
local output = file:read('*all')
|
||||
local success, msg, status = file:close()
|
||||
if success then
|
||||
if vis.mode == vis.modes.INSERT then
|
||||
vis:insert(output)
|
||||
elseif vis.mode == vis.modes.REPLACE then
|
||||
vis:replace(output)
|
||||
end
|
||||
elseif msg == 'exit' then
|
||||
if status == 2 then
|
||||
return -1 -- prefix need more input
|
||||
end
|
||||
vis:info(output)
|
||||
end
|
||||
return #keys
|
||||
end, "Insert digraph")
|
|
@ -0,0 +1,609 @@
|
|||
vis.ftdetect = {}
|
||||
|
||||
vis.ftdetect.ignoresuffixes = {
|
||||
"~$", "%.orig$", "%.bak$", "%.old$", "%.new$"
|
||||
}
|
||||
|
||||
vis.ftdetect.filetypes = {
|
||||
actionscript = {
|
||||
ext = { "%.as$", "%.asc$" },
|
||||
},
|
||||
ada = {
|
||||
ext = { "%.adb$", "%.ads$" },
|
||||
},
|
||||
ansi_c = {
|
||||
ext = { "%.c$", "%.C$", "%.h$" },
|
||||
mime = { "text/x-c" },
|
||||
},
|
||||
antlr = {
|
||||
ext = { "%.g$", "%.g4$" },
|
||||
},
|
||||
apdl = {
|
||||
ext = { "%.ans$", "%.inp$", "%.mac$" },
|
||||
},
|
||||
apl = {
|
||||
ext = { "%.apl$" }
|
||||
},
|
||||
applescript = {
|
||||
ext = { "%.applescript$" },
|
||||
},
|
||||
asm = {
|
||||
ext = { "%.asm$", "%.ASM$", "%.s$", "%.S$" },
|
||||
},
|
||||
asp = {
|
||||
ext = { "%.asa$", "%.asp$", "%.hta$" },
|
||||
},
|
||||
autoit = {
|
||||
ext = { "%.au3$", "%.a3x$" },
|
||||
},
|
||||
awk = {
|
||||
hashbang = { "^/usr/bin/[mng]awk%s+%-f" },
|
||||
utility = { "^[mgn]?awk$", "^goawk$" },
|
||||
ext = { "%.awk$" },
|
||||
},
|
||||
bash = {
|
||||
utility = { "^[db]ash$", "^sh$","^t?csh$","^zsh$" },
|
||||
ext = { "%.bash$", "%.csh$", "%.sh$", "%.zsh$" ,"^APKBUILD$", "%.ebuild$", "^.bashrc$", "^.bash_profile$" },
|
||||
mime = { "text/x-shellscript", "application/x-shellscript" },
|
||||
},
|
||||
batch = {
|
||||
ext = { "%.bat$", "%.cmd$" },
|
||||
},
|
||||
bibtex = {
|
||||
ext = { "%.bib$" },
|
||||
},
|
||||
boo = {
|
||||
ext = { "%.boo$" },
|
||||
},
|
||||
caml = {
|
||||
ext = { "%.caml$", "%.ml$", "%.mli$", "%.mll$", "%.mly$" },
|
||||
},
|
||||
chuck = {
|
||||
ext = { "%.ck$" },
|
||||
},
|
||||
clojure = {
|
||||
ext = { "%.clj$", "%.cljc$", "%.cljs$", "%.edn$" }
|
||||
},
|
||||
cmake = {
|
||||
ext = { "%.cmake$", "%.cmake.in$", "%.ctest$", "%.ctest.in$" },
|
||||
},
|
||||
coffeescript = {
|
||||
ext = { "%.coffee$" },
|
||||
mime = { "text/x-coffee" },
|
||||
},
|
||||
cpp = {
|
||||
ext = { "%.cpp$", "%.cxx$", "%.c++$", "%.cc$", "%.hh$", "%.hpp$", "%.hxx$", "%.h++$" },
|
||||
mime = { "text/x-c++" },
|
||||
},
|
||||
crontab = {
|
||||
ext = { "^crontab.*$" },
|
||||
cmd = { "set savemethod inplace" },
|
||||
},
|
||||
crystal = {
|
||||
ext = { "%.cr$" },
|
||||
},
|
||||
csharp = {
|
||||
ext = { "%.cs$" },
|
||||
},
|
||||
css = {
|
||||
ext = { "%.css$" },
|
||||
mime = { "text/x-css" },
|
||||
},
|
||||
cuda = {
|
||||
ext = { "%.cu$", "%.cuh$" },
|
||||
},
|
||||
dart = {
|
||||
ext = { "%.dart$" },
|
||||
},
|
||||
desktop = {
|
||||
ext = { "%.desktop$" },
|
||||
},
|
||||
diff = {
|
||||
ext = { "%.diff$", "%.patch$", "%.rej$", "^COMMIT_EDITMSG$" },
|
||||
cmd = { "set colorcolumn 72" },
|
||||
},
|
||||
dmd = {
|
||||
ext = { "%.d$", "%.di$" },
|
||||
},
|
||||
dockerfile = {
|
||||
ext = { "^Dockerfile$", "%.Dockerfile$" },
|
||||
},
|
||||
dot = {
|
||||
ext = { "%.dot$" },
|
||||
},
|
||||
dsv = {
|
||||
ext = { "^group$", "^gshadow$", "^passwd$", "^shadow$" },
|
||||
},
|
||||
eiffel = {
|
||||
ext = { "%.e$", "%.eif$" },
|
||||
},
|
||||
elixir = {
|
||||
ext = { "%.ex$", "%.exs$" },
|
||||
},
|
||||
elm = {
|
||||
ext = { "%.elm$" },
|
||||
},
|
||||
erlang = {
|
||||
ext = { "%.erl$", "%.hrl$" },
|
||||
},
|
||||
fantom = {
|
||||
ext = { "%.fan$" },
|
||||
},
|
||||
faust = {
|
||||
ext = { "%.dsp$" },
|
||||
},
|
||||
fennel = {
|
||||
ext = { "%.fnl$" },
|
||||
},
|
||||
fish = {
|
||||
utility = { "^fish$" },
|
||||
ext = { "%.fish$" },
|
||||
},
|
||||
forth = {
|
||||
ext = { "%.forth$", "%.frt$", "%.fs$", "%.fth$" },
|
||||
},
|
||||
fortran = {
|
||||
ext = { "%.f$", "%.for$", "%.ftn$", "%.fpp$", "%.f77$", "%.f90$", "%.f95$", "%.f03$", "%.f08$" },
|
||||
},
|
||||
fsharp = {
|
||||
ext = { "%.fs$" },
|
||||
},
|
||||
fstab = {
|
||||
ext = { "fstab" },
|
||||
},
|
||||
gap = {
|
||||
ext = { "%.g$", "%.gd$", "%.gi$", "%.gap$" },
|
||||
},
|
||||
gemini = {
|
||||
ext = { "%.gmi" },
|
||||
mime = { "text/gemini" },
|
||||
},
|
||||
gettext = {
|
||||
ext = { "%.po$", "%.pot$" },
|
||||
},
|
||||
gherkin = {
|
||||
ext = { "%.feature$" },
|
||||
},
|
||||
['git-rebase'] = {
|
||||
ext = { "git%-rebase%-todo" },
|
||||
},
|
||||
glsl = {
|
||||
ext = { "%.glslf$", "%.glslv$" },
|
||||
},
|
||||
gnuplot = {
|
||||
ext = { "%.dem$", "%.plt$" },
|
||||
},
|
||||
go = {
|
||||
ext = { "%.go$" },
|
||||
},
|
||||
groovy = {
|
||||
ext = { "%.groovy$", "%.gvy$", "^Jenkinsfile$" },
|
||||
},
|
||||
gtkrc = {
|
||||
ext = { "%.gtkrc$" },
|
||||
},
|
||||
hare = {
|
||||
ext = { "%.ha$" }
|
||||
},
|
||||
haskell = {
|
||||
ext = { "%.hs$" },
|
||||
mime = { "text/x-haskell" },
|
||||
},
|
||||
html = {
|
||||
ext = { "%.htm$", "%.html$", "%.shtm$", "%.shtml$", "%.xhtml$" },
|
||||
mime = { "text/x-html" },
|
||||
},
|
||||
icon = {
|
||||
ext = { "%.icn$" },
|
||||
},
|
||||
idl = {
|
||||
ext = { "%.idl$", "%.odl$" },
|
||||
},
|
||||
inform = {
|
||||
ext = { "%.inf$", "%.ni$" },
|
||||
},
|
||||
ini = {
|
||||
ext = { "%.cfg$", "%.cnf$", "%.conf$", "%.inf$", "%.ini$", "%.reg$" },
|
||||
},
|
||||
io_lang = {
|
||||
ext = { "%.io$" },
|
||||
},
|
||||
java = {
|
||||
ext = { "%.bsh$", "%.java$" },
|
||||
},
|
||||
javascript = {
|
||||
ext = { "%.cjs$", "%.js$", "%.jsfl$", "%.mjs$", "%.ts$", "%.jsx$", "%.tsx$" },
|
||||
},
|
||||
json = {
|
||||
ext = { "%.json$" },
|
||||
mime = { "text/x-json" },
|
||||
},
|
||||
jsp = {
|
||||
ext = { "%.jsp$" },
|
||||
},
|
||||
julia = {
|
||||
ext = { "%.jl$" },
|
||||
},
|
||||
latex = {
|
||||
ext = { "%.bbl$", "%.cls$", "%.dtx$", "%.ins$", "%.ltx$", "%.tex$", "%.sty$" },
|
||||
mime = { "text/x-tex" },
|
||||
},
|
||||
ledger = {
|
||||
ext = { "%.ledger$", "%.journal$" },
|
||||
},
|
||||
less = {
|
||||
ext = { "%.less$" },
|
||||
},
|
||||
lilypond = {
|
||||
ext = { "%.ily$", "%.ly$" },
|
||||
},
|
||||
lisp = {
|
||||
ext = { "%.cl$", "%.el$", "%.lisp$", "%.lsp$" },
|
||||
mime = { "text/x-lisp" },
|
||||
},
|
||||
litcoffee = {
|
||||
ext = { "%.litcoffee$" },
|
||||
},
|
||||
logtalk = {
|
||||
ext = { "%.lgt$" },
|
||||
},
|
||||
lua = {
|
||||
utility = {"^lua%-?5?%d?$", "^lua%-?5%.%d$" },
|
||||
ext = { "%.lua$" },
|
||||
mime = { "text/x-lua" },
|
||||
},
|
||||
makefile = {
|
||||
hashbang = {"^#!/usr/bin/make"},
|
||||
utility = {"^make$"},
|
||||
ext = { "%.iface$", "%.mak$", "%.mk$", "GNUmakefile", "makefile", "Makefile" },
|
||||
mime = { "text/x-makefile" },
|
||||
},
|
||||
man = {
|
||||
ext = {
|
||||
"%.1$", "%.2$", "%.3$", "%.4$", "%.5$", "%.6$", "%.7$",
|
||||
"%.8$", "%.9$", "%.1x$", "%.2x$", "%.3x$", "%.4x$",
|
||||
"%.5x$", "%.6x$", "%.7x$", "%.8x$", "%.9x$"
|
||||
},
|
||||
},
|
||||
markdown = {
|
||||
ext = { "%.md$", "%.markdown$" },
|
||||
mime = { "text/x-markdown" },
|
||||
},
|
||||
meson = {
|
||||
ext = { "^meson%.build$" },
|
||||
},
|
||||
moonscript = {
|
||||
ext = { "%.moon$" },
|
||||
mime = { "text/x-moon" },
|
||||
},
|
||||
myrddin = {
|
||||
ext = { "%.myr$" },
|
||||
},
|
||||
nemerle = {
|
||||
ext = { "%.n$" },
|
||||
},
|
||||
networkd = {
|
||||
ext = { "%.link$", "%.network$", "%.netdev$" },
|
||||
},
|
||||
nim = {
|
||||
ext = { "%.nim$" },
|
||||
},
|
||||
nsis = {
|
||||
ext = { "%.nsh$", "%.nsi$", "%.nsis$" },
|
||||
},
|
||||
objective_c = {
|
||||
ext = { "%.m$", "%.mm$", "%.objc$" },
|
||||
mime = { "text/x-objc" },
|
||||
},
|
||||
pascal = {
|
||||
ext = { "%.dpk$", "%.dpr$", "%.p$", "%.pas$" },
|
||||
},
|
||||
perl = {
|
||||
ext = { "%.al$", "%.perl$", "%.pl$", "%.pm$", "%.pod$" },
|
||||
mime = { "text/x-perl" },
|
||||
},
|
||||
php = {
|
||||
ext = { "%.inc$", "%.php$", "%.php3$", "%.php4$", "%.phtml$" },
|
||||
},
|
||||
pico8 = {
|
||||
ext = { "%.p8$" },
|
||||
},
|
||||
pike = {
|
||||
ext = { "%.pike$", "%.pmod$" },
|
||||
},
|
||||
pkgbuild = {
|
||||
ext = { "^PKGBUILD$", "%.PKGBUILD$" },
|
||||
},
|
||||
pony = {
|
||||
ext = { "%.pony$" },
|
||||
},
|
||||
powershell = {
|
||||
ext = { "%.ps1$" },
|
||||
},
|
||||
prolog = {
|
||||
ext = { "%.pl$", "%.pro$", "%.prolog$" },
|
||||
},
|
||||
props = {
|
||||
ext = { "%.props$", "%.properties$" },
|
||||
},
|
||||
protobuf = {
|
||||
ext = { "%.proto$" },
|
||||
},
|
||||
ps = {
|
||||
ext = { "%.eps$", "%.ps$" },
|
||||
},
|
||||
pure = {
|
||||
ext = { "%.pure$" },
|
||||
},
|
||||
python = {
|
||||
utility = { "^python%d?" },
|
||||
ext = { "%.sc$", "%.py$", "%.pyw$" },
|
||||
mime = { "text/x-python", "text/x-script.python" },
|
||||
},
|
||||
reason = {
|
||||
ext = { "%.re$" },
|
||||
},
|
||||
rc = {
|
||||
utility = {"^rc$"},
|
||||
ext = { "%.rc$", "%.es$" },
|
||||
},
|
||||
rebol = {
|
||||
ext = { "%.r$", "%.reb$" },
|
||||
},
|
||||
rest = {
|
||||
ext = { "%.rst$" },
|
||||
},
|
||||
rexx = {
|
||||
ext = { "%.orx$", "%.rex$" },
|
||||
},
|
||||
rhtml = {
|
||||
ext = { "%.erb$", "%.rhtml$" },
|
||||
},
|
||||
routeros = {
|
||||
ext = { "%.rsc" },
|
||||
detect = function(_, data)
|
||||
return data:match("^#.* by RouterOS")
|
||||
end
|
||||
},
|
||||
rstats = {
|
||||
ext = { "%.R$", "%.Rout$", "%.Rhistory$", "%.Rt$", "Rout.save", "Rout.fail" },
|
||||
},
|
||||
ruby = {
|
||||
ext = { "%.Rakefile$", "%.rake$", "%.rb$", "%.rbw$", "^Vagrantfile$" },
|
||||
mime = { "text/x-ruby" },
|
||||
},
|
||||
rust = {
|
||||
ext = { "%.rs$" },
|
||||
mime = { "text/x-rust" },
|
||||
},
|
||||
sass = {
|
||||
ext = { "%.sass$", "%.scss$" },
|
||||
mime = { "text/x-sass", "text/x-scss" },
|
||||
},
|
||||
scala = {
|
||||
ext = { "%.scala$" },
|
||||
mime = { "text/x-scala" },
|
||||
},
|
||||
scheme = {
|
||||
ext = { "%.rkt$", "%.sch$", "%.scm$", "%.sld$", "%.sls$", "%.ss$" },
|
||||
},
|
||||
smalltalk = {
|
||||
ext = { "%.changes$", "%.st$", "%.sources$" },
|
||||
},
|
||||
sml = {
|
||||
ext = { "%.sml$", "%.fun$", "%.sig$" },
|
||||
},
|
||||
snobol4 = {
|
||||
ext = { "%.sno$", "%.SNO$" },
|
||||
},
|
||||
spin = {
|
||||
ext = { "%.spin$" }
|
||||
},
|
||||
sql= {
|
||||
ext = { "%.ddl$", "%.sql$" },
|
||||
},
|
||||
strace = {
|
||||
detect = function(_, data)
|
||||
return data:match("^execve%(")
|
||||
end
|
||||
},
|
||||
systemd = {
|
||||
ext = {
|
||||
"%.automount$", "%.device$", "%.mount$", "%.path$",
|
||||
"%.scope$", "%.service$", "%.slice$", "%.socket$",
|
||||
"%.swap$", "%.target$", "%.timer$"
|
||||
},
|
||||
},
|
||||
taskpaper = {
|
||||
ext = { "%.taskpaper$" },
|
||||
},
|
||||
tcl = {
|
||||
utility = {"^tclsh$", "^jimsh$" },
|
||||
ext = { "%.tcl$", "%.tk$" },
|
||||
},
|
||||
texinfo = {
|
||||
ext = { "%.texi$" },
|
||||
},
|
||||
text = {
|
||||
ext = { "%.txt$" },
|
||||
-- Do *not* list mime "text/plain" here, it is covered below,
|
||||
-- see 'try text lexer as a last resort'
|
||||
},
|
||||
toml = {
|
||||
ext = { "%.toml$" },
|
||||
},
|
||||
vala = {
|
||||
ext = { "%.vala$" }
|
||||
},
|
||||
vb = {
|
||||
ext = {
|
||||
"%.asa$", "%.bas$", "%.ctl$", "%.dob$",
|
||||
"%.dsm$", "%.dsr$", "%.frm$", "%.pag$", "%.vb$",
|
||||
"%.vba$", "%.vbs$"
|
||||
},
|
||||
},
|
||||
vcard = {
|
||||
ext = { "%.vcf$", "%.vcard$" },
|
||||
},
|
||||
verilog = {
|
||||
ext = { "%.v$", "%.ver$", "%.sv$" },
|
||||
},
|
||||
vhdl = {
|
||||
ext = { "%.vh$", "%.vhd$", "%.vhdl$" },
|
||||
},
|
||||
wsf = {
|
||||
ext = { "%.wsf$" },
|
||||
},
|
||||
xs = {
|
||||
ext = { "%.xs$", "^%.xsin$", "^%.xsrc$" },
|
||||
},
|
||||
xml = {
|
||||
ext = {
|
||||
"%.dtd$", "%.glif$", "%.plist$", "%.svg$", "%.xml$",
|
||||
"%.xsd$", "%.xsl$", "%.xslt$", "%.xul$"
|
||||
},
|
||||
},
|
||||
xtend = {
|
||||
ext = {"%.xtend$" },
|
||||
},
|
||||
yaml = {
|
||||
ext = { "%.yaml$", "%.yml$" },
|
||||
mime = { "text/x-yaml" },
|
||||
},
|
||||
zig = {
|
||||
ext = { "%.zig$" },
|
||||
},
|
||||
}
|
||||
|
||||
vis.events.subscribe(vis.events.WIN_OPEN, function(win)
|
||||
|
||||
local set_filetype = function(syntax, filetype)
|
||||
for _, cmd in pairs(filetype.cmd or {}) do
|
||||
vis:command(cmd)
|
||||
end
|
||||
win:set_syntax(syntax)
|
||||
end
|
||||
|
||||
local name = win.file.name
|
||||
-- remove ignored suffixes from filename
|
||||
local sanitizedfn = name
|
||||
if sanitizedfn ~= nil then
|
||||
sanitizedfn = sanitizedfn:gsub('^.*/', '')
|
||||
repeat
|
||||
local changed = false
|
||||
for _, pattern in pairs(vis.ftdetect.ignoresuffixes) do
|
||||
local start = sanitizedfn:find(pattern)
|
||||
if start then
|
||||
sanitizedfn = sanitizedfn:sub(1, start-1)
|
||||
changed = true
|
||||
end
|
||||
end
|
||||
until not changed
|
||||
end
|
||||
|
||||
-- detect filetype by filename ending with a configured extension
|
||||
if sanitizedfn ~= nil then
|
||||
for lang, ft in pairs(vis.ftdetect.filetypes) do
|
||||
for _, pattern in pairs(ft.ext or {}) do
|
||||
if sanitizedfn:match(pattern) then
|
||||
set_filetype(lang, ft)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- run file(1) to determine mime type
|
||||
local mime
|
||||
if name ~= nil then
|
||||
local file = io.popen(string.format("file -bL --mime-type -- '%s'", name:gsub("'", "'\\''")))
|
||||
if file then
|
||||
mime = file:read('*all')
|
||||
file:close()
|
||||
if mime then
|
||||
mime = mime:gsub('%s*$', '')
|
||||
end
|
||||
if mime and #mime > 0 then
|
||||
for lang, ft in pairs(vis.ftdetect.filetypes) do
|
||||
for _, ft_mime in pairs(ft.mime or {}) do
|
||||
if mime == ft_mime then
|
||||
set_filetype(lang, ft)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- pass first few bytes of file to custom file type detector functions
|
||||
local file = win.file
|
||||
local data = file:content(0, 256)
|
||||
if data and #data > 0 then
|
||||
for lang, ft in pairs(vis.ftdetect.filetypes) do
|
||||
if type(ft.detect) == 'function' and ft.detect(file, data) then
|
||||
set_filetype(lang, ft)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
--[[ hashbang check
|
||||
hashbangs only have command <SPACE> argument
|
||||
if /env, find utility in args
|
||||
discard first arg if /-[^S]*S/; and all subsequent /=/
|
||||
NOTE: this means you can't have a command with /^-|=/
|
||||
return first field, which should be the utility.
|
||||
NOTE: long-options unsupported
|
||||
--]]
|
||||
local fullhb, utility = data:match"^#![ \t]*(/+[^/\n]+[^\n]*)"
|
||||
if fullhb then
|
||||
local i, field = 1, {}
|
||||
for m in fullhb:gmatch"%g+" do field[i],i = m,i+1 end
|
||||
-- NOTE: executables should not have a space (or =, see below)
|
||||
if field[1]:match"/env$" then
|
||||
table.remove(field,1)
|
||||
-- it is assumed that the first argument are short options, with -S inside
|
||||
if string.match(field[1] or "", "^%-[^S-]*S") then -- -S found
|
||||
table.remove(field,1)
|
||||
-- skip all name=value
|
||||
while string.match(field[1] or "","=") do
|
||||
table.remove(field,1)
|
||||
end
|
||||
-- (hopefully) whatever is left in field[1] should be the utility or nil
|
||||
end
|
||||
end
|
||||
utility = string.match(field[1] or "", "[^/]+$") -- remove filepath
|
||||
end
|
||||
|
||||
local function searcher(tbl, subject)
|
||||
for i, pattern in ipairs(tbl or {}) do
|
||||
if string.match(subject, pattern) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
if utility or fullhb then
|
||||
for lang, ft in pairs(vis.ftdetect.filetypes) do
|
||||
if
|
||||
utility and searcher(ft.utility, utility)
|
||||
or
|
||||
fullhb and searcher(ft.hashbang, fullhb)
|
||||
then
|
||||
set_filetype(lang, ft)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- try text lexer as a last resort
|
||||
if (mime or 'text/plain'):match('^text/.+$') then
|
||||
set_filetype('text', vis.ftdetect.filetypes.text)
|
||||
return
|
||||
end
|
||||
|
||||
win:set_syntax(nil)
|
||||
end)
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
-- increment/decrement number in dec/hex/oct format
|
||||
local lexer = vis.lexers
|
||||
local lpeg = vis.lpeg
|
||||
if not lexer.load or not lpeg then return end
|
||||
|
||||
local Cp = lpeg.Cp()
|
||||
local dec_num = lpeg.S('+-')^-1 * lexer.dec_num
|
||||
local pattern = lpeg.P{ Cp * (lexer.hex_num + lexer.oct_num + dec_num) * Cp + 1 * lpeg.V(1) }
|
||||
|
||||
local change = function(delta)
|
||||
|
||||
local win = vis.win
|
||||
local file = win.file
|
||||
local count = vis.count
|
||||
if not count then count = 1 end
|
||||
vis.count = nil -- reset count, otherwise it affects next motion
|
||||
|
||||
for selection in win:selections_iterator() do
|
||||
local pos = selection.pos
|
||||
if not pos then goto continue end
|
||||
local word = file:text_object_word(pos);
|
||||
if not word then goto continue end
|
||||
local data = file:content(word.start, 1024)
|
||||
if not data then goto continue end
|
||||
local s, e = pattern:match(data)
|
||||
if not s then goto continue end
|
||||
data = string.sub(data, s, e-1)
|
||||
if #data == 0 then goto continue end
|
||||
-- align start and end for fileindex
|
||||
s = word.start + s - 1
|
||||
e = word.start + e - 1
|
||||
local base, format, padding = 10, 'd', 0
|
||||
if lexer.oct_num:match(data) then
|
||||
base = 8
|
||||
format = 'o'
|
||||
padding = #data
|
||||
elseif lexer.hex_num:match(data) then
|
||||
base = 16
|
||||
format = 'x'
|
||||
padding = #data - #"0x"
|
||||
end
|
||||
local number = tonumber(data, base == 8 and 8 or nil)
|
||||
if not number then goto continue end
|
||||
number = number + delta * count
|
||||
-- string.format does not support negative hex/oct values
|
||||
if base ~= 10 and number < 0 then number = 0 end
|
||||
number = string.format((base == 16 and "0x" or "") .. "%0"..padding..format, number)
|
||||
if base == 8 and string.sub(number, 0, 1) ~= "0" then
|
||||
number = '0' .. number
|
||||
end
|
||||
file:delete(s, e - s)
|
||||
file:insert(s, number)
|
||||
selection.pos = s
|
||||
::continue::
|
||||
end
|
||||
end
|
||||
|
||||
vis:map(vis.modes.NORMAL, "<C-a>", function() change( 1) end, "Increment number")
|
||||
vis:map(vis.modes.NORMAL, "<C-x>", function() change(-1) end, "Decrement number")
|
|
@ -0,0 +1,31 @@
|
|||
-- text object matching a lexer token
|
||||
|
||||
local MAX_CONTEXT = 32768
|
||||
|
||||
vis:textobject_new("ii", function(win, pos)
|
||||
|
||||
if not win.syntax or not vis.lexers.load then
|
||||
return nil
|
||||
end
|
||||
|
||||
local before, after = pos - MAX_CONTEXT, pos + MAX_CONTEXT
|
||||
if before < 0 then
|
||||
before = 0
|
||||
end
|
||||
-- TODO make sure we start at a line boundary?
|
||||
|
||||
local lexer = vis.lexers.load(win.syntax, nil, true)
|
||||
local data = win.file:content(before, after - before)
|
||||
local tokens = lexer:lex(data)
|
||||
local cur = before
|
||||
|
||||
for i = 1, #tokens, 2 do
|
||||
local token_next = before + tokens[i+1] - 1
|
||||
if cur <= pos and pos < token_next then
|
||||
return cur, token_next
|
||||
end
|
||||
cur = token_next
|
||||
end
|
||||
|
||||
return nil
|
||||
end, "Current lexer token")
|
|
@ -0,0 +1,39 @@
|
|||
-- vis-filetype-settings
|
||||
-- (https://github.com/jocap/vis-filetype-settings)
|
||||
|
||||
-- This plugin provides a declarative interface for setting vis
|
||||
-- options depending on filetype.
|
||||
--
|
||||
-- It expects a global variable called `settings` to be defined:
|
||||
--
|
||||
-- settings = {
|
||||
-- markdown = {"set expandtab on", "set tabwidth 4"}
|
||||
-- }
|
||||
--
|
||||
-- In this variable, filetypes are mapped to sets of settings that are
|
||||
-- to be executed when a window containing the specified filetype is
|
||||
-- opened.
|
||||
--
|
||||
-- If you want to do more than setting simple options, you can specify a function instead:
|
||||
--
|
||||
-- settings = {
|
||||
-- bash = function(win)
|
||||
-- -- do things for shell scripts
|
||||
-- end
|
||||
-- }
|
||||
--
|
||||
-- Be sure not to run commands that open another window with the same
|
||||
-- filetype, leading to an infinite loop.
|
||||
|
||||
vis.events.subscribe(vis.events.WIN_OPEN, function(win)
|
||||
if settings == nil then return end
|
||||
local window_settings = settings[win.syntax]
|
||||
|
||||
if type(window_settings) == "table" then
|
||||
for _, setting in pairs(window_settings) do
|
||||
vis:command(setting)
|
||||
end
|
||||
elseif type(window_settings) == "function" then
|
||||
window_settings(win)
|
||||
end
|
||||
end)
|
|
@ -0,0 +1,11 @@
|
|||
# http://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*.lua]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[.gitlab-ci.yml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
|
@ -0,0 +1,23 @@
|
|||
image: imolein/luarocks:5.4
|
||||
|
||||
stages:
|
||||
- check
|
||||
- test
|
||||
|
||||
check-luacheck:
|
||||
stage: check
|
||||
script:
|
||||
- luarocks install luacheck
|
||||
- make check-luacheck
|
||||
|
||||
# check-format:
|
||||
# stage: check
|
||||
# script:
|
||||
# - luarocks install --server=https://luarocks.org/dev luaformatter
|
||||
# - make check-format
|
||||
|
||||
# test:
|
||||
# stage: test
|
||||
# script:
|
||||
# - luarocks install lunatest
|
||||
# - make test
|
|
@ -0,0 +1,27 @@
|
|||
column_limit: 100
|
||||
indent_width: 2
|
||||
use_tab: false
|
||||
spaces_before_call: 1
|
||||
keep_simple_control_block_one_line: false
|
||||
keep_simple_function_one_line: false
|
||||
align_args: true
|
||||
break_after_functioncall_lp: false
|
||||
break_before_functioncall_rp: false
|
||||
spaces_inside_functioncall_parens: false
|
||||
spaces_inside_functiondef_parens: false
|
||||
align_parameter: true
|
||||
chop_down_parameter: false
|
||||
break_after_functiondef_lp: false
|
||||
break_before_functiondef_rp: false
|
||||
align_table_field: true
|
||||
break_after_table_lb: true
|
||||
break_before_table_rb: true
|
||||
chop_down_table: true
|
||||
chop_down_kv_table: true
|
||||
table_sep: ","
|
||||
extra_sep_at_table_end: true
|
||||
column_table_limit: 80
|
||||
spaces_inside_table_braces: false
|
||||
break_after_operator: true
|
||||
double_quote_to_single_quote: true
|
||||
spaces_around_equals_in_field: true
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2016 Florian Fischer
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,14 @@
|
|||
.PHONY: check format check-luacheck check-format
|
||||
|
||||
LUA_FILES := $(wildcard *.lua)
|
||||
|
||||
check: check-luacheck check-format
|
||||
|
||||
check-luacheck:
|
||||
luacheck --globals=vis -- $(LUA_FILES)
|
||||
|
||||
check-format:
|
||||
for lf in $(LUA_FILES); do tools/check-format "$${lf}"; done
|
||||
|
||||
format:
|
||||
lua-format -i $(LUA_FILES)
|
|
@ -0,0 +1,45 @@
|
|||
# vis-spellcheck
|
||||
|
||||
A spellchecking lua plugin for the [vis editor](https://github.com/martanne/vis).
|
||||
|
||||
## Installation
|
||||
|
||||
1. Download `spellcheck.lua` or clone this repository into your plugin directory
|
||||
2. Load the plugin in your `visrc.lua` with `require('plugins/vis-spellcheck')`
|
||||
|
||||
## Usage
|
||||
|
||||
+ To enable highlighting of misspelled words press `<Ctrl-w>e` in normal mode.
|
||||
+ To disable highlighting press `<Ctrl-w>d` in normal mode.
|
||||
+ To toggle highlighting press `<F7>` in normal mode.
|
||||
+ To correct the word under the cursor press `<Ctrl+w>w` in normal mode.
|
||||
+ To ignore the word under the cursor press `<Ctrl+w>i` in normal mode.
|
||||
|
||||
## Configuration
|
||||
|
||||
The module table returned from `require(...)` has some configuration options:
|
||||
|
||||
* `cmd`: cmd that is passed to popen() and must return word corrections in Ispell format.
|
||||
* default: `enchant -d %s`
|
||||
* `list_cmd`: cmd that is passed to `popen()` and must output a list of misspelled words.
|
||||
* default: `enchant -l -d %s`
|
||||
* `default_lang`: The name of the used dictionary if the opened file does not specify one. The selected language is inserted in the cmd-strings at `%s`.
|
||||
* default: `$LANG` or `en_US`
|
||||
* `typo_style`: The style string with which misspellings should be highlighted when using the _full viewport_ method
|
||||
* default: `fore:red`
|
||||
* `check_tokens`: A table mapping all token names we consider for spellchecking to true
|
||||
* default: `{[vis.lexers.STRING]=true, [vis.lexers.COMMENT]=true, [vis.lexers.DEFAULT]=true}`
|
||||
* `disable_syntax_awareness`: Disable the syntax aware spellchecking and use always _full viewport_
|
||||
* default: `false`
|
||||
|
||||
A possible configuration could look like this:
|
||||
|
||||
spellcheck = require(...)
|
||||
spellcheck.cmd = "aspell -l %s -a"
|
||||
spellcheck.list_cmd = "aspell list -l %s -a"
|
||||
spellcheck.default_lang = "de_DE"
|
||||
|
||||
Changing language during runtime:
|
||||
|
||||
:set spelllang en_US
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
-- Copyright (c) 2021 Florian Fischer. All rights reserved.
|
||||
-- Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
local source_str = debug.getinfo(1, 'S').source:sub(2)
|
||||
local script_path = source_str:match('(.*/)')
|
||||
|
||||
return dofile(script_path .. 'spellcheck.lua')
|
|
@ -0,0 +1,445 @@
|
|||
-- Copyright (c) 2017-2019 Florian Fischer. All rights reserved.
|
||||
-- Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
local spellcheck = {}
|
||||
if os.getenv('LANG') then
|
||||
spellcheck.default_lang = os.getenv('LANG'):sub(0, 5)
|
||||
else
|
||||
spellcheck.default_lang = 'es_US'
|
||||
end
|
||||
|
||||
spellcheck.get_lang = function()
|
||||
if vis.win.file.spell_language then
|
||||
return vis.win.file.spell_language
|
||||
else
|
||||
return spellcheck.default_lang
|
||||
end
|
||||
end
|
||||
|
||||
local supress_stdout = ' >/dev/null'
|
||||
local supress_stderr = ' 2>/dev/null'
|
||||
local supress_output = supress_stdout .. supress_stderr
|
||||
if os.execute('type enchant' .. supress_output) then
|
||||
spellcheck.cmd = 'aspell -l %s -a'
|
||||
spellcheck.list_cmd = 'aspell list -l %s -a'
|
||||
elseif os.execute('type enchant-2' .. supress_output) then
|
||||
spellcheck.cmd = 'enchant-2 -d %s -a'
|
||||
spellcheck.list_cmd = 'enchant-2 -l -d %s'
|
||||
elseif os.execute('type aspell' .. supress_output) then
|
||||
spellcheck.cmd = 'aspell pipe -l %s'
|
||||
spellcheck.list_cmd = 'aspell list -l %s'
|
||||
elseif os.execute('type hunspell' .. supress_output) then
|
||||
spellcheck.cmd = 'hunspell -d %s'
|
||||
spellcheck.list_cmd = 'hunspell -l -d %s'
|
||||
else
|
||||
vis:info('WARNING: vis-spellcheck loaded but no spellchecker found')
|
||||
return nil
|
||||
end
|
||||
|
||||
spellcheck.typo_style_id = 42
|
||||
spellcheck.typo_style = 'fore:red'
|
||||
spellcheck.check_full_viewport = {}
|
||||
spellcheck.disable_syntax_awareness = false
|
||||
|
||||
spellcheck.check_tokens = {
|
||||
[vis.lexers.STRING] = true,
|
||||
[vis.lexers.COMMENT] = true,
|
||||
[vis.lexers.DEFAULT] = true,
|
||||
}
|
||||
|
||||
-- Return nil or a string of misspelled word in a specific file range or text
|
||||
-- by calling the spellchecker's list command.
|
||||
-- If given a range we will use vis:pipe to get our typos from the spellchecker.
|
||||
-- If a string was passed we call the spellchecker ourself and redirect its stdout
|
||||
-- to a temporary file. See http://lua-users.org/lists/lua-l/2007-10/msg00189.html.
|
||||
-- The returned string consists of each misspell followed by a newline.
|
||||
local function get_typos(range_or_text)
|
||||
local cmd = spellcheck.list_cmd:format(spellcheck.get_lang())
|
||||
local typos
|
||||
if type(range_or_text) == 'string' then
|
||||
local text = range_or_text
|
||||
local tmp_name = os.tmpname()
|
||||
local full_cmd = cmd .. '> ' .. tmp_name .. supress_stderr
|
||||
local proc = assert(io.popen(full_cmd, 'w'))
|
||||
proc:write(text)
|
||||
-- this error detection may need lua5.2
|
||||
local success, _, exit_code = proc:close()
|
||||
if not success then
|
||||
vis:info('calling ' .. cmd .. ' failed (' .. exit_code .. ')')
|
||||
return nil
|
||||
end
|
||||
|
||||
local tmp_file = assert(io.open(tmp_name, 'r'))
|
||||
typos = tmp_file:read('*a')
|
||||
tmp_file:close()
|
||||
os.remove(tmp_name)
|
||||
else
|
||||
local range = range_or_text
|
||||
local ret, so, _ = vis:pipe(vis.win.file, range, cmd)
|
||||
|
||||
if ret ~= 0 then
|
||||
vis:info('calling ' .. cmd .. ' failed (' .. ret .. ')')
|
||||
return nil
|
||||
end
|
||||
typos = so
|
||||
end
|
||||
|
||||
return typos
|
||||
end
|
||||
|
||||
-- plugin global list of ignored typos
|
||||
local ignored = {}
|
||||
|
||||
-- Return an iterator over all not ignored typos and their positions in text.
|
||||
-- The returned iterator is a self contained statefull iterator function closure.
|
||||
-- Which will return the next typo and its start and finish in the text, starting by 1.
|
||||
local function typo_iter(text, typos, ignored) -- luacheck: ignore ignored
|
||||
local index = 1
|
||||
local unfiltered_iterator, iter_state = typos:gmatch('(.-)\n')
|
||||
|
||||
-- see https://stackoverflow.com/questions/6705872/how-to-escape-a-variable-in-lua
|
||||
local escape_lua_pattern
|
||||
do
|
||||
local matches = {
|
||||
['^'] = '%^',
|
||||
['$'] = '%$',
|
||||
['('] = '%(',
|
||||
[')'] = '%)',
|
||||
['%'] = '%%',
|
||||
['.'] = '%.',
|
||||
['['] = '%[',
|
||||
[']'] = '%]',
|
||||
['*'] = '%*',
|
||||
['+'] = '%+',
|
||||
['-'] = '%-',
|
||||
['?'] = '%?',
|
||||
}
|
||||
|
||||
escape_lua_pattern = function(s)
|
||||
return (s:gsub('.', matches))
|
||||
end
|
||||
end
|
||||
|
||||
return function()
|
||||
local typo
|
||||
repeat
|
||||
typo = unfiltered_iterator(iter_state)
|
||||
until (not typo or (typo ~= '' and not ignored[typo]))
|
||||
|
||||
if typo then
|
||||
-- to prevent typos from being found in correct words before them
|
||||
-- ("stuff stuf", "broken ok", ...)
|
||||
-- we match typos only when they are enclosed in non-letter characters.
|
||||
local start, finish = text:find('[%A]' .. escape_lua_pattern(typo) ..
|
||||
'[%A]', index)
|
||||
-- typo was not found by our pattern this means it must be either
|
||||
-- the first or last word in the text
|
||||
if not start then
|
||||
-- check start of text
|
||||
start = 1
|
||||
finish = #typo
|
||||
-- typo is not the beginning must be the end of text
|
||||
if text:sub(start, finish) ~= typo then
|
||||
start = #text - #typo + 1
|
||||
finish = start + #typo - 1
|
||||
end
|
||||
|
||||
if text:sub(start, finish) ~= typo then
|
||||
vis:info(string.format(
|
||||
'can\'t find typo %s after %d. Please report this bug.',
|
||||
typo, index))
|
||||
end
|
||||
-- our pettern [%A]typo[%A] found it
|
||||
else
|
||||
start = start + 1 -- ignore leading non letter char
|
||||
finish = finish - 1 -- ignore trailing non letter char
|
||||
end
|
||||
index = finish
|
||||
|
||||
return typo, start, finish
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local last_viewport, last_data, last_typos = nil, '', ''
|
||||
|
||||
vis.events.subscribe(vis.events.WIN_HIGHLIGHT, function(win)
|
||||
if not spellcheck.check_full_viewport[win] or
|
||||
not win:style_define(spellcheck.typo_style_id, spellcheck.typo_style) then
|
||||
return
|
||||
end
|
||||
local viewport = win.viewport
|
||||
local viewport_text = win.file:content(viewport)
|
||||
|
||||
local typos
|
||||
if last_viewport == viewport_text then
|
||||
typos = last_typos
|
||||
else
|
||||
typos = get_typos(viewport) or ''
|
||||
if not typos then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
for _, start, finish in typo_iter(viewport_text, typos, ignored) do
|
||||
win:style(spellcheck.typo_style_id, viewport.start + start - 1,
|
||||
viewport.start + finish - 1)
|
||||
end
|
||||
|
||||
last_viewport = viewport_text
|
||||
last_typos = typos
|
||||
-- TODO: think about returning true here
|
||||
-- http://martanne.github.io/vis/doc/index.html#Events
|
||||
-- The vis documentation states that a no further event handlers are called if one
|
||||
-- returns not nil
|
||||
-- Should we terminate the WIN_HIGHLIGHT event handling if we are ready highltighting
|
||||
-- typos ?
|
||||
return true
|
||||
end)
|
||||
|
||||
local wrapped_lex_funcs = {}
|
||||
|
||||
local wrap_lex_func = function(old_lex_func)
|
||||
local old_new_tokens = {}
|
||||
|
||||
return function(lexer, data, index, redrawtime_max)
|
||||
local tokens, timedout = old_lex_func(lexer, data, index, redrawtime_max)
|
||||
|
||||
-- quit early if the lexer already took to long
|
||||
-- TODO: investigate further if timedout is actually set by the lexer.
|
||||
-- As I understand lpeg.match used by lexer.lex timedout will always be nil
|
||||
if timedout then
|
||||
return tokens, timedout
|
||||
end
|
||||
|
||||
local new_tokens = {}
|
||||
|
||||
local typos
|
||||
if last_data ~= data then
|
||||
typos = get_typos(data)
|
||||
if not typos then
|
||||
return tokens, timedout
|
||||
end
|
||||
last_data = data
|
||||
else
|
||||
return old_new_tokens
|
||||
end
|
||||
|
||||
local i = 1
|
||||
for _, typo_start, typo_end in typo_iter(data, typos, ignored) do
|
||||
repeat
|
||||
-- no tokens left
|
||||
if i > #tokens - 1 then
|
||||
break
|
||||
end
|
||||
|
||||
local token_type = tokens[i]
|
||||
local token_start = (tokens[i - 1] or 1) - 1
|
||||
local token_end = tokens[i + 1]
|
||||
|
||||
-- the current token ends before our typo -> append to new stream
|
||||
-- or is not spellchecked
|
||||
if token_end < typo_start or not spellcheck.check_tokens[token_type] then
|
||||
table.insert(new_tokens, token_type)
|
||||
table.insert(new_tokens, token_end)
|
||||
|
||||
-- done with this token -> advance token stream
|
||||
i = i + 2
|
||||
-- typo and checked token overlap
|
||||
else
|
||||
local pre_typo_end = typo_start - 1
|
||||
-- unchanged token part before typo
|
||||
if pre_typo_end > token_start then
|
||||
table.insert(new_tokens, token_type)
|
||||
table.insert(new_tokens, pre_typo_end + 1)
|
||||
end
|
||||
|
||||
-- highlight typo
|
||||
table.insert(new_tokens, vis.lexers.ERROR)
|
||||
-- the typo spans multiple tokens
|
||||
if token_end < typo_end then
|
||||
table.insert(new_tokens, token_end + 1)
|
||||
i = i + 2
|
||||
else
|
||||
table.insert(new_tokens, typo_end + 1)
|
||||
end
|
||||
end
|
||||
until (not token_end or token_end >= typo_end)
|
||||
end
|
||||
|
||||
-- add tokens left after we handled all typos
|
||||
for i = i, #tokens, 1 do -- luacheck: ignore i
|
||||
table.insert(new_tokens, tokens[i])
|
||||
end
|
||||
|
||||
old_new_tokens = new_tokens
|
||||
return new_tokens, timedout
|
||||
end
|
||||
end
|
||||
|
||||
local enable_spellcheck = function()
|
||||
-- prevent wrapping the lex function multiple times
|
||||
if wrapped_lex_funcs[vis.win] then
|
||||
return
|
||||
end
|
||||
|
||||
if not spellcheck.disable_syntax_awareness and vis.win.syntax and
|
||||
vis.lexers.load then
|
||||
local lexer = vis.lexers.load(vis.win.syntax, nil, true)
|
||||
if lexer and lexer.lex then
|
||||
local old_lex_func = lexer.lex
|
||||
wrapped_lex_funcs[vis.win] = old_lex_func
|
||||
lexer.lex = wrap_lex_func(old_lex_func)
|
||||
-- reset last data to enforce new highlighting
|
||||
last_data = ''
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- fallback check spellcheck the full viewport
|
||||
spellcheck.check_full_viewport[vis.win] = true
|
||||
end
|
||||
|
||||
local is_spellcheck_enabled = function()
|
||||
return spellcheck.check_full_viewport[vis.win] or wrapped_lex_funcs[vis.win]
|
||||
end
|
||||
|
||||
vis:map(vis.modes.NORMAL, '<C-w>e', function()
|
||||
enable_spellcheck()
|
||||
end, 'Enable spellchecking in the current window')
|
||||
|
||||
local disable_spellcheck = function()
|
||||
local old_lex_func = wrapped_lex_funcs[vis.win]
|
||||
if old_lex_func then
|
||||
local lexer = vis.lexers.load(vis.win.syntax, nil, true)
|
||||
lexer.lex = old_lex_func
|
||||
wrapped_lex_funcs[vis.win] = nil
|
||||
else
|
||||
spellcheck.check_full_viewport[vis.win] = nil
|
||||
end
|
||||
end
|
||||
|
||||
vis:map(vis.modes.NORMAL, '<C-w>d', function()
|
||||
disable_spellcheck()
|
||||
-- force new highlight
|
||||
vis.win:draw()
|
||||
end, 'Disable spellchecking in the current window')
|
||||
|
||||
-- toggle spellchecking on <F7>
|
||||
-- <F7> is used by some word processors (LibreOffice) for spellchecking
|
||||
-- Thanks to @leorosa for the hint.
|
||||
vis:map(vis.modes.NORMAL, '<F7>', function()
|
||||
if not is_spellcheck_enabled() then
|
||||
enable_spellcheck()
|
||||
else
|
||||
disable_spellcheck()
|
||||
vis.win:draw()
|
||||
end
|
||||
return 0
|
||||
end, 'Toggle spellchecking in the current window')
|
||||
|
||||
vis:map(vis.modes.NORMAL, '<C-w>w', function()
|
||||
local win = vis.win
|
||||
local file = win.file
|
||||
local pos = win.selection.pos
|
||||
if not pos then
|
||||
return
|
||||
end
|
||||
local range = file:text_object_word(pos);
|
||||
if not range then
|
||||
return
|
||||
end
|
||||
if range.start == range.finish then
|
||||
return
|
||||
end
|
||||
|
||||
local cmd = spellcheck.cmd:format(spellcheck.get_lang())
|
||||
local ret, so, se = vis:pipe(win.file, range, cmd)
|
||||
if ret ~= 0 then
|
||||
vis:message('calling ' .. cmd .. ' failed (' .. se .. ')')
|
||||
return false
|
||||
end
|
||||
|
||||
local answer_line = so:match('.-\n(.-)\n.*')
|
||||
if not answer_line then
|
||||
return false
|
||||
end
|
||||
|
||||
local suggestions
|
||||
local first_char = answer_line:sub(0, 1)
|
||||
if first_char == '*' then
|
||||
vis:info(file:content(range) .. ' is correctly spelled')
|
||||
return true
|
||||
elseif first_char == '#' then
|
||||
vis:info('No corrections available for ' .. file:content(range))
|
||||
return false
|
||||
elseif first_char == '&' then
|
||||
suggestions = answer_line:match('& %S+ %d+ %d+: (.*)')
|
||||
else
|
||||
vis:info('Unknown answer: ' .. answer_line)
|
||||
return false
|
||||
end
|
||||
|
||||
-- select a correction
|
||||
cmd = 'printf "' .. suggestions:gsub(', ', '\\n') .. '\\n" | vis-menu'
|
||||
local status, correction = vis:pipe(file, {start = 0, finish = 0}, cmd)
|
||||
if status == 0 then
|
||||
-- trim correction
|
||||
correction = correction:match('^%s*(.-)%s*$')
|
||||
win.file:delete(range)
|
||||
win.file:insert(range.start, correction)
|
||||
end
|
||||
|
||||
win.selection.pos = pos
|
||||
|
||||
win:draw()
|
||||
|
||||
return 0
|
||||
end, 'Correct misspelled word')
|
||||
|
||||
vis:map(vis.modes.NORMAL, '<C-w>i', function()
|
||||
local win = vis.win
|
||||
local file = win.file
|
||||
local pos = win.selection.pos
|
||||
if not pos then
|
||||
return
|
||||
end
|
||||
local range = file:text_object_word(pos);
|
||||
if not range then
|
||||
return
|
||||
end
|
||||
if range.start == range.finish then
|
||||
return
|
||||
end
|
||||
|
||||
ignored[file:content(range)] = true
|
||||
|
||||
-- Check if we use our syntax aware spellcheck lex-closure
|
||||
-- We must rebuild the closure because it captures ignored
|
||||
-- to include the new addition
|
||||
local old_lex_func = wrapped_lex_funcs[vis.win]
|
||||
if old_lex_func then
|
||||
local lexer = vis.lexers.load(vis.win.syntax, nil, true)
|
||||
lexer.lex = wrap_lex_func(old_lex_func)
|
||||
-- reset last data to enforce new highlighting
|
||||
last_data = ''
|
||||
end
|
||||
|
||||
win:draw()
|
||||
return 0
|
||||
end, 'Ignore misspelled word')
|
||||
|
||||
vis:option_register('spelllang', 'string', function(value)
|
||||
vis.win.file.spell_language = value
|
||||
vis:info('Spellchecking language is now ' .. value)
|
||||
-- force new highlight for full viewport
|
||||
last_viewport = nil
|
||||
-- force new highlight for syntax aware
|
||||
last_data = nil
|
||||
return true
|
||||
end, 'The language used for spellchecking')
|
||||
|
||||
vis:command_register('spelllang', function()
|
||||
vis:info('The spellchecking language is ' .. spellcheck.get_lang())
|
||||
end, 'Print the language used for spellchecking')
|
||||
|
||||
return spellcheck
|
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh
|
||||
|
||||
LUA_FILE=$1
|
||||
lua-format "${LUA_FILE}" > "${LUA_FILE}.fmt"
|
||||
diff "${LUA_FILE}" "${LUA_FILE}.fmt"
|
||||
RET=$?
|
||||
rm "${LUA_FILE}.fmt"
|
||||
exit ${RET}
|
|
@ -0,0 +1,20 @@
|
|||
function vimMotions()
|
||||
-- make `_` move to the first non-whitespace character
|
||||
vis:command('map! normal _ ^')
|
||||
|
||||
end
|
||||
|
||||
function vimCommands()
|
||||
-- support :cq
|
||||
vis:command_register("cq", function(argv, force, win, selection, range)
|
||||
vis:command("qall")
|
||||
os.exit(-1)
|
||||
end)
|
||||
end
|
||||
|
||||
function vimCompatibilityInit()
|
||||
vimMotions()
|
||||
vimCommands()
|
||||
end
|
||||
|
||||
vimCompatibilityInit()
|
|
@ -0,0 +1,61 @@
|
|||
-- Base16-vis (https://github.com/pshevtsov/base16-vis)
|
||||
-- by Petr Shevtsov
|
||||
-- Grayscale Dark scheme by Alexandre Gavioli (https://github.com/Alexx2/)
|
||||
|
||||
local lexers = vis.lexers
|
||||
|
||||
local colors = {
|
||||
['base00'] = '#101010',
|
||||
['base01'] = '#252525',
|
||||
['base02'] = '#464646',
|
||||
['base03'] = '#525252',
|
||||
['base04'] = '#ababab',
|
||||
['base05'] = '#b9b9b9',
|
||||
['base06'] = '#e3e3e3',
|
||||
['base07'] = '#f7f7f7',
|
||||
['base08'] = '#7c7c7c',
|
||||
['base09'] = '#999999',
|
||||
['base0A'] = '#a0a0a0',
|
||||
['base0B'] = '#8e8e8e',
|
||||
['base0C'] = '#868686',
|
||||
['base0D'] = '#686868',
|
||||
['base0E'] = '#747474',
|
||||
['base0F'] = '#5e5e5e',
|
||||
}
|
||||
|
||||
local fg = ',fore:'..colors.base05..','
|
||||
local bg = ',back:'..colors.base00..','
|
||||
|
||||
lexers.STYLE_DEFAULT = bg..fg
|
||||
lexers.STYLE_NOTHING = bg
|
||||
lexers.STYLE_CLASS = 'fore:'..colors.base0A
|
||||
lexers.STYLE_COMMENT = 'fore:'..colors.base03..',italics'
|
||||
lexers.STYLE_CONSTANT = 'fore:'..colors.base09
|
||||
lexers.STYLE_DEFINITION = 'fore:'..colors.base0E
|
||||
lexers.STYLE_ERROR = 'fore:'..colors.base08..',italics'
|
||||
lexers.STYLE_FUNCTION = 'fore:'..colors.base0D
|
||||
lexers.STYLE_KEYWORD = 'fore:'..colors.base0E
|
||||
lexers.STYLE_LABEL = 'fore:'..colors.base0A
|
||||
lexers.STYLE_NUMBER = 'fore:'..colors.base09
|
||||
lexers.STYLE_OPERATOR = 'fore:'..colors.base05
|
||||
lexers.STYLE_REGEX = 'fore:'..colors.base0C
|
||||
lexers.STYLE_STRING = 'fore:'..colors.base0B
|
||||
lexers.STYLE_PREPROCESSOR = 'fore:'..colors.base0A
|
||||
lexers.STYLE_TAG = 'fore:'..colors.base0A
|
||||
lexers.STYLE_TYPE = 'fore:'..colors.base0A
|
||||
lexers.STYLE_VARIABLE = 'fore:'..colors.base0D
|
||||
lexers.STYLE_WHITESPACE = 'fore:'..colors.base02
|
||||
lexers.STYLE_EMBEDDED = 'fore:'..colors.base0F
|
||||
lexers.STYLE_IDENTIFIER = 'fore:'..colors.base08
|
||||
|
||||
lexers.STYLE_LINENUMBER = 'fore:'..colors.base02..',back:'..colors.base00
|
||||
lexers.STYLE_CURSOR = 'fore:'..colors.base00..',back:'..colors.base05
|
||||
lexers.STYLE_CURSOR_PRIMARY = 'fore:'..colors.base00..',back:'..colors.base05
|
||||
lexers.STYLE_CURSOR_LINE = 'back:'..colors.base01
|
||||
lexers.STYLE_COLOR_COLUMN = 'back:'..colors.base01
|
||||
lexers.STYLE_SELECTION = 'back:'..colors.base02
|
||||
lexers.STYLE_STATUS = 'fore:'..colors.base04..',back:'..colors.base01
|
||||
lexers.STYLE_STATUS_FOCUSED = 'fore:'..colors.base09..',back:'..colors.base01
|
||||
lexers.STYLE_SEPARATOR = lexers.STYLE_DEFAULT
|
||||
lexers.STYLE_INFO = 'fore:default,back:default,bold'
|
||||
lexers.STYLE_EOF = ''
|
|
@ -0,0 +1,37 @@
|
|||
-- Eight-color scheme
|
||||
local lexers = vis.lexers
|
||||
-- dark
|
||||
lexers.STYLE_DEFAULT ='back:black,fore:white'
|
||||
lexers.STYLE_NOTHING = 'back:black'
|
||||
lexers.STYLE_CLASS = 'fore:yellow,bold'
|
||||
lexers.STYLE_COMMENT = 'fore:blue,bold'
|
||||
lexers.STYLE_CONSTANT = 'fore:cyan,bold'
|
||||
lexers.STYLE_DEFINITION = 'fore:blue,bold'
|
||||
lexers.STYLE_ERROR = 'fore:red,italics'
|
||||
lexers.STYLE_FUNCTION = 'fore:blue,bold'
|
||||
lexers.STYLE_KEYWORD = 'fore:yellow,bold'
|
||||
lexers.STYLE_LABEL = 'fore:green,bold'
|
||||
lexers.STYLE_NUMBER = 'fore:red,bold'
|
||||
lexers.STYLE_OPERATOR = 'fore:cyan,bold'
|
||||
lexers.STYLE_REGEX = 'fore:green,bold'
|
||||
lexers.STYLE_STRING = 'fore:red,bold'
|
||||
lexers.STYLE_PREPROCESSOR = 'fore:magenta,bold'
|
||||
lexers.STYLE_TAG = 'fore:red,bold'
|
||||
lexers.STYLE_TYPE = 'fore:green,bold'
|
||||
lexers.STYLE_VARIABLE = 'fore:blue,bold'
|
||||
lexers.STYLE_WHITESPACE = ''
|
||||
lexers.STYLE_EMBEDDED = 'back:blue,bold'
|
||||
lexers.STYLE_IDENTIFIER = 'fore:white'
|
||||
|
||||
lexers.STYLE_LINENUMBER = 'fore:white'
|
||||
lexers.STYLE_LINENUMBER_CURSOR = lexers.STYLE_LINENUMBER
|
||||
lexers.STYLE_CURSOR = 'reverse'
|
||||
lexers.STYLE_CURSOR_PRIMARY = lexers.STYLE_CURSOR..',fore:yellow'
|
||||
lexers.STYLE_CURSOR_LINE = 'underlined'
|
||||
lexers.STYLE_COLOR_COLUMN = 'back:red'
|
||||
lexers.STYLE_SELECTION = 'back:white'
|
||||
lexers.STYLE_STATUS = 'reverse'
|
||||
lexers.STYLE_STATUS_FOCUSED = 'reverse,bold'
|
||||
lexers.STYLE_SEPARATOR = lexers.STYLE_DEFAULT
|
||||
lexers.STYLE_INFO = 'fore:default,back:default,bold'
|
||||
lexers.STYLE_EOF = ''
|
|
@ -0,0 +1 @@
|
|||
dark-16.lua
|
|
@ -0,0 +1 @@
|
|||
zenburn.lua
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue