use external similar-sort repo
parent
fd27acc3ca
commit
4fcce3bf7e
|
@ -10,7 +10,7 @@ let
|
||||||
kak-tree = pkgs.callPackage ../pkgs/kak-tree { };
|
kak-tree = pkgs.callPackage ../pkgs/kak-tree { };
|
||||||
kak-ayu = pkgs.callPackage ../pkgs/kak-ayu { };
|
kak-ayu = pkgs.callPackage ../pkgs/kak-ayu { };
|
||||||
|
|
||||||
similar-sort = pkgs.callPackage ../pkgs/similar-sort { };
|
similar-sort = import sources.similar-sort { pkgs = nixpkgs.pkgs; };
|
||||||
similar-sort-files-cmd = arg:
|
similar-sort-files-cmd = arg:
|
||||||
"git ls-files --others --cached --exclude-standard | ${similar-sort}/bin/similar-sort ${arg} | grep -v ${arg} | fzf --tiebreak index";
|
"git ls-files --others --cached --exclude-standard | ${similar-sort}/bin/similar-sort ${arg} | grep -v ${arg} | fzf --tiebreak index";
|
||||||
|
|
||||||
|
|
|
@ -164,6 +164,13 @@
|
||||||
"url": "https://github.com/whereswaldon/shellcheck.kak/archive/9acad49508ee95c215541e58353335d9d5b8a927.tar.gz",
|
"url": "https://github.com/whereswaldon/shellcheck.kak/archive/9acad49508ee95c215541e58353335d9d5b8a927.tar.gz",
|
||||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||||
},
|
},
|
||||||
|
"similar-sort": {
|
||||||
|
"sha256": "0sykdp82cby1ikw4pxzcp1hrhj51dwz0zpprcsj03hhsyg0c1j7b",
|
||||||
|
"type": "tarball",
|
||||||
|
"url": "https://git.bytes.zone/brian/similar-sort/archive/301de2b5f83aba77a14b4df33347e8157de4f9ca.tar.gz",
|
||||||
|
"url_template": "https://git.bytes.zone/brian/similar-sort/archive/<version>.tar.gz",
|
||||||
|
"version": "301de2b5f83aba77a14b4df33347e8157de4f9ca"
|
||||||
|
},
|
||||||
"smarttab.kak": {
|
"smarttab.kak": {
|
||||||
"branch": "master",
|
"branch": "master",
|
||||||
"description": "Automatic handling different styles of indentation and alignment. Mirror of https://gitlab.com/andreyorst/smarttab.kak",
|
"description": "Automatic handling different styles of indentation and alignment. Mirror of https://gitlab.com/andreyorst/smarttab.kak",
|
||||||
|
|
|
@ -1,68 +1,7 @@
|
||||||
# Similar Sort
|
# Similar Sort
|
||||||
|
|
||||||
This is a small Go program that will:
|
Hello!
|
||||||
|
This project has moved to <https://git.bytes.zone/brian/similar-sort>.
|
||||||
|
|
||||||
1. take a reference string as the first argument
|
This file just exists to make sure people don't get lost when coming from my blog or other external links.
|
||||||
2. and a list of candidate strings in stdin
|
Have a nice day!
|
||||||
3. and output the candidates sorted according to their edit distance from the reference, lowest first.
|
|
||||||
|
|
||||||
"What use is this?" you may ask!
|
|
||||||
Well!
|
|
||||||
It turns out to be really useful to do fuzzy file finding a large project.
|
|
||||||
|
|
||||||
When I am in some filesystem hierarchy and I trigger my fuzzy-finder, I want to see sibling files before I see similarly-named files further away.
|
|
||||||
I also want to match on test files pretty easily.
|
|
||||||
Say I have this project structure:
|
|
||||||
|
|
||||||
```
|
|
||||||
example
|
|
||||||
└── src
|
|
||||||
├── Main.elm
|
|
||||||
└── Page
|
|
||||||
└── Learn
|
|
||||||
└── Home
|
|
||||||
├── Main.elm
|
|
||||||
└── View.elm
|
|
||||||
```
|
|
||||||
|
|
||||||
If I am in `src/Page/Learn/Home/View.elm` and I want to get to the sibling file `Main.elm`, the default `fzf` config shows me `src/Main.elm` first.
|
|
||||||
That's not what I wanted!
|
|
||||||
|
|
||||||
But if I sort the files instead by passing them through `similar-sort src/Page/Learn/Home/View.elm`, the sibling file will show up first.
|
|
||||||
This works surprisingly well, and I really like it!
|
|
||||||
|
|
||||||
It could probably perform a *little* better by doing some heuristic based on equivalent file structure except for the addition/removal of "tests", "specs", etc, but I haven't bothered yet.
|
|
||||||
|
|
||||||
## Installing
|
|
||||||
|
|
||||||
You can look in `dotfiles/kakoune.nix` in the root of this project to see how to use this in a home-manager context.
|
|
||||||
If you're not using home-manager, or you just want to install it globally, `cd` here and type:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
nix-env -if .
|
|
||||||
```
|
|
||||||
|
|
||||||
OR if you have `go` installed but not `nix`, just `go build similar-sort.go`; it has no external dependencies and will result in a static binary you can put wherever.
|
|
||||||
|
|
||||||
### Adding to Vim
|
|
||||||
|
|
||||||
Add this to your vim config:
|
|
||||||
|
|
||||||
```vim
|
|
||||||
nnoremap <silent> <C-t> :call fzf#run(fzf#wrap({
|
|
||||||
\ "source": "git ls-files --others --cached --exclude-standard \| similar-sort " . @% . " \| grep -v " . @%,
|
|
||||||
\ "sink": "edit",
|
|
||||||
\ "options": "--tiebreak index"
|
|
||||||
\ }))<CR>
|
|
||||||
```
|
|
||||||
|
|
||||||
(You'll need `fzf` and `fzf.vim` installed.)
|
|
||||||
This will bind ctrl-t to the fuzzy finder.
|
|
||||||
When you select a match, it will open in the current pane.
|
|
||||||
|
|
||||||
If you want to split or vsplit, change `"sink": "edit"` to `"sink": "split"` or `"sink": "vsplit"`.
|
|
||||||
See the docs for `fzf#run` for more customization options.
|
|
||||||
|
|
||||||
### Adding to Kakoune
|
|
||||||
|
|
||||||
I use [connect.kak](https://github.com/alexherbo2/connect.kak) to spawn a terminal window with about the same command line as in the vim config above.
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
sources = import ../../nix/sources.nix;
|
|
||||||
nixpkgs = import sources.nixpkgs { };
|
|
||||||
in with nixpkgs;
|
|
||||||
|
|
||||||
pkgs.stdenv.mkDerivation {
|
|
||||||
name = "similar-sort";
|
|
||||||
buildInputs = [ pkgs.go ];
|
|
||||||
src = ./.;
|
|
||||||
|
|
||||||
buildPhase = ''
|
|
||||||
env HOME=$(pwd) GOPATH=$(pwd) go build similar-sort.go
|
|
||||||
'';
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out/bin
|
|
||||||
cp similar-sort $out/bin
|
|
||||||
'';
|
|
||||||
}
|
|
|
@ -1,67 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import "bufio"
|
|
||||||
import "fmt"
|
|
||||||
import "os"
|
|
||||||
import "sort"
|
|
||||||
import "strings"
|
|
||||||
import "unicode/utf8"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
target := strings.Join(os.Args[1:], " ")
|
|
||||||
|
|
||||||
s := bufio.NewScanner(os.Stdin)
|
|
||||||
var lines []WithDistance
|
|
||||||
for s.Scan() {
|
|
||||||
lines = append(lines, WithDistance{s.Text(), Levenshtein(target, s.Text())})
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Slice(lines, func(i, j int) bool {
|
|
||||||
return lines[i].distance < lines[j].distance
|
|
||||||
})
|
|
||||||
|
|
||||||
for _, line := range lines {
|
|
||||||
fmt.Println(line.text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type WithDistance struct {
|
|
||||||
text string
|
|
||||||
distance int
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#Go
|
|
||||||
func Levenshtein(a, b string) int {
|
|
||||||
f := make([]int, utf8.RuneCountInString(b)+1)
|
|
||||||
|
|
||||||
for j := range f {
|
|
||||||
f[j] = j
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, ca := range a {
|
|
||||||
j := 1
|
|
||||||
fj1 := f[0] // fj1 is the value of f[j - 1] in last iteration
|
|
||||||
f[0]++
|
|
||||||
for _, cb := range b {
|
|
||||||
mn := min(f[j]+1, f[j-1]+1) // delete & insert
|
|
||||||
if cb != ca {
|
|
||||||
mn = min(mn, fj1+1) // change
|
|
||||||
} else {
|
|
||||||
mn = min(mn, fj1) // matched
|
|
||||||
}
|
|
||||||
|
|
||||||
fj1, f[j] = f[j], mn // save f[j] to fj1(j is about to increase), update f[j] to mn
|
|
||||||
j++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return f[len(f)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
func min(a, b int) int {
|
|
||||||
if a <= b {
|
|
||||||
return a
|
|
||||||
} else {
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue