[Feature proposal] Single instance #225
Comments
|
This could be easily developed, at least on unix, but it's not currently a feature of broot (you can change this question into a request if you want). |
|
No worries, thank you. |
|
Hello, I took a bit of a stab at trying, as a proof of concept, to do what I was proposing. I've managed to get the following code working as a PoC standalone program. If you agree with the following way of implementing what I was proposing, you think you could accept a "drive-by" PR?, where you could help me by roughly pointing out the places where I would place this code and I would add it, basically trying to save me time understanding the codebase, which unfortunately I cannot afford to. (I know I'm asking you to read my code but this is really small). By the way, while I've only tested on Linux, this code seems cross-platform to me. I would defer to you on the exact command names but I had 3 in mind (probably with a
use std::net::{
TcpStream,
TcpListener,
};
use std::fs::File;
use std::io::prelude::*;
enum Connection
{
StandAlone,
Listener( std::net::TcpListener ),
Sender( std::net::TcpStream ),
}
fn get_file_name_from_server<S: AsRef<str>>( server: S ) -> String {
String::from( "/tmp/broot-server-" ) + server.as_ref()
}
fn no_server_file_or_port_error<S: AsRef<str>>( e: S, server: S ) -> String
{
String::from(
"Could not connect to existing server. "
)
+ e.as_ref()
+ " Try deleting "
+ & get_file_name_from_server( server.as_ref() )
}
fn bind_to_unused_port() -> ( TcpListener, u16 )
{
for attemped_port in 10001 .. std::u16::MAX
{
if let Ok( listener ) = TcpListener::bind( ( "0.0.0.0", attemped_port ) )
{
return ( listener, attemped_port )
}
}
panic!( "Could not start server on an unused port" );
}
fn main()
{
let args: std::vec::Vec<String> = std::env::args().collect();
let server_nest = args
.split( |a| a == "-S" || a == "--server" )
.collect::< std::vec::Vec< _ > >()
;
let connection =
if server_nest.len() < 2
{
// carry on
Connection::StandAlone
}
else
{
let server_name = &server_nest[ 1 ][ 0 ];
let file_name = get_file_name_from_server( server_name );
let file_handle_result = File::open( & file_name );
let mut purported_port_string = String::new();
let connection = match file_handle_result{
Ok( mut f ) =>
{
f.read_to_string( & mut purported_port_string )
.expect( & no_server_file_or_port_error( "Could not read server file.", server_name ) )
;
let port = purported_port_string.parse::<u16>()
.expect( & no_server_file_or_port_error( "Could not read port number.", server_name ) )
;
Connection::Sender(
TcpStream::connect( ( "0", port ) )
.expect( "Could not connect to server" )
)
},
_ =>
{
// File doesn't exist => Server doesn't exist.
// So start
let ( listener, port ) = bind_to_unused_port();
let mut file = File::create( &file_name )
.expect( & ( String::from( "Failed to create or not allowed to read file " ) + &file_name ) )
;
file.write_all( port.to_string().as_bytes() )
.expect( & ( String::from( "Failed to write to file " ) + &file_name ) )
;
Connection::Listener( listener )
}
};
connection
}
;
match connection
{
Connection::Listener( me ) => {
let server_name = &server_nest[ 1 ][ 0 ];
let file_name = get_file_name_from_server( server_name );
for client in me.incoming() {
dbg!( client );
//handle_client( client.unwrap()) ;
}
// Delete file here, to be handled in the "quitting" thread.
// along with closing port.
// std::fs::remove_file( file_name )
// .expect( String::from( "Failed to delete, please manually delete" ) + &file_name )
},
Connection::Sender( mut server ) => {
let mut server_response = std::vec::Vec::new();
// Depending on the command line param,
// send PWD and maybe commands
// Two major functions-
// 1) is to ask server to navigate in the interface
// 2) Get server to return the currrent directory
server.write( b"$PWD + all the args and maybe command" )
.expect( "Could not send message to server." )
;
// Read from server
server.read( & mut server_response )
.expect( "Could not get server response" )
;
},
_ => {}
}
} |
|
I can't currently accept any PR as I'm rewriting broot (see the "panels" branch) for a big new set of features. The idea's still interesting, I'll have a loot at it later. |
|
Alright, thank you. Whenever you do, please do let me know and I'll do my part. I'm keen to help out with regards to this feature. I will change the title and keep the issue open if that's alright. |
|
I don't think it would be wise to have an automatic port grab: it would prevent having hardcoded commands in your editors or scripts. It could also be messy when you execute broot many times with the wrong arguments. Here's a draft of how I think the API could be:
Broot's event loop would probably be changed to accept incoming commands as events. note: now seems the right time for implementing this. I can do it (your prototype would help me not lose too much time looking in the docs) or we could do it together. |
|
I would recommend against ports and favor Unix sockets, for the simple reason that you can reach out to local ports from a browser. An example of what you could inspire yourself from would be screen/tmux, which have the concepts of "sessions". |
|
Hi, sorry my old account is having trouble so I missed your email-
I have to confess I'm not a very advanced broot user, I only use it for quick grokking (which is, to my beginner self, its distinctive feature). I mention this so that you know that I would need plenty of help from you. Do you have a room on |
|
You can either come to the broot room or to the more lively Code&Croissants room |
|
I messaged you there (but I don't see my own messages so not sure if you received them). I'm using the same github account. |
|
Note to readers of this issue: the discussion regarding this feature specification and implementation is done in the chat. Feel free to come and ask if you're interested. |
|
I added the --get-root launch argument. |
|
FWIW, there are currently 86 stars for https://github.com/cshuaimin/scd |

Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.

Context (not important): https://old.reddit.com/r/rust/comments/gasc1f/i_wrote_a_file_manager_that_syncs_its_current/fp2e0bq/?context=3
Hi, is there a way to achieve a "single instance" of broot open? Say i say
broot --go <dir>then it just opens that dir in the currently opened instance?The text was updated successfully, but these errors were encountered: