Skip to content

Commit 985b1db

Browse files
committed
Merge branch 'release/0.2.0'
2 parents 11fd3a8 + 0d5654e commit 985b1db

File tree

35 files changed

+649
-561
lines changed

35 files changed

+649
-561
lines changed

Cargo.lock

Lines changed: 19 additions & 42 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
11
[package]
2-
name = "autojump-rs"
3-
version = "0.1.0"
2+
name = "autojump"
3+
version = "0.2.0"
44
authors = ["Wang Xuerui <git@xen0n.name>"]
5-
6-
7-
[workspace]
8-
members = ["src/autojump", "src/autojump-data", "src/autojump-match", "src/autojump-utils"]
5+
description = "A Rust port and drop-in replacement of autojump"
6+
repository = "https://github.com/xen0n/autojump-rs"
7+
readme = "README.md"
8+
license = "GPL-3.0+"
9+
include = ["src/*.rs", "Cargo.toml", "build.rs"]
10+
build = "build.rs"
911

1012

1113
[dependencies]
12-
autojump = { path = "src/autojump", version = "0.1.0" }
13-
autojump-data = { path = "src/autojump-data", version = "0.1.0" }
14-
autojump-match = { path = "src/autojump-match", version = "0.1.0" }
15-
autojump-utils = { path = "src/autojump-utils", version = "0.1.0" }
16-
17-
rustc-serialize = "0.3"
14+
atomicwrites = "0.0.14"
1815
docopt = "0.6"
19-
docopt_macros = "0.6"
16+
regex = "0.1"
17+
rustc-serialize = "0.3"
18+
strsim = "0.5"
2019

2120

22-
[[bin]]
23-
name = "autojump"
24-
path = "src/autojump-cli/main.rs"
21+
[build-dependencies]
22+
walkdir = "0.1"

README.md

Lines changed: 95 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,80 @@ which is GPL, either version 3 or any later version. See [LICENSE](LICENSE)
1212
for details.
1313

1414

15-
## FAQ
15+
## Install
1616

17-
#### Why Rust?
17+
This isn't published on crates.io yet, but you can always clone the repository
18+
and `cargo build --release` yourself. Assuming you already have original
19+
`autojump` installed and properly set up, it's only a simple matter of putting
20+
the result executable on your `$PATH`, overriding the original script. (You
21+
may need to do a `hash -r` before using in your currently open shells, of
22+
course.)
1823

19-
Primarily for two reasons:
2024

21-
* The author is really tired of `autojump` breakage inside Python virtualenvs, and
22-
* Rust is simply *awesome* for CLI applications, with its performance and (code) slickness!
25+
## Features
2326

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

25-
#### Is the port compatible, bug-for-bug?
29+
* The author is *really* tired of `autojump` breakage inside Python virtualenvs, and
30+
* Rust is simply *awesome* for CLI applications, with its performance and (code) slickness!
2631

27-
The on-disk format of the text database should be identical. That said, edge
28-
cases certainly exist. The author is developing and using this on Linux, so
29-
other platforms may need a little more love.
32+
Indeed, being written in a compiled language, **`autojump-rs` is very light on
33+
modern hardware**. As the program itself is very short-running, the overhead of
34+
setting up and tearing down a whole Python VM could be overwhelming,
35+
especially on less capable hardware. With `autojump-rs` this latency is
36+
greatly reduced. Typical running time is like this on the author's Core
37+
i7-2670QM laptop, with a directory database of 256 entries:
38+
39+
```
40+
$ time ./autojump/bin/autojump au
41+
/home/xenon/src/autojump-rs
42+
./autojump/bin/autojump au 0.05s user 0.02s system 96% cpu 0.080 total
43+
44+
$ time ./autojump-rs/target/release/autojump au
45+
/home/xenon/src/autojump-rs
46+
./autojump-rs/target/release/autojump au 0.02s user 0.00s system 94% cpu 0.020 total
47+
```
48+
49+
The time savings are more pronounced on less powerful hardware, where every
50+
cycle shaved off counts. On a Loongson 3A2000 box running at 1.0 GHz the
51+
timings are like this, with a database of the same size:
52+
53+
```
54+
$ time ./autojump/bin/autojump au
55+
/opt/store/src/autojump-rs
56+
./autojump/bin/autojump au 0.15s user 0.02s system 97% cpu 0.178 total
57+
58+
$ time ./autojump-rs/target/release/autojump au
59+
/opt/store/src/autojump-rs
60+
./autojump-rs/target/release/autojump au 0.04s user 0.01s system 96% cpu 0.051 total
61+
```
62+
63+
And, of course, the program no longer interacts with Python in any way, so the
64+
virtualenv-related crashes are no more. Say goodbye to the dreaded
65+
`ImportError`'s *showing every `$PS1` in a virtualenv with the system-default
66+
Python*!
67+
68+
```
69+
# bye and you won't be missed!
70+
Traceback (most recent call last):
71+
File "/usr/lib/python-exec/python2.7/autojump", line 43, in <module>
72+
from autojump_data import dictify
73+
ImportError: No module named autojump_data
74+
```
75+
76+
77+
## Compatibility
78+
79+
All of the command line flags and arguments are now implemented, and behave
80+
exactly like the original. Being a drop-in replacement, all other shell
81+
features like tab completion should work too. (Except `jc` and `jco`; see
82+
below.)
83+
84+
As for the text database, the on-disk format should be identical. (Actually
85+
there is a little difference in the representation of floats, but it doesn't
86+
matter.) However, as the author is developing and using this on Linux, other
87+
platforms may need a little more love, although all the libraries used are
88+
lovingly cross-platform. (Patches are welcome, of course!)
3089

3190
That said, there're some IMO very minor deviations from the original Python
3291
implementation. These are:
@@ -38,17 +97,38 @@ implementation. These are:
3897
[`docopt.rs`][docopt.rs] library, as is shown in `crates.io` statistics
3998
and GitHub activities. So it's necessary to re-arrange the help messages
4099
at least, as the `docopt` family of argument parsers mandate a specific
41-
style for them.
100+
style for them. However this shouldn't be any problem, just that it's
101+
different. Again, who looks at the usage screen all the day? XD
102+
103+
* Different algorithm chosen for fuzzy matching.
104+
105+
The Python version uses the [`difflib.SequenceMatcher`][difflib] algorithm
106+
for its fuzzy matches. Since it's quite a bit of complexity, I chose to
107+
leverage the [`strsim`][strsim-rs] library instead. The [Jaro-Winkler
108+
distance][jaro] is computed between every filename and the last part of
109+
query needles respectively, and results are filtered based on that.
42110

43-
Also, due to [a limitation][docopt-limitation] optional flag arguments
44-
are not supported, so it's required to provide the weights when you do
45-
`--increase` or `--decrease`. The original defaults are `10` and `15`
46-
respectively, so you can manually specify them in the meantime.
111+
* `jc` doesn't work correctly at the moment.
112+
113+
Exact reason may be different filtering logic involved, but I'm not very
114+
sure about this one. I only use plain `j` mostly, so if you're heavily
115+
reliant on `jc` and its friends please open an issue!
47116

48117

49118
[rust-argparse]: https://github.com/tailhook/rust-argparse
50119
[docopt.rs]: https://github.com/docopt/docopt.rs
51-
[docopt-limitation]: https://github.com/docopt/docopt.rs/issues/167
120+
[difflib]: https://docs.python.org/3.5/library/difflib.html
121+
[strsim-rs]: https://github.com/dguo/strsim-rs
122+
[jaro]: https://en.wikipedia.org/wiki/Jaro%E2%80%93Winkler_distance
123+
124+
125+
## Future plans
126+
127+
After initial porting, it's now time to re-organize the code to be more
128+
library-like (rather than application-like) and Rustic. After that the project
129+
would likely be published on crates.io. Hell I even want to write a `fasd`
130+
backend too, but I don't presently have *that* much free time. Anyway,
131+
contributions and bug reports are welcome!
52132

53133

54134
<!-- vim:set ai et ts=4 sw=4 sts=4 fenc=utf-8: -->

build.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// NOTE: This is just `rustfmt`'s `build.rs` taken verbatim.
2+
// `rustfmt` is dual-licensed under the Apache License 2.0 and the MIT
3+
// license.
4+
5+
extern crate walkdir;
6+
7+
use std::env;
8+
use std::fs::File;
9+
use std::io::Write;
10+
use std::path::Path;
11+
use std::process::Command;
12+
13+
use walkdir::WalkDir;
14+
15+
fn main() {
16+
let out_dir = env::var("OUT_DIR").unwrap();
17+
let dest_path = Path::new(&out_dir).join("git_info.rs");
18+
let mut f = File::create(&dest_path).unwrap();
19+
20+
writeln!(f,
21+
"const COMMIT_HASH: Option<&'static str> = {:?};",
22+
git_head_sha1())
23+
.unwrap();
24+
writeln!(f,
25+
"const WORKTREE_CLEAN: Option<bool> = {:?};",
26+
git_tree_is_clean())
27+
.unwrap();
28+
29+
// cargo:rerun-if-changed requires one entry per individual file.
30+
for entry in WalkDir::new("src") {
31+
let entry = entry.unwrap();
32+
println!("cargo:rerun-if-changed={}", entry.path().display());
33+
}
34+
}
35+
36+
// Returns `None` if git is not available.
37+
fn git_head_sha1() -> Option<String> {
38+
Command::new("git")
39+
.arg("rev-parse")
40+
.arg("--short")
41+
.arg("HEAD")
42+
.output()
43+
.ok()
44+
.and_then(|o| String::from_utf8(o.stdout).ok())
45+
.map(|mut s| {
46+
let len = s.trim_right().len();
47+
s.truncate(len);
48+
s
49+
})
50+
}
51+
52+
// Returns `None` if git is not available.
53+
fn git_tree_is_clean() -> Option<bool> {
54+
Command::new("git")
55+
.arg("status")
56+
.arg("--porcelain")
57+
.arg("--untracked-files=no")
58+
.output()
59+
.ok()
60+
.map(|o| o.stdout.is_empty())
61+
}

src/autojump-data/Cargo.toml

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/autojump-data/src/lib.rs

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/autojump-match/Cargo.toml

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/autojump-match/src/lib.rs

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)