You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
xplr/docs/en/src/awesome-hacks.md

10 KiB

Awesome Hacks

Here's a list of cool xplr hacks, i.e. snippets of code that you can just copy and paste into your configuration or the appropriate file, that are too small or too niche for a full fledge plugin.

Do you have something cool to share?

Edit this file or share them here or let us know.

cd on quit

Change directory using xplr.

Expand for details

With this alias set, you can navigate directories using xplr by entering xcd command, and when you quit by pressing enter, you will enter the directory.

You can of course, quit with plain Quit (i.e. by pressing q) to gracefully cancel "cd on quit".

alias xcd='cd "$(xplr --print-pwd-as-result)"'

Spawn multiple sessions in different tabs (iTerm2)

Creating a new session that starts with iTerm2.

Expand for details
  • Author: @lmburns
  • Requires: iTerm2
  • Tested on: MacOS
xplr.config.modes.builtin.default.key_bindings.on_key["ctrl-n"] = {
  help = "new session",
  messages = {
    { BashExecSilently = [[
        osascript <<EOF
        tell application "iTerm2"
          tell current window
            create tab with default profile
            tell current session to write text "xplr"
          end tell
        end tell
      ]]
    },
  },
}

Bookmark

Bookmark files using m and fuzzy search bookmarks using backtick.

Expand for details

xplr-bookmark.gif

xplr.config.modes.builtin.default.key_bindings.on_key.m = {
  help = "bookmark",
  messages = {
    {
      BashExecSilently = [===[
        PTH="${XPLR_FOCUS_PATH:?}"
        if echo "${PTH:?}" >> "${XPLR_SESSION_PATH:?}/bookmarks"; then
          echo "LogSuccess: ${PTH:?} added to bookmarks" >> "${XPLR_PIPE_MSG_IN:?}"
        else
          echo "LogError: Failed to bookmark ${PTH:?}" >> "${XPLR_PIPE_MSG_IN:?}"
        fi
      ]===],
    },
  },
}

xplr.config.modes.builtin.default.key_bindings.on_key["`"] = {
  help = "go to bookmark",
  messages = {
    {
      BashExec = [===[
        PTH=$(cat "${XPLR_SESSION_PATH:?}/bookmarks" | fzf --no-sort)
        if [ "$PTH" ]; then
          echo FocusPath: "'"${PTH:?}"'" >> "${XPLR_PIPE_MSG_IN:?}"
        fi
      ]===],
    },
  },
}

Persistent, multi-session bookmark

A bookmark mode that allows for a bookmark file to be used throughout multiples sessions. It is set to the environment variable $XPLR_BOOKMARK_FILE. A bookmark can be added, deleted, or jumped to.

Expand for details
  • Author: @lmburns
  • Requires: fzf, sd
  • Tested on: MacOS
-- Bookmark: mode binding
xplr.config.modes.custom.bookmark = {
  name = "bookmark",
  key_bindings = {
    on_key = {
      m = {
        help = "bookmark dir",
        messages = {
          { BashExecSilently = [[
              PTH="${XPLR_FOCUS_PATH:?}"
              if [ -d "${PTH}" ]; then
                PTH="${PTH}"
              elif [ -f "${PTH}" ]; then
                PTH="$(dirname "${PTH}")"
              fi
              if echo "${PTH:?}" >> "${XPLR_BOOKMARK_FILE:?}"; then
                echo "LogSuccess: ${PTH:?} added to bookmarks" >> "${XPLR_PIPE_MSG_IN:?}"
              else
                echo "LogError: Failed to bookmark ${PTH:?}" >> "${XPLR_PIPE_MSG_IN:?}"
              fi
            ]]
          },
        },
      },
      g = {
        help = "go to bookmark",
        messages = {
          {
            BashExec = [===[
              PTH=$(cat "${XPLR_BOOKMARK_FILE:?}" | fzf --no-sort)
              if [ "$PTH" ]; then
                echo FocusPath: "'"${PTH:?}"'" >> "${XPLR_PIPE_MSG_IN:?}"
              fi
            ]===]
          },
        },
      },
      d = {
        help = "delete bookmark",
        messages = {
          { BashExec = [[
              PTH=$(cat "${XPLR_BOOKMARK_FILE:?}" | fzf --no-sort)
              sd "$PTH\n" "" "${XPLR_BOOKMARK_FILE:?}"
            ]]
          },
        },
      },
      esc = {
        help = "cancel",
        messages = {
          "PopMode",
        },
      },
    },
  },
}

Another bookmark manager type thing, taken from wfxr's zsh plugin.

Another bookmark manager type thing, taken from wfxr's zsh plugin which has colored output with fzf.

Expand for details
  • Author: @lmburns
  • Requires: fzf, exa
  • Tested on: MacOS
xplr.config.modes.builtin.go_to.key_bindings.on_key.b = {
  help = "bookmark jump",
  messages = {
    "PopMode",
    { BashExec = [===[
        field='\(\S\+\s*\)'
        esc=$(printf '\033')
        N="${esc}[0m"
        R="${esc}[31m"
        G="${esc}[32m"
        Y="${esc}[33m"
        B="${esc}[34m"
        pattern="s#^${field}${field}${field}${field}#$Y\1$R\2$N\3$B\4$N#"
        PTH=$(sed 's#: # -> #' "$PATHMARKS_FILE"| nl| column -t \
        | gsed "${pattern}" \
        | fzf --ansi \
            --height '40%' \
            --preview="echo {}|sed 's#.*->  ##'| xargs exa --color=always" \
            --preview-window="right:50%" \
        | sed 's#.*->  ##')
        if [ "$PTH" ]; then
          echo ChangeDirectory: "'"${PTH:?}"'" >> "${XPLR_PIPE_MSG_IN:?}"
        fi
      ]===]
    },
  }
}

Fuzzy search history

Fuzzy search the last visited directories.

Expand for details
xplr.config.modes.builtin.go_to.key_bindings.on_key.h = {
  help = "history",
  messages = {
    "PopMode",
    {
      BashExec = [===[
        PTH=$(cat "${XPLR_PIPE_HISTORY_OUT:?}" | sort -u | fzf --no-sort)
        if [ "$PTH" ]; then
          echo ChangeDirectory: "'"${PTH:?}"'" >> "${XPLR_PIPE_MSG_IN:?}"
        fi
      ]===],
    },
  },
}

Batch rename

Batch rename the selected or visible files and directories in $PWD.

Expand for details

xplr-rename.gif

xplr.config.modes.builtin.default.key_bindings.on_key.R = {
  help = "batch rename",
  messages = {
    {
      BashExec = [===[
       SELECTION=$(cat "${XPLR_PIPE_SELECTION_OUT:?}")
       NODES=${SELECTION:-$(cat "${XPLR_PIPE_DIRECTORY_NODES_OUT:?}")}
       if [ "$NODES" ]; then
         echo -e "$NODES" | renamer
         echo ExplorePwdAsync >> "${XPLR_PIPE_MSG_IN:?}"
       fi
     ]===],
    },
  },
}

Serve $PWD

Serve $PWD using a static web server via LAN.

Expand for details
xplr.config.modes.builtin.default.key_bindings.on_key.S = {
  help = "serve $PWD",
  messages = {
    {
      BashExec = [===[
        IP=$(ip addr | grep -w inet | cut -d/ -f1 | grep -Eo '[0-9]{1,3}\.[0-9]{      1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | fzf --prompt 'Select IP > ')
        echo "IP: ${IP:?}"
        read -p "Port (default 5000): " PORT
        echo
        sfz --all --cors --no-ignore --bind ${IP:?} --port ${PORT:-5000} . &
        sleep 1 && read -p '[press enter to exit]'
        kill -9 %1
      ]===],
    },
  },
}

Image viewer (imv)

Preview images using imv.

Expand for details
xplr.config.modes.builtin.default.key_bindings.on_key.P = {
  help = "preview",
  messages = {
    {
      BashExecSilently = [===[
        FIFO_PATH="/tmp/xplr.fifo"

        if [ -e "$FIFO_PATH" ]; then
          echo StopFifo >> "$XPLR_PIPE_MSG_IN"
          rm "$FIFO_PATH"
        else
          mkfifo "$FIFO_PATH"
          "$HOME/.local/bin/imv-open.sh" "$FIFO_PATH" "$XPLR_FOCUS_PATH" &
          echo "StartFifo: '$FIFO_PATH'" >> "$XPLR_PIPE_MSG_IN"
        fi
      ]===],
    },
  },
}

$HOME/.local/bin/imv-open.sh

#!/usr/bin/env bash

FIFO_PATH="$1"
IMAGE="$2"
MAINWINDOW="$(xdotool getactivewindow)"
IMV_PID="$(pgrep imv)"

if [ ! "$IMV_PID" ]; then
  imv "$IMAGE" &
  IMV_PID=$!
fi

sleep 0.5

xdotool windowactivate "$MAINWINDOW"

while read -r path; do
  imv-msg "$IMV_PID" close all
  imv-msg "$IMV_PID" open "$path"
done < "$FIFO_PATH"

imv-msg "$IMV_PID" quit
[ -e "$FIFO_PATH" ] && rm -f "$FIFO_PATH"

Text preview pane

Preview text files in a native xplr pane (should be fast enough).

Expand for details
local function stat(node)
  return node.mime_essence
end

local function read(path, lines)
  local out = ""
  local p = io.open(path)

  if p == nil then
    return stat(path)
  end

  local i = 0
  for line in p:lines() do
    out = out .. line .. "\n"
    if i == lines then
      break
    end
    i = i + 1
  end
  p:close()

  return out
end

xplr.config.layouts.builtin.default = {
  Horizontal = {
    config = {
      constraints = {
        { Percentage = 60 },
        { Percentage = 40 },
      },
    },
    splits = {
      "Table",
      {
        CustomContent = {
          title = "preview",
          body = { DynamicParagraph = { render = "custom.preview_pane.render" } },
        },
      },
    },
  },
}

xplr.fn.custom.preview_pane = {}
xplr.fn.custom.preview_pane.render = function(ctx)
  local n = ctx.app.focused_node

  if n.canonical then
    n = n.canonical
  end

  if n then
    if n.is_file then
      return read(n.absolute_path, ctx.layout_size.height)
    else
      return stat(n)
    end
  else
    return ""
  end
end

Also See: