Giter Site home page Giter Site logo

xen0n / autojump-rs Goto Github PK

View Code? Open in Web Editor NEW
246.0 5.0 14.0 514 KB

A fast drop-in replacement of autojump written in Rust

Home Page: https://github.com/xen0n/autojump-rs/releases

License: GNU General Public License v3.0

Rust 75.26% Shell 20.82% Batchfile 2.33% Lua 1.60%
rust cli-utilities autojump

autojump-rs's Introduction

autojump-rs Crates.io version Crates.io downloads Crates.io license GitHub branch checks state

A port of the wildly popular helper application autojump to Rust.

License

As this project is technically a fork, the license is the same as autojump, which is GPL, either version 3 or any later version. See LICENSE for details.

Install

We have prebuilt binaries available for a while now, thanks to the trust project!

The package is a drop-in replacement of autojump. Assuming autojump is already installed, or at least the shell script part of it has been properly set up, and you have in $PATH ~/.cargo/bin before the system binary locations, all you have to do is to put a binary of your choice architecture in your PATH, overriding the original autojump script.

You may have to issue hash -r for the shell to forget previous location of autojump, if you don't want to re-exec your shell.

(Manually cloning the repository and building is okay, of course.)

Features

Why do a port when the original version works? Primarily for two reasons:

  • The author is really tired of autojump breakage inside Python virtualenvs, and
  • Rust is simply awesome for CLI applications, with its performance and (code) slickness!

Indeed, being written in a compiled language, autojump-rs is very light on modern hardware. As the program itself is very short-running, the overhead of setting up and tearing down a whole Python VM could be overwhelming, especially on less capable hardware. With autojump-rs this latency is greatly reduced. Typical running time is like this on the author's Core i7-2670QM laptop, with a directory database of 1014 entries:

$ time ./autojump/bin/autojump au
/home/xenon/src/autojump-rs
./autojump/bin/autojump au  0.09s user 0.01s system 99% cpu 0.103 total

$ time ./autojump-rs/target/release/autojump au
/home/xenon/src/autojump-rs
./autojump-rs/target/release/autojump au  0.00s user 0.00s system 87% cpu 0.007 total

The time savings are more pronounced on less powerful hardware, where every cycle shaved off counts. The running time on a 1.4GHz Loongson 3A3000 is about 10ms, for example, which is very close to the x86 figures despite the clock frequency difference.

And, of course, the program no longer interacts with Python in any way, so the virtualenv-related crashes are no more. Say goodbye to the dreaded ImportError's showing every $PS1 in a virtualenv with the system-default Python!

# bye and you won't be missed!
Traceback (most recent call last):
  File "/usr/lib/python-exec/python2.7/autojump", line 43, in <module>
    from autojump_data import dictify
ImportError: No module named autojump_data

Compatibility

All of the command line flags and arguments are now implemented, and behave exactly like the original. Being a drop-in replacement, all other shell features like tab completion should work too. (Except jc and jco; see below.)

As for the text database, the on-disk format should be identical. (Actually there is a little difference in the representation of floats, but it doesn't matter.) However, as the author is developing and using this on Linux, other platforms may need a little more love, although all the libraries used are lovingly cross-platform. (Patches are welcome, of course!)

The Windows batch files shipped with the original autojump has Python hard-coded into them, and obviously that won't work with autojump-rs. Use the batch files in the windows directory instead; just replacing the original files and putting autojump.exe along with them should work. (Thanks @tomv564 for the Windows testing!)

That said, there're some IMO very minor deviations from the original Python implementation. These are:

  • Argument handling and help messages.

    Original autojump uses Python's argparse to parse its arguments. There is a Rust port of it, but it's nowhere as popular as the docopt.rs library, as is shown in crates.io statistics and GitHub activities. So it's necessary to re-arrange the help messages at least, as the docopt family of argument parsers mandate a specific style for them. However this shouldn't be any problem, just that it's different. Again, who looks at the usage screen all the day? XD

  • Different algorithm chosen for fuzzy matching.

    The Python version uses the difflib.SequenceMatcher algorithm for its fuzzy matches. Since it's quite a bit of complexity, I chose to leverage the strsim library instead. The Jaro-Winkler distance is computed between every filename and the last part of query needles respectively, and results are filtered based on that.

  • jc may jump outside current directory.

    Exact reason may be different filtering logic involved, but I'm not very sure about this one. The behavior is also observed on original autojump, but the frequency seems to be lower, and both implementations actually don't check if the target is below current directory. However I only use plain j mostly, so if you're heavily reliant on jc and its friends please open an issue!

Future plans

Now that platform support is mostly considered okay, next steps would be more refactoring and bug fixing. The jc behavior differences are observed on original autojump too, in that you could jump outside $(pwd), but the actual directory jumped to is different; this needs further investigation. Hell I even want to write a fasd backend too, but I don't presently have that much free time. Anyway, contributions and bug reports are welcome!

autojump-rs's People

Contributors

dependabot[bot] avatar mucinoab avatar nooberfsh avatar smlavine avatar tomv564 avatar vojtechstep avatar xen0n avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

autojump-rs's Issues

Frustratingly chooses the wrong directory when I make minor typos

I've encountered this issue for a while, where autojump will choose the wrong directory from the database when I make a minor typo. It seems like the fuzzy matching algorithm is a little off.

Here's a case where I've encountered this:

> j facbeook-worker # I meant to say facebook-worker
[redacted]/facebook 

# I wanted the facebook-worker directory

The relevant weights from my database:

34.6:   [redacted]/facebook-worker
...
57.5:   [redacted]/facebook

Could you explain why autojump chooses the latter directory even though it has a much further Levenshtein difference from my input?

Difference between facbeook-worker and facebook-worker: 2
Difference between facbeook-worker and facebook: 8

I suppose that I'm basically complaining about the choice of Jaro-Winkler over Levenshtein or Damerau–Levenshtein which are also implemented as a part of strsim-rs.

binary releases

provide binary releases
also the nightly channel is needed

Missing x86-64 glibc linux binary

Am I missing something, or is there no x86-64-linux-gnu pre-built binary available?
I'd assume that to be the most used target, yet I can't find it in downloads.

Powershell integration

From what I can find, autojump-rs currently has no (real) powershell support.
As I believe powershell has mostly superseded cmd for manual shell use on Windows, a powershell integration is pretty essential for windows support.
The commands that should discover directories (such as cd) could then be hooked by just running the hook command/script inside the Powershell $PROFILE file.
(See similar: Installation flow for starship)

Originates from #45 (comment)

Allow for XDG_CONFIG_HOME on darwin (macOS)

At some point I expect to open a PR to update this, but would appreciate some reassurance that it would be well-received.

Specifically, I would like to update

let mut tmp = home_dir();
to accept an environment variable specifying the location.

Ideally, it would use XDG_CONFIG_HOME on darwin - a number of utilities on the platform respect XDG_CONFIG_HOME.

When I can't set this environment variable, I use symlinks to put the file in my typical place (i.e., my dotfiles repo), which I incrementally backup with a borgbackup cron job and version some files (altho prolly not this one). In this case, I noticed that I wasn't able to set up a symlink from my dotfiles to the destination - my symlink kept getting clobbered.

Question: Should <dir> in "autojump --add <dir>" be an absolute path?

I was looking for something cross-plat (windows, macos, linux) that could work in bash, zsh and windows-powershell.

I had to write the j script myself in powershell (because j.bat only works in CMD). I had to hook into cd (set-location), pushd (Push-Location) and popd (Pop-Location), such that the tool could learn how I navigate the filesystem. I have chosen to convert any new location to an absolute path before calling --add sub-command, in order for .., ../.. and other relative paths to have universal meaning (at least at my windows pc).

I wanted to avoid someting like this (because relative paths would loose all meaning in the dynamic config because the tool doesn't know relative to what folder!)

10.0:   .\Projects\config\dotfiles-powershell\
14.1:   .\Projects\
14.1:   ..
17.3:   C:\Users\maxfire\Projects\

Is this how it should be done?

Consistent behavior when XDG_DATA_HOME is specified

Currently, when the environment variable XDG_DATA_HOME is not
specified, autojump-rs puts its data files under
~/.local/share/autojump/..., but if it is specified, it puts it into
the directory directly - no autojump folder is created.

I feel this behavior is inconsistent, because it does different things
when the data home is set to its default value, ~/.local/share.

I think we should always use a separate directory for autojump inside
whatever data directory is specified.

Handle '/' in j.bat

When j.bat is executed with paths having '/'(forward slash), cmd's pushd fails to work.

Duplicate entries in suggestions list

I'm seeing an issue where there are duplicate entries in the suggestions list.

I can replicate this with a minimal example of having

51.9615242269   /Users/foo/bar

in the autojump.txt and running

autojump --complete bar

which returns

1__/Users/foo/bar
2__/Users/foo/bar
3__/Users/foo/bar

I added some debug statements in query:

Entries [Entry { path: "/Users/foo/bar", weight: 51.9615242269 }] 
Query Result ["/Users/foo/bar", "/Users/foo/bar", "/Users/foo/bar"] 

and isolated the issue to somewhere in the matcher (src/matcher/).

autojump-rs is slower

autojump-rs is slower than z.lua, autojump-rs takes 0.050s to change directory while z.lua only needs 0.017s.

shell autocompletion not working

hey there,

thanks for a great project, I switched recently to the -rs variant as it's so much faster to start compared to the original autojump. I'm a bash user (old habits die hard) and it seems like the autocompletion capabilites of autojump-rs are not working for some reason. I.e. independent of what gets passed to autojump --complete, I always get the same list of 9 responses, which is wrong:

# I could run this as many times as I want, or pass any arbitrary
$ autojump --complete $$
__1__/home/milian/projects/kdab/foo/build-asan
__2__/home/milian/projects/kdab/foo
__3__/home/milian/projects/kdab/foo/build-profile
__4__/home/milian/projects/kf5/src/extragear/kdevelop/kdevelop
__5__/home/milian/projects/src/heaptrack
__6__/home/milian/projects/kdab/rnd/hotspot/build
__7__/home/milian/projects/kdab/foo/testdata
__8__/tmp
__9__/home/milian/projects/kdab/rnd/hotspot

so here already I would expect the result set to take the arg passed to --complete into account and filter by that?

then, when I use the builtin bash completion to actually trigger it, the __N__ prefixes actually make this totally unusable, as I always end up with

$ j something<TAB>
$ j __

here, bash decides to pick the common prefix, __ and enters that, without showing me anything else 🤷

Is this a setup issue on my end? I'm using the 0.5.1-2 package from AUR, if that matters.

Cheers

Fix oh-my-zsh integration

Currently, if you manually edit oh-my-zsh's autojump plugin to point to this autojump it dies pretty horribly:

➜ zsh
[8] 44848
/Users/mdunlap/.cargo/bin/autojump:1: command not found: ^C
/Users/mdunlap/.cargo/bin/autojump:3: parse error near `)'
/Users/mdunlap/.cargo/bin/autojump:1: parse error in command substitution
[8]  + 44848 exit 127    >
/Users/mdunlap/.cargo/bin/autojump:7: command not found: H\M-\t}\M-xH\M-\tu\M-pH\M-^ME\M-xH\M-\tE\M-PH\M-^M^E\M-^A\M-U^E
/Users/mdunlap/.cargo/bin/autojump:7: no matches found: M\M-\tn^HI\M-\t^^PH\M-^C\M-D^H[AA]A^A_]þ^A^@^@^@H\M-\t\M-_\M-h0\M-u\M-^?\M-^?\M->^A^@^@^@L\M-\t\M-o\M-h#\M-u\M-^?\M-^?^O^_^@UH\M-\t\M-eH\M-^C\M-lH\M-\t}\M-xH\M-\tu\M-pH\M-^ME\M-xH\M-\tE\M-PH\M-^M^E^Q\M-U^E^@H\M-\tE\M-XH\M-^MM\M-pH\M-\tM\M-`H\M-\tE\M-hH\M-^M^E

Shell integration is a pretty strong argument in favor of the Python version, at least for me. Do you have an estimate of how hard this would be to fix? I could probably spare some cycles to scratch my own itch if you think it's something a newcomer could handle fixing.

Arch Linux package

I was very excited to find this project, so I went ahead and made an Arch Linux package out of it: autojump-rs.

Some notes:

  • It basically runs the installer from the original autojump to get all the shell completion stuff, and then just tidies up the Python bits and replaces bin/autojump.
  • It seems to work very well!
  • I'm getting some warnings about the released binary (0.4.0):
    autojump-rs W: ELF file ('usr/bin/autojump') lacks FULL RELRO, check LDFLAGS.
    autojump-rs W: ELF file ('usr/bin/autojump') lacks PIE.
    
  • I opted to remove the man page that the original autojump provides, since there are a couple of differences between what they provide (as you outline in the README). Is there an easy way to generate a manpage and include that in the release tarballs?
  • 0.4.0 is getting pretty old — it'd be nice to have a new release with updated dependencies :)

Autojump subdirectory when XDG_DATA_HOME is specified does not behave properly

An issue regarding this bug (#14) was already submitted and allegedly fixed, but I am currently experiencing similar behaviour:

When XDG_DATA_HOME isn't specified, the directory inside ~/.local/share is created, but when the variable is specified to be ~/.local/share (in ~/.zshenv for example) the subdirectory is created but autojump does not write the database inside it, but in ~/.local/share.

When there is an already existing subdirectory autojump fails to recognize the already existing database inside it and proceeds to create a new database outside the subdirectory.

Installation instructions are incomplete

Thanks for porting and maintaining autojump! I had the same idea and now I'm glad that I don't have to do it myself.

It seems that not all the installation instructions are present in this repo, namely function definitions, completion setup and shell integration. Are you planning to provide those?

build failure under macOS

error[E0433]: failed to resolve. Use of undeclared type or module `autojump`
  --> .cargo/registry/src/github.com-1ecc6299db9ec823/autojump-0.2.1/src/data/datafile.rs:18:23
   |
18 |     let xdg_aj_home = autojump::xdg_home_hardcoded();
   |                       ^^^^^^^^ Use of undeclared type or module `autojump`

error[E0308]: mismatched types
  --> .cargo/registry/src/github.com-1ecc6299db9ec823/autojump-0.2.1/src/data/datafile.rs:20:9
   |
20 |         Ok(())
   |         ^^^^^^- help: try adding a semicolon: `;`
   |         |
   |         expected (), found enum `std::result::Result`
   |
   = note: expected type `()`
              found type `std::result::Result<(), _>`

error[E0308]: mismatched types
  --> .cargo/registry/src/github.com-1ecc6299db9ec823/autojump-0.2.1/src/data/datafile.rs:17:60
   |
17 |   fn migrate_osx_xdg_data(config: &Config) -> io::Result<()> {
   |  ____________________________________________________________^
18 | |     let xdg_aj_home = autojump::xdg_home_hardcoded();
19 | |     if !xdg_aj_home.exists() {
20 | |         Ok(())
...  |
29 | |     fs::remove_file(old_config.backup_path)?;
30 | | }
   | |_^ expected enum `std::result::Result`, found ()
   |
   = note: expected type `std::result::Result<(), std::io::Error>`
              found type `()`

error: aborting due to 3 previous errors

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.