Skip to content

Commit

Permalink
Add messages SetVroot and ResetVroot
Browse files Browse the repository at this point in the history
  • Loading branch information
sayanarijit committed Oct 27, 2022
1 parent a62b72b commit e3a5f3c
Show file tree
Hide file tree
Showing 14 changed files with 160 additions and 39 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ gethostname = "0.3.0"
fuzzy-matcher = "0.3.7"
serde_json = "1.0.87"
path-absolutize = "3.0.14"
which = "4.3.0"

[dependencies.lazy_static]
version = "1.4.0"
Expand Down
6 changes: 6 additions & 0 deletions docs/en/src/environment-variables-and-pipes.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ The other variables are single-line variables containing simple information:
- [XPLR_MODE][34]
- [XPLR_PID][35]
- [XPLR_SESSION_PATH][36]
- [XPLR_VROOT][39]

### Environment variables

Expand Down Expand Up @@ -90,6 +91,10 @@ Contains the process ID of the current xplr process.
Contains the current session path, like /tmp/runtime-"$USER"/xplr/session/"$XPLR_PID"/,
you can find temporary files here, such as pipes.

#### XPLR_VROOT

Contains the path of current virtual root, is set.

### Pipes

#### Input pipe
Expand Down Expand Up @@ -214,3 +219,4 @@ xplr.config.modes.builtin.default.key_bindings.on_key.X = {
[36]: #xplr_session_path
[37]: messages.md#reading-input
[38]: #xplr
[39]: #xplr_vroot
2 changes: 2 additions & 0 deletions docs/en/src/layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ Hence, only the following fields are avilable.

- [version][40]
- [pwd][41]
- [vroot][52]
- [focused_node][42]
- [selection][43]
- [mode][44]
Expand Down Expand Up @@ -448,3 +449,4 @@ Hence, only the following fields are avilable.
[49]: lua-function-calls.md#explorer_config
[50]: lua-function-calls.md#directory_buffer
[51]: layouts.md
[52]: #vroot
10 changes: 9 additions & 1 deletion docs/en/src/lua-function-calls.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ It contains the following information:

- [version][29]
- [pwd][31]
- [vroot][75]
- [focused_node][32]
- [directory_buffer][33]
- [selection][34]
Expand All @@ -39,7 +40,13 @@ xplr version. Can be used to test compatibility.

Type: string

The present working directory/
The present working directory.

### vroot

Type: nullable string

The current virtual root.

### focused_node

Expand Down Expand Up @@ -384,3 +391,4 @@ xplr.config.modes.builtin.default.key_bindings.on_key.space = {
[72]: #last_modified
[73]: #uid
[74]: #gid
[75]: #vroot
21 changes: 21 additions & 0 deletions docs/en/src/messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,27 @@ Example:
Lua: `"FollowSymlink"`
YAML: `FollowSymlink`

#### SetVroot

Sets the virtual root for isolating xplr navigation, similar to `--vroot`.
If the $PWD is outside the vroot, xplr will automatically enter vroot.

Type: { SetVroot = "string" }

Example:

Lua: `{ SetVroot = "/tmp" }`
YAML: `SetVroot: /tmp`

#### ResetVroot

Resets the virtual root bach to the value passed by `--vroot` or `/`.

Example:

- Lua: `"ResetVroot"`
- YAML: `ResetVroot`

### Reading Input

#### SetInputPrompt
Expand Down
71 changes: 55 additions & 16 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ impl History {
pub struct LuaContextHeavy {
pub version: String,
pub pwd: String,
pub vroot: Option<String>,
pub focused_node: Option<Node>,
pub directory_buffer: Option<DirectoryBuffer>,
pub selection: IndexSet<Node>,
Expand All @@ -145,6 +146,7 @@ pub struct LuaContextHeavy {
pub struct LuaContextLight {
pub version: String,
pub pwd: String,
pub vroot: Option<String>,
pub focused_node: Option<Node>,
pub selection: IndexSet<Node>,
pub mode: Mode,
Expand All @@ -167,7 +169,8 @@ pub struct App {
pub version: String,
pub config: Config,
pub hooks: Hooks,
pub vroot: String,
pub vroot: Option<String>,
pub initial_vroot: Option<String>,
pub pwd: String,
pub directory_buffer: Option<DirectoryBuffer>,
pub last_focus: HashMap<String, Option<String>>,
Expand All @@ -190,7 +193,7 @@ pub struct App {
impl App {
pub fn create(
bin: String,
vroot: PathBuf,
vroot: Option<PathBuf>,
pwd: PathBuf,
lua: &mlua::Lua,
config_file: Option<PathBuf>,
Expand Down Expand Up @@ -298,15 +301,19 @@ impl App {

let hostname = gethostname().to_string_lossy().to_string();

if !pwd.starts_with(&vroot) {
bail!(
"{:?} is outside of virtual root {:?}",
pwd.to_string_lossy(),
vroot.to_string_lossy()
)
if let Some(vroot) = vroot.as_ref() {
if !pwd.starts_with(&vroot) {
bail!(
"{:?} is outside of virtual root {:?}",
pwd.to_string_lossy(),
vroot.to_string_lossy()
)
}
}

let pwd = pwd.to_string_lossy().to_string();
let vroot = vroot.to_string_lossy().to_string();
let vroot = vroot.map(|v| v.to_string_lossy().to_string());
let initial_vroot = vroot.clone();
env::set_current_dir(&pwd)?;

let input = InputBuffer {
Expand All @@ -319,6 +326,7 @@ impl App {
version: VERSION.to_string(),
config,
vroot,
initial_vroot,
pwd,
directory_buffer: Default::default(),
last_focus: Default::default(),
Expand Down Expand Up @@ -440,6 +448,8 @@ impl App {
LastVisitedPath => self.last_visited_path(),
NextVisitedPath => self.next_visited_path(),
FollowSymlink => self.follow_symlink(),
SetVroot(p) => self.set_vroot(&p),
ResetVroot => self.reset_vroot(),
SetInputPrompt(p) => self.set_input_prompt(p),
UpdateInputBuffer(op) => self.update_input_buffer(op),
UpdateInputBufferFromKey => self.update_input_buffer_from_key(key),
Expand Down Expand Up @@ -755,16 +765,43 @@ impl App {
}
}

fn set_vroot(mut self, path: &String) -> Result<Self> {
let vroot = PathBuf::from(path).absolutize()?.to_path_buf();

if vroot.is_dir() {
self.vroot = Some(vroot.to_string_lossy().to_string());
if !PathBuf::from(&self.pwd).starts_with(&vroot) {
self.change_directory(path, true)
} else {
Ok(self)
}
} else {
self.log_error(format!(
"not a valid directory: {}",
vroot.to_string_lossy()
))
}
}

fn reset_vroot(self) -> Result<Self> {
if let Some(vroot) = self.initial_vroot.clone() {
self.set_vroot(&vroot)
} else {
Ok(self)
}
}

fn change_directory(mut self, dir: &str, save_history: bool) -> Result<Self> {
let dir = PathBuf::from(dir).absolutize()?.to_path_buf();

let vroot = &self.vroot.clone();
if !dir.starts_with(&self.vroot) {
return self.log_error(format!(
"{:?} is outside of virtual root {:?}",
dir.to_string_lossy(),
vroot,
));
if let Some(vroot) = &self.vroot.clone() {
if !dir.starts_with(&vroot) {
return self.log_error(format!(
"{:?} is outside of virtual root {:?}",
dir.to_string_lossy(),
vroot,
));
}
}

match env::set_current_dir(&dir) {
Expand Down Expand Up @@ -1722,6 +1759,7 @@ impl App {
LuaContextHeavy {
version: self.version.clone(),
pwd: self.pwd.clone(),
vroot: self.vroot.clone(),
focused_node: self.focused_node().cloned(),
directory_buffer: self.directory_buffer.clone(),
selection: self.selection.clone(),
Expand All @@ -1740,6 +1778,7 @@ impl App {
LuaContextLight {
version: self.version.clone(),
pwd: self.pwd.clone(),
vroot: self.vroot.clone(),
focused_node: self.focused_node().cloned(),
selection: self.selection.clone(),
mode: self.mode.clone(),
Expand Down
3 changes: 1 addition & 2 deletions src/bin/xplr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ fn main() {
"$HOME/.config/xplr/init.lua")
-C, --extra-config <PATH>... Specifies extra config files to load
--on-load <MESSAGE>... Sends messages when xplr loads
--vroot <PATH> Treats the specified path as the virtual root for
navigation, but uses full path for interaction"###;
--vroot <PATH> Treats the specified path as the virtual root"###;

let args = r###"
<PATH> Path to focus on, or enter if directory, (default is `.`)
Expand Down
10 changes: 9 additions & 1 deletion src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,15 @@ impl Cli {
pub fn parse(args: env::Args) -> Result<Self> {
let mut cli = Self::default();
let mut args = args.peekable();
cli.bin = args.next().context("failed to parse xplr binary path")?;
cli.bin = args
.next()
.map(which::which)
.context("failed to parse xplr binary path")?
.context("failed to find xplr binary path")?
.absolutize()?
.to_path_buf()
.to_string_lossy()
.to_string();

let mut flag_ends = false;

Expand Down
10 changes: 7 additions & 3 deletions src/explorer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ pub(crate) fn explore_async(

pub(crate) fn explore_recursive_async(
config: ExplorerConfig,
root: PathBuf,
vroot: Option<PathBuf>,
parent: PathBuf,
focused_path: Option<PathBuf>,
fallback_focus: usize,
Expand All @@ -116,10 +116,14 @@ pub(crate) fn explore_recursive_async(
tx_msg_in.clone(),
);
if let Some(grand_parent) = parent.parent() {
if grand_parent.starts_with(&root) {
if vroot
.as_ref()
.map(|v| grand_parent.starts_with(v))
.unwrap_or(true)
{
explore_recursive_async(
config,
root,
vroot,
grand_parent.into(),
parent.file_name().map(|p| p.into()),
0,
Expand Down
2 changes: 1 addition & 1 deletion src/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1827,9 +1827,9 @@ xplr.config.modes.builtin.action = {
["!"] = {
help = "shell",
messages = {
"PopMode",
{ Call0 = { command = "bash", args = { "-i" } } },
"ExplorePwdAsync",
"PopModeKeepingInputBuffer",
},
},
["c"] = {
Expand Down
20 changes: 19 additions & 1 deletion src/msg/in_/external.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,6 @@ pub enum ExternalMsg {
/// - YAML: `NextVisitedPath`
NextVisitedPath,

///
/// Follow the symlink under focus to its actual location.
///
/// Example:
Expand All @@ -267,6 +266,25 @@ pub enum ExternalMsg {
/// YAML: `FollowSymlink`
FollowSymlink,

/// Sets the virtual root for isolating xplr navigation, similar to `--vroot`.
/// If the $PWD is outside the vroot, xplr will automatically enter vroot.
///
/// Type: { SetVroot = "string" }
///
/// Example:
///
/// Lua: `{ SetVroot = "/tmp" }`
/// YAML: `SetVroot: /tmp`
SetVroot(String),

/// Resets the virtual root bach to the value passed by `--vroot` or `/`.
///
/// Example:
///
/// - Lua: `"ResetVroot"`
/// - YAML: `ResetVroot`
ResetVroot,

/// ### Reading Input -----------------------------------------------------

/// Set the input prompt temporarily, until the input buffer is reset.
Expand Down
Loading

0 comments on commit e3a5f3c

Please sign in to comment.