Repository: Canop/broot (language: rust)

Issue:
Keep working directory of broot process in sync with directory of its currently focused panel
Hello. I'd like to suggest to keep broot's main process working directory in sync with the directory it is currently displaying just like the famous **nnn** file browser does (where you can literally just `ls -la /proc/<pid of specific nnn process>/cwd` to get the currently opened directory in that specific nnn instance).

This would have immediate benefits at least in:
- Zellij (terminal multiplexer) where a new pane gets opened in the working directory of the process running in the currently focused pane.
- Alacritty (terminal) where _SpawnNewInstance_ command opens a new window in the working directory of the current TTY controlling process of the current window.

(Caveat: Zellij seems to be using CWD of the oldest still running process in the currently focused pane so **nnn** (or broot in the future) must be running in that pane directly without underlying shell like bash or fish (which is quite normal and common anyway in Zellij). Alacritty is more inteligent and uses CWD of the current TTY controlling process.)


Discussion / hints:

Fix patch:
diff --git a/resources/default-conf/conf.hjson b/resources/default-conf/conf.hjson
index 88afc0be..962f465c 100644
--- a/resources/default-conf/conf.hjson
+++ b/resources/default-conf/conf.hjson
@@ -167,6 +167,15 @@ content_search_max_file_size: 10MB
 # open
 # max_panels_count: 2
 
+###############################################################
+# Update work dir
+#
+# By default, broot process' work dir is kept in sync with the
+# current's panel root. If you want to keep it unchanged,
+# uncomment this setting
+#
+# update_work_dir: false
+
 ###############################################################
 # Imports
 #
diff --git a/src/app/app.rs b/src/app/app.rs
index 23427772..8b7dc069 100644
--- a/src/app/app.rs
+++ b/src/app/app.rs
@@ -589,6 +589,11 @@ impl App {
         if let Some(path) = self.state().tree_root() {
             app_state.root = path.to_path_buf();
             terminal::update_title(w, app_state, con);
+            if con.update_work_dir {
+                if let Err(e) = std::env::set_current_dir(&app_state.root) {
+                    warn!("Failed to set current dir: {e}");
+                }
+            }
             if let Some(shared_root) = &mut self.shared_root {
                 if let Ok(mut root) = shared_root.lock() {
                     *root = app_state.root.clone();
diff --git a/src/app/app_context.rs b/src/app/app_context.rs
index e520eca1..59634405 100644
--- a/src/app/app_context.rs
+++ b/src/app/app_context.rs
@@ -101,6 +101,9 @@ pub struct AppContext {
     /// the optional pattern used to change the terminal's title
     /// (if none, the title isn't modified)
     pub terminal_title_pattern: Option<ExecPattern>,
+
+    /// whether to sync broot's work dir with the current panel's root
+    pub update_work_dir: bool,
 }
 
 impl AppContext {
@@ -197,6 +200,7 @@ impl AppContext {
             max_staged_count,
             content_search_max_file_size,
             terminal_title_pattern,
+            update_work_dir: config.update_work_dir.unwrap_or(true),
         })
     }
     /// Return the --cmd argument, coming from the launch arguments (prefered)
diff --git a/src/conf/conf.rs b/src/conf/conf.rs
index a68a1889..b5b2432c 100644
--- a/src/conf/conf.rs
+++ b/src/conf/conf.rs
@@ -112,6 +112,9 @@ pub struct Conf {
     #[serde(alias="terminal-title")]
     pub terminal_title: Option<ExecPattern>,
 
+    #[serde(alias="update-work-dir")]
+    pub update_work_dir: Option<bool>,
+
     // BEWARE: entries added here won't be usable unless also
     // added in read_file!
 }
@@ -195,6 +198,7 @@ impl Conf {
         overwrite!(self, show_matching_characters_on_path_searches, conf);
         overwrite!(self, content_search_max_file_size, conf);
         overwrite!(self, terminal_title, conf);
+        overwrite!(self, update_work_dir, conf);
         self.verbs.append(&mut conf.verbs);
         // the following maps are "additive": we can add entries from several
         // config files and they still make sense
diff --git a/website/docs/conf_file.md b/website/docs/conf_file.md
index 7701b79f..1b451fef 100644
--- a/website/docs/conf_file.md
+++ b/website/docs/conf_file.md
@@ -304,6 +304,19 @@ quit_on_last_cancel: true
 ```TOML
 quit_on_last_cancel = true
 ```
+
+## Update broot's work dir
+
+By default, the work dir of the broot process is synchronized with the root of the current panel.
+If you prefer to keep the work dir unchanged, disable this feature with
+
+```Hjson
+update_work_dir: false
+```
+```TOML
+update_work_dir = false
+```
+
 ## Only show file name even when the pattern is on paths
 
 When your search pattern is applied to a path, the path is shown on each line so that you see why the line matches:


Test patch: