Compare commits
No commits in common. "bare" and "master" have entirely different histories.
12
.bashrc
12
.bashrc
|
@ -1,12 +0,0 @@
|
||||||
alias l="ls -lah"
|
|
||||||
alias la="ls -ah"
|
|
||||||
alias ls="ls -h"
|
|
||||||
alias ll="ls -lh"
|
|
||||||
alias grep="grep --color"
|
|
||||||
alias egrep="grep -E"
|
|
||||||
alias lgrep="find | grep"
|
|
||||||
alias psgrep="ps axu | grep"
|
|
||||||
alias isotime='date +"%Y-%m-%dT%H:%M:%S%z"'
|
|
||||||
alias isodate='date +%Y-%m-%dT%H:%M:%S%z'
|
|
||||||
alias gls=/bin/ls
|
|
||||||
export HISTFILE=/dev/null
|
|
|
@ -0,0 +1,200 @@
|
||||||
|
#? Config file for btop v. 1.2.3
|
||||||
|
|
||||||
|
#* Name of a btop++/bpytop/bashtop formatted ".theme" file, "Default" and "TTY" for builtin themes.
|
||||||
|
#* Themes should be placed in "../share/btop/themes" relative to binary or "$HOME/.config/btop/themes"
|
||||||
|
color_theme = "gruvbox_dark_v2"
|
||||||
|
|
||||||
|
#* If the theme set background should be shown, set to False if you want terminal background transparency.
|
||||||
|
theme_background = False
|
||||||
|
|
||||||
|
#* Sets if 24-bit truecolor should be used, will convert 24-bit colors to 256 color (6x6x6 color cube) if false.
|
||||||
|
truecolor = True
|
||||||
|
|
||||||
|
#* Set to true to force tty mode regardless if a real tty has been detected or not.
|
||||||
|
#* Will force 16-color mode and TTY theme, set all graph symbols to "tty" and swap out other non tty friendly symbols.
|
||||||
|
force_tty = False
|
||||||
|
|
||||||
|
#* Define presets for the layout of the boxes. Preset 0 is always all boxes shown with default settings. Max 9 presets.
|
||||||
|
#* Format: "box_name:P:G,box_name:P:G" P=(0 or 1) for alternate positions, G=graph symbol to use for box.
|
||||||
|
#* Use withespace " " as separator between different presets.
|
||||||
|
#* Example: "cpu:0:default,mem:0:tty,proc:1:default cpu:0:braille,proc:0:tty"
|
||||||
|
presets = "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:default cpu:0:block,net:0:tty"
|
||||||
|
|
||||||
|
#* Set to True to enable "h,j,k,l" keys for directional control in lists.
|
||||||
|
#* Conflicting keys for h:"help" and k:"kill" is accessible while holding shift.
|
||||||
|
vim_keys = True
|
||||||
|
|
||||||
|
#* Rounded corners on boxes, is ignored if TTY mode is ON.
|
||||||
|
rounded_corners = True
|
||||||
|
|
||||||
|
#* Default symbols to use for graph creation, "braille", "block" or "tty".
|
||||||
|
#* "braille" offers the highest resolution but might not be included in all fonts.
|
||||||
|
#* "block" has half the resolution of braille but uses more common characters.
|
||||||
|
#* "tty" uses only 3 different symbols but will work with most fonts and should work in a real TTY.
|
||||||
|
#* Note that "tty" only has half the horizontal resolution of the other two, so will show a shorter historical view.
|
||||||
|
graph_symbol = "block"
|
||||||
|
|
||||||
|
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
|
||||||
|
graph_symbol_cpu = "default"
|
||||||
|
|
||||||
|
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
|
||||||
|
graph_symbol_mem = "default"
|
||||||
|
|
||||||
|
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
|
||||||
|
graph_symbol_net = "default"
|
||||||
|
|
||||||
|
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
|
||||||
|
graph_symbol_proc = "default"
|
||||||
|
|
||||||
|
#* Manually set which boxes to show. Available values are "cpu mem net proc", separate values with whitespace.
|
||||||
|
shown_boxes = "cpu mem net proc"
|
||||||
|
|
||||||
|
#* Update time in milliseconds, recommended 2000 ms or above for better sample times for graphs.
|
||||||
|
update_ms = 1000
|
||||||
|
|
||||||
|
#* Processes sorting, "pid" "program" "arguments" "threads" "user" "memory" "cpu lazy" "cpu responsive",
|
||||||
|
#* "cpu lazy" sorts top process over time (easier to follow), "cpu responsive" updates top process directly.
|
||||||
|
proc_sorting = "cpu direct"
|
||||||
|
|
||||||
|
#* Reverse sorting order, True or False.
|
||||||
|
proc_reversed = False
|
||||||
|
|
||||||
|
#* Show processes as a tree.
|
||||||
|
proc_tree = False
|
||||||
|
|
||||||
|
#* Use the cpu graph colors in the process list.
|
||||||
|
proc_colors = True
|
||||||
|
|
||||||
|
#* Use a darkening gradient in the process list.
|
||||||
|
proc_gradient = True
|
||||||
|
|
||||||
|
#* If process cpu usage should be of the core it's running on or usage of the total available cpu power.
|
||||||
|
proc_per_core = False
|
||||||
|
|
||||||
|
#* Show process memory as bytes instead of percent.
|
||||||
|
proc_mem_bytes = True
|
||||||
|
|
||||||
|
#* Use /proc/[pid]/smaps for memory information in the process info box (very slow but more accurate)
|
||||||
|
proc_info_smaps = False
|
||||||
|
|
||||||
|
#* Show proc box on left side of screen instead of right.
|
||||||
|
proc_left = False
|
||||||
|
|
||||||
|
#* Sets the CPU stat shown in upper half of the CPU graph, "total" is always available.
|
||||||
|
#* Select from a list of detected attributes from the options menu.
|
||||||
|
cpu_graph_upper = "total"
|
||||||
|
|
||||||
|
#* Sets the CPU stat shown in lower half of the CPU graph, "total" is always available.
|
||||||
|
#* Select from a list of detected attributes from the options menu.
|
||||||
|
cpu_graph_lower = "user"
|
||||||
|
|
||||||
|
#* Toggles if the lower CPU graph should be inverted.
|
||||||
|
cpu_invert_lower = False
|
||||||
|
|
||||||
|
#* Set to True to completely disable the lower CPU graph.
|
||||||
|
cpu_single_graph = False
|
||||||
|
|
||||||
|
#* Show cpu box at bottom of screen instead of top.
|
||||||
|
cpu_bottom = False
|
||||||
|
|
||||||
|
#* Shows the system uptime in the CPU box.
|
||||||
|
show_uptime = True
|
||||||
|
|
||||||
|
#* Show cpu temperature.
|
||||||
|
check_temp = True
|
||||||
|
|
||||||
|
#* Which sensor to use for cpu temperature, use options menu to select from list of available sensors.
|
||||||
|
cpu_sensor = "Auto"
|
||||||
|
|
||||||
|
#* Show temperatures for cpu cores also if check_temp is True and sensors has been found.
|
||||||
|
show_coretemp = True
|
||||||
|
|
||||||
|
#* Set a custom mapping between core and coretemp, can be needed on certain cpus to get correct temperature for correct core.
|
||||||
|
#* Use lm-sensors or similar to see which cores are reporting temperatures on your machine.
|
||||||
|
#* Format "x:y" x=core with wrong temp, y=core with correct temp, use space as separator between multiple entries.
|
||||||
|
#* Example: "4:0 5:1 6:3"
|
||||||
|
cpu_core_map = ""
|
||||||
|
|
||||||
|
#* Which temperature scale to use, available values: "celsius", "fahrenheit", "kelvin" and "rankine".
|
||||||
|
temp_scale = "celsius"
|
||||||
|
|
||||||
|
#* Use base 10 for bits/bytes sizes, KB = 1000 instead of KiB = 1024.
|
||||||
|
base_10_sizes = False
|
||||||
|
|
||||||
|
#* Show CPU frequency.
|
||||||
|
show_cpu_freq = True
|
||||||
|
|
||||||
|
#* Draw a clock at top of screen, formatting according to strftime, empty string to disable.
|
||||||
|
#* Special formatting: /host = hostname | /user = username | /uptime = system uptime
|
||||||
|
clock_format = "/user@/host %X"
|
||||||
|
|
||||||
|
#* Update main ui in background when menus are showing, set this to false if the menus is flickering too much for comfort.
|
||||||
|
background_update = True
|
||||||
|
|
||||||
|
#* Custom cpu model name, empty string to disable.
|
||||||
|
custom_cpu_name = ""
|
||||||
|
|
||||||
|
#* Optional filter for shown disks, should be full path of a mountpoint, separate multiple values with whitespace " ".
|
||||||
|
#* Begin line with "exclude=" to change to exclude filter, otherwise defaults to "most include" filter. Example: disks_filter="exclude=/boot /home/user".
|
||||||
|
disks_filter = "exclude=/boot /proc /boot/efi"
|
||||||
|
|
||||||
|
#* Show graphs instead of meters for memory values.
|
||||||
|
mem_graphs = True
|
||||||
|
|
||||||
|
#* Show mem box below net box instead of above.
|
||||||
|
mem_below_net = False
|
||||||
|
|
||||||
|
#* If swap memory should be shown in memory box.
|
||||||
|
show_swap = True
|
||||||
|
|
||||||
|
#* Show swap as a disk, ignores show_swap value above, inserts itself after first disk.
|
||||||
|
swap_disk = True
|
||||||
|
|
||||||
|
#* If mem box should be split to also show disks info.
|
||||||
|
show_disks = True
|
||||||
|
|
||||||
|
#* Filter out non physical disks. Set this to False to include network disks, RAM disks and similar.
|
||||||
|
only_physical = True
|
||||||
|
|
||||||
|
#* Read disks list from /etc/fstab. This also disables only_physical.
|
||||||
|
use_fstab = True
|
||||||
|
|
||||||
|
#* Set to true to show available disk space for privileged users.
|
||||||
|
disk_free_priv = False
|
||||||
|
|
||||||
|
#* Toggles if io activity % (disk busy time) should be shown in regular disk usage view.
|
||||||
|
show_io_stat = True
|
||||||
|
|
||||||
|
#* Toggles io mode for disks, showing big graphs for disk read/write speeds.
|
||||||
|
io_mode = True
|
||||||
|
|
||||||
|
#* Set to True to show combined read/write io graphs in io mode.
|
||||||
|
io_graph_combined = False
|
||||||
|
|
||||||
|
#* Set the top speed for the io graphs in MiB/s (100 by default), use format "mountpoint:speed" separate disks with whitespace " ".
|
||||||
|
#* Example: "/mnt/media:100 /:20 /boot:1".
|
||||||
|
io_graph_speeds = ""
|
||||||
|
|
||||||
|
#* Set fixed values for network graphs in Mebibits. Is only used if net_auto is also set to False.
|
||||||
|
net_download = 1000
|
||||||
|
|
||||||
|
net_upload = 100
|
||||||
|
|
||||||
|
#* Use network graphs auto rescaling mode, ignores any values set above and rescales down to 10 Kibibytes at the lowest.
|
||||||
|
net_auto = True
|
||||||
|
|
||||||
|
#* Sync the auto scaling for download and upload to whichever currently has the highest scale.
|
||||||
|
net_sync = True
|
||||||
|
|
||||||
|
#* Starts with the Network Interface specified here.
|
||||||
|
net_iface = ""
|
||||||
|
|
||||||
|
#* Show battery stats in top right if battery is present.
|
||||||
|
show_battery = True
|
||||||
|
|
||||||
|
#* Which battery to use if multiple are present. "Auto" for auto detection.
|
||||||
|
selected_battery = "Auto"
|
||||||
|
|
||||||
|
#* Set loglevel for "~/.config/btop/btop.log" levels are: "ERROR" "WARNING" "INFO" "DEBUG".
|
||||||
|
#* The level set includes all lower levels, i.e. "DEBUG" will show all logging info.
|
||||||
|
log_level = "WARNING"
|
|
@ -0,0 +1,40 @@
|
||||||
|
font_family FiraCode Nerd Font
|
||||||
|
font_size 15.0
|
||||||
|
disable_ligatures never
|
||||||
|
scrollback_pager nvim -c 'setlocal number|Man!' -c "autocmd VimEnter * normal G" -
|
||||||
|
enable_audio_bell no
|
||||||
|
visual_bell_duration 0.01
|
||||||
|
visual_bell_color yellow
|
||||||
|
window_alert_on_bell yes
|
||||||
|
bell_on_tab "🔔 "
|
||||||
|
tab_bar_edge top
|
||||||
|
tab_bar_style powerline
|
||||||
|
tab_powerline_style slanted
|
||||||
|
tab_title_template "{index} {fmt.fg.red}{bell_symbol}{activity_symbol}{fmt.fg.tab}{title}"
|
||||||
|
foreground #dddddd
|
||||||
|
background #111111
|
||||||
|
shell zsh
|
||||||
|
editor nvim
|
||||||
|
allow_remote_control socket-only
|
||||||
|
listen_on unix:///tmp/kitty.sock
|
||||||
|
env KITTY_TERM=TRUE
|
||||||
|
shell_integration enabled
|
||||||
|
|
||||||
|
# kitty-scrollback.nvim Kitten alias
|
||||||
|
action_alias kitty_scrollback_nvim kitten /home/plex/.local/share/nvim/lazy/kitty-scrollback.nvim/python/kitty_scrollback_nvim.py --nvim-args /tmp/kitty_scrollback.sh
|
||||||
|
|
||||||
|
# Browse scrollback buffer in nvim
|
||||||
|
map kitty_mod+h kitty_scrollback_nvim
|
||||||
|
# Browse output of the last shell command in nvim
|
||||||
|
map kitty_mod+g kitty_scrollback_nvim --config ksb_builtin_last_cmd_output
|
||||||
|
# Show clicked command output in nvim
|
||||||
|
mouse_map ctrl+shift+right press ungrabbed combine : mouse_select_command_output : kitty_scrollback_nvim --config ksb_builtin_last_visited_cmd_output
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
map alt+e next_tab
|
||||||
|
map alt+q previous_tab
|
||||||
|
# i want that for neovim
|
||||||
|
map ctrl+shift+s no_op
|
||||||
|
|
||||||
|
map shift+alt+f11 toggle_fullscreen
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 69118b111d4cc6dc78edd64a5a724b6871cccff4
|
|
@ -0,0 +1 @@
|
||||||
|
edition = "2021"
|
|
@ -0,0 +1,373 @@
|
||||||
|
[ActivityManager][Global Shortcuts]
|
||||||
|
switch-to-activity-=
|
||||||
|
switch-to-activity-9497743c-b928-4711-9a15-88ae73a36745=
|
||||||
|
switch-to-activity-b81d941f-2f97-41a3-ad5f-a685736616e0=
|
||||||
|
|
||||||
|
[KDE Keyboard Layout Switcher][Global Shortcuts]
|
||||||
|
Switch keyboard layout to German=
|
||||||
|
Switch to Next Keyboard Layout=Ctrl+Alt+K
|
||||||
|
|
||||||
|
[StandardShortcuts]
|
||||||
|
AboutApp=
|
||||||
|
AboutKDE=
|
||||||
|
Activate Next Tab=Ctrl+PgDown; Ctrl+]
|
||||||
|
Activate Previous Tab=Ctrl+PgUp; Ctrl+[
|
||||||
|
ActualSize=Ctrl+0
|
||||||
|
AddBookmark=Ctrl+B
|
||||||
|
Back=Back; Alt+Left
|
||||||
|
BackwardWord=Ctrl+Left
|
||||||
|
Begin=Ctrl+Home
|
||||||
|
BeginningOfLine=Home
|
||||||
|
Clear=
|
||||||
|
Close=Ctrl+W; Ctrl+Esc
|
||||||
|
ConfigureNotifications=
|
||||||
|
ConfigureToolbars=
|
||||||
|
Copy=Ctrl+Ins; Ctrl+C
|
||||||
|
CreateFolder=F10
|
||||||
|
Cut=Ctrl+X; Shift+Del
|
||||||
|
DeleteFile=Shift+Del
|
||||||
|
DeleteWordBack=Ctrl+Backspace
|
||||||
|
DeleteWordForward=Ctrl+Del
|
||||||
|
Deselect=Ctrl+Shift+A
|
||||||
|
DocumentBack=Alt+Shift+Left
|
||||||
|
DocumentForward=Alt+Shift+Right
|
||||||
|
Donate=
|
||||||
|
EditBookmarks=
|
||||||
|
End=Ctrl+End
|
||||||
|
EndOfLine=End
|
||||||
|
Find=Ctrl+F
|
||||||
|
FindNext=F3
|
||||||
|
FindPrev=Shift+F3
|
||||||
|
FitToHeight=
|
||||||
|
FitToPage=
|
||||||
|
FitToWidth=
|
||||||
|
Forward=Alt+Right; Forward
|
||||||
|
ForwardWord=Ctrl+Right
|
||||||
|
FullScreen=Ctrl+Shift+F
|
||||||
|
Goto=
|
||||||
|
GotoLine=Ctrl+G
|
||||||
|
GotoPage=
|
||||||
|
Help=F1
|
||||||
|
Home=Alt+Home; Home Page
|
||||||
|
KeyBindings=Ctrl+Alt+,
|
||||||
|
Mail=
|
||||||
|
MoveToTrash=Del
|
||||||
|
New=Ctrl+N
|
||||||
|
Next=PgDown
|
||||||
|
NextCompletion=Ctrl+Down
|
||||||
|
Open=Ctrl+O
|
||||||
|
OpenRecent=
|
||||||
|
Paste=Ctrl+V; Shift+Ins
|
||||||
|
Paste Selection=Ctrl+Shift+Ins
|
||||||
|
Preferences=Ctrl+Shift+,
|
||||||
|
PrevCompletion=Ctrl+Up
|
||||||
|
Print=Ctrl+P
|
||||||
|
PrintPreview=
|
||||||
|
Prior=PgUp
|
||||||
|
Quit=Ctrl+Q
|
||||||
|
Redo=Ctrl+Shift+Z
|
||||||
|
Reload=Refresh; F5
|
||||||
|
RenameFile=F2
|
||||||
|
Replace=Ctrl+R
|
||||||
|
ReportBug=
|
||||||
|
Revert=
|
||||||
|
RotateDown=Down
|
||||||
|
RotateUp=Up
|
||||||
|
Save=Ctrl+S
|
||||||
|
SaveAs=Ctrl+Shift+S
|
||||||
|
SaveOptions=
|
||||||
|
SelectAll=Ctrl+A
|
||||||
|
ShowHideHiddenFiles=Alt+.; Ctrl+H
|
||||||
|
ShowMenubar=Ctrl+M
|
||||||
|
ShowStatusbar=
|
||||||
|
ShowToolbar=
|
||||||
|
Spelling=
|
||||||
|
SubstringCompletion=Ctrl+T
|
||||||
|
SwitchApplicationLanguage=
|
||||||
|
TextCompletion=Ctrl+E
|
||||||
|
TipofDay=
|
||||||
|
Undo=Ctrl+Z
|
||||||
|
Up=Alt+Up
|
||||||
|
WhatsThis=Shift+F1
|
||||||
|
Zoom=
|
||||||
|
ZoomIn=Ctrl+=; Ctrl++
|
||||||
|
ZoomOut=Ctrl+-
|
||||||
|
|
||||||
|
[discord-screenaudio][Global Shortcuts]
|
||||||
|
toggleDeafen=
|
||||||
|
toggleMute=
|
||||||
|
|
||||||
|
[kaccess][Global Shortcuts]
|
||||||
|
Toggle Screen Reader On and Off=Meta+Alt+S
|
||||||
|
|
||||||
|
[kcm_touchpad][Global Shortcuts]
|
||||||
|
Disable Touchpad=Touchpad Off
|
||||||
|
Enable Touchpad=Touchpad On
|
||||||
|
Toggle Touchpad=Touchpad Toggle
|
||||||
|
|
||||||
|
[kded5][Global Shortcuts]
|
||||||
|
Show System Activity=Ctrl+Esc
|
||||||
|
display=Meta+P; Display
|
||||||
|
|
||||||
|
[khotkeys][Global Shortcuts]
|
||||||
|
{90040de6-4095-4f8e-b05b-8c65f08be0c0}=
|
||||||
|
{d03619b6-9b3c-48cc-9d9c-a2aadb485550}=
|
||||||
|
|
||||||
|
[kitty.desktop][Global Shortcuts]
|
||||||
|
_launch=Ctrl+Alt+T
|
||||||
|
|
||||||
|
[kmix][Global Shortcuts]
|
||||||
|
decrease_microphone_volume=Microphone Volume Down
|
||||||
|
decrease_volume=Volume Down
|
||||||
|
increase_microphone_volume=Microphone Volume Up
|
||||||
|
increase_volume=Volume Up
|
||||||
|
mic_mute=Microphone Mute; Meta+Volume Mute
|
||||||
|
mute=Volume Mute
|
||||||
|
|
||||||
|
[ksmserver][Global Shortcuts]
|
||||||
|
Halt Without Confirmation=
|
||||||
|
Lock Session=Screensaver; Meta+L; Ctrl+Alt+L
|
||||||
|
Log Out=Ctrl+Alt+Del
|
||||||
|
Log Out Without Confirmation=
|
||||||
|
Reboot Without Confirmation=
|
||||||
|
|
||||||
|
[kwin][Global Shortcuts]
|
||||||
|
Activate Window Demanding Attention=Ctrl+Alt+A
|
||||||
|
Decrease Opacity=
|
||||||
|
Expose=Ctrl+F9
|
||||||
|
ExposeAll=Launch (C); Ctrl+F10
|
||||||
|
ExposeClass=Ctrl+F7
|
||||||
|
Increase Opacity=
|
||||||
|
Invert Screen Colors=
|
||||||
|
Kill Window=Ctrl+Alt+Esc
|
||||||
|
MoveMouseToCenter=Meta+F6
|
||||||
|
MoveMouseToFocus=Meta+F5
|
||||||
|
MoveZoomDown=
|
||||||
|
MoveZoomLeft=
|
||||||
|
MoveZoomRight=
|
||||||
|
MoveZoomUp=
|
||||||
|
Setup Window Shortcut=
|
||||||
|
Show Desktop=Meta+D
|
||||||
|
ShowDesktopGrid=Ctrl+F8
|
||||||
|
Suspend Compositing=Alt+Shift+F12
|
||||||
|
Switch One Desktop Down=Ctrl+Alt+Down
|
||||||
|
Switch One Desktop Up=Ctrl+Alt+Up
|
||||||
|
Switch One Desktop to the Left=Ctrl+Alt+Left
|
||||||
|
Switch One Desktop to the Right=Ctrl+Alt+Right
|
||||||
|
Switch Window Down=Meta+Alt+Down
|
||||||
|
Switch Window Left=Meta+Alt+Left
|
||||||
|
Switch Window Right=Meta+Alt+Right
|
||||||
|
Switch Window Up=Meta+Alt+Up
|
||||||
|
Switch to Desktop 1=Ctrl+Alt+1; Ctrl+F1
|
||||||
|
Switch to Desktop 10=Ctrl+Alt+0
|
||||||
|
Switch to Desktop 11=
|
||||||
|
Switch to Desktop 12=
|
||||||
|
Switch to Desktop 13=
|
||||||
|
Switch to Desktop 14=
|
||||||
|
Switch to Desktop 15=
|
||||||
|
Switch to Desktop 16=
|
||||||
|
Switch to Desktop 17=
|
||||||
|
Switch to Desktop 18=
|
||||||
|
Switch to Desktop 19=
|
||||||
|
Switch to Desktop 2=Ctrl+F2; Ctrl+Alt+2
|
||||||
|
Switch to Desktop 20=
|
||||||
|
Switch to Desktop 3=Ctrl+F3; Ctrl+Alt+3
|
||||||
|
Switch to Desktop 4=Ctrl+F4; Ctrl+Alt+4
|
||||||
|
Switch to Desktop 5=Ctrl+Alt+5
|
||||||
|
Switch to Desktop 6=Ctrl+Alt+6
|
||||||
|
Switch to Desktop 7=Ctrl+Alt+7
|
||||||
|
Switch to Desktop 8=Ctrl+Alt+8
|
||||||
|
Switch to Desktop 9=Ctrl+Alt+9
|
||||||
|
Switch to Next Desktop=
|
||||||
|
Switch to Next Screen=
|
||||||
|
Switch to Previous Desktop=
|
||||||
|
Switch to Previous Screen=
|
||||||
|
Switch to Screen 0=
|
||||||
|
Switch to Screen 1=
|
||||||
|
Switch to Screen 2=
|
||||||
|
Switch to Screen 3=
|
||||||
|
Switch to Screen 4=
|
||||||
|
Switch to Screen 5=
|
||||||
|
Switch to Screen 6=
|
||||||
|
Switch to Screen 7=
|
||||||
|
Toggle Night Color=
|
||||||
|
Toggle Window Raise/Lower=
|
||||||
|
Walk Through Desktop List=
|
||||||
|
Walk Through Desktop List (Reverse)=
|
||||||
|
Walk Through Desktops=
|
||||||
|
Walk Through Desktops (Reverse)=
|
||||||
|
Walk Through Windows=Alt+Tab
|
||||||
|
Walk Through Windows (Reverse)=Alt+Shift+Backtab
|
||||||
|
Walk Through Windows Alternative=
|
||||||
|
Walk Through Windows Alternative (Reverse)=
|
||||||
|
Walk Through Windows of Current Application=Alt+`
|
||||||
|
Walk Through Windows of Current Application (Reverse)=Alt+~
|
||||||
|
Walk Through Windows of Current Application Alternative=
|
||||||
|
Walk Through Windows of Current Application Alternative (Reverse)=
|
||||||
|
Window Above Other Windows=Alt+F8
|
||||||
|
Window Below Other Windows=Alt+F7
|
||||||
|
Window Close=Alt+F4
|
||||||
|
Window Fullscreen=Alt+F11
|
||||||
|
Window Grow Horizontal=
|
||||||
|
Window Grow Vertical=
|
||||||
|
Window Lower=
|
||||||
|
Window Maximize=Meta+PgUp; Alt+F10
|
||||||
|
Window Maximize Horizontal=
|
||||||
|
Window Maximize Vertical=
|
||||||
|
Window Minimize=Meta+PgDown
|
||||||
|
Window Move=
|
||||||
|
Window Move Center=
|
||||||
|
Window No Border=
|
||||||
|
Window On All Desktops=Alt+F9
|
||||||
|
Window One Desktop Down=Meta+Ctrl+Shift+Down
|
||||||
|
Window One Desktop Up=Meta+Ctrl+Shift+Up
|
||||||
|
Window One Desktop to the Left=Meta+Ctrl+Shift+Left
|
||||||
|
Window One Desktop to the Right=Meta+Ctrl+Shift+Right
|
||||||
|
Window Operations Menu=Alt+F3
|
||||||
|
Window Pack Down=
|
||||||
|
Window Pack Left=
|
||||||
|
Window Pack Right=
|
||||||
|
Window Pack Up=
|
||||||
|
Window Quick Tile Bottom=Meta+Down
|
||||||
|
Window Quick Tile Bottom Left=
|
||||||
|
Window Quick Tile Bottom Right=
|
||||||
|
Window Quick Tile Left=Meta+Left
|
||||||
|
Window Quick Tile Right=Meta+Right
|
||||||
|
Window Quick Tile Top=Meta+Up
|
||||||
|
Window Quick Tile Top Left=
|
||||||
|
Window Quick Tile Top Right=
|
||||||
|
Window Raise=
|
||||||
|
Window Resize=
|
||||||
|
Window Shade=
|
||||||
|
Window Shrink Horizontal=
|
||||||
|
Window Shrink Vertical=
|
||||||
|
Window to Desktop 1=Ctrl+Alt+!
|
||||||
|
Window to Desktop 10=Ctrl+Alt+=
|
||||||
|
Window to Desktop 11=
|
||||||
|
Window to Desktop 12=
|
||||||
|
Window to Desktop 13=
|
||||||
|
Window to Desktop 14=
|
||||||
|
Window to Desktop 15=
|
||||||
|
Window to Desktop 16=
|
||||||
|
Window to Desktop 17=
|
||||||
|
Window to Desktop 18=
|
||||||
|
Window to Desktop 19=
|
||||||
|
Window to Desktop 2=Ctrl+Alt+"
|
||||||
|
Window to Desktop 20=
|
||||||
|
Window to Desktop 3=Ctrl+Alt+§
|
||||||
|
Window to Desktop 4=Ctrl+Alt+$
|
||||||
|
Window to Desktop 5=Ctrl+Alt+%
|
||||||
|
Window to Desktop 6=Ctrl+Alt+&
|
||||||
|
Window to Desktop 7=Ctrl+Alt+/
|
||||||
|
Window to Desktop 8=Ctrl+Alt+(
|
||||||
|
Window to Desktop 9=Ctrl+Alt+)
|
||||||
|
Window to Next Desktop=Ctrl+Alt+Shift+Right
|
||||||
|
Window to Next Screen=Meta+Shift+Right
|
||||||
|
Window to Previous Desktop=Ctrl+Alt+Shift+Left
|
||||||
|
Window to Previous Screen=Meta+Shift+Left
|
||||||
|
Window to Screen 0=
|
||||||
|
Window to Screen 1=
|
||||||
|
Window to Screen 2=
|
||||||
|
Window to Screen 3=
|
||||||
|
Window to Screen 4=
|
||||||
|
Window to Screen 5=
|
||||||
|
Window to Screen 6=
|
||||||
|
Window to Screen 7=
|
||||||
|
view_actual_size=Meta+0
|
||||||
|
view_zoom_in=Meta+=
|
||||||
|
view_zoom_out=Meta+-
|
||||||
|
|
||||||
|
[mediacontrol][Global Shortcuts]
|
||||||
|
mediavolumedown=
|
||||||
|
mediavolumeup=
|
||||||
|
nextmedia=Media Next
|
||||||
|
pausemedia=Media Pause
|
||||||
|
playmedia=
|
||||||
|
playpausemedia=Media Play
|
||||||
|
previousmedia=Media Previous
|
||||||
|
stopmedia=Media Stop
|
||||||
|
|
||||||
|
[org.kde.dolphin.desktop][Global Shortcuts]
|
||||||
|
_launch=Meta+E
|
||||||
|
|
||||||
|
[org.kde.krunner.desktop][Global Shortcuts]
|
||||||
|
RunClipboard=Alt+Shift+F2
|
||||||
|
_launch=Search; Alt+Space; Alt+F2
|
||||||
|
|
||||||
|
[org.kde.plasma.emojier.desktop][Global Shortcuts]
|
||||||
|
_launch=Meta+.
|
||||||
|
|
||||||
|
[org.kde.spectacle.desktop][Global Shortcuts]
|
||||||
|
ActiveWindowScreenShot=Meta+Print
|
||||||
|
CurrentMonitorScreenShot=
|
||||||
|
FullScreenScreenShot=
|
||||||
|
OpenWithoutScreenshot=
|
||||||
|
RectangularRegionScreenShot=Meta+Shift+Print; Print
|
||||||
|
WindowUnderCursorScreenShot=Meta+Ctrl+Print
|
||||||
|
_launch=Shift+Print
|
||||||
|
|
||||||
|
[org_kde_powerdevil][Global Shortcuts]
|
||||||
|
Decrease Keyboard Brightness=Keyboard Brightness Down
|
||||||
|
Decrease Screen Brightness=Monitor Brightness Down
|
||||||
|
Hibernate=Hibernate
|
||||||
|
Increase Keyboard Brightness=Keyboard Brightness Up
|
||||||
|
Increase Screen Brightness=Monitor Brightness Up
|
||||||
|
PowerDown=Power Down
|
||||||
|
PowerOff=Power Off
|
||||||
|
Sleep=Sleep
|
||||||
|
Toggle Keyboard Backlight=Keyboard Light On/Off
|
||||||
|
Turn Off Screen=
|
||||||
|
|
||||||
|
[plasmashell][Global Shortcuts]
|
||||||
|
activate task manager entry 1=Meta+1
|
||||||
|
activate task manager entry 10=
|
||||||
|
activate task manager entry 2=Meta+2
|
||||||
|
activate task manager entry 3=Meta+3
|
||||||
|
activate task manager entry 4=Meta+4
|
||||||
|
activate task manager entry 5=Meta+5
|
||||||
|
activate task manager entry 6=Meta+6
|
||||||
|
activate task manager entry 7=Meta+7
|
||||||
|
activate task manager entry 8=Meta+8
|
||||||
|
activate task manager entry 9=Meta+9
|
||||||
|
activate widget 18=Meta+C
|
||||||
|
activate widget 26=
|
||||||
|
activate widget 3=Alt+F1
|
||||||
|
activate widget 47=
|
||||||
|
activate widget 75=
|
||||||
|
clear-history=
|
||||||
|
clipboard_action=Ctrl+Alt+X
|
||||||
|
cycleNextAction=
|
||||||
|
cyclePrevAction=
|
||||||
|
edit_clipboard=
|
||||||
|
manage activities=Meta+Q
|
||||||
|
next activity=Meta+Tab; Meta+A
|
||||||
|
previous activity=Meta+Shift+Tab
|
||||||
|
repeat_action=Ctrl+Alt+R
|
||||||
|
show dashboard=Ctrl+F12
|
||||||
|
show-barcode=
|
||||||
|
show-on-mouse-pos=Meta+V
|
||||||
|
stop current activity=Meta+S
|
||||||
|
switch to next activity=
|
||||||
|
switch to previous activity=
|
||||||
|
toggle do not disturb=
|
||||||
|
|
||||||
|
[systemsettings.desktop][Global Shortcuts]
|
||||||
|
_launch=Tools
|
||||||
|
kcm-kscreen=
|
||||||
|
kcm-lookandfeel=
|
||||||
|
kcm-users=
|
||||||
|
powerdevilprofilesconfig=
|
||||||
|
screenlocker=
|
||||||
|
|
||||||
|
[wacomtablet][Global Shortcuts]
|
||||||
|
Map to fullscreen=Meta+Ctrl+F
|
||||||
|
Map to screen 1=Meta+Ctrl+1
|
||||||
|
Map to screen 2=Meta+Ctrl+2
|
||||||
|
Next Profile=Meta+Ctrl+N
|
||||||
|
Previous Profile=Meta+Ctrl+P
|
||||||
|
Toggle screen map selection=Meta+Ctrl+M
|
||||||
|
Toggle stylus mode=Meta+Ctrl+S
|
||||||
|
Toggle touch tool=Meta+Ctrl+T
|
||||||
|
|
||||||
|
[yakuake][Global Shortcuts]
|
||||||
|
toggle-window-state=Shift+F12
|
|
@ -0,0 +1,15 @@
|
||||||
|
# This file is written by xdg-user-dirs-update
|
||||||
|
# If you want to change or add directories, just edit the line you're
|
||||||
|
# interested in. All local changes will be retained on the next run.
|
||||||
|
# Format is XDG_xxx_DIR="$HOME/yyy", where yyy is a shell-escaped
|
||||||
|
# homedir-relative path, or XDG_xxx_DIR="/yyy", where /yyy is an
|
||||||
|
# absolute path. No other format is supported.
|
||||||
|
#
|
||||||
|
XDG_DESKTOP_DIR="$HOME/Desktop/"
|
||||||
|
XDG_DOWNLOAD_DIR="$HOME/Downloads"
|
||||||
|
XDG_TEMPLATES_DIR="$HOME/Templates"
|
||||||
|
XDG_PUBLICSHARE_DIR="$HOME/"
|
||||||
|
XDG_DOCUMENTS_DIR="$HOME/Documents"
|
||||||
|
XDG_MUSIC_DIR="$HOME/"
|
||||||
|
XDG_PICTURES_DIR="$HOME/Pictures"
|
||||||
|
XDG_VIDEOS_DIR="$HOME/Videos"
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
wips=$(git log --oneline --no-decorate | grep -i wip )
|
||||||
|
wips_n=$(echo "$wips" | wc -l)
|
||||||
|
LOCKFILE=/tmp/githook.allow_wip
|
||||||
|
|
||||||
|
if [[ ! -f $LOCKFILE && -n "$wips" ]]; then
|
||||||
|
# Allows us to read user input below, assigns stdin to keyboard
|
||||||
|
exec < /dev/tty
|
||||||
|
echo "contains $wips_n WIP commit(s)"
|
||||||
|
read -p "Really push? (Y/N) " -n 1 -r
|
||||||
|
case "$REPLY" in
|
||||||
|
y|Y ) echo -e "\ncontinuing..."; touch $LOCKFILE;;
|
||||||
|
* ) echo -e "\naborting."; exit 1;;
|
||||||
|
esac
|
||||||
|
fi
|
|
@ -0,0 +1,37 @@
|
||||||
|
# ignore all
|
||||||
|
*
|
||||||
|
|
||||||
|
# except:
|
||||||
|
!.zshrc
|
||||||
|
!.zprofile
|
||||||
|
!.vimrc
|
||||||
|
!.ideavimrc
|
||||||
|
!.githooks
|
||||||
|
!.githooks/**
|
||||||
|
!.config
|
||||||
|
!.config/nvim
|
||||||
|
!.config/nvim/**
|
||||||
|
!.config/btop
|
||||||
|
!.config/btop/**
|
||||||
|
!.config/kitty
|
||||||
|
!.config/kitty/**
|
||||||
|
!.config/rustfmt/**
|
||||||
|
!.config/rustfmt/
|
||||||
|
!.gitignore
|
||||||
|
!.zsh
|
||||||
|
!.zsh/**
|
||||||
|
!.tmux.conf
|
||||||
|
!.local/fzf
|
||||||
|
!.local/fzf/**
|
||||||
|
!.local/nvim
|
||||||
|
!.local/nvim/**
|
||||||
|
!.local/share/nvim
|
||||||
|
!.local/share/nvim/**
|
||||||
|
!.terminfo
|
||||||
|
!.terminfo/**
|
||||||
|
!.config/shortkuts.kksrc
|
||||||
|
!.config/user-dirs.dirs
|
||||||
|
|
||||||
|
# except except
|
||||||
|
.config/btop/btop.log
|
||||||
|
.config/btop/btop.log
|
|
@ -0,0 +1,9 @@
|
||||||
|
[submodule "NvChad"]
|
||||||
|
path = .config/nvim
|
||||||
|
url = https://git.cscherr.de/PlexSheep/neovim-confs
|
||||||
|
[submodule "nvchad-custom"]
|
||||||
|
path = .custon/nvim/lua/custom
|
||||||
|
url = https://git.cscherr.de/PlexSheep/nvchad-custom
|
||||||
|
[submodule ".zsh/plugins/zsh-autoquoter"]
|
||||||
|
path = .zsh/plugins/zsh-autoquoter
|
||||||
|
url = https://github.com/ianthehenry/zsh-autoquoter
|
|
@ -0,0 +1,26 @@
|
||||||
|
"" Source your .vimrc
|
||||||
|
source /home/plex/.vimrc
|
||||||
|
|
||||||
|
"" -- Suggested options --
|
||||||
|
" Show a few lines of context around the cursor. Note that this makes the
|
||||||
|
" text scroll if you mouse-click near the start or end of the window.
|
||||||
|
set scrolloff=5
|
||||||
|
|
||||||
|
" Do incremental searching.
|
||||||
|
set incsearch
|
||||||
|
|
||||||
|
" Do the joining with the ide
|
||||||
|
set ideajoin
|
||||||
|
|
||||||
|
"" -- Map IDE actions to IdeaVim -- https://jb.gg/abva4t
|
||||||
|
"" Map \r to the Reformat Code action
|
||||||
|
"map \r <Action>(ReformatCode)
|
||||||
|
|
||||||
|
"" Map <leader>d to start debug
|
||||||
|
"map <leader>d <Action>(Debug)
|
||||||
|
|
||||||
|
"" Map \b to toggle the breakpoint on the current line
|
||||||
|
"map \b <Action>(ToggleLineBreakpoint)
|
||||||
|
|
||||||
|
|
||||||
|
" Find more examples here: https://jb.gg/share-ideavimrc
|
|
@ -0,0 +1,381 @@
|
||||||
|
# ____ ____
|
||||||
|
# / __/___ / __/
|
||||||
|
# / /_/_ / / /_
|
||||||
|
# / __/ / /_/ __/
|
||||||
|
# /_/ /___/_/ completion.bash
|
||||||
|
#
|
||||||
|
# - $FZF_TMUX (default: 0)
|
||||||
|
# - $FZF_TMUX_OPTS (default: empty)
|
||||||
|
# - $FZF_COMPLETION_TRIGGER (default: '**')
|
||||||
|
# - $FZF_COMPLETION_OPTS (default: empty)
|
||||||
|
|
||||||
|
if [[ $- =~ i ]]; then
|
||||||
|
|
||||||
|
# To use custom commands instead of find, override _fzf_compgen_{path,dir}
|
||||||
|
if ! declare -f _fzf_compgen_path > /dev/null; then
|
||||||
|
_fzf_compgen_path() {
|
||||||
|
echo "$1"
|
||||||
|
command find -L "$1" \
|
||||||
|
-name .git -prune -o -name .hg -prune -o -name .svn -prune -o \( -type d -o -type f -o -type l \) \
|
||||||
|
-a -not -path "$1" -print 2> /dev/null | sed 's@^\./@@'
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! declare -f _fzf_compgen_dir > /dev/null; then
|
||||||
|
_fzf_compgen_dir() {
|
||||||
|
command find -L "$1" \
|
||||||
|
-name .git -prune -o -name .hg -prune -o -name .svn -prune -o -type d \
|
||||||
|
-a -not -path "$1" -print 2> /dev/null | sed 's@^\./@@'
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
###########################################################
|
||||||
|
|
||||||
|
# To redraw line after fzf closes (printf '\e[5n')
|
||||||
|
bind '"\e[0n": redraw-current-line' 2> /dev/null
|
||||||
|
|
||||||
|
__fzf_comprun() {
|
||||||
|
if [[ "$(type -t _fzf_comprun 2>&1)" = function ]]; then
|
||||||
|
_fzf_comprun "$@"
|
||||||
|
elif [[ -n "${TMUX_PANE-}" ]] && { [[ "${FZF_TMUX:-0}" != 0 ]] || [[ -n "${FZF_TMUX_OPTS-}" ]]; }; then
|
||||||
|
shift
|
||||||
|
fzf-tmux ${FZF_TMUX_OPTS:--d${FZF_TMUX_HEIGHT:-40%}} -- "$@"
|
||||||
|
else
|
||||||
|
shift
|
||||||
|
fzf "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
__fzf_orig_completion() {
|
||||||
|
local l comp f cmd
|
||||||
|
while read -r l; do
|
||||||
|
if [[ "$l" =~ ^(.*\ -F)\ *([^ ]*).*\ ([^ ]*)$ ]]; then
|
||||||
|
comp="${BASH_REMATCH[1]}"
|
||||||
|
f="${BASH_REMATCH[2]}"
|
||||||
|
cmd="${BASH_REMATCH[3]}"
|
||||||
|
[[ "$f" = _fzf_* ]] && continue
|
||||||
|
printf -v "_fzf_orig_completion_${cmd//[^A-Za-z0-9_]/_}" "%s" "${comp} %s ${cmd} #${f}"
|
||||||
|
if [[ "$l" = *" -o nospace "* ]] && [[ ! "${__fzf_nospace_commands-}" = *" $cmd "* ]]; then
|
||||||
|
__fzf_nospace_commands="${__fzf_nospace_commands-} $cmd "
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
_fzf_opts_completion() {
|
||||||
|
local cur prev opts
|
||||||
|
COMPREPLY=()
|
||||||
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
|
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||||
|
opts="
|
||||||
|
-x --extended
|
||||||
|
-e --exact
|
||||||
|
--algo
|
||||||
|
-i +i
|
||||||
|
-n --nth
|
||||||
|
--with-nth
|
||||||
|
-d --delimiter
|
||||||
|
+s --no-sort
|
||||||
|
--tac
|
||||||
|
--tiebreak
|
||||||
|
-m --multi
|
||||||
|
--no-mouse
|
||||||
|
--bind
|
||||||
|
--cycle
|
||||||
|
--no-hscroll
|
||||||
|
--jump-labels
|
||||||
|
--height
|
||||||
|
--literal
|
||||||
|
--reverse
|
||||||
|
--margin
|
||||||
|
--inline-info
|
||||||
|
--prompt
|
||||||
|
--pointer
|
||||||
|
--marker
|
||||||
|
--header
|
||||||
|
--header-lines
|
||||||
|
--ansi
|
||||||
|
--tabstop
|
||||||
|
--color
|
||||||
|
--no-bold
|
||||||
|
--history
|
||||||
|
--history-size
|
||||||
|
--preview
|
||||||
|
--preview-window
|
||||||
|
-q --query
|
||||||
|
-1 --select-1
|
||||||
|
-0 --exit-0
|
||||||
|
-f --filter
|
||||||
|
--print-query
|
||||||
|
--expect
|
||||||
|
--sync"
|
||||||
|
|
||||||
|
case "${prev}" in
|
||||||
|
--tiebreak)
|
||||||
|
COMPREPLY=( $(compgen -W "length begin end index" -- "$cur") )
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
--color)
|
||||||
|
COMPREPLY=( $(compgen -W "dark light 16 bw" -- "$cur") )
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
--history)
|
||||||
|
COMPREPLY=()
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [[ "$cur" =~ ^-|\+ ]]; then
|
||||||
|
COMPREPLY=( $(compgen -W "${opts}" -- "$cur") )
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_fzf_handle_dynamic_completion() {
|
||||||
|
local cmd orig_var orig ret orig_cmd orig_complete
|
||||||
|
cmd="$1"
|
||||||
|
shift
|
||||||
|
orig_cmd="$1"
|
||||||
|
orig_var="_fzf_orig_completion_$cmd"
|
||||||
|
orig="${!orig_var-}"
|
||||||
|
orig="${orig##*#}"
|
||||||
|
if [[ -n "$orig" ]] && type "$orig" > /dev/null 2>&1; then
|
||||||
|
$orig "$@"
|
||||||
|
elif [[ -n "${_fzf_completion_loader-}" ]]; then
|
||||||
|
orig_complete=$(complete -p "$orig_cmd" 2> /dev/null)
|
||||||
|
_completion_loader "$@"
|
||||||
|
ret=$?
|
||||||
|
# _completion_loader may not have updated completion for the command
|
||||||
|
if [[ "$(complete -p "$orig_cmd" 2> /dev/null)" != "$orig_complete" ]]; then
|
||||||
|
__fzf_orig_completion < <(complete -p "$orig_cmd" 2> /dev/null)
|
||||||
|
if [[ "${__fzf_nospace_commands-}" = *" $orig_cmd "* ]]; then
|
||||||
|
eval "${orig_complete/ -F / -o nospace -F }"
|
||||||
|
else
|
||||||
|
eval "$orig_complete"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
return $ret
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
__fzf_generic_path_completion() {
|
||||||
|
local cur base dir leftover matches trigger cmd
|
||||||
|
cmd="${COMP_WORDS[0]}"
|
||||||
|
if [[ $cmd == \\* ]]; then
|
||||||
|
cmd="${cmd:1}"
|
||||||
|
fi
|
||||||
|
cmd="${cmd//[^A-Za-z0-9_=]/_}"
|
||||||
|
COMPREPLY=()
|
||||||
|
trigger=${FZF_COMPLETION_TRIGGER-'**'}
|
||||||
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
|
if [[ "$cur" == *"$trigger" ]]; then
|
||||||
|
base=${cur:0:${#cur}-${#trigger}}
|
||||||
|
eval "base=$base"
|
||||||
|
|
||||||
|
dir=
|
||||||
|
[[ $base = *"/"* ]] && dir="$base"
|
||||||
|
while true; do
|
||||||
|
if [[ -z "$dir" ]] || [[ -d "$dir" ]]; then
|
||||||
|
leftover=${base/#"$dir"}
|
||||||
|
leftover=${leftover/#\/}
|
||||||
|
[[ -z "$dir" ]] && dir='.'
|
||||||
|
[[ "$dir" != "/" ]] && dir="${dir/%\//}"
|
||||||
|
matches=$(eval "$1 $(printf %q "$dir")" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore ${FZF_DEFAULT_OPTS-} ${FZF_COMPLETION_OPTS-} $2" __fzf_comprun "$4" -q "$leftover" | while read -r item; do
|
||||||
|
printf "%q " "${item%$3}$3"
|
||||||
|
done)
|
||||||
|
matches=${matches% }
|
||||||
|
[[ -z "$3" ]] && [[ "${__fzf_nospace_commands-}" = *" ${COMP_WORDS[0]} "* ]] && matches="$matches "
|
||||||
|
if [[ -n "$matches" ]]; then
|
||||||
|
COMPREPLY=( "$matches" )
|
||||||
|
else
|
||||||
|
COMPREPLY=( "$cur" )
|
||||||
|
fi
|
||||||
|
printf '\e[5n'
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
dir=$(dirname "$dir")
|
||||||
|
[[ "$dir" =~ /$ ]] || dir="$dir"/
|
||||||
|
done
|
||||||
|
else
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
_fzf_handle_dynamic_completion "$cmd" "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_fzf_complete() {
|
||||||
|
# Split arguments around --
|
||||||
|
local args rest str_arg i sep
|
||||||
|
args=("$@")
|
||||||
|
sep=
|
||||||
|
for i in "${!args[@]}"; do
|
||||||
|
if [[ "${args[$i]}" = -- ]]; then
|
||||||
|
sep=$i
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ -n "$sep" ]]; then
|
||||||
|
str_arg=
|
||||||
|
rest=("${args[@]:$((sep + 1)):${#args[@]}}")
|
||||||
|
args=("${args[@]:0:$sep}")
|
||||||
|
else
|
||||||
|
str_arg=$1
|
||||||
|
args=()
|
||||||
|
shift
|
||||||
|
rest=("$@")
|
||||||
|
fi
|
||||||
|
|
||||||
|
local cur selected trigger cmd post
|
||||||
|
post="$(caller 0 | awk '{print $2}')_post"
|
||||||
|
type -t "$post" > /dev/null 2>&1 || post=cat
|
||||||
|
|
||||||
|
cmd="${COMP_WORDS[0]//[^A-Za-z0-9_=]/_}"
|
||||||
|
trigger=${FZF_COMPLETION_TRIGGER-'**'}
|
||||||
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
|
if [[ "$cur" == *"$trigger" ]]; then
|
||||||
|
cur=${cur:0:${#cur}-${#trigger}}
|
||||||
|
|
||||||
|
selected=$(FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore ${FZF_DEFAULT_OPTS-} ${FZF_COMPLETION_OPTS-} $str_arg" __fzf_comprun "${rest[0]}" "${args[@]}" -q "$cur" | $post | tr '\n' ' ')
|
||||||
|
selected=${selected% } # Strip trailing space not to repeat "-o nospace"
|
||||||
|
if [[ -n "$selected" ]]; then
|
||||||
|
COMPREPLY=("$selected")
|
||||||
|
else
|
||||||
|
COMPREPLY=("$cur")
|
||||||
|
fi
|
||||||
|
printf '\e[5n'
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_fzf_handle_dynamic_completion "$cmd" "${rest[@]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_fzf_path_completion() {
|
||||||
|
__fzf_generic_path_completion _fzf_compgen_path "-m" "" "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Deprecated. No file only completion.
|
||||||
|
_fzf_file_completion() {
|
||||||
|
_fzf_path_completion "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
_fzf_dir_completion() {
|
||||||
|
__fzf_generic_path_completion _fzf_compgen_dir "" "/" "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
_fzf_complete_kill() {
|
||||||
|
_fzf_proc_completion "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
_fzf_proc_completion() {
|
||||||
|
_fzf_complete -m --preview 'echo {}' --preview-window down:3:wrap --min-height 15 -- "$@" < <(
|
||||||
|
command ps -ef | sed 1d
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
_fzf_proc_completion_post() {
|
||||||
|
awk '{print $2}'
|
||||||
|
}
|
||||||
|
|
||||||
|
_fzf_host_completion() {
|
||||||
|
_fzf_complete +m -- "$@" < <(
|
||||||
|
command cat <(command tail -n +1 ~/.ssh/config ~/.ssh/config.d/* /etc/ssh/ssh_config 2> /dev/null | command grep -i '^\s*host\(name\)\? ' | awk '{for (i = 2; i <= NF; i++) print $1 " " $i}' | command grep -v '[*?%]') \
|
||||||
|
<(command grep -oE '^[[a-z0-9.,:-]+' ~/.ssh/known_hosts | tr ',' '\n' | tr -d '[' | awk '{ print $1 " " $1 }') \
|
||||||
|
<(command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0') |
|
||||||
|
awk '{if (length($2) > 0) {print $2}}' | sort -u
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
_fzf_var_completion() {
|
||||||
|
_fzf_complete -m -- "$@" < <(
|
||||||
|
declare -xp | sed -En 's|^declare [^ ]+ ([^=]+).*|\1|p'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
_fzf_alias_completion() {
|
||||||
|
_fzf_complete -m -- "$@" < <(
|
||||||
|
alias | sed -En 's|^alias ([^=]+).*|\1|p'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
# fzf options
|
||||||
|
complete -o default -F _fzf_opts_completion fzf
|
||||||
|
# fzf-tmux is a thin fzf wrapper that has only a few more options than fzf
|
||||||
|
# itself. As a quick improvement we take fzf's completion. Adding the few extra
|
||||||
|
# fzf-tmux specific options (like `-w WIDTH`) are left as a future patch.
|
||||||
|
complete -o default -F _fzf_opts_completion fzf-tmux
|
||||||
|
|
||||||
|
d_cmds="${FZF_COMPLETION_DIR_COMMANDS:-cd pushd rmdir}"
|
||||||
|
a_cmds="
|
||||||
|
awk cat diff diff3
|
||||||
|
emacs emacsclient ex file ftp g++ gcc gvim head hg java
|
||||||
|
javac ld less more mvim nvim patch perl python ruby
|
||||||
|
sed sftp sort source tail tee uniq vi view vim wc xdg-open
|
||||||
|
basename bunzip2 bzip2 chmod chown curl cp dirname du
|
||||||
|
find git grep gunzip gzip hg jar
|
||||||
|
ln ls mv open rm rsync scp
|
||||||
|
svn tar unzip zip"
|
||||||
|
|
||||||
|
# Preserve existing completion
|
||||||
|
__fzf_orig_completion < <(complete -p $d_cmds $a_cmds 2> /dev/null)
|
||||||
|
|
||||||
|
if type _completion_loader > /dev/null 2>&1; then
|
||||||
|
_fzf_completion_loader=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
__fzf_defc() {
|
||||||
|
local cmd func opts orig_var orig def
|
||||||
|
cmd="$1"
|
||||||
|
func="$2"
|
||||||
|
opts="$3"
|
||||||
|
orig_var="_fzf_orig_completion_${cmd//[^A-Za-z0-9_]/_}"
|
||||||
|
orig="${!orig_var-}"
|
||||||
|
if [[ -n "$orig" ]]; then
|
||||||
|
printf -v def "$orig" "$func"
|
||||||
|
eval "$def"
|
||||||
|
else
|
||||||
|
complete -F "$func" $opts "$cmd"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Anything
|
||||||
|
for cmd in $a_cmds; do
|
||||||
|
__fzf_defc "$cmd" _fzf_path_completion "-o default -o bashdefault"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Directory
|
||||||
|
for cmd in $d_cmds; do
|
||||||
|
__fzf_defc "$cmd" _fzf_dir_completion "-o nospace -o dirnames"
|
||||||
|
done
|
||||||
|
|
||||||
|
unset cmd d_cmds a_cmds
|
||||||
|
|
||||||
|
_fzf_setup_completion() {
|
||||||
|
local kind fn cmd
|
||||||
|
kind=$1
|
||||||
|
fn=_fzf_${1}_completion
|
||||||
|
if [[ $# -lt 2 ]] || ! type -t "$fn" > /dev/null; then
|
||||||
|
echo "usage: ${FUNCNAME[0]} path|dir|var|alias|host|proc COMMANDS..."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
__fzf_orig_completion < <(complete -p "$@" 2> /dev/null)
|
||||||
|
for cmd in "$@"; do
|
||||||
|
case "$kind" in
|
||||||
|
dir) __fzf_defc "$cmd" "$fn" "-o nospace -o dirnames" ;;
|
||||||
|
var) __fzf_defc "$cmd" "$fn" "-o default -o nospace -v" ;;
|
||||||
|
alias) __fzf_defc "$cmd" "$fn" "-a" ;;
|
||||||
|
*) __fzf_defc "$cmd" "$fn" "-o default -o bashdefault" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Environment variables / Aliases / Hosts / Process
|
||||||
|
_fzf_setup_completion 'var' export unset
|
||||||
|
_fzf_setup_completion 'alias' unalias
|
||||||
|
_fzf_setup_completion 'host' ssh telnet
|
||||||
|
_fzf_setup_completion 'proc' kill
|
||||||
|
|
||||||
|
fi
|
|
@ -0,0 +1,324 @@
|
||||||
|
# ____ ____
|
||||||
|
# / __/___ / __/
|
||||||
|
# / /_/_ / / /_
|
||||||
|
# / __/ / /_/ __/
|
||||||
|
# /_/ /___/_/ completion.zsh
|
||||||
|
#
|
||||||
|
# - $FZF_TMUX (default: 0)
|
||||||
|
# - $FZF_TMUX_OPTS (default: '-d 40%')
|
||||||
|
# - $FZF_COMPLETION_TRIGGER (default: '**')
|
||||||
|
# - $FZF_COMPLETION_OPTS (default: empty)
|
||||||
|
|
||||||
|
# Both branches of the following `if` do the same thing -- define
|
||||||
|
# __fzf_completion_options such that `eval $__fzf_completion_options` sets
|
||||||
|
# all options to the same values they currently have. We'll do just that at
|
||||||
|
# the bottom of the file after changing options to what we prefer.
|
||||||
|
#
|
||||||
|
# IMPORTANT: Until we get to the `emulate` line, all words that *can* be quoted
|
||||||
|
# *must* be quoted in order to prevent alias expansion. In addition, code must
|
||||||
|
# be written in a way works with any set of zsh options. This is very tricky, so
|
||||||
|
# careful when you change it.
|
||||||
|
#
|
||||||
|
# Start by loading the builtin zsh/parameter module. It provides `options`
|
||||||
|
# associative array that stores current shell options.
|
||||||
|
if 'zmodload' 'zsh/parameter' 2>'/dev/null' && (( ${+options} )); then
|
||||||
|
# This is the fast branch and it gets taken on virtually all Zsh installations.
|
||||||
|
#
|
||||||
|
# ${(kv)options[@]} expands to array of keys (option names) and values ("on"
|
||||||
|
# or "off"). The subsequent expansion# with (j: :) flag joins all elements
|
||||||
|
# together separated by spaces. __fzf_completion_options ends up with a value
|
||||||
|
# like this: "options=(shwordsplit off aliases on ...)".
|
||||||
|
__fzf_completion_options="options=(${(j: :)${(kv)options[@]}})"
|
||||||
|
else
|
||||||
|
# This branch is much slower because it forks to get the names of all
|
||||||
|
# zsh options. It's possible to eliminate this fork but it's not worth the
|
||||||
|
# trouble because this branch gets taken only on very ancient or broken
|
||||||
|
# zsh installations.
|
||||||
|
() {
|
||||||
|
# That `()` above defines an anonymous function. This is essentially a scope
|
||||||
|
# for local parameters. We use it to avoid polluting global scope.
|
||||||
|
'local' '__fzf_opt'
|
||||||
|
__fzf_completion_options="setopt"
|
||||||
|
# `set -o` prints one line for every zsh option. Each line contains option
|
||||||
|
# name, some spaces, and then either "on" or "off". We just want option names.
|
||||||
|
# Expansion with (@f) flag splits a string into lines. The outer expansion
|
||||||
|
# removes spaces and everything that follow them on every line. __fzf_opt
|
||||||
|
# ends up iterating over option names: shwordsplit, aliases, etc.
|
||||||
|
for __fzf_opt in "${(@)${(@f)$(set -o)}%% *}"; do
|
||||||
|
if [[ -o "$__fzf_opt" ]]; then
|
||||||
|
# Option $__fzf_opt is currently on, so remember to set it back on.
|
||||||
|
__fzf_completion_options+=" -o $__fzf_opt"
|
||||||
|
else
|
||||||
|
# Option $__fzf_opt is currently off, so remember to set it back off.
|
||||||
|
__fzf_completion_options+=" +o $__fzf_opt"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
# The value of __fzf_completion_options here looks like this:
|
||||||
|
# "setopt +o shwordsplit -o aliases ..."
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Enable the default zsh options (those marked with <Z> in `man zshoptions`)
|
||||||
|
# but without `aliases`. Aliases in functions are expanded when functions are
|
||||||
|
# defined, so if we disable aliases here, we'll be sure to have no pesky
|
||||||
|
# aliases in any of our functions. This way we won't need prefix every
|
||||||
|
# command with `command` or to quote every word to defend against global
|
||||||
|
# aliases. Note that `aliases` is not the only option that's important to
|
||||||
|
# control. There are several others that could wreck havoc if they are set
|
||||||
|
# to values we don't expect. With the following `emulate` command we
|
||||||
|
# sidestep this issue entirely.
|
||||||
|
'emulate' 'zsh' '-o' 'no_aliases'
|
||||||
|
|
||||||
|
# This brace is the start of try-always block. The `always` part is like
|
||||||
|
# `finally` in lesser languages. We use it to *always* restore user options.
|
||||||
|
{
|
||||||
|
|
||||||
|
# Bail out if not interactive shell.
|
||||||
|
[[ -o interactive ]] || return 0
|
||||||
|
|
||||||
|
# To use custom commands instead of find, override _fzf_compgen_{path,dir}
|
||||||
|
if ! declare -f _fzf_compgen_path > /dev/null; then
|
||||||
|
_fzf_compgen_path() {
|
||||||
|
echo "$1"
|
||||||
|
command find -L "$1" \
|
||||||
|
-name .git -prune -o -name .hg -prune -o -name .svn -prune -o \( -type d -o -type f -o -type l \) \
|
||||||
|
-a -not -path "$1" -print 2> /dev/null | sed 's@^\./@@'
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! declare -f _fzf_compgen_dir > /dev/null; then
|
||||||
|
_fzf_compgen_dir() {
|
||||||
|
command find -L "$1" \
|
||||||
|
-name .git -prune -o -name .hg -prune -o -name .svn -prune -o -type d \
|
||||||
|
-a -not -path "$1" -print 2> /dev/null | sed 's@^\./@@'
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
###########################################################
|
||||||
|
|
||||||
|
__fzf_comprun() {
|
||||||
|
if [[ "$(type _fzf_comprun 2>&1)" =~ function ]]; then
|
||||||
|
_fzf_comprun "$@"
|
||||||
|
elif [ -n "${TMUX_PANE-}" ] && { [ "${FZF_TMUX:-0}" != 0 ] || [ -n "${FZF_TMUX_OPTS-}" ]; }; then
|
||||||
|
shift
|
||||||
|
if [ -n "${FZF_TMUX_OPTS-}" ]; then
|
||||||
|
fzf-tmux ${(Q)${(Z+n+)FZF_TMUX_OPTS}} -- "$@"
|
||||||
|
else
|
||||||
|
fzf-tmux -d ${FZF_TMUX_HEIGHT:-40%} -- "$@"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
shift
|
||||||
|
fzf "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Extract the name of the command. e.g. foo=1 bar baz**<tab>
|
||||||
|
__fzf_extract_command() {
|
||||||
|
local token tokens
|
||||||
|
tokens=(${(z)1})
|
||||||
|
for token in $tokens; do
|
||||||
|
token=${(Q)token}
|
||||||
|
if [[ "$token" =~ [[:alnum:]] && ! "$token" =~ "=" ]]; then
|
||||||
|
echo "$token"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "${tokens[1]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
__fzf_generic_path_completion() {
|
||||||
|
local base lbuf cmd compgen fzf_opts suffix tail dir leftover matches
|
||||||
|
base=$1
|
||||||
|
lbuf=$2
|
||||||
|
cmd=$(__fzf_extract_command "$lbuf")
|
||||||
|
compgen=$3
|
||||||
|
fzf_opts=$4
|
||||||
|
suffix=$5
|
||||||
|
tail=$6
|
||||||
|
|
||||||
|
setopt localoptions nonomatch
|
||||||
|
eval "base=$base"
|
||||||
|
[[ $base = *"/"* ]] && dir="$base"
|
||||||
|
while [ 1 ]; do
|
||||||
|
if [[ -z "$dir" || -d ${dir} ]]; then
|
||||||
|
leftover=${base/#"$dir"}
|
||||||
|
leftover=${leftover/#\/}
|
||||||
|
[ -z "$dir" ] && dir='.'
|
||||||
|
[ "$dir" != "/" ] && dir="${dir/%\//}"
|
||||||
|
matches=$(eval "$compgen $(printf %q "$dir")" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore ${FZF_DEFAULT_OPTS-} ${FZF_COMPLETION_OPTS-}" __fzf_comprun "$cmd" ${(Q)${(Z+n+)fzf_opts}} -q "$leftover" | while read item; do
|
||||||
|
item="${item%$suffix}$suffix"
|
||||||
|
echo -n "${(q)item} "
|
||||||
|
done)
|
||||||
|
matches=${matches% }
|
||||||
|
if [ -n "$matches" ]; then
|
||||||
|
LBUFFER="$lbuf$matches$tail"
|
||||||
|
fi
|
||||||
|
zle reset-prompt
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
dir=$(dirname "$dir")
|
||||||
|
dir=${dir%/}/
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
_fzf_path_completion() {
|
||||||
|
__fzf_generic_path_completion "$1" "$2" _fzf_compgen_path \
|
||||||
|
"-m" "" " "
|
||||||
|
}
|
||||||
|
|
||||||
|
_fzf_dir_completion() {
|
||||||
|
__fzf_generic_path_completion "$1" "$2" _fzf_compgen_dir \
|
||||||
|
"" "/" ""
|
||||||
|
}
|
||||||
|
|
||||||
|
_fzf_feed_fifo() (
|
||||||
|
command rm -f "$1"
|
||||||
|
mkfifo "$1"
|
||||||
|
cat <&0 > "$1" &
|
||||||
|
)
|
||||||
|
|
||||||
|
_fzf_complete() {
|
||||||
|
setopt localoptions ksh_arrays
|
||||||
|
# Split arguments around --
|
||||||
|
local args rest str_arg i sep
|
||||||
|
args=("$@")
|
||||||
|
sep=
|
||||||
|
for i in {0..${#args[@]}}; do
|
||||||
|
if [[ "${args[$i]-}" = -- ]]; then
|
||||||
|
sep=$i
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ -n "$sep" ]]; then
|
||||||
|
str_arg=
|
||||||
|
rest=("${args[@]:$((sep + 1)):${#args[@]}}")
|
||||||
|
args=("${args[@]:0:$sep}")
|
||||||
|
else
|
||||||
|
str_arg=$1
|
||||||
|
args=()
|
||||||
|
shift
|
||||||
|
rest=("$@")
|
||||||
|
fi
|
||||||
|
|
||||||
|
local fifo lbuf cmd matches post
|
||||||
|
fifo="${TMPDIR:-/tmp}/fzf-complete-fifo-$$"
|
||||||
|
lbuf=${rest[0]}
|
||||||
|
cmd=$(__fzf_extract_command "$lbuf")
|
||||||
|
post="${funcstack[1]}_post"
|
||||||
|
type $post > /dev/null 2>&1 || post=cat
|
||||||
|
|
||||||
|
_fzf_feed_fifo "$fifo"
|
||||||
|
matches=$(FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore ${FZF_DEFAULT_OPTS-} ${FZF_COMPLETION_OPTS-} $str_arg" __fzf_comprun "$cmd" "${args[@]}" -q "${(Q)prefix}" < "$fifo" | $post | tr '\n' ' ')
|
||||||
|
if [ -n "$matches" ]; then
|
||||||
|
LBUFFER="$lbuf$matches"
|
||||||
|
fi
|
||||||
|
command rm -f "$fifo"
|
||||||
|
}
|
||||||
|
|
||||||
|
_fzf_complete_telnet() {
|
||||||
|
_fzf_complete +m -- "$@" < <(
|
||||||
|
command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0' |
|
||||||
|
awk '{if (length($2) > 0) {print $2}}' | sort -u
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
_fzf_complete_ssh() {
|
||||||
|
_fzf_complete +m -- "$@" < <(
|
||||||
|
setopt localoptions nonomatch
|
||||||
|
command cat <(command tail -n +1 ~/.ssh/config ~/.ssh/config.d/* /etc/ssh/ssh_config 2> /dev/null | command grep -i '^\s*host\(name\)\? ' | awk '{for (i = 2; i <= NF; i++) print $1 " " $i}' | command grep -v '[*?%]') \
|
||||||
|
<(command grep -oE '^[[a-z0-9.,:-]+' ~/.ssh/known_hosts | tr ',' '\n' | tr -d '[' | awk '{ print $1 " " $1 }') \
|
||||||
|
<(command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0') |
|
||||||
|
awk '{if (length($2) > 0) {print $2}}' | sort -u
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
_fzf_complete_export() {
|
||||||
|
_fzf_complete -m -- "$@" < <(
|
||||||
|
declare -xp | sed 's/=.*//' | sed 's/.* //'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
_fzf_complete_unset() {
|
||||||
|
_fzf_complete -m -- "$@" < <(
|
||||||
|
declare -xp | sed 's/=.*//' | sed 's/.* //'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
_fzf_complete_unalias() {
|
||||||
|
_fzf_complete +m -- "$@" < <(
|
||||||
|
alias | sed 's/=.*//'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
_fzf_complete_kill() {
|
||||||
|
_fzf_complete -m --preview 'echo {}' --preview-window down:3:wrap --min-height 15 -- "$@" < <(
|
||||||
|
command ps -ef | sed 1d
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
_fzf_complete_kill_post() {
|
||||||
|
awk '{print $2}'
|
||||||
|
}
|
||||||
|
|
||||||
|
fzf-completion() {
|
||||||
|
local tokens cmd prefix trigger tail matches lbuf d_cmds
|
||||||
|
setopt localoptions noshwordsplit noksh_arrays noposixbuiltins
|
||||||
|
|
||||||
|
# http://zsh.sourceforge.net/FAQ/zshfaq03.html
|
||||||
|
# http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion-Flags
|
||||||
|
tokens=(${(z)LBUFFER})
|
||||||
|
if [ ${#tokens} -lt 1 ]; then
|
||||||
|
zle ${fzf_default_completion:-expand-or-complete}
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
cmd=$(__fzf_extract_command "$LBUFFER")
|
||||||
|
|
||||||
|
# Explicitly allow for empty trigger.
|
||||||
|
trigger=${FZF_COMPLETION_TRIGGER-'**'}
|
||||||
|
[ -z "$trigger" -a ${LBUFFER[-1]} = ' ' ] && tokens+=("")
|
||||||
|
|
||||||
|
# When the trigger starts with ';', it becomes a separate token
|
||||||
|
if [[ ${LBUFFER} = *"${tokens[-2]-}${tokens[-1]}" ]]; then
|
||||||
|
tokens[-2]="${tokens[-2]-}${tokens[-1]}"
|
||||||
|
tokens=(${tokens[0,-2]})
|
||||||
|
fi
|
||||||
|
|
||||||
|
lbuf=$LBUFFER
|
||||||
|
tail=${LBUFFER:$(( ${#LBUFFER} - ${#trigger} ))}
|
||||||
|
|
||||||
|
# Trigger sequence given
|
||||||
|
if [ ${#tokens} -gt 1 -a "$tail" = "$trigger" ]; then
|
||||||
|
d_cmds=(${=FZF_COMPLETION_DIR_COMMANDS:-cd pushd rmdir})
|
||||||
|
|
||||||
|
[ -z "$trigger" ] && prefix=${tokens[-1]} || prefix=${tokens[-1]:0:-${#trigger}}
|
||||||
|
[ -n "${tokens[-1]}" ] && lbuf=${lbuf:0:-${#tokens[-1]}}
|
||||||
|
|
||||||
|
if eval "type _fzf_complete_${cmd} > /dev/null"; then
|
||||||
|
prefix="$prefix" eval _fzf_complete_${cmd} ${(q)lbuf}
|
||||||
|
zle reset-prompt
|
||||||
|
elif [ ${d_cmds[(i)$cmd]} -le ${#d_cmds} ]; then
|
||||||
|
_fzf_dir_completion "$prefix" "$lbuf"
|
||||||
|
else
|
||||||
|
_fzf_path_completion "$prefix" "$lbuf"
|
||||||
|
fi
|
||||||
|
# Fall back to default completion
|
||||||
|
else
|
||||||
|
zle ${fzf_default_completion:-expand-or-complete}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
[ -z "$fzf_default_completion" ] && {
|
||||||
|
binding=$(bindkey '^I')
|
||||||
|
[[ $binding =~ 'undefined-key' ]] || fzf_default_completion=$binding[(s: :w)2]
|
||||||
|
unset binding
|
||||||
|
}
|
||||||
|
|
||||||
|
zle -N fzf-completion
|
||||||
|
bindkey '^I' fzf-completion
|
||||||
|
|
||||||
|
} always {
|
||||||
|
# Restore the original options.
|
||||||
|
eval $__fzf_completion_options
|
||||||
|
'unset' '__fzf_completion_options'
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
# ____ ____
|
||||||
|
# / __/___ / __/
|
||||||
|
# / /_/_ / / /_
|
||||||
|
# / __/ / /_/ __/
|
||||||
|
# /_/ /___/_/ key-bindings.bash
|
||||||
|
#
|
||||||
|
# - $FZF_TMUX_OPTS
|
||||||
|
# - $FZF_CTRL_T_COMMAND
|
||||||
|
# - $FZF_CTRL_T_OPTS
|
||||||
|
# - $FZF_CTRL_R_OPTS
|
||||||
|
# - $FZF_ALT_C_COMMAND
|
||||||
|
# - $FZF_ALT_C_OPTS
|
||||||
|
|
||||||
|
# Key bindings
|
||||||
|
# ------------
|
||||||
|
__fzf_select__() {
|
||||||
|
local cmd opts
|
||||||
|
cmd="${FZF_CTRL_T_COMMAND:-"command find -L . -mindepth 1 \\( -path '*/\\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \\) -prune \
|
||||||
|
-o -type f -print \
|
||||||
|
-o -type d -print \
|
||||||
|
-o -type l -print 2> /dev/null | cut -b3-"}"
|
||||||
|
opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore --reverse ${FZF_DEFAULT_OPTS-} ${FZF_CTRL_T_OPTS-} -m"
|
||||||
|
eval "$cmd" |
|
||||||
|
FZF_DEFAULT_OPTS="$opts" $(__fzfcmd) "$@" |
|
||||||
|
while read -r item; do
|
||||||
|
printf '%q ' "$item" # escape special chars
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ $- =~ i ]]; then
|
||||||
|
|
||||||
|
__fzfcmd() {
|
||||||
|
[[ -n "${TMUX_PANE-}" ]] && { [[ "${FZF_TMUX:-0}" != 0 ]] || [[ -n "${FZF_TMUX_OPTS-}" ]]; } &&
|
||||||
|
echo "fzf-tmux ${FZF_TMUX_OPTS:--d${FZF_TMUX_HEIGHT:-40%}} -- " || echo "fzf"
|
||||||
|
}
|
||||||
|
|
||||||
|
fzf-file-widget() {
|
||||||
|
local selected="$(__fzf_select__ "$@")"
|
||||||
|
READLINE_LINE="${READLINE_LINE:0:$READLINE_POINT}$selected${READLINE_LINE:$READLINE_POINT}"
|
||||||
|
READLINE_POINT=$(( READLINE_POINT + ${#selected} ))
|
||||||
|
}
|
||||||
|
|
||||||
|
__fzf_cd__() {
|
||||||
|
local cmd opts dir
|
||||||
|
cmd="${FZF_ALT_C_COMMAND:-"command find -L . -mindepth 1 \\( -path '*/\\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \\) -prune \
|
||||||
|
-o -type d -print 2> /dev/null | cut -b3-"}"
|
||||||
|
opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore --reverse ${FZF_DEFAULT_OPTS-} ${FZF_ALT_C_OPTS-} +m"
|
||||||
|
dir=$(eval "$cmd" | FZF_DEFAULT_OPTS="$opts" $(__fzfcmd)) && printf 'builtin cd -- %q' "$dir"
|
||||||
|
}
|
||||||
|
|
||||||
|
__fzf_history__() {
|
||||||
|
local output opts script
|
||||||
|
opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore ${FZF_DEFAULT_OPTS-} -n2..,.. --scheme=history --bind=ctrl-r:toggle-sort ${FZF_CTRL_R_OPTS-} +m --read0"
|
||||||
|
script='BEGIN { getc; $/ = "\n\t"; $HISTCOUNT = $ENV{last_hist} + 1 } s/^[ *]//; print $HISTCOUNT - $. . "\t$_" if !$seen{$_}++'
|
||||||
|
output=$(
|
||||||
|
builtin fc -lnr -2147483648 |
|
||||||
|
last_hist=$(HISTTIMEFORMAT='' builtin history 1) perl -n -l0 -e "$script" |
|
||||||
|
FZF_DEFAULT_OPTS="$opts" $(__fzfcmd) --query "$READLINE_LINE"
|
||||||
|
) || return
|
||||||
|
READLINE_LINE=${output#*$'\t'}
|
||||||
|
if [[ -z "$READLINE_POINT" ]]; then
|
||||||
|
echo "$READLINE_LINE"
|
||||||
|
else
|
||||||
|
READLINE_POINT=0x7fffffff
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Required to refresh the prompt after fzf
|
||||||
|
bind -m emacs-standard '"\er": redraw-current-line'
|
||||||
|
|
||||||
|
bind -m vi-command '"\C-z": emacs-editing-mode'
|
||||||
|
bind -m vi-insert '"\C-z": emacs-editing-mode'
|
||||||
|
bind -m emacs-standard '"\C-z": vi-editing-mode'
|
||||||
|
|
||||||
|
if (( BASH_VERSINFO[0] < 4 )); then
|
||||||
|
# CTRL-T - Paste the selected file path into the command line
|
||||||
|
bind -m emacs-standard '"\C-t": " \C-b\C-k \C-u`__fzf_select__`\e\C-e\er\C-a\C-y\C-h\C-e\e \C-y\ey\C-x\C-x\C-f"'
|
||||||
|
bind -m vi-command '"\C-t": "\C-z\C-t\C-z"'
|
||||||
|
bind -m vi-insert '"\C-t": "\C-z\C-t\C-z"'
|
||||||
|
|
||||||
|
# CTRL-R - Paste the selected command from history into the command line
|
||||||
|
bind -m emacs-standard '"\C-r": "\C-e \C-u\C-y\ey\C-u"$(__fzf_history__)"\e\C-e\er"'
|
||||||
|
bind -m vi-command '"\C-r": "\C-z\C-r\C-z"'
|
||||||
|
bind -m vi-insert '"\C-r": "\C-z\C-r\C-z"'
|
||||||
|
else
|
||||||
|
# CTRL-T - Paste the selected file path into the command line
|
||||||
|
bind -m emacs-standard -x '"\C-t": fzf-file-widget'
|
||||||
|
bind -m vi-command -x '"\C-t": fzf-file-widget'
|
||||||
|
bind -m vi-insert -x '"\C-t": fzf-file-widget'
|
||||||
|
|
||||||
|
# CTRL-R - Paste the selected command from history into the command line
|
||||||
|
bind -m emacs-standard -x '"\C-r": __fzf_history__'
|
||||||
|
bind -m vi-command -x '"\C-r": __fzf_history__'
|
||||||
|
bind -m vi-insert -x '"\C-r": __fzf_history__'
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ALT-C - cd into the selected directory
|
||||||
|
bind -m emacs-standard '"\ec": " \C-b\C-k \C-u`__fzf_cd__`\e\C-e\er\C-m\C-y\C-h\e \C-y\ey\C-x\C-x\C-d"'
|
||||||
|
bind -m vi-command '"\ec": "\C-z\ec\C-z"'
|
||||||
|
bind -m vi-insert '"\ec": "\C-z\ec\C-z"'
|
||||||
|
|
||||||
|
fi
|
|
@ -0,0 +1,121 @@
|
||||||
|
# ____ ____
|
||||||
|
# / __/___ / __/
|
||||||
|
# / /_/_ / / /_
|
||||||
|
# / __/ / /_/ __/
|
||||||
|
# /_/ /___/_/ key-bindings.zsh
|
||||||
|
#
|
||||||
|
# - $FZF_TMUX_OPTS
|
||||||
|
# - $FZF_CTRL_T_COMMAND
|
||||||
|
# - $FZF_CTRL_T_OPTS
|
||||||
|
# - $FZF_CTRL_R_OPTS
|
||||||
|
# - $FZF_ALT_C_COMMAND
|
||||||
|
# - $FZF_ALT_C_OPTS
|
||||||
|
|
||||||
|
# Key bindings
|
||||||
|
# ------------
|
||||||
|
|
||||||
|
# The code at the top and the bottom of this file is the same as in completion.zsh.
|
||||||
|
# Refer to that file for explanation.
|
||||||
|
if 'zmodload' 'zsh/parameter' 2>'/dev/null' && (( ${+options} )); then
|
||||||
|
__fzf_key_bindings_options="options=(${(j: :)${(kv)options[@]}})"
|
||||||
|
else
|
||||||
|
() {
|
||||||
|
__fzf_key_bindings_options="setopt"
|
||||||
|
'local' '__fzf_opt'
|
||||||
|
for __fzf_opt in "${(@)${(@f)$(set -o)}%% *}"; do
|
||||||
|
if [[ -o "$__fzf_opt" ]]; then
|
||||||
|
__fzf_key_bindings_options+=" -o $__fzf_opt"
|
||||||
|
else
|
||||||
|
__fzf_key_bindings_options+=" +o $__fzf_opt"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
'emulate' 'zsh' '-o' 'no_aliases'
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
[[ -o interactive ]] || return 0
|
||||||
|
|
||||||
|
# CTRL-T - Paste the selected file path(s) into the command line
|
||||||
|
__fsel() {
|
||||||
|
local cmd="${FZF_CTRL_T_COMMAND:-"command find -L . -mindepth 1 \\( -path '*/\\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \\) -prune \
|
||||||
|
-o -type f -print \
|
||||||
|
-o -type d -print \
|
||||||
|
-o -type l -print 2> /dev/null | cut -b3-"}"
|
||||||
|
setopt localoptions pipefail no_aliases 2> /dev/null
|
||||||
|
local item
|
||||||
|
eval "$cmd" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore ${FZF_DEFAULT_OPTS-} ${FZF_CTRL_T_OPTS-}" $(__fzfcmd) -m "$@" | while read item; do
|
||||||
|
echo -n "${(q)item} "
|
||||||
|
done
|
||||||
|
local ret=$?
|
||||||
|
echo
|
||||||
|
return $ret
|
||||||
|
}
|
||||||
|
|
||||||
|
__fzfcmd() {
|
||||||
|
[ -n "${TMUX_PANE-}" ] && { [ "${FZF_TMUX:-0}" != 0 ] || [ -n "${FZF_TMUX_OPTS-}" ]; } &&
|
||||||
|
echo "fzf-tmux ${FZF_TMUX_OPTS:--d${FZF_TMUX_HEIGHT:-40%}} -- " || echo "fzf"
|
||||||
|
}
|
||||||
|
|
||||||
|
fzf-file-widget() {
|
||||||
|
LBUFFER="${LBUFFER}$(__fsel)"
|
||||||
|
local ret=$?
|
||||||
|
zle reset-prompt
|
||||||
|
return $ret
|
||||||
|
}
|
||||||
|
zle -N fzf-file-widget
|
||||||
|
bindkey -M emacs '^T' fzf-file-widget
|
||||||
|
bindkey -M vicmd '^T' fzf-file-widget
|
||||||
|
bindkey -M viins '^T' fzf-file-widget
|
||||||
|
|
||||||
|
# ALT-C - cd into the selected directory
|
||||||
|
fzf-cd-widget() {
|
||||||
|
local cmd="${FZF_ALT_C_COMMAND:-"command find -L . -mindepth 1 \\( -path '*/\\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \\) -prune \
|
||||||
|
-o -type d -print 2> /dev/null | cut -b3-"}"
|
||||||
|
setopt localoptions pipefail no_aliases 2> /dev/null
|
||||||
|
local dir="$(eval "$cmd" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore ${FZF_DEFAULT_OPTS-} ${FZF_ALT_C_OPTS-}" $(__fzfcmd) +m)"
|
||||||
|
if [[ -z "$dir" ]]; then
|
||||||
|
zle redisplay
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
zle push-line # Clear buffer. Auto-restored on next prompt.
|
||||||
|
BUFFER="builtin cd -- ${(q)dir}"
|
||||||
|
zle accept-line
|
||||||
|
local ret=$?
|
||||||
|
unset dir # ensure this doesn't end up appearing in prompt expansion
|
||||||
|
zle reset-prompt
|
||||||
|
return $ret
|
||||||
|
}
|
||||||
|
zle -N fzf-cd-widget
|
||||||
|
bindkey -M emacs '\ec' fzf-cd-widget
|
||||||
|
bindkey -M vicmd '\ec' fzf-cd-widget
|
||||||
|
bindkey -M viins '\ec' fzf-cd-widget
|
||||||
|
|
||||||
|
# CTRL-R - Paste the selected command from history into the command line
|
||||||
|
# EDIT BY plex: removed --scheme-history , as it causes errors on some debian based systems as it seems.
|
||||||
|
fzf-history-widget() {
|
||||||
|
local selected num
|
||||||
|
setopt localoptions noglobsubst noposixbuiltins pipefail no_aliases 2> /dev/null
|
||||||
|
selected=( $(fc -rl 1 | awk '{ cmd=$0; sub(/^[ \t]*[0-9]+\**[ \t]+/, "", cmd); if (!seen[cmd]++) print $0 }' |
|
||||||
|
FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} ${FZF_DEFAULT_OPTS-} -n2..,.. --bind=ctrl-r:toggle-sort,ctrl-z:ignore ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER} +m" $(__fzfcmd)) )
|
||||||
|
local ret=$?
|
||||||
|
if [ -n "$selected" ]; then
|
||||||
|
num=$selected[1]
|
||||||
|
if [ -n "$num" ]; then
|
||||||
|
zle vi-fetch-history -n $num
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
zle reset-prompt
|
||||||
|
return $ret
|
||||||
|
}
|
||||||
|
zle -N fzf-history-widget
|
||||||
|
bindkey -M emacs '^R' fzf-history-widget
|
||||||
|
bindkey -M vicmd '^R' fzf-history-widget
|
||||||
|
bindkey -M viins '^R' fzf-history-widget
|
||||||
|
|
||||||
|
} always {
|
||||||
|
eval $__fzf_key_bindings_options
|
||||||
|
'unset' '__fzf_key_bindings_options'
|
||||||
|
}
|
|
@ -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,378 @@
|
||||||
|
<h1 align="center">nnn plugins</h1>
|
||||||
|
|
||||||
|
<p align="center"><img src="https://i.imgur.com/SpT0L2W.png" /></p>
|
||||||
|
<p align="center"><i>read ebooks with plugin gutenread (Android)</i></p>
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
Plugins extend the capabilities of `nnn`. They are _executable_ scripts (or binaries) `nnn` can communicate with and trigger. This mechanism fits perfectly with the fundamental design to keep the core file manager lean and fast, by delegating repetitive (but not necessarily file manager-specific) tasks to the plugins which can be run with custom hotkeys.
|
||||||
|
|
||||||
|
`nnn` is _**language-agnostic**_ when it comes to plugins. You can write a plugin in any (scripting) language you are comfortable in!
|
||||||
|
|
||||||
|
## List of plugins
|
||||||
|
|
||||||
|
| Plugin (a-z) | Description [Clears selection<sup>1</sup>] | Lang | Dependencies |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| [autojump](autojump) | Navigate to dir/path | sh | [jump](https://github.com/gsamokovarov/jump)/autojump/<br>zoxide/z/[z.lua](https://github.com/skywind3000/z.lua) |
|
||||||
|
| [boom](boom) | Play random music from dir | sh | [moc](http://moc.daper.net/) |
|
||||||
|
| [bulknew](bulknew) | Create multiple files/dirs at once | bash | sed, xargs, mktemp |
|
||||||
|
| [cdpath](cdpath) | `cd` to the directory from `CDPATH` | sh | fzf |
|
||||||
|
| [chksum](chksum) | Create and verify checksums [✓] | sh | md5sum,<br>sha256sum |
|
||||||
|
| [cmusq](cmusq) | Queue/play files/dirs in cmus player [✓] | sh | cmus, pgrep |
|
||||||
|
| [diffs](diffs) | Diff for selection (limited to 2 for directories) [✓] | sh | vimdiff, mktemp |
|
||||||
|
| [dragdrop](dragdrop) | Drag/drop files from/into nnn | sh | [dragon](https://github.com/mwh/dragon) |
|
||||||
|
| [dups](dups) | List non-empty duplicate files in current dir | bash | find, md5sum,<br>sort uniq xargs |
|
||||||
|
| [finder](finder) | Run custom find command (**stored in histfile**) and list | sh | - |
|
||||||
|
| [fixname](fixname) | Clean filename to be more shell-friendly [✓] | bash | sed |
|
||||||
|
| [fzcd](fzcd) | Fuzzy search multiple dirs (or `$PWD`) and visit file | sh | fzf, (find) |
|
||||||
|
| [fzhist](fzhist) | Fuzzy-select a cmd from history, edit in `$EDITOR` and run | sh | fzf, mktemp |
|
||||||
|
| [fzopen](fzopen) | Fuzzy find file(s) in subtree to edit/open/pick | sh | fzf, xdg-open/open |
|
||||||
|
| [fzplug](fzplug) | Fuzzy find, preview and run other plugins | sh | fzf |
|
||||||
|
| [getplugs](getplugs) | Update plugins to installed `nnn` version | sh | curl |
|
||||||
|
| [gitroot](gitroot) | Cd to the root of current git repo | sh | git |
|
||||||
|
| [gpge](gpge) | Encrypt/decrypt files using GPG [✓] | sh | gpg |
|
||||||
|
| [gutenread](gutenread) | Browse, download, read from Project Gutenberg | sh | curl, unzip, w3m<br>[epr](https://github.com/wustho/epr) (optional) |
|
||||||
|
| [gsconnect](gsconnect) | GNOME's implementation of kdeconnect [✓] | sh | gsconnect |
|
||||||
|
| [imgresize](imgresize) | Batch resize images in dir to screen resolution | sh | [imgp](https://github.com/jarun/imgp) |
|
||||||
|
| [imgur](imgur) | Upload an image to imgur (from [imgur-screenshot](https://github.com/jomo/imgur-screenshot)) | bash | - |
|
||||||
|
| [imgview](imgview) | View (thumbnail)images, set wallpaper, [rename](https://github.com/jarun/nnn/wiki/Basic-use-cases#browse-rename-images) and [more](https://wiki.archlinux.org/index.php/Sxiv#Assigning_keyboard_shortcuts)| sh | _see in-file docs_ |
|
||||||
|
| [ipinfo](ipinfo) | Fetch external IP address and whois information | sh | curl, whois |
|
||||||
|
| [kdeconnect](kdeconnect) | Send selected files to an Android device [✓] | sh | kdeconnect-cli |
|
||||||
|
| [launch](launch) | GUI application launcher | sh | fzf |
|
||||||
|
| [mimelist](mimelist) | List files by mime in subtree | sh | - |
|
||||||
|
| [moclyrics](moclyrics) | Show lyrics of the track playing in moc | sh | [ddgr](https://github.com/jarun/ddgr), [moc](http://moc.daper.net/) |
|
||||||
|
| [mocq](mocq) | Queue/play selection/dir/file in moc [✓] | sh | [moc](http://moc.daper.net/) |
|
||||||
|
| [mp3conv](mp3conv) | Extract audio from multimedia as mp3 | sh | ffmpeg |
|
||||||
|
| [mtpmount](mtpmount) | Toggle mount of MTP device (eg. Android) | sh | gvfs-mtp |
|
||||||
|
| [nbak](nbak) | Backs up `nnn` config | sh | tar, awk, mktemp |
|
||||||
|
| [nmount](nmount) | Toggle mount status of a device as normal user | sh | pmount, udisks2 |
|
||||||
|
| [nuke](nuke) | Sample file opener (CLI-only by default) | sh | _see in-file docs_ |
|
||||||
|
| [oldbigfile](oldbigfile) | List large files by access time | sh | find, sort |
|
||||||
|
| [openall](openall) | Open selected files together or one by one [✓] | bash | - |
|
||||||
|
| [organize](organize) | Auto-organize files in directories by file type [✓] | sh | file |
|
||||||
|
| [pdfread](pdfread) | Read a PDF or text file aloud | sh | pdftotext, mpv,<br>pico2wave |
|
||||||
|
| [preview-tabbed](preview-tabbed) | Preview files with Tabbed/xembed | bash | _see in-file docs_ |
|
||||||
|
| [preview-tui](preview-tui) | Preview with Tmux/kitty/[QuickLook](https://github.com/QL-Win/QuickLook)/xterm/`$TERMINAL` | sh | _see in-file docs_ |
|
||||||
|
| [pskill](pskill) | Fuzzy list by name and kill process or zombie | sh | fzf, ps, sudo/doas |
|
||||||
|
| [renamer](renamer) | Batch rename selection or files in dir [✓] | sh | [qmv](https://www.nongnu.org/renameutils/)/[vidir](https://joeyh.name/code/moreutils/) |
|
||||||
|
| [ringtone](ringtone) | Create a variable bitrate mp3 ringtone from file | sh | date, ffmpeg |
|
||||||
|
| [rsynccp](rsynccp) | Gives copy-paste verbose progress percentage [✓] | sh | rsync |
|
||||||
|
| [splitjoin](splitjoin) | Split file or join selection [✓] | sh | split, cat |
|
||||||
|
| [suedit](suedit) | Edit file using superuser permissions | sh | sudoedit/sudo/doas |
|
||||||
|
| [togglex](togglex) | Toggle executable mode for selection [✓] | sh | chmod |
|
||||||
|
| [umounttree](umounttree) | Unmount a remote mountpoint from within | sh | fusermount |
|
||||||
|
| [upload](upload) | Upload to Firefox Send or ix.io (text) or file.io (bin) | sh | [ffsend](https://github.com/timvisee/ffsend), curl, jq, tr |
|
||||||
|
| [wallpaper](wall) | Set wallpaper or change colorscheme | sh | nitrogen/pywal |
|
||||||
|
| [x2sel](x2sel) | Copy file list from system clipboard to selection | sh | _see in-file docs_ |
|
||||||
|
| [xdgdefault](xdgdefault) | Set the default app for the hovered file type | sh | xdg-utils, fzf/dmenu |
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
1. A plugin has to explicitly request `nnn` to clear the selection e.g. after operating on the selected files.
|
||||||
|
2. Files starting with a dot in the `plugins` directory are internal files and should not be used as plugins.
|
||||||
|
|
||||||
|
### Table of contents
|
||||||
|
|
||||||
|
- [Installation](#installation)
|
||||||
|
- [Configuration](#configuration)
|
||||||
|
- [Skip directory refresh after running a plugin](#skip-directory-refresh-after-running-a-plugin)
|
||||||
|
- [Running commands as plugin](#running-commands-as-plugin)
|
||||||
|
- [Skip user confirmation after command execution](#skip-user-confirmation-after-command-execution)
|
||||||
|
- [Run a GUI app as plugin](#run-a-gui-app-as-plugin)
|
||||||
|
- [Page non-interactive command output](#page-non-interactive-command-output)
|
||||||
|
- [Some useful key-command examples](#some-useful-key-command-examples)
|
||||||
|
- [Access level of plugins](#access-level-of-plugins)
|
||||||
|
- [Create your own plugins](#create-your-own-plugins)
|
||||||
|
- [Send data to `nnn`](#send-data-to-nnn)
|
||||||
|
- [Get notified on file hover](#get-notified-on-file-hover)
|
||||||
|
- [Examples](#examples)
|
||||||
|
- [Contributing plugins](#contributing-plugins)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
The following command installs or updates (after backup) all plugins:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -Ls https://raw.githubusercontent.com/jarun/nnn/master/plugins/getplugs | sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Plugins are installed to `${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins`.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Set environment variable `NNN_PLUG` to assign keybinds and invoke plugins directly using the plugin shortcut (<kbd>;</kbd>) followed by the assigned key character. E.g., with the below config:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export NNN_PLUG='f:finder;o:fzopen;p:mocq;d:diffs;t:nmount;v:imgview'
|
||||||
|
```
|
||||||
|
|
||||||
|
plugin `finder` can be invoked with the keybind <kbd>;f</kbd>, `fzopen` can be run with <kbd>;o</kbd> and so on... The key vs. plugin pairs are shown in the help and config screen.
|
||||||
|
|
||||||
|
Alternatively, combine with <kbd>Alt</kbd> (i.e. <kbd>Alt+key</kbd>).
|
||||||
|
|
||||||
|
To pick and run an unassigned plugin, press <kbd>Enter</kbd> (to _enter_ the plugin dir) at the plugin prompt.
|
||||||
|
|
||||||
|
To run a plugin at startup, use the option `-P` followed by the plugin key.
|
||||||
|
|
||||||
|
If the plugins list gets too long, try breaking them up into sections:
|
||||||
|
|
||||||
|
```
|
||||||
|
NNN_PLUG_PERSONAL='g:personal/convert2zoom;p:personal/echo'
|
||||||
|
NNN_PLUG_WORK='j:work/prettyjson;d:work/foobar'
|
||||||
|
NNN_PLUG_INLINE='e:!go run $nnn*'
|
||||||
|
NNN_PLUG_DEFAULT='1:ipinfo;p:preview-tui;o:fzz;b:nbak'
|
||||||
|
NNN_PLUG="$NNN_PLUG_PERSONAL;$NNN_PLUG_WORK;$NNN_PLUG_DEFAULT;$NNN_PLUG_INLINE"
|
||||||
|
export NNN_PLUG
|
||||||
|
```
|
||||||
|
|
||||||
|
Note:
|
||||||
|
- `'g:personal/convert2zoom'` will look in the personal sub-folder inside the plugin folder.
|
||||||
|
- `'b:boom;b:bulknew` will result in only the first definition of *b* (`b:boom`) being used.
|
||||||
|
- A keybinding definition of more than 1 character will prevent nnn from starting.
|
||||||
|
|
||||||
|
|
||||||
|
#### Skip directory refresh after running a plugin [`-`]
|
||||||
|
|
||||||
|
`nnn` refreshes the directory after running a plugin to reflect any changes by the plugin. To disable this add a `-` before the plugin name:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export NNN_PLUG='p:-plugin'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running commands as plugin [`!`]
|
||||||
|
|
||||||
|
To assign keys to arbitrary non-background cli commands and invoke like plugins, add `!` (underscore) before the command.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export NNN_PLUG='x:!chmod +x $nnn;g:!git log;s:!smplayer $nnn'
|
||||||
|
```
|
||||||
|
|
||||||
|
Now <kbd>;x</kbd> can be used to make a file executable, <kbd>;g</kbd> can be used to the git log of a git project directory, <kbd>;s</kbd> can be used to preview a partially downloaded media file.
|
||||||
|
|
||||||
|
#### Skip user confirmation after command execution [`*`]
|
||||||
|
|
||||||
|
`nnn` waits for user confirmation (the prompt `Press Enter to continue`) after it executes a command as plugin (unlike plugins which can add a `read` to wait). To skip this, add a `*` after the command.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export NNN_PLUG='s:!smplayer $nnn*;n:-!vim /home/vaio/Dropbox/Public/synced_note*'
|
||||||
|
```
|
||||||
|
|
||||||
|
Now there will be no prompt after <kbd>;s</kbd> and <kbd>;n</kbd>.
|
||||||
|
|
||||||
|
Note: Do not use `*` with programs those run and exit e.g. cat.
|
||||||
|
|
||||||
|
#### Run a GUI app as plugin [`&`]
|
||||||
|
|
||||||
|
To run a GUI app as plugin, add a `&` after `!`.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export NNN_PLUG='m:-!&mousepad $nnn'
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: `$nnn` must be the last argument in this case.
|
||||||
|
|
||||||
|
#### Page non-interactive command output [`|`]
|
||||||
|
|
||||||
|
To show the output of run-and-exit commands which do not need user input, add `|` (pipe) after `!`.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export NNN_PLUG='m:-!|mediainfo $nnn;t:-!|tree -ps;l:-!|ls -lah --group-directories-first'
|
||||||
|
```
|
||||||
|
|
||||||
|
This option is incompatible with `&` (terminal output is masked for GUI programs) and ignores `*` (output is already paged for user).
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
1. Use single quotes for `$NNN_PLUG` so `$nnn` is not interpreted
|
||||||
|
2. `$nnn` must be the last argument (if used) to run a _command as plugin_
|
||||||
|
3. (_Again_) add `!` before the command
|
||||||
|
4. To disable directory refresh after running a _command as plugin_, prefix with `-!`
|
||||||
|
|
||||||
|
#### Some useful key-command examples
|
||||||
|
|
||||||
|
| Key:Command | Description |
|
||||||
|
|---|---|
|
||||||
|
| `c:!convert $nnn png:- \| xclip -sel clipboard -t image/png*` | Copy image to clipboard |
|
||||||
|
| `e:-!sudo -E vim $nnn*` | Edit file as root in vim |
|
||||||
|
| `g:-!git diff` | Show git diff |
|
||||||
|
| `h:-!hx $nnn*` | Open hovered file in [hx](https://github.com/krpors/hx) hex editor |
|
||||||
|
| `k:-!fuser -kiv $nnn*` | Interactively kill process(es) using hovered file |
|
||||||
|
| `l:-!git log` | Show git log |
|
||||||
|
| `n:-!vi /home/user/Dropbox/dir/note*` | Take quick notes in a synced file/dir of notes |
|
||||||
|
| `p:-!less -iR $nnn*` | Page through hovered file in less |
|
||||||
|
| `s:-!&smplayer -minigui $nnn` | Play hovered media file, even unfinished download |
|
||||||
|
| `x:!chmod +x $nnn` | Make the hovered file executable |
|
||||||
|
| `y:-!sync*` | Flush cached writes |
|
||||||
|
|
||||||
|
## Access level of plugins
|
||||||
|
|
||||||
|
When `nnn` executes a plugin, it does the following:
|
||||||
|
- Changes to the directory where the plugin is to be run (`$PWD` pointing to the active directory)
|
||||||
|
- Passes three arguments to the script:
|
||||||
|
1. `$1`: The hovered file's name.
|
||||||
|
2. `$2`: The working directory (might differ from `$PWD` in case of symlinked paths; non-canonical).
|
||||||
|
3. `$3`: The picker mode output file (`-` for stdout) if `nnn` is executed as a file picker.
|
||||||
|
- Sets the environment variable `NNN_PIPE` used to control `nnn` active directory.
|
||||||
|
- Sets the environment variable `NNN_INCLUDE_HIDDEN` to `1` if hidden files are active, `0` otherwise.
|
||||||
|
- Exports the [special variables](https://github.com/jarun/nnn/wiki/Concepts#special-variables).
|
||||||
|
|
||||||
|
Plugins can also read the `.selection` file in the config directory.
|
||||||
|
|
||||||
|
## Create your own plugins
|
||||||
|
|
||||||
|
Plugins can be written in any scripting language. However, POSIX-compliant shell scripts runnable in `sh` are preferred.
|
||||||
|
|
||||||
|
**Make the file executable**. Drop it in the plugin directory. Optionally add a hotkey in `$NNN_PLUG` for frequent usage.
|
||||||
|
|
||||||
|
#### Send data to `nnn`
|
||||||
|
`nnn` provides a mechanism for plugins to send data to `nnn` to control its active directory or invoke the list mode.
|
||||||
|
The way to do so is by writing to the pipe pointed by the environment variable `NNN_PIPE`.
|
||||||
|
The plugin should write a single string in the format `(<->)<ctxcode><opcode><data>` without a newline at the end. For example, `1c/etc`.
|
||||||
|
|
||||||
|
The optional `-` at the **beginning of the stream** instructs `nnn` to clear the selection.
|
||||||
|
In cases where the data transfer to `nnn` has to happen while the selection file is being read (e.g. in a loop), the plugin should
|
||||||
|
create a tmp copy of the selection file, inform `nnn` to clear the selection and then do the subsequent processing with the tmp file.
|
||||||
|
A paged [`|`] or GUI [`&`] cmd run as plugin cannot clear selection.
|
||||||
|
|
||||||
|
The `ctxcode` indicates the context to change the active directory of.
|
||||||
|
|
||||||
|
| Context code | Meaning |
|
||||||
|
|:---:| --- |
|
||||||
|
| `+` | smart context (next inactive else current) |
|
||||||
|
| `0` | current context |
|
||||||
|
| `1`-`4` | context number |
|
||||||
|
|
||||||
|
The `opcode` indicates the operation type.
|
||||||
|
|
||||||
|
| Opcode | Operation |
|
||||||
|
|:---:| --- |
|
||||||
|
| `c` | change directory |
|
||||||
|
| `l` | list files in list mode |
|
||||||
|
| `p` | picker file overwritten |
|
||||||
|
|
||||||
|
For convenience, we provided a helper script named `.nnn-plugin-helper` and a function named `nnn_cd` to ease this process. `nnn_cd` receives the path to change to as the first argument, and the context as an optional second argument.
|
||||||
|
If a context is not provided, it is asked for explicitly. To skip this and choose the current context, set the `CUR_CTX` variable in `.nnn-plugin-helper` (or in the specific plugin after sourcing `.nnn-plugin-helper`) to 1.
|
||||||
|
Usage examples can be found in the Examples section below.
|
||||||
|
|
||||||
|
#### Get notified on file hover
|
||||||
|
|
||||||
|
If `NNN_FIFO` is set, `nnn` will open it and write every hovered files. This can be used in plugins and external scripts, e.g. to implement file previews.
|
||||||
|
|
||||||
|
Don't forget to fork in the background to avoid blocking `nnn`.
|
||||||
|
|
||||||
|
For more details on configuration and usage of the preview plugins, visit [Live Previews](https://github.com/jarun/nnn/wiki/Live-previews).
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
There are many plugins provided by `nnn` which can be used as examples. Here are a few simple selected examples.
|
||||||
|
|
||||||
|
#### Show the git log of changes to the particular file along with the code for a quick and easy review.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
git log -p -- "$1"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Change to directory in clipboard using helper script
|
||||||
|
|
||||||
|
```sh
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
. $(dirname $0)/.nnn-plugin-helper
|
||||||
|
|
||||||
|
nnn_cd "$(xsel -ob)"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Change directory to the location of a link using helper script with specific context (current)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
. $(dirname $0)/.nnn-plugin-helper
|
||||||
|
|
||||||
|
nnn_cd "$(dirname $(readlink -fn $1))" 0
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Change to arbitrary directory without helper script
|
||||||
|
|
||||||
|
```sh
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
printf "cd to: "
|
||||||
|
read -r dir
|
||||||
|
|
||||||
|
printf "%s" "0c$dir" > "$NNN_PIPE"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Send every hovered file to X selection
|
||||||
|
|
||||||
|
```sh
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
if [ -z "$NNN_FIFO" ] ; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while read FILE ; do
|
||||||
|
printf "%s" "$FILE" | xsel
|
||||||
|
done < "$NNN_FIFO" &
|
||||||
|
disown
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Quick `find` the first match in subtree and open in `nuke`
|
||||||
|
|
||||||
|
```sh
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
NUKE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins/nuke"
|
||||||
|
|
||||||
|
printf "file name: "
|
||||||
|
read -r pattern
|
||||||
|
|
||||||
|
entry=$(find . -type f -iname "$pattern" -print -quit 2>/dev/null)
|
||||||
|
|
||||||
|
if [ -n "$entry" ]; then
|
||||||
|
"$NUKE" "$entry"
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Quick find (using `fd`)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
. "$(dirname "$0")"/.nnn-plugin-helper
|
||||||
|
|
||||||
|
printf "pattern: "
|
||||||
|
read -r pattern
|
||||||
|
|
||||||
|
if [ -n "$pattern" ]; then
|
||||||
|
printf "%s" "+l" > "$NNN_PIPE"
|
||||||
|
eval "fd -HI $pattern -0" > "$NNN_PIPE"
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Quick grep (using `rg`)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
. "$(dirname "$0")"/.nnn-plugin-helper
|
||||||
|
|
||||||
|
printf "pattern: "
|
||||||
|
read -r pattern
|
||||||
|
|
||||||
|
if [ -n "$pattern" ]; then
|
||||||
|
printf "%s" "+l" > "$NNN_PIPE"
|
||||||
|
eval "rg -l0 --hidden -S $pattern" > "$NNN_PIPE"
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contributing plugins
|
||||||
|
|
||||||
|
1. Add informative sections like _Description_, _Notes_, _Dependencies_, _Shell_, _Author_ etc. in the plugin.
|
||||||
|
2. Add an entry in the table above. Note that the list is alphabetically ordered by plugin name.
|
||||||
|
3. Keep non-portable commands (like `notify-send`) commented so users from any other OS/DE aren't surprised.
|
||||||
|
4. The plugin file should be executable.
|
||||||
|
5. If your plugin stores data, use `${XDG_CACHE_HOME:-$HOME/.cache}/nnn`. Document it _in-file_.
|
|
@ -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,75 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# Description: Create and verify checksums
|
||||||
|
#
|
||||||
|
# Note: On macOS, install the relevant checksum packages from Homebrew with:
|
||||||
|
# brew install coreutils
|
||||||
|
#
|
||||||
|
# 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,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,113 @@
|
||||||
|
#!/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://codeberg.org/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" = "viu" ] || [ "$1" = "catimg" ]; then
|
||||||
|
[ -d "$target" ] && exit_prompt "$1 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" != "sxiv" ] &&
|
||||||
|
ffmpeg -i "$file" "$NNN_PREVIEWDIR$file.jpg" -y >/dev/null 2>&1 ;;
|
||||||
|
video/*) [ "$1" != "ucollage" ] &&
|
||||||
|
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 lsix
|
||||||
|
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 ucollage
|
||||||
|
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 sxiv
|
||||||
|
view_files sxiv >/dev/null 2>&1 &
|
||||||
|
elif type nsxiv >/dev/null 2>&1; then
|
||||||
|
type ffmpegthumbnailer >/dev/null 2>&1 && make_thumbs sxiv
|
||||||
|
view_files nsxiv >/dev/null 2>&1 &
|
||||||
|
elif type imv >/dev/null 2>&1; then
|
||||||
|
make_thumbs imv
|
||||||
|
view_files imv >/dev/null 2>&1 &
|
||||||
|
elif type imvr >/dev/null 2>&1; then
|
||||||
|
make_thumbs imv
|
||||||
|
view_files imvr >/dev/null 2>&1 &
|
||||||
|
elif type viu >/dev/null 2>&1; then
|
||||||
|
clear
|
||||||
|
make_thumbs viu
|
||||||
|
viu -n "$ret"
|
||||||
|
exit_prompt
|
||||||
|
elif type catimg >/dev/null 2>&1; then
|
||||||
|
make_thumbs 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://codeberg.org/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
|
||||||
|
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 -m -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
|
||||||
|
exec >/dev/tty
|
||||||
|
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,45 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# Description: Selections are uploaded using Firefox Send
|
||||||
|
# For single files:
|
||||||
|
# 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
|
||||||
|
|
||||||
|
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
|
||||||
|
if [ -s "$selection" ]; then
|
||||||
|
if type ffsend >/dev/null 2>&1; then
|
||||||
|
# File name will be randomized foo.tar
|
||||||
|
xargs -0 < "$selection" ffsend u
|
||||||
|
else
|
||||||
|
printf "ffsend is required to upload selection."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clear selection
|
||||||
|
printf "-" > "$NNN_PIPE"
|
||||||
|
else
|
||||||
|
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
|
||||||
|
fi
|
||||||
|
|
||||||
|
read -r _
|
|
@ -0,0 +1,37 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# Description: Set the selected image as wallpaper.
|
||||||
|
# Uses nitrogen or pywal on X11, swww on wayland.
|
||||||
|
#
|
||||||
|
# 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 [ "$XDG_SESSION_TYPE" = "x11" ]; 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
|
||||||
|
else
|
||||||
|
if type swww >/dev/null 2>&1; then
|
||||||
|
swww img "$1"
|
||||||
|
else
|
||||||
|
printf "swww missing"
|
||||||
|
read -r _
|
||||||
|
fi
|
||||||
|
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,30 @@
|
||||||
|
n ()
|
||||||
|
{
|
||||||
|
# Block nesting of nnn in subshells
|
||||||
|
if [[ "${NNNLVL:-0}" -ge 1 ]]; then
|
||||||
|
echo "nnn is already running"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# The behaviour is set to cd on quit (nnn checks if NNN_TMPFILE is set)
|
||||||
|
# If NNN_TMPFILE is set to a custom path, it must be exported for nnn to
|
||||||
|
# see. To cd on quit only on ^G, remove the "export" and make sure not to
|
||||||
|
# use a custom path, i.e. set NNN_TMPFILE *exactly* as follows:
|
||||||
|
# NNN_TMPFILE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.lastd"
|
||||||
|
export NNN_TMPFILE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.lastd"
|
||||||
|
|
||||||
|
# Unmask ^Q (, ^V etc.) (if required, see `stty -a`) to Quit nnn
|
||||||
|
# stty start undef
|
||||||
|
# stty stop undef
|
||||||
|
# stty lwrap undef
|
||||||
|
# stty lnext undef
|
||||||
|
|
||||||
|
# The backslash allows one to alias n to nnn if desired without making an
|
||||||
|
# infinitely recursive alias
|
||||||
|
\nnn "$@"
|
||||||
|
|
||||||
|
if [ -f "$NNN_TMPFILE" ]; then
|
||||||
|
. "$NNN_TMPFILE"
|
||||||
|
rm -f "$NNN_TMPFILE" > /dev/null
|
||||||
|
fi
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
# NOTE: set NNN_TMPFILE correctly if you use 'XDG_CONFIG_HOME'
|
||||||
|
|
||||||
|
# The behaviour is set to cd on quit (nnn checks if NNN_TMPFILE is set)
|
||||||
|
# If NNN_TMPFILE is set to a custom path, it must be exported for nnn to see.
|
||||||
|
# To cd on quit only on ^G, set NNN_TMPFILE after the nnn invocation, and make
|
||||||
|
# sure not to use a custom path.
|
||||||
|
set NNN_TMPFILE=~/.config/nnn/.lastd
|
||||||
|
|
||||||
|
# Unmask ^Q (, ^V etc.) (if required, see `stty -a`) to Quit nnn
|
||||||
|
# stty start undef
|
||||||
|
# stty stop undef
|
||||||
|
# stty lwrap undef
|
||||||
|
# stty lnext undef
|
||||||
|
|
||||||
|
# The backslash allows one to alias n to nnn if desired without making an
|
||||||
|
# infinitely recursive alias
|
||||||
|
alias n '\nnn; source "$NNN_TMPFILE"; rm -f "$NNN_TMPFILE"'
|
|
@ -0,0 +1,41 @@
|
||||||
|
# Append this file to ~/.elvish/rc.elv (Elvish > 0.17.0)
|
||||||
|
|
||||||
|
use path
|
||||||
|
|
||||||
|
fn n {|@a|
|
||||||
|
# Block nesting of nnn in subshells
|
||||||
|
if (has-env NNNLVL) {
|
||||||
|
try {
|
||||||
|
if (>= $E:NNNLVL 1) {
|
||||||
|
echo "nnn is already running"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} catch e {
|
||||||
|
nop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# The behaviour is set to cd on quit (nnn checks if NNN_TMPFILE is set)
|
||||||
|
# If NNN_TMPFILE is set to a custom path, it must be exported for nnn to
|
||||||
|
# see.
|
||||||
|
if (has-env XDG_CONFIG_HOME) {
|
||||||
|
set-env NNN_TMPFILE $E:XDG_CONFIG_HOME/nnn/.lastd
|
||||||
|
} else {
|
||||||
|
set-env NNN_TMPFILE $E:HOME/.config/nnn/.lastd
|
||||||
|
}
|
||||||
|
|
||||||
|
# Unmask ^Q (, ^V etc.) (if required, see `stty -a`) to Quit nnn
|
||||||
|
# stty start undef
|
||||||
|
# stty stop undef
|
||||||
|
# stty lwrap undef
|
||||||
|
# stty lnext undef
|
||||||
|
|
||||||
|
# The e: prefix allows one to alias n to nnn if desired without making an
|
||||||
|
# infinitely recursive alias
|
||||||
|
e:nnn $@a
|
||||||
|
|
||||||
|
if (path:is-regular $E:NNN_TMPFILE) {
|
||||||
|
eval (slurp < $E:NNN_TMPFILE)
|
||||||
|
rm $E:NNN_TMPFILE
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
# Rename this file to match the name of the function
|
||||||
|
# e.g. ~/.config/fish/functions/n.fish
|
||||||
|
# or, add the lines to the 'config.fish' file.
|
||||||
|
|
||||||
|
function n --wraps nnn --description 'support nnn quit and change directory'
|
||||||
|
# Block nesting of nnn in subshells
|
||||||
|
if test -n "$NNNLVL" -a "$NNNLVL" -ge 1
|
||||||
|
echo "nnn is already running"
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
# The behaviour is set to cd on quit (nnn checks if NNN_TMPFILE is set)
|
||||||
|
# If NNN_TMPFILE is set to a custom path, it must be exported for nnn to
|
||||||
|
# see. To cd on quit only on ^G, remove the "-x" from both lines below,
|
||||||
|
# without changing the paths.
|
||||||
|
if test -n "$XDG_CONFIG_HOME"
|
||||||
|
set -x NNN_TMPFILE "$XDG_CONFIG_HOME/nnn/.lastd"
|
||||||
|
else
|
||||||
|
set -x NNN_TMPFILE "$HOME/.config/nnn/.lastd"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Unmask ^Q (, ^V etc.) (if required, see `stty -a`) to Quit nnn
|
||||||
|
# stty start undef
|
||||||
|
# stty stop undef
|
||||||
|
# stty lwrap undef
|
||||||
|
# stty lnext undef
|
||||||
|
|
||||||
|
# The command function allows one to alias this function to `nnn` without
|
||||||
|
# making an infinitely recursive alias
|
||||||
|
command nnn $argv
|
||||||
|
|
||||||
|
if test -e $NNN_TMPFILE
|
||||||
|
source $NNN_TMPFILE
|
||||||
|
rm $NNN_TMPFILE
|
||||||
|
end
|
||||||
|
end
|
15
.profile
15
.profile
|
@ -1,15 +0,0 @@
|
||||||
# ~/.profile: executed by Bourne-compatible login shells.
|
|
||||||
|
|
||||||
export LC_ALL=C
|
|
||||||
export LANG=C
|
|
||||||
export LANGUAGE=C
|
|
||||||
export EDITOR=vim
|
|
||||||
export VISUAL=vim
|
|
||||||
|
|
||||||
if [ "$BASH" ]; then
|
|
||||||
if [ -f ~/.bashrc ]; then
|
|
||||||
. ~/.bashrc
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
mesg n 2> /dev/null || true
|
|
|
@ -1,3 +0,0 @@
|
||||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCvrP6uUJJodYEL9vn6azufoz8rNhRmi7f4kBJge9BzhLJJjn39xe6aQESHqjNxUdy4ef2C1hsxxbakS+caioPvJHvvvE3dI/kWFjlwpfnVPLyDHfLLglKg/fH7Y9FYKKV/bt38+usv0uRxTKBZ2T+Jy2pUa3EAy0h/LainCbQpDjTOFYT8ONgFsYCalUcqNm3kwJBN+bvv7SawnrWJNDIzns0ewO6WYGGnUZNxgsby6E40Wemy3G7GZGirlt1uXMjV//9rzSiyLb76ZBvbRGy0rVkzNLOFhmIl3AJO7Q+VxchIaZsrNF6Jh1fWojj0gBvLauocen0cuFjQcjfvXbJ/ root@homeserver
|
|
||||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCUSOYJR2E7tab8LnynSd2TWA+ROykheTXNP7u2dQWOCMtEK/4S9JGBQKpzVW+nR+4qJG6CVkNKUTNlW6xNau1AnRL1s4bopqbwZgPqtOBfPJV92ainAr3s0+Zlm0NwQvCFM690K/Xw3LDNBWmOCmIz5Ak2uStyjJh0cuph0EtWZ9vBD4sp6brJwKkkf1rKL47Y/zJ7weepyhU3Z4nGgUoUEOKJY/4aNpSgkb0iWxOueZsRajaj+7lO7CqNz75o+ZfmZaidfPE/GdqF++MnCCxychYzgxNqZQeXxeJuAyX1CAfbEmWgQ70Vx74ktKEFD1UmBYdFyONZaoQBps89s8pXmB7YUWS70rycqZ8W87sZgBp+s6DyzoBjchgyL/S8Gn64q7n67Ei+FaCkrTq6ZU+GFrwqK4uRB4wKGBNZuXZaIPQsL8Wurg7onaeiOEQ+r6BQ5aah5n2Iir61E7EoOSZaD5xsgisFET8Y5J5Rf22UsHOU/D/x4ZXXSi/RgTkKBzs= plex@theseus
|
|
||||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMalrcG0FB8zj+/OHIUuZHxoZH3DaCzLmlPDfufJErwQ plex@homeserver
|
|
Binary file not shown.
|
@ -0,0 +1,269 @@
|
||||||
|
xterm-kitty|KovIdTTY,
|
||||||
|
Su,
|
||||||
|
Tc,
|
||||||
|
XF,
|
||||||
|
am,
|
||||||
|
ccc,
|
||||||
|
fullkbd,
|
||||||
|
hs,
|
||||||
|
km,
|
||||||
|
mc5i,
|
||||||
|
mir,
|
||||||
|
msgr,
|
||||||
|
npc,
|
||||||
|
xenl,
|
||||||
|
colors#256,
|
||||||
|
cols#80,
|
||||||
|
it#8,
|
||||||
|
lines#24,
|
||||||
|
pairs#32767,
|
||||||
|
BD=\E[?2004l,
|
||||||
|
BE=\E[?2004h,
|
||||||
|
Cr=\E]112\007,
|
||||||
|
Cs=\E]12;%p1%s\007,
|
||||||
|
Ms=\E]52;%p1%s;%p2%s\E\\,
|
||||||
|
PE=\E[201~,
|
||||||
|
PS=\E[200~,
|
||||||
|
RV=\E[>c,
|
||||||
|
Se=\E[2\sq,
|
||||||
|
Setulc=\E[58:2:%p1%{65536}%/%d:%p1%{256}%/%{255}%&%d:%p1%{255}%&%d%;m,
|
||||||
|
Smulx=\E[4:%p1%dm,
|
||||||
|
Ss=\E[%p1%d\sq,
|
||||||
|
Sync=\EP=%p1%ds\E\\,
|
||||||
|
XR=\E[>0q,
|
||||||
|
acsc=++\,\,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
|
||||||
|
bel=^G,
|
||||||
|
bold=\E[1m,
|
||||||
|
cbt=\E[Z,
|
||||||
|
civis=\E[?25l,
|
||||||
|
clear=\E[H\E[2J,
|
||||||
|
cnorm=\E[?12h\E[?25h,
|
||||||
|
cr=^M,
|
||||||
|
csr=\E[%i%p1%d;%p2%dr,
|
||||||
|
cub=\E[%p1%dD,
|
||||||
|
cub1=^H,
|
||||||
|
cud=\E[%p1%dB,
|
||||||
|
cud1=^J,
|
||||||
|
cuf=\E[%p1%dC,
|
||||||
|
cuf1=\E[C,
|
||||||
|
cup=\E[%i%p1%d;%p2%dH,
|
||||||
|
cuu=\E[%p1%dA,
|
||||||
|
cuu1=\E[A,
|
||||||
|
cvvis=\E[?12;25h,
|
||||||
|
dch=\E[%p1%dP,
|
||||||
|
dch1=\E[P,
|
||||||
|
dim=\E[2m,
|
||||||
|
dl=\E[%p1%dM,
|
||||||
|
dl1=\E[M,
|
||||||
|
dsl=\E]2;\E\\,
|
||||||
|
ech=\E[%p1%dX,
|
||||||
|
ed=\E[J,
|
||||||
|
el=\E[K,
|
||||||
|
el1=\E[1K,
|
||||||
|
fd=\E[?1004l,
|
||||||
|
fe=\E[?1004h,
|
||||||
|
flash=\E[?5h$<100/>\E[?5l,
|
||||||
|
fsl=^G,
|
||||||
|
home=\E[H,
|
||||||
|
hpa=\E[%i%p1%dG,
|
||||||
|
ht=^I,
|
||||||
|
hts=\EH,
|
||||||
|
ich=\E[%p1%d@,
|
||||||
|
il=\E[%p1%dL,
|
||||||
|
il1=\E[L,
|
||||||
|
ind=^J,
|
||||||
|
indn=\E[%p1%dS,
|
||||||
|
initc=\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\,
|
||||||
|
kBEG=\E[1;2E,
|
||||||
|
kBEG3=\E[1;3E,
|
||||||
|
kBEG4=\E[1;4E,
|
||||||
|
kBEG5=\E[1;5E,
|
||||||
|
kBEG6=\E[1;6E,
|
||||||
|
kBEG7=\E[1;7E,
|
||||||
|
kDC=\E[3;2~,
|
||||||
|
kDC3=\E[3;3~,
|
||||||
|
kDC4=\E[3;4~,
|
||||||
|
kDC5=\E[3;5~,
|
||||||
|
kDC6=\E[3;6~,
|
||||||
|
kDC7=\E[3;7~,
|
||||||
|
kDN=\E[1;2B,
|
||||||
|
kDN3=\E[1;3B,
|
||||||
|
kDN4=\E[1;4B,
|
||||||
|
kDN5=\E[1;5B,
|
||||||
|
kDN6=\E[1;6B,
|
||||||
|
kDN7=\E[1;7B,
|
||||||
|
kEND=\E[1;2F,
|
||||||
|
kEND3=\E[1;3F,
|
||||||
|
kEND4=\E[1;4F,
|
||||||
|
kEND5=\E[1;5F,
|
||||||
|
kEND6=\E[1;6F,
|
||||||
|
kEND7=\E[1;7F,
|
||||||
|
kHOM=\E[1;2H,
|
||||||
|
kHOM3=\E[1;3H,
|
||||||
|
kHOM4=\E[1;4H,
|
||||||
|
kHOM5=\E[1;5H,
|
||||||
|
kHOM6=\E[1;6H,
|
||||||
|
kHOM7=\E[1;7H,
|
||||||
|
kIC=\E[2;2~,
|
||||||
|
kIC3=\E[2;3~,
|
||||||
|
kIC4=\E[2;4~,
|
||||||
|
kIC5=\E[2;5~,
|
||||||
|
kIC6=\E[2;6~,
|
||||||
|
kIC7=\E[2;7~,
|
||||||
|
kLFT=\E[1;2D,
|
||||||
|
kLFT3=\E[1;3D,
|
||||||
|
kLFT4=\E[1;4D,
|
||||||
|
kLFT5=\E[1;5D,
|
||||||
|
kLFT6=\E[1;6D,
|
||||||
|
kLFT7=\E[1;7D,
|
||||||
|
kNXT=\E[6;2~,
|
||||||
|
kNXT3=\E[6;3~,
|
||||||
|
kNXT4=\E[6;4~,
|
||||||
|
kNXT5=\E[6;5~,
|
||||||
|
kNXT6=\E[6;6~,
|
||||||
|
kNXT7=\E[6;7~,
|
||||||
|
kPRV=\E[5;2~,
|
||||||
|
kPRV3=\E[5;3~,
|
||||||
|
kPRV4=\E[5;4~,
|
||||||
|
kPRV5=\E[5;5~,
|
||||||
|
kPRV6=\E[5;6~,
|
||||||
|
kPRV7=\E[5;7~,
|
||||||
|
kRIT=\E[1;2C,
|
||||||
|
kRIT3=\E[1;3C,
|
||||||
|
kRIT4=\E[1;4C,
|
||||||
|
kRIT5=\E[1;5C,
|
||||||
|
kRIT6=\E[1;6C,
|
||||||
|
kRIT7=\E[1;7C,
|
||||||
|
kUP=\E[1;2A,
|
||||||
|
kUP3=\E[1;3A,
|
||||||
|
kUP4=\E[1;4A,
|
||||||
|
kUP5=\E[1;5A,
|
||||||
|
kUP6=\E[1;6A,
|
||||||
|
kUP7=\E[1;7A,
|
||||||
|
ka1=,
|
||||||
|
ka3=,
|
||||||
|
kbeg=\EOE,
|
||||||
|
kbs=\177,
|
||||||
|
kc1=,
|
||||||
|
kc3=,
|
||||||
|
kcbt=\E[Z,
|
||||||
|
kcub1=\EOD,
|
||||||
|
kcud1=\EOB,
|
||||||
|
kcuf1=\EOC,
|
||||||
|
kcuu1=\EOA,
|
||||||
|
kdch1=\E[3~,
|
||||||
|
kend=\EOF,
|
||||||
|
kf1=\EOP,
|
||||||
|
kf10=\E[21~,
|
||||||
|
kf11=\E[23~,
|
||||||
|
kf12=\E[24~,
|
||||||
|
kf13=\E[1;2P,
|
||||||
|
kf14=\E[1;2Q,
|
||||||
|
kf15=\E[13;2~,
|
||||||
|
kf16=\E[1;2S,
|
||||||
|
kf17=\E[15;2~,
|
||||||
|
kf18=\E[17;2~,
|
||||||
|
kf19=\E[18;2~,
|
||||||
|
kf2=\EOQ,
|
||||||
|
kf20=\E[19;2~,
|
||||||
|
kf21=\E[20;2~,
|
||||||
|
kf22=\E[21;2~,
|
||||||
|
kf23=\E[23;2~,
|
||||||
|
kf24=\E[24;2~,
|
||||||
|
kf25=\E[1;5P,
|
||||||
|
kf26=\E[1;5Q,
|
||||||
|
kf27=\E[13;5~,
|
||||||
|
kf28=\E[1;5S,
|
||||||
|
kf29=\E[15;5~,
|
||||||
|
kf3=\EOR,
|
||||||
|
kf30=\E[17;5~,
|
||||||
|
kf31=\E[18;5~,
|
||||||
|
kf32=\E[19;5~,
|
||||||
|
kf33=\E[20;5~,
|
||||||
|
kf34=\E[21;5~,
|
||||||
|
kf35=\E[23;5~,
|
||||||
|
kf36=\E[24;5~,
|
||||||
|
kf37=\E[1;6P,
|
||||||
|
kf38=\E[1;6Q,
|
||||||
|
kf39=\E[13;6~,
|
||||||
|
kf4=\EOS,
|
||||||
|
kf40=\E[1;6S,
|
||||||
|
kf41=\E[15;6~,
|
||||||
|
kf42=\E[17;6~,
|
||||||
|
kf43=\E[18;6~,
|
||||||
|
kf44=\E[19;6~,
|
||||||
|
kf45=\E[20;6~,
|
||||||
|
kf46=\E[21;6~,
|
||||||
|
kf47=\E[23;6~,
|
||||||
|
kf48=\E[24;6~,
|
||||||
|
kf49=\E[1;3P,
|
||||||
|
kf5=\E[15~,
|
||||||
|
kf50=\E[1;3Q,
|
||||||
|
kf51=\E[13;3~,
|
||||||
|
kf52=\E[1;3S,
|
||||||
|
kf53=\E[15;3~,
|
||||||
|
kf54=\E[17;3~,
|
||||||
|
kf55=\E[18;3~,
|
||||||
|
kf56=\E[19;3~,
|
||||||
|
kf57=\E[20;3~,
|
||||||
|
kf58=\E[21;3~,
|
||||||
|
kf59=\E[23;3~,
|
||||||
|
kf6=\E[17~,
|
||||||
|
kf60=\E[24;3~,
|
||||||
|
kf61=\E[1;4P,
|
||||||
|
kf62=\E[1;4Q,
|
||||||
|
kf63=\E[13;4~,
|
||||||
|
kf7=\E[18~,
|
||||||
|
kf8=\E[19~,
|
||||||
|
kf9=\E[20~,
|
||||||
|
khlp=,
|
||||||
|
khome=\EOH,
|
||||||
|
kich1=\E[2~,
|
||||||
|
kind=\E[1;2B,
|
||||||
|
kmous=\E[M,
|
||||||
|
knp=\E[6~,
|
||||||
|
kpp=\E[5~,
|
||||||
|
kri=\E[1;2A,
|
||||||
|
kund=,
|
||||||
|
kxIN=\E[I,
|
||||||
|
kxOUT=\E[O,
|
||||||
|
oc=\E]104\007,
|
||||||
|
op=\E[39;49m,
|
||||||
|
rc=\E8,
|
||||||
|
rep=%p1%c\E[%p2%{1}%-%db,
|
||||||
|
rev=\E[7m,
|
||||||
|
ri=\EM,
|
||||||
|
rin=\E[%p1%dT,
|
||||||
|
ritm=\E[23m,
|
||||||
|
rmacs=\E(B,
|
||||||
|
rmam=\E[?7l,
|
||||||
|
rmcup=\E[?1049l,
|
||||||
|
rmir=\E[4l,
|
||||||
|
rmkx=\E[?1l,
|
||||||
|
rmso=\E[27m,
|
||||||
|
rmul=\E[24m,
|
||||||
|
rmxx=\E[29m,
|
||||||
|
rs1=\E]\E\\\Ec,
|
||||||
|
sc=\E7,
|
||||||
|
setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
|
||||||
|
setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
|
||||||
|
setrgbb=\E[48:2:%p1%d:%p2%d:%p3%dm,
|
||||||
|
setrgbf=\E[38:2:%p1%d:%p2%d:%p3%dm,
|
||||||
|
sgr=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m,
|
||||||
|
sgr0=\E(B\E[m,
|
||||||
|
sitm=\E[3m,
|
||||||
|
smacs=\E(0,
|
||||||
|
smam=\E[?7h,
|
||||||
|
smcup=\E[?1049h,
|
||||||
|
smir=\E[4h,
|
||||||
|
smkx=\E[?1h,
|
||||||
|
smso=\E[7m,
|
||||||
|
smul=\E[4m,
|
||||||
|
smxx=\E[9m,
|
||||||
|
tbc=\E[3g,
|
||||||
|
tsl=\E]2;,
|
||||||
|
u6=\E[%i%d;%dR,
|
||||||
|
u7=\E[6n,
|
||||||
|
u8=\E[?%[;0123456789]c,
|
||||||
|
u9=\E[c,
|
||||||
|
vpa=\E[%i%p1%dd,
|
Binary file not shown.
|
@ -0,0 +1,144 @@
|
||||||
|
# thanks to this awesome guide: https://thevaluable.dev/tmux-config-mouseless/ (visited 2023-02-04
|
||||||
|
|
||||||
|
# make ctrl-space the prefix. Unbind default ctrl-b
|
||||||
|
set -g prefix C-Space
|
||||||
|
set -g prefix C-Space
|
||||||
|
unbind -T prefix C-b
|
||||||
|
unbind -n C-b
|
||||||
|
unbind C-b
|
||||||
|
bind-key -n C-b send-keys C-b
|
||||||
|
|
||||||
|
# enable using the mouse
|
||||||
|
set -g mouse on
|
||||||
|
|
||||||
|
# prefix-r to reload the config file
|
||||||
|
|
||||||
|
# prefix-r to reload the config file
|
||||||
|
unbind r
|
||||||
|
bind r source-file ~/.tmux.conf \; display "Reloaded ~/.tmux.conf"
|
||||||
|
|
||||||
|
# change split hotkeys
|
||||||
|
# v and h are not bound by default, but we never know in the next versions...
|
||||||
|
unbind v
|
||||||
|
unbind h
|
||||||
|
|
||||||
|
unbind % # Split vertically
|
||||||
|
unbind '"' # Split horizontally
|
||||||
|
|
||||||
|
# split horizontal with or prefix-"
|
||||||
|
#bind h split-window -h -c "#{pane_current_path}"
|
||||||
|
bind '"' split-window -h -c "#{pane_current_path}"
|
||||||
|
|
||||||
|
# split vertical with or prefix-%
|
||||||
|
#bind v split-window -v -c "#{pane_current_path}"
|
||||||
|
bind % split-window -v -c "#{pane_current_path}"
|
||||||
|
|
||||||
|
# navigate panels with vim or arrow keys
|
||||||
|
# arrows are the default
|
||||||
|
bind h select-pane -L
|
||||||
|
bind j select-pane -D
|
||||||
|
bind k select-pane -U
|
||||||
|
bind l select-pane -R
|
||||||
|
|
||||||
|
# reorder panels with prefix+shift+{jk}
|
||||||
|
bind K swap-pane -U
|
||||||
|
bind J swap-pane -D
|
||||||
|
|
||||||
|
# rotate panels with prefix+ctrl+o and prefix+ctrl+shift+o (reversed)
|
||||||
|
# default
|
||||||
|
|
||||||
|
# rename windows/sessions with prefix-n-<w|s>
|
||||||
|
unbind n #DEFAULT KEY: Move to next split-window
|
||||||
|
bind -T prefix n switch-client -T naming_table
|
||||||
|
bind -T naming_table s command-prompt "rename-session '%%'"
|
||||||
|
bind -T naming_table w command-prompt "rename-window '%%'"
|
||||||
|
|
||||||
|
# set the first window id to 1, I know computer scientists always start from 0, but 0 is so far away from my left hand.
|
||||||
|
# remember: prefix-{digit} brings you to the window with the id {digit}
|
||||||
|
set -g base-index 1
|
||||||
|
set-window-option -g pane-base-index 1
|
||||||
|
|
||||||
|
# next window with alt-<comma>, last with alt-<dot>, no prefix needed.
|
||||||
|
bind -n M-, previous-window
|
||||||
|
bind -n M-. next-window
|
||||||
|
|
||||||
|
# tmux modes stuff. we have default mode and copy mode.
|
||||||
|
# change the copy mode key to prefix-N , the default config isnt good for qwertz keyboards.
|
||||||
|
bind-key N copy-mode
|
||||||
|
|
||||||
|
# obviously use vim keys for copymode (think normal mode in vim)
|
||||||
|
# with these options we can yank the tmux copy stuff into the system clipboard.
|
||||||
|
set-window-option -g mode-keys vi
|
||||||
|
|
||||||
|
# Use prefix-p to paste
|
||||||
|
unbind ] #Default for pasting
|
||||||
|
bind p paste-buffer
|
||||||
|
|
||||||
|
unbind -T copy-mode-vi Space; #Default for begin-selection
|
||||||
|
unbind -T copy-mode-vi Enter; #Default for copy-selection
|
||||||
|
|
||||||
|
|
||||||
|
bind -T copy-mode-vi v send-keys -X begin-selection
|
||||||
|
# copy to wayland clipboard. If you use XORG use the commented version with xsel.
|
||||||
|
#bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "xsel --clipboard"
|
||||||
|
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "wl-copy"
|
||||||
|
|
||||||
|
# magic tweaks for better use with vim or neovim
|
||||||
|
#s#et -g -a terminal-overrides ',*:Ss=\E[%p1%d q:Se=\E[2 q'
|
||||||
|
# Smart pane switching with awareness of Vim splits.
|
||||||
|
# See: https://github.com/christoomey/vim-tmux-navigator
|
||||||
|
|
||||||
|
# send esc to the process instantly!
|
||||||
|
set-option -s escape-time 10
|
||||||
|
|
||||||
|
is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
|
||||||
|
| grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"
|
||||||
|
bind -n C-h if-shell "$is_vim" "send-keys C-h" "select-pane -L"
|
||||||
|
bind -n C-j if-shell "$is_vim" "send-keys C-j" "select-pane -D"
|
||||||
|
bind -n C-k if-shell "$is_vim" "send-keys C-k" "select-pane -U"
|
||||||
|
bind -n C-l if-shell "$is_vim" "send-keys C-l" "select-pane -R"
|
||||||
|
bind -n C-\\ if-shell "$is_vim" "send-keys C-\\" "select-pane -l"
|
||||||
|
|
||||||
|
# shell comaptability stuff
|
||||||
|
is_shell="ps -o state= -o comm= -t '#{pane_tty}' \
|
||||||
|
| grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(zsh|bash|sh)(diff)?$'"
|
||||||
|
|
||||||
|
# clear panel with ctrl-l (like bash or zsh)
|
||||||
|
unbind C-l # Default for go to last window
|
||||||
|
bind -n C-l if-shell "$is_shell" "bind -n C-l send-keys C-l ; run 'sleep 0.1' ; clear-history"
|
||||||
|
|
||||||
|
# use all colors
|
||||||
|
set -g default-terminal "tmux-256color"
|
||||||
|
#set-option -sa terminal-overrides ',XXX:RGB'
|
||||||
|
|
||||||
|
# theming, See https://github.com/seebi/tmux-colors-solarized/blob/master/tmuxcolors-dark.conf
|
||||||
|
|
||||||
|
#### COLOUR (Solarized dark)
|
||||||
|
|
||||||
|
# default statusbar colors
|
||||||
|
set-option -g status-style fg=yellow,bg=black #yellow and base02
|
||||||
|
|
||||||
|
# default window title colors
|
||||||
|
set-window-option -g window-status-style fg=brightblue,bg=default #base0 and default
|
||||||
|
#set-window-option -g window-status-style dim
|
||||||
|
|
||||||
|
# active window title colors
|
||||||
|
set-window-option -g window-status-current-style fg=brightred,bg=default #orange and default
|
||||||
|
#set-window-option -g window-status-current-style bright
|
||||||
|
|
||||||
|
# pane border
|
||||||
|
set-option -g pane-border-style fg=black #base02
|
||||||
|
set-option -g pane-active-border-style fg=brightgreen #base01
|
||||||
|
|
||||||
|
# message text
|
||||||
|
set-option -g message-style fg=brightred,bg=black #orange and base01
|
||||||
|
|
||||||
|
# pane number display
|
||||||
|
set-option -g display-panes-active-colour brightred #orange
|
||||||
|
set-option -g display-panes-colour blue #blue
|
||||||
|
|
||||||
|
# clock
|
||||||
|
set-window-option -g clock-mode-colour green #green
|
||||||
|
|
||||||
|
# bell
|
||||||
|
set-window-option -g window-status-bell-style fg=black,bg=red #base02, red
|
|
@ -0,0 +1,11 @@
|
||||||
|
export GEM_HOME="$HOME/.local/share/gems"
|
||||||
|
export PATH="/usr/bin:/usr/sbin:$HOME/.local/bin:$HOME/.cargo/bin:/usr/local/bin:$HOME/.deno/bin:/usr/games/:$GEM_HOME/bin"
|
||||||
|
export EDITOR=nvim
|
||||||
|
export editor=nvim
|
||||||
|
export XDG_CONFIG_HOME=~/.config
|
||||||
|
|
||||||
|
export GTK_IM_MODULE=ibus
|
||||||
|
export QT_IM_MODULE=ibus
|
||||||
|
export SDL_IM_MODULE=ibus
|
||||||
|
export GLFW_IM_MODULE=ibus
|
||||||
|
export XMODIFIERS=@im=ibus
|
|
@ -0,0 +1,98 @@
|
||||||
|
# -*- mode: sh; sh-indentation: 4; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||||
|
# Almost all code borrowed from Zshell's _make function
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Sebastian Gniazdowski
|
||||||
|
|
||||||
|
local -a TARGETS
|
||||||
|
|
||||||
|
.make-expandVars() {
|
||||||
|
local open close var val front='' rest=$1
|
||||||
|
|
||||||
|
while [[ $rest == (#b)[^$]#($)* ]]; do
|
||||||
|
front=$front${rest[1,$mbegin[1]-1]}
|
||||||
|
rest=${rest[$mbegin[1],-1]}
|
||||||
|
|
||||||
|
case $rest[2] in
|
||||||
|
($) # '$$'. may not appear in target and variable's value
|
||||||
|
front=$front\$\$
|
||||||
|
rest=${rest[3,-1]}
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
(\() # Variable of the form $(foobar)
|
||||||
|
open='('
|
||||||
|
close=')'
|
||||||
|
;;
|
||||||
|
({) # ${foobar}
|
||||||
|
open='{'
|
||||||
|
close='}'
|
||||||
|
;;
|
||||||
|
([[:alpha:]]) # $foobar. This is exactly $(f)oobar.
|
||||||
|
open=''
|
||||||
|
close=''
|
||||||
|
var=$rest[2]
|
||||||
|
;;
|
||||||
|
(*) # bad parameter name
|
||||||
|
print -- $front$rest
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [[ -n $open ]]; then
|
||||||
|
if [[ $rest == \$$open(#b)([[:alnum:]_]##)(#B)$close* ]]; then
|
||||||
|
var=$match
|
||||||
|
else # unmatched () or {}, or bad parameter name
|
||||||
|
print -- $front$rest
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
val=''
|
||||||
|
if [[ -n ${VAR_ARGS[(i)$var]} ]]; then
|
||||||
|
val=${VAR_ARGS[$var]}
|
||||||
|
else
|
||||||
|
if [[ -n $opt_args[(I)(-e|--environment-overrides)] ]]; then
|
||||||
|
if [[ $parameters[$var] == scalar-export* ]]; then
|
||||||
|
val=${(P)var}
|
||||||
|
elif [[ -n ${VARIABLES[(i)$var]} ]]; then
|
||||||
|
val=${VARIABLES[$var]}
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [[ -n ${VARIABLES[(i)$var]} ]]; then
|
||||||
|
val=${VARIABLES[$var]}
|
||||||
|
elif [[ $parameters[$var] == scalar-export* ]]; then
|
||||||
|
val=${(P)var}
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
rest=${rest//\$$open$var$close/$val}
|
||||||
|
done
|
||||||
|
|
||||||
|
print -- ${front}${rest}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.make-parseMakefile () {
|
||||||
|
local input var val target dep TAB=$'\t' tmp IFS=
|
||||||
|
|
||||||
|
while read input
|
||||||
|
do
|
||||||
|
case "$input " in
|
||||||
|
# TARGET: dependencies
|
||||||
|
# TARGET1 TARGET2 TARGET3: dependencies
|
||||||
|
([[*?[:alnum:]$][^$TAB:=%]#:[^=]*)
|
||||||
|
target=$(.make-expandVars ${input%%:*})
|
||||||
|
TARGETS+=( ${(z)target} )
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ -z "${FAST_HIGHLIGHT[chroma-make-cache]}" || $(( EPOCHSECONDS - FAST_HIGHLIGHT[chroma-make-cache-born-at] )) -gt 7 ]]; then
|
||||||
|
.make-parseMakefile
|
||||||
|
FAST_HIGHLIGHT[chroma-make-cache-born-at]="$EPOCHSECONDS"
|
||||||
|
FAST_HIGHLIGHT[chroma-make-cache]="${(j:;:)TARGETS}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
reply2=( "${(s:;:)FAST_HIGHLIGHT[chroma-make-cache]}" )
|
||||||
|
|
||||||
|
# vim:ft=zsh:et
|
|
@ -0,0 +1,30 @@
|
||||||
|
# Copyright (c) 2018 Sebastian Gniazdowski
|
||||||
|
#
|
||||||
|
# $1 - path to the ini file to parse
|
||||||
|
# $2 - name of output hash (INI by default)
|
||||||
|
# $3 - prefix for keys in the hash (can be empty)
|
||||||
|
#
|
||||||
|
# Writes to given hash under keys built in following way: ${3}<section>_field.
|
||||||
|
# Values are values from ini file.
|
||||||
|
|
||||||
|
local __ini_file="$1" __out_hash="${2:-INI}" __key_prefix="$3"
|
||||||
|
local IFS='' __line __cur_section="void" __access_string
|
||||||
|
local -a match mbegin mend
|
||||||
|
|
||||||
|
[[ ! -r "$__ini_file" ]] && { builtin print -r "fast-syntax-highlighting: an ini file is unreadable ($__ini_file)"; return 1; }
|
||||||
|
|
||||||
|
while read -r -t 1 __line; do
|
||||||
|
if [[ "$__line" = [[:blank:]]#\;* ]]; then
|
||||||
|
continue
|
||||||
|
elif [[ "$__line" = (#b)[[:blank:]]#\[([^\]]##)\][[:blank:]]# ]]; then
|
||||||
|
__cur_section="${match[1]}"
|
||||||
|
elif [[ "$__line" = (#b)[[:blank:]]#([^[:blank:]=]##)[[:blank:]]#[=][[:blank:]]#(*) ]]; then
|
||||||
|
match[2]="${match[2]%"${match[2]##*[! $'\t']}"}" # remove trailing whitespace
|
||||||
|
__access_string="${__out_hash}[${__key_prefix}<$__cur_section>_${match[1]}]"
|
||||||
|
: "${(P)__access_string::=${match[2]}}"
|
||||||
|
fi
|
||||||
|
done < "$__ini_file"
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# vim:ft=zsh:sw=4:sts=4:et
|
|
@ -0,0 +1,37 @@
|
||||||
|
# -*- mode: sh; sh-indentation: 4; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||||
|
# Copyright (c) 2018 Sebastian Gniazdowski
|
||||||
|
#
|
||||||
|
# FAST_HIGHLIGHT hash serves as container for variables that
|
||||||
|
# prevents creating them in global scope. (P) flag is not used,
|
||||||
|
# output array is fixed (__lines_list).
|
||||||
|
#
|
||||||
|
# $1 - the command, e.g. "git remote"; 2>/dev/null redirection is
|
||||||
|
# added automatically
|
||||||
|
# $2 - FAST_HIGHLIGHT field name, e.g. "chroma-git-branches"; two
|
||||||
|
# additional fields will be used, $2-cache, $2-cache-born-at
|
||||||
|
# $3 - what to remove from beginning of the lines returned by the
|
||||||
|
# command
|
||||||
|
# $4 - cache validity time, default 5 (seconds)
|
||||||
|
#
|
||||||
|
# Output: array __lines_list, with output of the command ran
|
||||||
|
|
||||||
|
# User should not forget to define this array, the below code
|
||||||
|
# will only ensure that it's array (can also define a global)
|
||||||
|
typeset -ga __lines_list
|
||||||
|
local -a __response
|
||||||
|
|
||||||
|
if [[ -z "${FAST_HIGHLIGHT[$2-cache]}" || $(( EPOCHSECONDS - FAST_HIGHLIGHT[$2-cache-born-at] )) -gt ${4:-5} ]]; then
|
||||||
|
FAST_HIGHLIGHT[$2-cache-born-at]="$EPOCHSECONDS"
|
||||||
|
__response=( ${${(f)"$(command ${(Qz)1#+} 2>/dev/null)"}#${~3}} )
|
||||||
|
[[ "$1" = "+"* ]] && __lines_list+=( "${__response[@]}" ) || __lines_list=( "${__response[@]}" )
|
||||||
|
FAST_HIGHLIGHT[$2-cache]="${(j:;:)__response}"
|
||||||
|
else
|
||||||
|
# Quoted (s:;:) flag without @ will skip empty elements. It
|
||||||
|
# still produces array output, interesingly. All this is for
|
||||||
|
# the trailing ";" above, to skip last, empty element.
|
||||||
|
[[ "$1" = "+"* ]] && \
|
||||||
|
__lines_list+=( "${(@s:;:)FAST_HIGHLIGHT[$2-cache]}" ) || \
|
||||||
|
__lines_list=( "${(@s:;:)FAST_HIGHLIGHT[$2-cache]}" )
|
||||||
|
fi
|
||||||
|
|
||||||
|
# vim:ft=zsh:et:sw=4
|
|
@ -0,0 +1,60 @@
|
||||||
|
# -*- mode: sh; sh-indentation: 4; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||||
|
# Copyright (c) 2018 Sebastian Gniazdowski
|
||||||
|
#
|
||||||
|
# It runs given command, which in general will be a git command,
|
||||||
|
# automatically looking at cache first (a field named *-cache,
|
||||||
|
# in FAST_HIGHLIGHT), which is valid for 5 seconds, and in case
|
||||||
|
# of outdated or not existing cache, runs the command, splitting
|
||||||
|
# on new-lines, first checking if PWD is inside git repository.
|
||||||
|
#
|
||||||
|
# FAST_HIGHLIGHT hash serves as container for variables that
|
||||||
|
# prevents creating them in global scope. (P) flag is not used,
|
||||||
|
# output array is fixed (__lines_list).
|
||||||
|
#
|
||||||
|
# $1 - the command, e.g. "git remote"; 2>/dev/null redirection is
|
||||||
|
# added automatically
|
||||||
|
# $2 - FAST_HIGHLIGHT field name, e.g. "chroma-git-branches"; two
|
||||||
|
# additional fields will be used, $2-cache, $2-cache-born-at
|
||||||
|
# $3 - what to remove from beginning of the lines returned by the
|
||||||
|
# command
|
||||||
|
# $4 - cache validity time, default 5 (seconds)
|
||||||
|
#
|
||||||
|
# Output: array __lines_list, with output of the (git) command ran
|
||||||
|
|
||||||
|
# User should not forget to define this array, the below code
|
||||||
|
# will only ensure that it's array (can also define a global)
|
||||||
|
typeset -ga __lines_list
|
||||||
|
local -a __response
|
||||||
|
|
||||||
|
if [[ $1 == --status ]] {
|
||||||
|
integer __status=1
|
||||||
|
shift
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ -z ${FAST_HIGHLIGHT[$2-cache]} || $(( EPOCHSECONDS - FAST_HIGHLIGHT[$2-cache-born-at] )) -gt ${4:-5} ]]; then
|
||||||
|
FAST_HIGHLIGHT[$2-cache-born-at]=$EPOCHSECONDS
|
||||||
|
if [[ "$(command git rev-parse --is-inside-work-tree 2>/dev/null)" = true ]]; then
|
||||||
|
__response=( ${${(f)"$(command ${(Qz)${1#+}} 2>/dev/null)"}#$3} )
|
||||||
|
integer retval=$?
|
||||||
|
if (( __status )) {
|
||||||
|
__response=( $retval )
|
||||||
|
__lines_list=( $retval )
|
||||||
|
} else {
|
||||||
|
[[ "$1" = "+"* ]] && \
|
||||||
|
__lines_list+=( "${__response[@]}" ) || \
|
||||||
|
__lines_list=( "${__response[@]}" )
|
||||||
|
}
|
||||||
|
else
|
||||||
|
__lines_list=()
|
||||||
|
fi
|
||||||
|
FAST_HIGHLIGHT[$2-cache]="${(j:;:)__response}"
|
||||||
|
else
|
||||||
|
# Quoted (s:;:) flag without @ will skip empty elements. It
|
||||||
|
# still produces array output, interesingly. All this is for
|
||||||
|
# the trailing ";" above, to skip last, empty element.
|
||||||
|
[[ "$1" = "+"* ]] && \
|
||||||
|
__lines_list+=( "${(@s:;:)FAST_HIGHLIGHT[$2-cache]}" ) || \
|
||||||
|
__lines_list=( "${(@s:;:)FAST_HIGHLIGHT[$2-cache]}" )
|
||||||
|
fi
|
||||||
|
|
||||||
|
# vim:ft=zsh:et:sw=4
|
|
@ -0,0 +1,17 @@
|
||||||
|
# $1 - file-descriptor to be read from
|
||||||
|
# $2 - name of output variable (default: REPLY)
|
||||||
|
|
||||||
|
local __in_fd=${1:-0} __out_var=${2:-REPLY}
|
||||||
|
local -a __tmp
|
||||||
|
integer __ret=1 __repeat=10 __tmp_size=0
|
||||||
|
|
||||||
|
while sysread -s 65535 -i "$__in_fd" '__tmp[__tmp_size + 1]'; do
|
||||||
|
(( ( __ret=$? ) == 0 )) && (( ++ __tmp_size ))
|
||||||
|
(( __ret == 5 )) && { __ret=0; (( --__repeat == 0 )) && break; }
|
||||||
|
done
|
||||||
|
|
||||||
|
: ${(P)__out_var::="${(j::)__tmp}"}
|
||||||
|
|
||||||
|
return __ret
|
||||||
|
|
||||||
|
# vim: ft=zsh:et:sw=4:sts=4
|
|
@ -0,0 +1,5 @@
|
||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
github: psprint
|
||||||
|
patreon: psprint
|
||||||
|
ko_fi: psprint
|
|
@ -0,0 +1,24 @@
|
||||||
|
current_theme.zsh
|
||||||
|
secondary_theme.zsh
|
||||||
|
theme_overlay.zsh
|
||||||
|
*.txt
|
||||||
|
test/out.parse
|
||||||
|
test/res
|
||||||
|
hold/*
|
||||||
|
*.zwc
|
||||||
|
|
||||||
|
### Vim
|
||||||
|
# Swap
|
||||||
|
[._]*.s[a-v][a-z]
|
||||||
|
[._]*.sw[a-p]
|
||||||
|
[._]s[a-v][a-z]
|
||||||
|
[._]sw[a-p]
|
||||||
|
|
||||||
|
# Session
|
||||||
|
Session.vim
|
||||||
|
|
||||||
|
# Temporary
|
||||||
|
.netrwhist
|
||||||
|
*~
|
||||||
|
# Auto-generated tag files
|
||||||
|
tags
|
|
@ -0,0 +1,13 @@
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
zsh
|
||||||
|
install:
|
||||||
|
- mkdir .bin
|
||||||
|
- curl -L https://github.com/zunit-zsh/zunit/releases/download/v0.8.2/zunit > .bin/zunit
|
||||||
|
- curl -L https://raw.githubusercontent.com/molovo/revolver/master/revolver > .bin/revolver
|
||||||
|
- curl -L https://raw.githubusercontent.com/molovo/color/master/color.zsh > .bin/color
|
||||||
|
before_script:
|
||||||
|
- chmod u+x .bin/{color,revolver,zunit}
|
||||||
|
- export PATH="$PWD/.bin:$PATH"
|
||||||
|
script: zunit
|
|
@ -0,0 +1,8 @@
|
||||||
|
tap: false
|
||||||
|
directories:
|
||||||
|
tests: tests
|
||||||
|
output: tests/_output
|
||||||
|
support: tests/_support
|
||||||
|
time_limit: 0
|
||||||
|
fail_fast: false
|
||||||
|
allow_risky: false
|
|
@ -0,0 +1,144 @@
|
||||||
|
# News On Updates in F-Sy-H
|
||||||
|
|
||||||
|
**2018-08-09**
|
||||||
|
|
||||||
|
Added ideal string highlighting – FSH now handles any legal quoting and combination of `"`,`'` and `\` when
|
||||||
|
highlighting program arguments. See the introduction for an example (item #14).
|
||||||
|
|
||||||
|
**2018-08-02**
|
||||||
|
|
||||||
|
Global aliases are now supported:
|
||||||
|
|
||||||
|
![image](https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/global-alias.png)
|
||||||
|
|
||||||
|
**2018-08-01**
|
||||||
|
|
||||||
|
Hint – how to customize styles when using Zplugin and turbo mode:
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
zplugin ice wait"1" atload"set_fast_theme"
|
||||||
|
zplugin light zdharma/fast-syntax-highlighting
|
||||||
|
|
||||||
|
set_fast_theme() {
|
||||||
|
FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}paired-bracket]='bg=blue'
|
||||||
|
FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}bracket-level-1]='fg=red,bold'
|
||||||
|
FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}bracket-level-2]='fg=magenta,bold'
|
||||||
|
FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}bracket-level-3]='fg=cyan,bold'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you have set theme before an update of styles (e.g. recent addition of bracket highlighting)
|
||||||
|
then please repeat `fast-theme {theme}` call to regenerate theme files. (**2018-08-09**: FSH
|
||||||
|
now has full user-theme support, refer to [appropriate section of README](#customization)).
|
||||||
|
|
||||||
|
**2018-07-30**
|
||||||
|
|
||||||
|
Ideal highlighting of brackets (pairing, etc.) – no quoting can disturb the result:
|
||||||
|
|
||||||
|
![image](https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/brackets.gif)
|
||||||
|
|
||||||
|
`FAST_HIGHLIGHT[use_brackets]=1` to enable this feature (**2018-07-31**: not needed anymore, this highlighting is active by default).
|
||||||
|
|
||||||
|
**2018-07-21**
|
||||||
|
|
||||||
|
Chroma architecture now supports aliases. You can have `alias mygit="git commit"` and when `mygit`
|
||||||
|
will be invoked everything will work as expected (Git chroma will be ran).
|
||||||
|
|
||||||
|
**2018-07-11**
|
||||||
|
|
||||||
|
There were problems with Ctrl-C not working when using FSH. After many days I've found a fix
|
||||||
|
for this, it's pushed to master.
|
||||||
|
|
||||||
|
Second, asynchronous path checking (useful on e.g. slow network drives, or when there are many files in directory)
|
||||||
|
is now optional. Set `FAST_HIGHLIGHT[use_async]=1` to enable it. This saves some users from Zshell crashes
|
||||||
|
– there's an unknown bug in Zsh.
|
||||||
|
|
||||||
|
**2018-06-09**
|
||||||
|
|
||||||
|
New chroma functions: `awk`, `make`, `perl`, `vim`. Checkout the [video](https://asciinema.org/a/186234),
|
||||||
|
it shows functionality of `awk` – compiling of code and NOT running it. Perl can do this too:
|
||||||
|
[video](https://asciinema.org/a/186098).
|
||||||
|
|
||||||
|
**2018-06-06**
|
||||||
|
|
||||||
|
FSH gained a new architecture – "chroma functions". They are similar to "completion functions", i.e. they
|
||||||
|
are defined **per-command**, but instead of completing that command, they colorize it. Two chroma exist,
|
||||||
|
for `Git` ([video](https://asciinema.org/a/185707), [video](https://asciinema.org/a/185811)) and for `grep`
|
||||||
|
([video](https://asciinema.org/a/185942)). Checkout
|
||||||
|
[example chroma](https://github.com/zdharma/fast-syntax-highlighting/blob/master/chroma/-example.ch) if you
|
||||||
|
would like to highlight a command.
|
||||||
|
|
||||||
|
![sshot](https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/git_chroma.png)
|
||||||
|
|
||||||
|
**2018-06-01**
|
||||||
|
|
||||||
|
Highlighting of command substitution (i.e. `$(...)`) with alternate theme – two themes at once! It was just white before:
|
||||||
|
|
||||||
|
![sshot](https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/cmdsubst.png)
|
||||||
|
|
||||||
|
To select which theme to use for `$(...)` set the key `secondary=` in [theme ini file](https://github.com/zdharma/fast-syntax-highlighting/blob/master/themes/free.ini#L7).
|
||||||
|
All shipped themes have this key set (only the `default` theme doesn't use second theme).
|
||||||
|
|
||||||
|
Also added correct highlighting of descriptor-variables passed to `exec`:
|
||||||
|
|
||||||
|
![sshot](https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/execfd.png)
|
||||||
|
|
||||||
|
**2018-05-30**
|
||||||
|
|
||||||
|
For-loop is highlighted, it has separate settings in [theme file](https://github.com/zdharma/fast-syntax-highlighting/blob/master/themes/free.ini).
|
||||||
|
|
||||||
|
![sshot](https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/for-loop.png)
|
||||||
|
|
||||||
|
**2018-05-27**
|
||||||
|
|
||||||
|
Added support for 256-color themes. There are six themes shipped with FSH. The command to
|
||||||
|
switch theme is `fast-theme {theme-name}`, it has a completion which lists available themes
|
||||||
|
and options. Checkout [asciinema recording](https://asciinema.org/a/183814) that presents
|
||||||
|
the themes.
|
||||||
|
|
||||||
|
**2018-05-25**
|
||||||
|
|
||||||
|
Hash holding paths that shouldn't be grepped (globbed) – blacklist for slow disks, mounts, etc.:
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
typeset -gA FAST_BLIST_PATTERNS
|
||||||
|
FAST_BLIST_PATTERNS[/mount/nfs1/*]=1
|
||||||
|
FAST_BLIST_PATTERNS[/mount/disk2/*]=1
|
||||||
|
```
|
||||||
|
|
||||||
|
**2018-05-23**
|
||||||
|
|
||||||
|
Assign colorizing now spans to variables defined by `typeset`, `export`, `local`, etc.:
|
||||||
|
|
||||||
|
![sshot](https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/typeset.png)
|
||||||
|
|
||||||
|
Also, `zcalc` has a separate math mode and specialized highlighting – no more light-red colors because of
|
||||||
|
treating `zcalc` like a regular command-line:
|
||||||
|
|
||||||
|
![sshot](https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/zcalc.png)
|
||||||
|
|
||||||
|
**2018-05-22**
|
||||||
|
|
||||||
|
Array assignments were still boring, so I throwed in bracked colorizing:
|
||||||
|
|
||||||
|
![sshot](https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/array-assign.png)
|
||||||
|
|
||||||
|
**2018-05-22**<a name="assign-update"></a>
|
||||||
|
|
||||||
|
Assignments are no more one-colour default-white. When used in assignment, highlighted are:
|
||||||
|
|
||||||
|
- variables (outside strings),
|
||||||
|
- strings (double-quoted and single-quoted),
|
||||||
|
- math-mode (`val=$(( ... ))`).
|
||||||
|
|
||||||
|
![sshot](https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/assign.png)
|
||||||
|
|
||||||
|
**2018-01-06**
|
||||||
|
|
||||||
|
Math mode is highlighted – expressions `(( ... ))` and `$(( ... ))`. Empty variables are colorized as red.
|
||||||
|
There are 3 style names (fields of
|
||||||
|
[FAST_HIGHLIGHT_STYLES](https://github.com/zdharma/fast-syntax-highlighting/blob/master/fast-highlight#L34)
|
||||||
|
hash) for math-variable, number and empty variable (error): `mathvar`, `mathnum`, `matherr`. You can set
|
||||||
|
them (like the animation below shows) to change colors.
|
||||||
|
|
||||||
|
![animation](https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/math.gif)
|
|
@ -0,0 +1,166 @@
|
||||||
|
# Chroma Guide for F-Sy-H
|
||||||
|
|
||||||
|
## Motivation
|
||||||
|
|
||||||
|
Someone might want to create a detailed highlighting for a **specific program**
|
||||||
|
and this document helps achieving this. It explains how chroma functions – the
|
||||||
|
code behind such detailed highlighting – are constructed and used.
|
||||||
|
|
||||||
|
## Keywords
|
||||||
|
|
||||||
|
- `chroma` - a shorthand for `chroma function` – the thing that literally colorizes selected commands, like `git`, `grep`, etc. invocations, see `chroma function` below,
|
||||||
|
- `big loop` - main highlighting code, a loop over tokens and at least 2 large structular constructs (big `if` and `case`);
|
||||||
|
it is advanced, e.g. parses `case` statements, here-string, it basically constitutes 90% of the F-Sy-H project,
|
||||||
|
- `chroma function` - a plugin-function that is called when a specific command occurs (e.g. when user enters `git` at
|
||||||
|
command line) suppressing activity of `big loop` (i.e. no standard highlighting unless requested),
|
||||||
|
- `token` - result of splitting whole command line (i.e. `$BUFFER`, the Zle variable) into bits called tokens, which are
|
||||||
|
words in general, separated by spaces on the command line.
|
||||||
|
|
||||||
|
## Overview Of Functioning
|
||||||
|
|
||||||
|
1. Big loop is working – token by token processes command line, changes states (e.g. enters state "inside case
|
||||||
|
statement") and in the end decides on color of the token currently processed.
|
||||||
|
|
||||||
|
2. Big loop occurs a command that has a chroma, e.g. `git`.
|
||||||
|
|
||||||
|
3. Big loop enters "chroma" state, calls associated chroma function.
|
||||||
|
|
||||||
|
4. Chroma takes care of "chroma" state, ensures it will be set also for next token.
|
||||||
|
|
||||||
|
5. "chroma" state is active, so all following tokens are routed to the chroma (in general skipping big-loop, see next items),
|
||||||
|
|
||||||
|
6. When processing of a single token is complete, the associated chroma returns 0
|
||||||
|
(shell-truth) to request no further processing by the big loop.
|
||||||
|
|
||||||
|
7. It can also return 1 so that single, current token will be passed into big-loop
|
||||||
|
for processing (to do a standard highlighting).
|
||||||
|
|
||||||
|
## Chroma-Function Arguments
|
||||||
|
|
||||||
|
- `$1` - 0 or 1, denoting if it's the first call to the chroma, or a following one,
|
||||||
|
|
||||||
|
- `$2` - the current token, also accessible by `$\__arg` from the upper scope -
|
||||||
|
basically a private copy of `$__arg`; the token can be eg.: "grep",
|
||||||
|
|
||||||
|
- `$3` - a private copy of `$_start_pos`, i.e. the position of the token in the
|
||||||
|
command line buffer, used to add region_highlight entry (see man),
|
||||||
|
because Zsh colorizes by *ranges* applied onto command line buffer (e.g.
|
||||||
|
`from-10 to-13 fg=red`),
|
||||||
|
|
||||||
|
- `$4` - a private copy of `$_end_pos` from the upper scope; denotes where current token
|
||||||
|
ends (at which index in the string being the command line).
|
||||||
|
|
||||||
|
So example invocation could look like this:
|
||||||
|
|
||||||
|
----
|
||||||
|
chroma/-example.ch 1 "grep" "$_start_pos" "$_end_pos"
|
||||||
|
----
|
||||||
|
|
||||||
|
Big-loop will be doing such calls for the user, after occurring a specific chroma-enabled command (like e.g. `awk`), and then until chroma will detect end of this chroma-enabled command (end of whole invocation, with arguments, etc.; in other words, when e.g. new line or `;`-character occurs, etc.).
|
||||||
|
|
||||||
|
## Example Chroma-Function
|
||||||
|
|
||||||
|
[source,zsh]
|
||||||
|
----
|
||||||
|
# -*- mode: sh; sh-indentation: 4; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||||
|
# Copyright (c) 2018 Sebastian Gniazdowski
|
||||||
|
#
|
||||||
|
# Example chroma function. It colorizes first two arguments as `builtin' style,
|
||||||
|
# third and following arguments as `globbing' style. First two arguments may
|
||||||
|
# be "strings", they will be passed through to normal higlighter (by returning 1).
|
||||||
|
#
|
||||||
|
# $1 - 0 or 1, denoting if it's first call to the chroma, or following one
|
||||||
|
#
|
||||||
|
# $2 - like above document says
|
||||||
|
#
|
||||||
|
# $3 - ...
|
||||||
|
#
|
||||||
|
# $4 - ...
|
||||||
|
#
|
||||||
|
# Other tips are:
|
||||||
|
# - $CURSOR holds cursor position
|
||||||
|
# - $BUFFER holds whole command line buffer
|
||||||
|
# - $LBUFFER holds command line buffer that is left from the cursor, i.e. it's a
|
||||||
|
# BUFFER substring 1 .. $CURSOR
|
||||||
|
# - $RBUFFER is the same as LBUFFER but holds part of BUFFER right to the cursor
|
||||||
|
#
|
||||||
|
# The function receives $BUFFER but via sequence of tokens, which are shell words,
|
||||||
|
# e.g. "a b c" is a shell word, while a b c are 3 shell words.
|
||||||
|
#
|
||||||
|
# FAST_HIGHLIGHT is a friendly hash array which allows to store strings without
|
||||||
|
# creating global parameters (variables). If you need hash, go ahead and use it,
|
||||||
|
# declaring first, under some distinct name like: typeset -gA CHROMA_EXPLE_DICT.
|
||||||
|
# Remember to reset the hash and others at __first_call == 1, so that you have
|
||||||
|
# a fresh state for new command.
|
||||||
|
|
||||||
|
# Keep chroma-takever state meaning: until ;, handle highlighting via chroma.
|
||||||
|
# So the below 8192 assignment takes care that next token will be routed to chroma.
|
||||||
|
(( next_word = 2 | 8192 ))
|
||||||
|
|
||||||
|
local __first_call="$1" __wrd="$2" __start_pos="$3" __end_pos="$4"
|
||||||
|
local __style
|
||||||
|
integer __idx1 __idx2
|
||||||
|
|
||||||
|
(( __first_call )) && {
|
||||||
|
# Called for the first time - new command.
|
||||||
|
# FAST_HIGHLIGHT is used because it survives between calls, and
|
||||||
|
# allows to use a single global hash only, instead of multiple
|
||||||
|
# global string variables.
|
||||||
|
FAST_HIGHLIGHT[chroma-example-counter]=0
|
||||||
|
|
||||||
|
# Set style for region_highlight entry. It is used below in
|
||||||
|
# '[[ -n "$__style" ]] ...' line, which adds highlight entry,
|
||||||
|
# like "10 12 fg=green", through `reply' array.
|
||||||
|
#
|
||||||
|
# Could check if command `example' exists and set `unknown-token'
|
||||||
|
# style instead of `command'
|
||||||
|
__style=${FAST_THEME_NAME}command
|
||||||
|
|
||||||
|
} || {
|
||||||
|
# Following call, i.e. not the first one
|
||||||
|
|
||||||
|
# Check if chroma should end – test if token is of type
|
||||||
|
# "starts new command", if so pass-through – chroma ends
|
||||||
|
[[ "$__arg_type" = 3 ]] && return 2
|
||||||
|
|
||||||
|
if [[ "$__wrd" = -* ]]; then
|
||||||
|
# Detected option, add style for it.
|
||||||
|
[[ "$__wrd" = --* ]] && __style=${FAST_THEME_NAME}double-hyphen-option || \
|
||||||
|
__style=${FAST_THEME_NAME}single-hyphen-option
|
||||||
|
else
|
||||||
|
# Count non-option tokens
|
||||||
|
(( FAST_HIGHLIGHT[chroma-example-counter] += 1, __idx1 = FAST_HIGHLIGHT[chroma-example-counter] ))
|
||||||
|
|
||||||
|
# Colorize 1..2 as builtin, 3.. as glob
|
||||||
|
if (( FAST_HIGHLIGHT[chroma-example-counter] <= 2 )); then
|
||||||
|
if [[ "$__wrd" = \"* ]]; then
|
||||||
|
# Pass through, fsh main code will do the highlight!
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
__style=${FAST_THEME_NAME}builtin
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
__style=${FAST_THEME_NAME}globbing
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add region_highlight entry (via `reply' array).
|
||||||
|
# If 1 will be added to __start_pos, this will highlight "oken".
|
||||||
|
# If 1 will be subtracted from __end_pos, this will highlight "toke".
|
||||||
|
# $PREBUFFER is for specific situations when users does command \<ENTER>
|
||||||
|
# i.e. when multi-line command using backslash is entered.
|
||||||
|
#
|
||||||
|
# This is a common place of adding such entry, but any above code can do
|
||||||
|
# it itself (and it does in other chromas) and skip setting __style to
|
||||||
|
# this way disable this code.
|
||||||
|
[[ -n "$__style" ]] && (( __start=__start_pos-${#PREBUFFER}, __end=__end_pos-${#PREBUFFER}, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[$__style]}")
|
||||||
|
|
||||||
|
# We aren't passing-through, do obligatory things ourselves.
|
||||||
|
# _start_pos=$_end_pos advainces pointers in command line buffer.
|
||||||
|
(( this_word = next_word ))
|
||||||
|
_start_pos=$_end_pos
|
||||||
|
|
||||||
|
return 0
|
||||||
|
----
|
||||||
|
|
|
@ -0,0 +1,441 @@
|
||||||
|
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||||
|
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||||
|
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
|
||||||
|
|
||||||
|
- [2018-08-14, received $30](#2018-08-14-received-30)
|
||||||
|
- [2018-08-03, received $8](#2018-08-03-received-8)
|
||||||
|
- [2018-08-02, received $3 from Patreon](#2018-08-02-received-3-from-patreon)
|
||||||
|
- [2018-07-31, received $7](#2018-07-31-received-7)
|
||||||
|
- [2018-07-28, received $2](#2018-07-28-received-2)
|
||||||
|
- [2018-07-25, received $3](#2018-07-25-received-3)
|
||||||
|
- [2018-07-20, received $3](#2018-07-20-received-3)
|
||||||
|
- [2018-06-17, received ~$155 (200 CAD)](#2018-06-17-received-155-200-cad)
|
||||||
|
- [2018-06-10, received $10](#2018-06-10-received-10)
|
||||||
|
- [2018-05-25, received $50](#2018-05-25-received-50)
|
||||||
|
|
||||||
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||||
|
|
||||||
|
Below are reports about what is being done with donations, i.e. which commits
|
||||||
|
are created thanks to them, which new features are added, etc. From the money
|
||||||
|
I receive I buy myself coffee and organize the time to work on the requested
|
||||||
|
features, sometimes many days in a row.
|
||||||
|
|
||||||
|
## 2018-08-14, received $30
|
||||||
|
|
||||||
|
* **Project**: **[Zplugin](https://github.com/zdharma/zplugin)**
|
||||||
|
* **Goal**: Create a binary Zsh module with one Zplugin optimization and optionally some
|
||||||
|
other features.
|
||||||
|
* **Status**: The job is done.
|
||||||
|
|
||||||
|
Thanks to this donation I have finally started to code **[binary Zplugin module](
|
||||||
|
https://github.com/zdharma/zplugin#quick-start-module-only)**, which is a big step onward
|
||||||
|
in evolution of Zplugin. I've implemented and published the module with 3 complete
|
||||||
|
features: 1) `load` optimization, 2) autocompilation of scripts, 3) profiling of script
|
||||||
|
load times.
|
||||||
|
|
||||||
|
Commit list:
|
||||||
|
```
|
||||||
|
2018-08-22 7b96fad doc: mod-install.sh
|
||||||
|
2018-08-22 ba1ba64 module: Update zpmod usage text
|
||||||
|
2018-08-22 b0d72e8 zplugin,*autoload: `module' command, manages new zdharma/zplugin module
|
||||||
|
2018-08-22 706bbb3 Update Zsh source files to latest
|
||||||
|
2018-08-20 b77426f module: source-study builds report with milliseconds without fractions
|
||||||
|
2018-08-20 c3cc09b module: Updated zpmod_usage, i.a. with `source-study' sub-command
|
||||||
|
2018-08-20 6190295 module: Go back to subcommand-interface to `zpmod'; simple option parser
|
||||||
|
2018-08-20 881005f module: Report on sourcing times is shown on `zpmod -S`. Done generation
|
||||||
|
2018-08-19 e5d046a module: Correct conditions on zwc file vs. script file (after stats)
|
||||||
|
2018-08-19 1282c21 module: Duration of sourcing a file is measured and stored into a hash
|
||||||
|
2018-08-18 e080153 module: Overload both `source' and `.' builtins
|
||||||
|
2018-08-18 580efb8 module: Invoke bin_zcompile with -U option (i.e. no alias expansion)
|
||||||
|
2018-08-18 b7d9836 module: Custom `source' ensures script is compiled, compiles if not
|
||||||
|
2018-08-18 1e75a47 module: Code cleanup, vim folding
|
||||||
|
2018-08-18 a4a02f3 module: Finally working `source'/`.' overload (used options translating)
|
||||||
|
2018-08-16 99bba56 module: zpmod_usage gained content
|
||||||
|
2018-08-16 04703cd module: Add the main builtin zpmod with report-append which is working
|
||||||
|
2018-08-16 cd6dc19 module: my_ztrdup_glen, zp_unmetafy_zalloc
|
||||||
|
2018-08-16 6d44e36 module: Cleanup, `source' overload after patron leoj3n restarted module
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2018-08-03, received $8
|
||||||
|
|
||||||
|
* **Project**: **[zdharma/history-search-multi-word](https://github.com/zdharma/history-search-multi-word)**
|
||||||
|
* **Goal**: Allow calling `zle reset-prompt` (Zshell feature).
|
||||||
|
* **Status**: The job is done.
|
||||||
|
|
||||||
|
A user wanted to be able to call `reset-prompt` Zshell widget without disturbing my project
|
||||||
|
`history-search-multi-word`. I've implemented the necessary changes to HSMW.
|
||||||
|
|
||||||
|
Commit list:
|
||||||
|
|
||||||
|
```
|
||||||
|
2018-08-04 9745d3d hsmw: reset-prompt-protect zstyle – allow users to run zle reset-prompt
|
||||||
|
2018-08-04 ce48a53 hsmw: More typo-like lackings of % substitution
|
||||||
|
2018-08-04 7e2d79b hsmw: A somewhat typo, missing % substitution
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2018-08-02, received $3 from Patreon
|
||||||
|
|
||||||
|
* **Project**: **[zdharma/fast-syntax-highlighting](https://github.com/zdharma/fast-syntax-highlighting)**
|
||||||
|
* **Goal**: No goal set up.
|
||||||
|
* **Status**: Bug-fixing work.
|
||||||
|
|
||||||
|
I did bug-fixing run on `fast-syntax-highlighting`, spotted many small and sometimes important things to
|
||||||
|
improve. Did one bigger thing – added global-aliases functionality.
|
||||||
|
|
||||||
|
Commit list:
|
||||||
|
|
||||||
|
```
|
||||||
|
2018-08-02 1e854f5 -autoload.ch: Don't check existence for arguments that are variables
|
||||||
|
2018-08-02 14cdc5e *-string-*: Support highlighter cooperation in presence of $PREBUFFER
|
||||||
|
2018-08-02 2d8f0e4 *-highlight: Correctly highlight $VAR, $~VAR, ${+VAR}, etc. in strings
|
||||||
|
2018-08-02 e3032d9 *-highlight: ${#PREBUFFER} -> __PBUFLEN, equal performance
|
||||||
|
2018-08-02 f0a7121 *-highlight: Make case conditions and brackets highlighter compatible
|
||||||
|
2018-08-02 781f68e *-highlight: Recognize more case-item-end tokens
|
||||||
|
2018-08-02 206c122 *-highlight: Remove unused 4th __arg_type
|
||||||
|
2018-08-02 c6da477 *-string-*: Handle 'abc\' – no slash-quoting here. Full quoting support
|
||||||
|
2018-08-02 52e0176 *-string-*: Fix bug, third level was getting wrong style
|
||||||
|
2018-08-02 5edbfae -git.ch: Support "--message=..." syntax (commit)
|
||||||
|
2018-08-02 669d4b7 -git.ch: Handle "--" argument (stops options)
|
||||||
|
2018-08-02 4fae1f2 -make.ch: Handle make's -f option
|
||||||
|
2018-08-02 3fd32fe -make.ch: Handle make's -C option
|
||||||
|
2018-08-02 31751f5 -make.ch: Recognize options that obtain argument
|
||||||
|
2018-08-02 e480f18 -make.ch: Fix reply-var clash, gained consistency
|
||||||
|
2018-08-02 0e8bc1e Updated README.md
|
||||||
|
2018-08-02 eee0034 images: global-alias.png
|
||||||
|
2018-08-02 00b41ef *-highlight,themes,fast-theme: Support for global aliases #41
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2018-07-31, received $7
|
||||||
|
|
||||||
|
* **Project**: **[zdharma/fast-syntax-highlighting](https://github.com/zdharma/fast-syntax-highlighting)**
|
||||||
|
* **Goal**: Implement ideal brackets highlighting.
|
||||||
|
* **Status**: The job is done.
|
||||||
|
|
||||||
|
When a source code is edited e.g. in `Notepad++` or some IDE, then most often brackets are somehow matched to
|
||||||
|
each other, so that the programmer can detect mistakes. `Fast-syntax-highlighting` too gained that feature. It
|
||||||
|
was done in such a way that FSH cannot make any mistake, colors will perfectly match brackets to each other.
|
||||||
|
|
||||||
|
Commit list:
|
||||||
|
|
||||||
|
```
|
||||||
|
2018-07-31 2889860 *-highlight: Correct place to initialize $_FAST_COMPLEX_BRACKETS
|
||||||
|
2018-07-31 2bde2a9 Performance status -15/8/8
|
||||||
|
2018-07-31 5078261 *-highlight,README: Brackets highlighter active by default
|
||||||
|
2018-07-31 2ee3073 *-highlight,*string-*: Brackets in [[..]], ((..)), etc. handled normally
|
||||||
|
2018-07-31 776b12d plugin.zsh: $_ZSH_HIGHLIGHT_MAIN_CACHE -> $_FAST_MAIN_CACHE
|
||||||
|
2018-07-30 2867712 plugin.zsh: Fix array parameter created without declaring #43
|
||||||
|
2018-07-30 cbe5fc8 Updated README.md
|
||||||
|
2018-07-30 2bd3291 images: brackets.gif
|
||||||
|
2018-07-30 ef23a96 *-string-*: Bug-fix, correctly use theme styles
|
||||||
|
2018-07-30 9046f82 plugin.zsh: Attach the new brackets highlighter; F_H[use_brackets]=1
|
||||||
|
2018-07-30 b33a5fd fast-theme: Support 4 new styles (for brackets)
|
||||||
|
2018-07-30 a03f004 themes: Add 4 new styles (brackets)
|
||||||
|
2018-07-30 2448cdc *-string-*: Additional highlight of bracket under cursor; more styles
|
||||||
|
2018-07-30 5e1795e *-string-*: Highlighter for brackets, handles all quotings; detached
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2018-07-28, received $2
|
||||||
|
|
||||||
|
* **Project**: **[zdharma/fast-syntax-highlighting](https://github.com/zdharma/fast-syntax-highlighting)**
|
||||||
|
* **Goal**: Distinguish file and directory when highlighting
|
||||||
|
* **Status**: The job is done.
|
||||||
|
|
||||||
|
A user requested that when `fast-syntax-highlighting` colorizes the command line it should use different
|
||||||
|
styles (e.g. colors) for token that's a *file* and that's a *directory*. It was a reasonable idea and I've
|
||||||
|
implemented it.
|
||||||
|
|
||||||
|
Commit list:
|
||||||
|
```
|
||||||
|
2018-07-28 7f48e04 themes: Extend all themes with new style `path-to-dir'
|
||||||
|
2018-07-28 c7c6a91 fast-theme: Support for new style `path-to-dir'
|
||||||
|
2018-07-28 264676c *-highlight: Differentiate path and to-dir path. New style: path-to-dir
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2018-07-25, received $3
|
||||||
|
|
||||||
|
* **Project**: **[zdharma/zshelldoc](https://github.com/zdharma/zshelldoc)**
|
||||||
|
* **Goal**: Implement documenting of used environment variables.
|
||||||
|
* **Status**: The job is done.
|
||||||
|
|
||||||
|
Zshelldoc generates code-documentation like Doxygen or Javadoc, etc. User requested a
|
||||||
|
new feature: the generated docs should enumerate environment variables used and/or
|
||||||
|
exported by every function. Everything went fine and this feature has been implemented.
|
||||||
|
|
||||||
|
Commit list:
|
||||||
|
|
||||||
|
```
|
||||||
|
2018-07-26 f63ea25 Updated README.md
|
||||||
|
2018-07-26 3af0cf7 *detect: Get `var' from ${var:-...} and ${...:+${var}} and other subst
|
||||||
|
2018-07-25 2932510 *adoc: Better language in output document (about exported vars) #5
|
||||||
|
2018-07-25 f858dd8 *adoc: Include (in the output document) data on env-vars used #5
|
||||||
|
2018-07-25 80e3763 *adoc: Include data on exports (environment) in the output document #5
|
||||||
|
2018-07-25 ca576e2 *detect: Detect which env-vars are used, store meta-data in data/ #5
|
||||||
|
2018-07-25 f369dcc *detect: Function `find-variables' reported "$" as a variable, fixed #5
|
||||||
|
2018-07-25 e243dab *detect: Function `find-variables' #5
|
||||||
|
2018-07-25 5b34bb1 *transform: Detect exports done by function/script-body, store #5
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2018-07-20, received $3
|
||||||
|
|
||||||
|
* **Project**: **[zdharma/zshelldoc](https://github.com/zdharma/zshelldoc)**
|
||||||
|
* **Goal**: Implement stripping of leading `#` char from functions' descriptions.
|
||||||
|
* **Status**: The job is done.
|
||||||
|
|
||||||
|
A user didn't like that functions' descriptions in the JavaDoc-like document (generated with Zshelldoc) all
|
||||||
|
contain a leading `#` character. I've added stripping of this character (it is there in the processed source
|
||||||
|
code) controlled by a new Zshelldoc option.
|
||||||
|
|
||||||
|
Commit list:
|
||||||
|
```
|
||||||
|
2018-07-20 172c220 zsd,*adoc,README: Option --scomm to strip "#" from function descriptions
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2018-06-17, received ~$155 (200 CAD)
|
||||||
|
|
||||||
|
* **Project**: **[zdharma/fast-syntax-highlighting](https://github.com/zdharma/fast-syntax-highlighting)**
|
||||||
|
* **Goal**: No goal set up.
|
||||||
|
* **Status**: Done intense research.
|
||||||
|
|
||||||
|
I've created 2 new branches: `Hue-optimization` (33 commits) and `Tidbits-feature` (22 commits). Those were
|
||||||
|
branches with architectural changes and extraordinary features. The changes yielded to be too slow, and I had
|
||||||
|
to withdraw the merge. Below are fixing and optimizing commits (i.e. the valuable ones) that I've restored
|
||||||
|
from the two branches into master.
|
||||||
|
|
||||||
|
Commit list:
|
||||||
|
```
|
||||||
|
2018-07-21 dab6576 *-highlight: Merge-restore: remove old comments
|
||||||
|
2018-07-21 637521f *-highlight: Merge-restore: a threshold on # of zle .redisplay calls
|
||||||
|
2018-07-21 4163d4d *-highlight: Merge-restore: optimize four $__arg[1] = ... cases
|
||||||
|
2018-07-21 0f01195 *-highlight: Merge-restore: can remove one (Q) dequoting
|
||||||
|
2018-07-21 39a4ec6 *-highlight: Merge-restore: $v = A* is faster than $v[1] = A, tests:
|
||||||
|
2018-07-21 99d6b33 *-highlight: Merge-restore: optimize-out ${var:1} Bash syntax
|
||||||
|
2018-07-21 719c092 *-highlight: Merge-restore: allow $V/cmd, "$V/cmd, "$V/cmd", "${V}/cmd"
|
||||||
|
2018-07-21 026941d *-highlight: Merge-restore: stack pop in single instruction, not two
|
||||||
|
2018-07-21 3467e3d *-highlight: Merge-restore: more reasonable redirection-detecting code
|
||||||
|
2018-07-21 00d25ee *-highlight: Merge-restore: one active_command="$__arg" not needed (?)
|
||||||
|
2018-07-21 1daa6b3 *-highlight: Merge-restore: simplify ; and \n code short-paths
|
||||||
|
2018-07-21 55d65be *-highlight: Merge-restore: proc_buf advancement via patterns (not (i))
|
||||||
|
2018-07-21 cc55546 *-highlight: Merge-restore: pattern matching to replace (i) flag
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2018-06-10, received $10
|
||||||
|
|
||||||
|
* **Project**: **[zdharma/fast-syntax-highlighting](https://github.com/zdharma/fast-syntax-highlighting)**
|
||||||
|
* **Goal**: No goal set up.
|
||||||
|
* **Status**: Done intense experimenting.
|
||||||
|
|
||||||
|
I was working on *chromas* – command-specific colorization. I've added `which` and
|
||||||
|
`printf` colorization, then added asynchronous path checking (needed on slow network
|
||||||
|
drives), then coded experimental `ZPath` feature for chromas, but it couldn't be optimized
|
||||||
|
so I had to resign of it.
|
||||||
|
|
||||||
|
Commit list:
|
||||||
|
```
|
||||||
|
2018-06-12 c4ed1c6 Optimization – the same idea as in previous patch, better method
|
||||||
|
2018-06-12 c36feef Optimization – a) don't index large buffer, b) with negative index
|
||||||
|
2018-06-12 2f03829 Performance status 2298 / 1850
|
||||||
|
2018-06-12 14f5159 New working feature – ZPath. It requires optimization
|
||||||
|
2018-06-12 e027c40 -which.ch: One of commands can apparently return via stderr (#27)
|
||||||
|
2018-06-11 5b8004f New chroma `ruby', works like chroma `perl', checks syntax via -ce opts
|
||||||
|
2018-06-10 ca2e18b *-highlight: Async path checking has now 8-second cache
|
||||||
|
2018-06-10 e071469 *-highlight: Remove path-exists queue clearing
|
||||||
|
2018-06-10 5a6684c *-highlight: Support for asynchronous path checking
|
||||||
|
2018-06-10 1d7d6f5 New chroma: `printf', highlights special sequences like %s, %20s, etc.
|
||||||
|
2018-06-10 8f59868 -which.ch: Update main comment on purpose of this chroma
|
||||||
|
2018-06-10 5f4ece2 -which.ch: Added `whatis', it has only 1st line if output used
|
||||||
|
2018-06-10 e2d173e -which.ch: Uplift: handle `which' called on a function, /usr/bin/which
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2018-05-25, received $50
|
||||||
|
|
||||||
|
* **Project**: **[zdharma/fast-syntax-highlighting](https://github.com/zdharma/fast-syntax-highlighting)**
|
||||||
|
* **Goal**: No goal set up.
|
||||||
|
* **Status**: New ideas and features.
|
||||||
|
|
||||||
|
I was working from May, 25 to June, 9 and came up with key ideas and implemented them. First were *themes*
|
||||||
|
that were very special because they were using `INI` files instead of some Zsh-script format. Creating themes
|
||||||
|
for `fast-syntax-highlighting` is thus easy and fun. Then I came up with *chromas*, command-specific
|
||||||
|
highlighting, which redefine how syntax-highlighting for Zshell works – detailed highlighting for e.g. Git
|
||||||
|
became possible, the user is informed about e.g. a mistake even before running a command. Overall 178 commits
|
||||||
|
in 16 days.
|
||||||
|
|
||||||
|
```
|
||||||
|
2018-06-09 3f72e6c -git.ch: `revert' works almost like `checkout', attach `revert' there
|
||||||
|
2018-06-09 b892743 Updated CHROMA_GUIDE.adoc
|
||||||
|
2018-06-09 f05643d Revert "Revert "Updated CHROMA_GUIDE.md""
|
||||||
|
2018-06-09 729bf7f Revert "Revert "CHROMA_GUIDE: Remove redundant comments, uplift""
|
||||||
|
2018-06-09 48a4e0c Revert "CHROMA_GUIDE: Remove redundant comments, uplift"
|
||||||
|
2018-06-09 55ede0a Revert "Updated CHROMA_GUIDE.md"
|
||||||
|
2018-06-09 17a28ba New chroma `-docker.ch' that verifies image ID passed to `image rm'
|
||||||
|
2018-06-09 868812a -make.ch,*-make-targets: Check Makefile exists, use 7 second cache, #24
|
||||||
|
2018-06-09 73df278 -sh.ch: Attach fish, has -c option, though different syntax, let's try
|
||||||
|
2018-06-09 3a73b8e Updated CHROMA_GUIDE.md
|
||||||
|
2018-06-09 29d04c8 CHROMA_GUIDE: Remove redundant comments, uplift
|
||||||
|
2018-06-09 22ce1d8 -sh.ch,*-highlight: Attach to 2 other shells, Zsh and Bash
|
||||||
|
2018-06-09 f54e44f New chroma `-sh.ch', colorizes code passed to `sh' with -c option
|
||||||
|
2018-06-09 f5d2375 CHROMA_GUIDE: Add example code block (rendered broken in mdown)
|
||||||
|
2018-06-09 08f4b28 CHROMA_GUIDE: Switch to asciidoc (rename)
|
||||||
|
2018-06-09 4e03609 CHROMA_GUIDE.md
|
||||||
|
2018-06-09 bbcf2d6 -source.ch: Word "source" should be highlighted as builtin
|
||||||
|
2018-06-09 6739b8b New chroma – `source' to handle . and source builtins
|
||||||
|
2018-06-09 b961211 gitignore: ignore more paths
|
||||||
|
2018-06-09 59d5d09 Updated README.md
|
||||||
|
2018-06-09 f6d4d19 Updated README.md
|
||||||
|
2018-06-09 eb31324 Update README.md (figlet logo)
|
||||||
|
2018-06-09 71dcc5f Performance status 298 / 479
|
||||||
|
2018-06-09 00c5f8f *-highlight: Add comments
|
||||||
|
2018-06-09 232903c -awk.ch: Highlight `sub' function, not working {, } highlighting
|
||||||
|
2018-06-09 b5241ba *-highlight: Much better $( ) recursion, would say problems-free, maybe
|
||||||
|
2018-06-08 6c69437 *-highlight: Larger buffer (110 -> 250) for $( ) matching
|
||||||
|
2018-06-08 f2b7a96 -awk.ch: Syntax check code passed to awk. Awk is very forgiving, though
|
||||||
|
2018-06-08 c53d8ba -vim.ch: Pass almost everything to big-loop, check if vim exists
|
||||||
|
2018-06-08 7fbf7cd chroma: New chroma `vim', shows last opened files under prompt
|
||||||
|
2018-06-08 06e4570 gitignore: Extend .gitignore
|
||||||
|
2018-06-08 3184ba1 chroma: All chroma functions end chroma mode on e.g. | and similar
|
||||||
|
2018-06-08 070077d *-highlight,-example.ch: Rename arg_type -> __arg_type, use it to end
|
||||||
|
2018-06-08 6c2411e -awk.ch: Use the new theme style `subtle-bg'
|
||||||
|
2018-06-08 9ec8d63 themes: All themes (remaining 4) to support `subtle-bg' style
|
||||||
|
2018-06-08 66e848b fast-theme: New theme key `subtle-bg', default & clean.ini support it
|
||||||
|
2018-06-08 1e794f9 -awk.ch: More keywords highlighted
|
||||||
|
2018-06-08 f3bbaca -awk.ch: Don't highlight keywords when they only contain proper keyword
|
||||||
|
2018-06-08 e4d5283 -awk.ch: Fix mistake (indices), was highlighting 1 extra trailing letter
|
||||||
|
2018-06-08 eebbb19 -awk.ch: Initialize FSH_LIST
|
||||||
|
2018-06-08 8ec24ca *-highlight: Missing math function for awk
|
||||||
|
2018-06-08 d8e423a -awk.ch: Highlight more keywords, via more general code
|
||||||
|
2018-06-07 ee26e66 Commit missing -fast-make-targets
|
||||||
|
2018-06-07 9d4f2b5 New chroma `-awk.ch', colorizes regex characters and a keyword (print)
|
||||||
|
2018-06-07 def5133 -example.ch: Add comments
|
||||||
|
2018-06-07 f31a2d0 New chroma -make.ch, verifies if target is correct
|
||||||
|
2018-06-07 623b8ce -perl.ch: Use correct keys in FAST_HIGHLIGHT hash
|
||||||
|
2018-06-07 090f420 themes: Make all themes provide {in,}correct-subtle styles
|
||||||
|
2018-06-07 2201fb6 New -perl.ch chroma, syntax-checks perl code; 2 new theme entries
|
||||||
|
2018-06-06 4b9598e *-highlight: Fix bug in math highlight – allow variables starting with _
|
||||||
|
2018-06-06 708afec *-highlight: Fix FAST_BLIST_PATTERNS not expanding path to absolute one
|
||||||
|
2018-06-06 caef05a -example.ch: Update, fix typos, remove unused code
|
||||||
|
2018-06-06 3fb192a Updated README.md
|
||||||
|
2018-06-06 6de0c82 images: git_chroma.png
|
||||||
|
2018-06-06 2852fdd -grep.ch (new): Special highlighting for grep – -grep.ch chroma function
|
||||||
|
2018-06-06 f216785 -example.ch: Added comments
|
||||||
|
2018-06-06 4ab5b36 -example.ch: Add comments
|
||||||
|
2018-06-06 380cd12 -example.ch: Added comments
|
||||||
|
2018-06-06 c8947cc -example.ch: Add comments
|
||||||
|
2018-06-06 f2e273e -example.ch: Add comments
|
||||||
|
2018-06-06 2f3565b plugin.zsh: Fix parse error
|
||||||
|
2018-06-06 4f1a9bd plugin.zsh: Added $fpath handling, to match what README contains
|
||||||
|
2018-06-06 cc9adb5 -example.ch: Change and extend comments
|
||||||
|
2018-06-06 3128fff -git.ch: More intelligent `checkout' highlighting – ref is first
|
||||||
|
2018-06-06 4b6f54b -git.ch: Support for `checkout' subcommand
|
||||||
|
2018-06-06 1930d37 -example.ch: Added example chroma function
|
||||||
|
2018-06-05 d79cd85 -git.ch: Add comments
|
||||||
|
2018-06-05 1473c9e -git.ch: Add comments
|
||||||
|
2018-06-05 0cb1419 -git.ch: Message passed after -m is checked for the 72 chars boundary
|
||||||
|
2018-06-05 3f99944 -git.ch: Architectural uplift of git chroma
|
||||||
|
2018-06-05 e044d13 -git.ch: Single place to add entry to $reply (target: region_highlight)
|
||||||
|
2018-06-05 3a84364 -git.ch: Handle quoted non-option arguments, also partly quoted: "abc
|
||||||
|
2018-06-05 d635bf4 -fast-run-git-command, it handles cache automatically, decimates source
|
||||||
|
2018-06-05 102ea78 -git.ch: Smart handling of `git push', remotes and branches are verified
|
||||||
|
2018-06-04 be88850 Performance status [+] 39+77=116 / -26+24=-2
|
||||||
|
2018-06-04 0e033f8 Experimental chroma support, currently active only on command `git'
|
||||||
|
2018-06-04 43ae221 *-highlight: Emacs mode-line
|
||||||
|
2018-06-04 938ad29 test: New "-git" parsing option, test results, -git.ch included
|
||||||
|
2018-06-04 e433fbc fast-theme: Explicitly return 0; added Emacs mode-line
|
||||||
|
2018-06-04 66e9b3c *-highlight: Detection of $( ) now doesn't go for $(( )) as a candidate
|
||||||
|
2018-06-04 488a580 chroma: Empty chroma function for `git'
|
||||||
|
2018-06-04 f54d770 *-highlight: Rename $cur_cmd to $active_command
|
||||||
|
2018-06-04 3f24e68 *-highlight: Make sudo and always-block compatible with `case' handling
|
||||||
|
2018-06-02 cd82637 themes: forest.ini to support 3 new `case' styles
|
||||||
|
2018-06-02 e1e993e themes: safari.ini & zdharma.ini to support 3 new `case' styles
|
||||||
|
2018-06-02 2e78a02 themes: clean.ini & default.ini to support 3 new `case' styles
|
||||||
|
2018-06-02 c1c3aab themes: free.ini to support 3 new `case' styles
|
||||||
|
2018-06-02 70a7e18 fast-theme,*-highlight: 3 new styles for `case' higlighting
|
||||||
|
2018-06-02 8d90dc2 *-highlight: Support for `case' highlighting
|
||||||
|
2018-06-02 10d291c *-highlight: Softer state manipulation, less rigid =1 etc. assignments
|
||||||
|
2018-06-02 6159507 *-highlight: Don't highlight closing ) with style `assign'
|
||||||
|
2018-06-02 1fc2450 *-highlight: One complex math command optimization, top of the loop
|
||||||
|
2018-06-02 cc49247 *-highlight: Fix improper state after assignment (command | regular)
|
||||||
|
2018-06-02 02942b8 Updated README.md
|
||||||
|
2018-06-02 5e28259 images: eval_cmp.png
|
||||||
|
2018-06-02 df92fed *-highlight: Fix removal of trailing "/' when recursing in eval
|
||||||
|
2018-06-02 4f61938 Performance status 46 / 44
|
||||||
|
2018-06-02 a5ade0e *-highlight: Recursive highlighting of eval string argument
|
||||||
|
2018-06-02 e91847b *-highlight: Don't recurse when not at main *-process call
|
||||||
|
2018-06-02 fca8603 *-highlight: Support assignments of arrays when key is taken from array
|
||||||
|
2018-06-02 5d70f01 *-highlight: Math highlighting recognizes ${+VAR}
|
||||||
|
2018-06-02 c48eb0d *-highlight: Math colorizing recognizes variables in braces ${HISTISZE}
|
||||||
|
2018-06-02 53dd85a *-highlight: Allow -- for precommand modifiers command & exec
|
||||||
|
2018-06-02 d9fe110 *-highlight: Detect globbing also when `##' occurs
|
||||||
|
2018-06-02 55c923d Performance status 132 / 66
|
||||||
|
2018-06-02 3bd8f07 themes: safari.ini to have globbing color specifically selected
|
||||||
|
2018-06-02 2b55260 themes: free.ini to have globbing color specifically selected
|
||||||
|
2018-06-02 494868e themes: clean.ini to have globbing color specifically selected
|
||||||
|
2018-06-01 fca6b3d images: herestring.png #9
|
||||||
|
2018-06-01 f9842c1 themes: forest.ini to use underline instead of bg color #9
|
||||||
|
2018-06-01 c25c539 themes: Small tune-up of forest & zdharma themes for here-string #9
|
||||||
|
2018-06-01 988d504 themes: Rudimentary (all same) configuration of here-string tokens #9
|
||||||
|
2018-06-01 99842d2 fast-theme,*-highlight: Support for here-string, can use bg color #9
|
||||||
|
2018-06-01 f739c30 Updated README.md
|
||||||
|
2018-06-01 7fa8451 images: execfd.png execfd_cmp.png
|
||||||
|
2018-06-01 d7384f1 themes: All themes gained `exec-descriptor=` key, now supported by code
|
||||||
|
2018-06-01 d66d140 themes: Fix improper effect of s/red/.../ substitution in clean,forest
|
||||||
|
2018-06-01 f7ee5e2 fast-theme,*-highlight: Support highlighting of {FD} etc. passed to exec
|
||||||
|
2018-06-01 e5c5534 *-highlight: Proper states for precmd (command,exec) option handling
|
||||||
|
2018-06-01 647b198 images: New cmdsubst.png
|
||||||
|
2018-06-01 74bdc4c Updated README.md
|
||||||
|
2018-06-01 86eb15e images: theme.png
|
||||||
|
2018-06-01 5169e82 Updated README.md
|
||||||
|
2018-06-01 1c462b7 Updated README.md
|
||||||
|
2018-06-01 4c21da4 images: cmdsubst.png
|
||||||
|
2018-06-01 b39996e *-highlight: Switch theme to secondary when descending into $() #15
|
||||||
|
2018-06-01 bf96045 themes: Equip all themes with key `secondary' (an alternate theme) #15
|
||||||
|
2018-06-01 aa1b112 fast-theme: Generate secondary theme (from key `secondary' in theme) #15
|
||||||
|
2018-06-01 6dd3bd3 *-highlight: Support for multiple active themes #15
|
||||||
|
2018-06-01 8a32944 *-highlight: Fix "$() found?" comparison
|
||||||
|
2018-06-01 3651605 *-highlight: Significant change: the parser is called recursively on $()
|
||||||
|
2018-05-31 882d88b test,*-highlight: New -ooo performance test; highlighter takes arguments
|
||||||
|
2018-05-31 5ba1178 *-highlight: Optimization - compute __arg length once
|
||||||
|
2018-05-30 b2a0126 *-highlight: Allow multiple separate options for `command', `exec' (#10)
|
||||||
|
2018-05-30 5804e9a *-highlight: Correct state after option for precommand (#10)
|
||||||
|
2018-05-30 1247b64 *-highlight: Simpler and more accurate option-testing for exec, command (#10)
|
||||||
|
2018-05-30 d87fed4 *-highlight: Correctly highlight options for `command' and `exec' (#10)
|
||||||
|
2018-05-30 8c3e75e *-highlight: Double-hyphen (--) stops option recognition and colorizing
|
||||||
|
2018-05-30 1c5a56c *-highlight: Support ${VAR} at command position (not only $VAR)
|
||||||
|
2018-05-30 f19d761 Updated README.md
|
||||||
|
2018-05-30 4a27351 images: for-loop
|
||||||
|
2018-05-30 4d650de themes: zdharma.ini to support for-loop
|
||||||
|
2018-05-30 45cafbc themes: safari.ini to support for-loop
|
||||||
|
2018-05-30 8bb9ee0 themes: free.ini to support for-loop
|
||||||
|
2018-05-30 f25a059 themes: forest.ini to support for-loop
|
||||||
|
2018-05-29 093d79e themes: default.ini to support for-loop
|
||||||
|
2018-05-29 446cb7b clean.ini,fast-theme: Clean-theme & theme subsystem to support for-loop
|
||||||
|
2018-05-29 1bb701f *-highlight: Move $variable highlighting from case to if-block
|
||||||
|
2018-05-29 b8413e9 *-highlight: For-loop highlighting, working, needs few upgrades
|
||||||
|
2018-05-28 7bec6e5 *-highlight: Three more simple vs. complex math operation optimizations
|
||||||
|
2018-05-27 baae683 *-highlight: Optimise complex math command into single one with & and ~
|
||||||
|
2018-05-27 2dc3103 *-highlight: Optimise complex math command into single one with & and ~
|
||||||
|
2018-05-27 291f905 _fast-theme: Update -t/--test description
|
||||||
|
2018-05-27 ec305f6 fast-theme: Help message treats about -t/--test
|
||||||
|
2018-05-27 0e1d19a Updated README.md
|
||||||
|
2018-05-27 5c3c911 Updated README.md
|
||||||
|
2018-05-26 76af248 themes: A fix for zdharma theme, 61 -> 63, a lighter color for builtins
|
||||||
|
2018-05-26 8eca0f2 *fast-theme: Ability to test theme after setting it (-t/--test)
|
||||||
|
2018-05-26 d3a7922 *-highlight: Fix in_array_assignment setting when closing ) found
|
||||||
|
2018-05-26 796c482 *-highlight: Make parameters' names exotic blank-var detection to work
|
||||||
|
2018-05-26 ae3913f _fast-theme: Complete theme names
|
||||||
|
2018-05-26 d212945 *-highlight,plugin.zsh,default.ini: Uplift of fg=112-fix code
|
||||||
|
2018-05-26 ee56f65 *-highlight,plugin.zsh: Final fix for fg=112 assignment – use zstyle
|
||||||
|
2018-05-26 391f5a4 fast-theme: Set `theme' zstyle in `:plugin:fast...' to given theme
|
||||||
|
2018-05-26 e0dc086 plugin.zsh: Fix the fg=112 assignment done for `variable' style
|
||||||
|
2018-05-26 17c9286 Updated README.md
|
||||||
|
2018-05-26 4774c1c fast-theme: Add completion for this function
|
||||||
|
2018-05-26 d971f39 fast-theme: Detect lack of theme name in arguments
|
||||||
|
2018-05-26 74f0d4d fast-theme: Use standard option parsing (zparseopts) and typical options
|
||||||
|
2018-05-26 d9c6180 New theme: `forest'
|
||||||
|
2018-05-26 419c156 New theme: `zdharma'
|
||||||
|
2018-05-26 a7735df gitignore
|
||||||
|
2018-05-26 99db69a New theme: `free'
|
||||||
|
2018-05-26 73619ff New theme: `clean'
|
||||||
|
2018-05-25 52307fb Theme support, 1 extra theme – `safari'
|
||||||
|
2018-05-25 41df55b *-highlight: (k) subscript flag is sufficient, no need for (K)
|
||||||
|
2018-05-25 cb21c05 Updated README.md
|
||||||
|
2018-05-25 a580cff *-highlight: FAST_BLIST_PATTERNS
|
||||||
|
```
|
|
@ -0,0 +1,23 @@
|
||||||
|
Copyright (c) 2010-2016 zsh-syntax-highlighting contributors
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||||
|
and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||||
|
conditions and the following disclaimer in the documentation and/or other materials provided
|
||||||
|
with the distribution.
|
||||||
|
* Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors
|
||||||
|
may be used to endorse or promote products derived from this software without specific prior
|
||||||
|
written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||||
|
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,290 @@
|
||||||
|
[![paypal](https://img.shields.io/badge/-Donate-yellow.svg?longCache=true&style=for-the-badge)](https://www.paypal.me/ZdharmaInitiative)
|
||||||
|
[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=D54B3S7C6HGME)
|
||||||
|
[![patreon](https://img.shields.io/badge/-Patreon-orange.svg?longCache=true&style=for-the-badge)](https://www.patreon.com/psprint)
|
||||||
|
<br/>New: You can request a feature when donating, even fancy or advanced ones get implemented this way. [There are
|
||||||
|
reports](DONATIONS.md) about what is being done with the money received.
|
||||||
|
|
||||||
|
# Fast Syntax Highlighting (F-Sy-H)
|
||||||
|
|
||||||
|
Feature rich syntax highlighting for Zsh.
|
||||||
|
|
||||||
|
<div style="width:100%;background-color:black;border:3px solid black;border-radius:6px;margin:5px 0;padding:2px 5px">
|
||||||
|
<img
|
||||||
|
src="https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/highlight-much.png"
|
||||||
|
alt="image could not be loaded"
|
||||||
|
style="color:red;background-color:black;font-weight:bold"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
### Table of Contents
|
||||||
|
|
||||||
|
- [News](#news)
|
||||||
|
- [Installation](#installation)
|
||||||
|
- [Features](#features)
|
||||||
|
- [Performance](#performance)
|
||||||
|
- [IRC Channel](#irc-channel)
|
||||||
|
|
||||||
|
### Other Contents
|
||||||
|
- [License](https://github.com/zdharma/fast-syntax-highlighting/blob/master/LICENSE)
|
||||||
|
- [Changelog](https://github.com/zdharma/fast-syntax-highlighting/blob/master/CHANGELOG.md)
|
||||||
|
- [Theme Guide](https://github.com/zdharma/fast-syntax-highlighting/blob/master/THEME_GUIDE.md)
|
||||||
|
- [Chroma Guide](https://github.com/zdharma/fast-syntax-highlighting/blob/master/CHROMA_GUIDE.adoc)
|
||||||
|
|
||||||
|
# News
|
||||||
|
|
||||||
|
* 15-06-2019
|
||||||
|
- A new architecture for defining the highlighting for **specific commands**: it now
|
||||||
|
uses **abstract definitions** instead of **top-down, regular code**. The first effect
|
||||||
|
is the highlighting for the `git` command it is now **maximally faithful**, it
|
||||||
|
follows the `git` command almost completely.
|
||||||
|
[Screencast](https://asciinema.org/a/253411)
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
|
||||||
|
### Manual
|
||||||
|
|
||||||
|
Clone the Repository.
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
git clone https://github.com/zdharma/fast-syntax-highlighting ~/path/to/fsh
|
||||||
|
```
|
||||||
|
|
||||||
|
And add the following to your `zshrc` file.
|
||||||
|
```zsh
|
||||||
|
source ~/path/to/fsh/fast-syntax-highlighting.plugin.zsh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Zinit
|
||||||
|
|
||||||
|
Add the following to your `zshrc` file.
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
zinit light zdharma/fast-syntax-highlighting
|
||||||
|
```
|
||||||
|
|
||||||
|
Here's an example of how to load the plugin together with a few other popular
|
||||||
|
ones with the use of
|
||||||
|
[Turbo](https://zdharma.org/zinit/wiki/INTRODUCTION/#turbo_mode_zsh_62_53),
|
||||||
|
i.e.: speeding up the Zsh startup by loading the plugin right after the first
|
||||||
|
prompt, in background:
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
zinit wait lucid for \
|
||||||
|
atinit"ZINIT[COMPINIT_OPTS]=-C; zicompinit; zicdreplay" \
|
||||||
|
zdharma/fast-syntax-highlighting \
|
||||||
|
blockf \
|
||||||
|
zsh-users/zsh-completions \
|
||||||
|
atload"!_zsh_autosuggest_start" \
|
||||||
|
zsh-users/zsh-autosuggestions
|
||||||
|
```
|
||||||
|
|
||||||
|
### Antigen
|
||||||
|
|
||||||
|
Add the following to your `zshrc` file.
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
antigen bundle zdharma/fast-syntax-highlighting
|
||||||
|
```
|
||||||
|
|
||||||
|
### Zgen
|
||||||
|
|
||||||
|
Add the following to your `.zshrc` file in the same place you're doing
|
||||||
|
your other `zgen load` calls in.
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
zgen load zdharma/fast-syntax-highlighting
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Oh-My-Zsh
|
||||||
|
|
||||||
|
Clone the Repository.
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
git clone https://github.com/zdharma/fast-syntax-highlighting.git \
|
||||||
|
${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/fast-syntax-highlighting
|
||||||
|
```
|
||||||
|
|
||||||
|
And add `fast-syntax-highlighting` to your plugin list.
|
||||||
|
|
||||||
|
# Features
|
||||||
|
|
||||||
|
### Themes
|
||||||
|
|
||||||
|
Switch themes via `fast-theme {theme-name}`.
|
||||||
|
|
||||||
|
<div style="width:100%;background-color:black;border:3px solid black;border-radius:6px;margin:5px 0;padding:2px 5px">
|
||||||
|
<img
|
||||||
|
src="https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/theme.png"
|
||||||
|
alt="image could not be loaded"
|
||||||
|
style="color:red;background-color:black;font-weight:bold"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Run `fast-theme -t {theme-name}` option to obtain the snippet above.
|
||||||
|
|
||||||
|
Run `fast-theme -l` to list available themes.
|
||||||
|
|
||||||
|
### Variables
|
||||||
|
|
||||||
|
Comparing to the project `zsh-users/zsh-syntax-highlighting` (the upper line):
|
||||||
|
|
||||||
|
<div style="width:100%;background-color:black;border:3px solid black;border-radius:6px;margin:5px 0;padding:2px 5px">
|
||||||
|
<img
|
||||||
|
src="https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/parameter.png"
|
||||||
|
alt="image could not be loaded"
|
||||||
|
style="color:red;background-color:black;font-weight:bold"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="width:100%;background-color:black;border:3px solid black;border-radius:6px;margin:5px 0;padding:2px 5px">
|
||||||
|
<img
|
||||||
|
src="https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/in_string.png"
|
||||||
|
alt="image could not be loaded"
|
||||||
|
style="color:red;background-color:black;font-weight:bold"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
### Brackets
|
||||||
|
|
||||||
|
<div style="width:100%;background-color:black;border:3px solid black;border-radius:6px;margin:5px 0;padding:2px 5px">
|
||||||
|
<img
|
||||||
|
src="https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/brackets.gif"
|
||||||
|
alt="image could not be loaded"
|
||||||
|
style="color:red;background-color:black;font-weight:bold"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
### Conditions
|
||||||
|
|
||||||
|
Comparing to the project `zsh-users/zsh-syntax-highlighting` (the upper line):
|
||||||
|
|
||||||
|
<div style="width:100%;background-color:black;border:3px solid black;border-radius:6px;margin:5px 0;padding:2px 5px">
|
||||||
|
<img
|
||||||
|
src="https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/cplx_cond.png"
|
||||||
|
alt="image could not be loaded"
|
||||||
|
style="color:red;background-color:black;font-weight:bold"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
### Strings
|
||||||
|
|
||||||
|
Exact highlighting that recognizes quotings.
|
||||||
|
|
||||||
|
<div style="width:100%;background-color:black;border:3px solid black;border-radius:6px;margin:5px 0;padding:2px 5px">
|
||||||
|
<img
|
||||||
|
src="https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/ideal-string.png"
|
||||||
|
alt="image could not be loaded"
|
||||||
|
style="color:red;background-color:black;font-weight:bold"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
### here-strings
|
||||||
|
|
||||||
|
<div style="width:100%;background-color:black;border:3px solid black;border-radius:6px;margin:5px 0;padding:2px 5px">
|
||||||
|
<img
|
||||||
|
src="https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/herestring.png"
|
||||||
|
alt="image could not be loaded"
|
||||||
|
style="color:red;background-color:black;font-weight:bold"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
### `exec` descriptor-variables
|
||||||
|
|
||||||
|
Comparing to the project `zsh-users/zsh-syntax-highlighting` (the upper line):
|
||||||
|
|
||||||
|
<div style="width:100%;background-color:black;border:3px solid black;border-radius:6px;margin:5px 0;padding:2px 5px">
|
||||||
|
<img
|
||||||
|
src="https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/execfd_cmp.png"
|
||||||
|
alt="image could not be loaded"
|
||||||
|
style="color:red;background-color:black;font-weight:bold"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
### for-loops and alternate syntax (brace `{`/`}` blocks)
|
||||||
|
|
||||||
|
<div style="width:100%;background-color:black;border:3px solid black;border-radius:6px;margin:5px 0;padding:2px 5px">
|
||||||
|
<img
|
||||||
|
src="https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/for-loop-cmp.png"
|
||||||
|
alt="image could not be loaded"
|
||||||
|
style="color:red;background-color:black;font-weight:bold"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
### Function definitions
|
||||||
|
|
||||||
|
Comparing to the project `zsh-users/zsh-syntax-highlighting` (the upper 2 lines):
|
||||||
|
|
||||||
|
<div style="width:100%;background-color:black;border:3px solid black;border-radius:6px;margin:5px 0;padding:2px 5px">
|
||||||
|
<img
|
||||||
|
src="https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/function.png"
|
||||||
|
alt="image could not be loaded"
|
||||||
|
style="color:red;background-color:black;font-weight:bold"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
### Recursive `eval` and `$( )` highlighting
|
||||||
|
|
||||||
|
Comparing to the project `zsh-users/zsh-syntax-highlighting` (the upper line):
|
||||||
|
|
||||||
|
<div style="width:100%;background-color:black;border:3px solid black;border-radius:6px;margin:5px 0;padding:2px 5px">
|
||||||
|
<img
|
||||||
|
src="https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/eval_cmp.png"
|
||||||
|
alt="image could not be loaded"
|
||||||
|
style="color:red;background-color:black;font-weight:bold"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
### Chroma functions
|
||||||
|
|
||||||
|
Highlighting that is specific for a given command.
|
||||||
|
|
||||||
|
<div style="width:100%;background-color:black;border:3px solid black;border-radius:6px;margin:5px 0;padding:2px 5px">
|
||||||
|
<img
|
||||||
|
src="https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/git_chroma.png"
|
||||||
|
alt="image could not be loaded"
|
||||||
|
style="color:red;background-color:black;font-weight:bold"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
The [chromas](https://github.com/zdharma/fast-syntax-highlighting/tree/master/chroma)
|
||||||
|
that are enabled by default can be found
|
||||||
|
[here](https://github.com/zdharma/fast-syntax-highlighting/blob/master/fast-highlight#L166).
|
||||||
|
|
||||||
|
### Math-mode highlighting
|
||||||
|
|
||||||
|
<div style="width:100%;background-color:black;border:3px solid black;border-radius:6px;margin:5px 0;padding:2px 5px">
|
||||||
|
<img
|
||||||
|
src="https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/math.gif"
|
||||||
|
alt="image could not be loaded"
|
||||||
|
style="color:red;background-color:black;font-weight:bold"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
### Zcalc highlighting
|
||||||
|
|
||||||
|
<div style="width:100%;background-color:black;border:3px solid black;border-radius:6px;margin:5px 0;padding:2px 5px">
|
||||||
|
<img
|
||||||
|
src="https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/zcalc.png"
|
||||||
|
alt="image could not be loaded"
|
||||||
|
style="color:red;background-color:black;font-weight:bold"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
# Performance
|
||||||
|
Performance differences can be observed in this Asciinema recording, where a `10 kB` function is being edited.
|
||||||
|
|
||||||
|
<div style="width:100%;background-color:#121314;border:3px solid #121314;border-radius:6px;margin:5px 0;padding:2px 5px">
|
||||||
|
<a href="https://asciinema.org/a/112367">
|
||||||
|
<img src="https://asciinema.org/a/112367.png" alt="asciicast">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
## IRC Channel
|
||||||
|
|
||||||
|
Channel `#zinit@freenode` is a support place for all author's projects. Connect to:
|
||||||
|
[chat.freenode.net:6697](ircs://chat.freenode.net:6697/%23zinit) (SSL) or [chat.freenode.net:6667](irc://chat.freenode.net:6667/%23zinit)
|
||||||
|
and join #zinit.
|
||||||
|
|
||||||
|
Following is a quick access via Webchat [![IRC](https://kiwiirc.com/buttons/chat.freenode.net/zinit.png)](https://kiwiirc.com/client/chat.freenode.net:+6697/#zinit)
|
|
@ -0,0 +1,76 @@
|
||||||
|
# Theme Guide for F-Sy-H
|
||||||
|
|
||||||
|
`fast-theme` tool is used to select a theme. There are 6 shipped themes, they can be listed with `fast-theme -l`.
|
||||||
|
Themes are basic [INI files](https://github.com/zdharma/fast-syntax-highlighting/tree/master/themes) where each
|
||||||
|
key is a *style*.
|
||||||
|
Besides shipped themes, user can point this tool to any other theme, by simple `fast-theme ~/mytheme.ini`. To
|
||||||
|
obtain template to work on when creating own theme, issue `fast-theme --copy-shipped-theme {theme-name}`.
|
||||||
|
|
||||||
|
To alter just a few styles and not create a whole new theme, use **overlay**. What is overlay? It is in the same
|
||||||
|
format as full theme, but can have only a few styles defined, and these styles will overwrite styles in main-theme.
|
||||||
|
Example overlay file:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
; overlay.ini
|
||||||
|
[base]
|
||||||
|
commandseparator = yellow,bold
|
||||||
|
comment = 17
|
||||||
|
|
||||||
|
[command-point]
|
||||||
|
function = green
|
||||||
|
command = 180
|
||||||
|
```
|
||||||
|
|
||||||
|
File name `overlay.ini` is treated specially.
|
||||||
|
|
||||||
|
When specifing path, following short-hands can be used:
|
||||||
|
|
||||||
|
```
|
||||||
|
XDG: = ~/.config/fsh (respects $XDG_CONFIG_HOME env var)
|
||||||
|
LOCAL: = /usr/local/share/fsh/
|
||||||
|
HOME: = ~/.fsh/
|
||||||
|
OPT: = /opt/local/share/fsh/
|
||||||
|
```
|
||||||
|
|
||||||
|
So for example, issue `fast-theme XDG:overlay` to load `~/.config/fsh/overlay.ini` as overlay. The `.ini`
|
||||||
|
extension is optional.
|
||||||
|
|
||||||
|
## Secondary Theme
|
||||||
|
|
||||||
|
Each theme has key `secondary`, e.g. for theme `free`:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
; free.ini
|
||||||
|
[base]
|
||||||
|
default = none
|
||||||
|
unknown-token = red,bold
|
||||||
|
; ...
|
||||||
|
; ...
|
||||||
|
; ...
|
||||||
|
secondary = zdharma
|
||||||
|
```
|
||||||
|
|
||||||
|
Secondary theme (`zdharma` in the example) will be used for highlighting of argument for `eval`
|
||||||
|
and of `$( ... )` interior (i.e. of interior of command substitution). Basically, recursive
|
||||||
|
highlighting uses alternate theme to make the highlighted code distinct:
|
||||||
|
|
||||||
|
![sshot](https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/cmdsubst.png)
|
||||||
|
|
||||||
|
In the above screen-shot the interior of `$( ... )` uses different colors than the rest of the
|
||||||
|
code. Example for `eval`:
|
||||||
|
|
||||||
|
![image](https://raw.githubusercontent.com/zdharma/fast-syntax-highlighting/master/images/eval_cmp.png)
|
||||||
|
|
||||||
|
First line doesn't use recursive highlighting, highlights `eval` argument as regular string.
|
||||||
|
Second line switches theme to `zdharma` and does full recursive highlighting of eval argument.
|
||||||
|
|
||||||
|
## Custom Working Directory
|
||||||
|
|
||||||
|
Set `$FAST_WORK_DIR` before loading the plugin to have e.g. processed theme files (ready to
|
||||||
|
load, in Zsh format, not INI) kept under specified location. This is handy if e.g. you install
|
||||||
|
Fast-Syntax-Highlighting system-wide (e.g. from AUR on ArchLinux) and want to have per-user
|
||||||
|
theme setup.
|
||||||
|
|
||||||
|
You can use "~" in the path, e.g. `FAST_WORK_DIR=~/.fsh` and also the `XDG:`, `LOCAL:`, `OPT:`,
|
||||||
|
etc. short-hands, so e.g. `FAST_WORK_DIR=XDG` or `FAST_WORK_DIR=XDG:` is allowed (in this case
|
||||||
|
it will be changed to `$HOME/.config/fsh` by default by F-Sy-H loader).
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue