Right-Click File Download in WebShell
WebShell recently added right-click download support. Here’s a summary of the implementation.
Notes
- Tech stack
Implementation
Text selection
- xterm.js supports double-click word selection. If a folder name contains a space like
hello world
, you’ll need to drag to select the full name. - The shell output doesn’t directly indicate whether text is a file, directory, or the PS1 prompt. Themes can style colors, but you can’t reliably infer types from colors since themes vary.
- xterm.js supports double-click word selection. If a folder name contains a space like
Current Working Directory (CWD)
Use shell integration via function hooks. After each command finishes, capture the current directory and send it to the client, storing it in hidden escape sequences so it doesn’t render in the terminal. The app can continuously extract and cache the current directory.
source /usr/local/bash-precmd/bash-preexec.sh preexec() { printf "\x1B]1337;PreExec;Timestamp=$(date +%s);\x7"; } precmd() { printf "\x1B]1337;PostExec;Exit=$?;CurrentDir=$(pwd);Timestamp=$(date +%s);\x7"; }
With CWD known and text selected, basic download is straightforward.
Directory history
- If the user selects a file on the latest line, no problem. But each line can come from a different working directory, so you need to track CWD over time.
- Don’t map CWD one-to-one by xterm’s visual line numbers. For example,
ls
may span multiple terminal rows. A better approach is to associate the CWD with the N rows written by a single output operation.
File metadata
Selected text isn’t guaranteed to be a file. You need to detect type/size/permissions, etc.
ssh2-sftp-client
exposes stat for this.stat.mode
is a number like33279
. Convert it to octal to getrwx
bits:(rslt.mode & parseInt('777', 8)).toString(8)
For symlinks,
list
returnstype = 'l'
, butstat.isSymbolicLink
may befalse
—a discrepancy without a great workaround yet.
Download
Final Thoughts
With right-click download, the experience is smoother, though the underlying mechanism is similar to other download paths.