]> Sergey Matveev's repositories - path-extractor.git/commitdiff
Initial commit
authorEdgar HIPP <edgar.hipp@netapsys.fr>
Sun, 21 Jun 2015 13:33:05 +0000 (15:33 +0200)
committerEdgar HIPP <edgar.hipp@netapsys.fr>
Sun, 21 Jun 2015 13:33:05 +0000 (15:33 +0200)
.gitignore [new file with mode: 0644]
README.md [new file with mode: 0644]
extractor.go [new file with mode: 0644]
pe.go [new file with mode: 0644]
pe_test.go [new file with mode: 0644]
validators.go [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..3f008b9
--- /dev/null
@@ -0,0 +1,3 @@
+pe
+*.txt
+demo.gif
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..67fb3d1
--- /dev/null
+++ b/README.md
@@ -0,0 +1,65 @@
+# PathExtractor (pe)
+
+![demo](raw.github.com/edi9999/i/master/demo.gif)
+
+PathExtractor is a command line tool that extracts a list of files/paths from stdin.
+
+Advantages over [fpp](https://github.com/facebook/PathPicker):
+
+ * It does only one thing : more unixy
+ * You can use it with any fuzzy finder, such as [fzf](https://github.com/junegunn/fzf),[peco](https://github.com/peco/peco),[percol](https://github.com/mooz/percol),[pick](https://github.com/thoughtbot/pick),[selecta](https://github.com/garybernhardt/selecta/)
+ * It doesn't wait for stdin to be finished to output the paths
+ * It is faster
+ * It is much smaller (easily understandable)
+ * You can also use it without a fuzzy finder for programmatic usage
+
+For example, you could write:
+
+    git status | pe
+
+to get a list of the files that were added/changed, without all the formating
+
+One of the most common usage is to create an alias that will automatically run :
+
+  `pe` + a command line fuzzy finder such as fzf + an action such as opening that file in your favorite editor.
+
+For example, using `zsh` , I have as an alias:
+
+    alias -g P='| pe | fzf | read filename; [ ! -z $filename ] && vim $filename'
+
+With `bash`:
+
+    bind '"PP": "| pe | fzf | read filename; [ ! -z $filename ] && vim $filename"'
+
+So that If I run
+
+    `git status P`
+
+or
+
+    `git status PP`
+
+to quickly open one of the changed files in vim
+
+Other usage ideas:
+
+With zsh:
+
+    # Copy selected path to clipboard
+    alias -g C='| pe | fzf | read filename; [ ! -z $filename ] && echo -n $filename | xclip -selection c'
+
+With bash:
+
+    bind '"CC": "| pe | fzf | read filename; [ ! -z $filename ] && echo -n $filename | xclip -selection c"'
+
+# Installation
+
+```
+git clone # in your go path
+
+go test
+
+go build
+
+go install
+```
diff --git a/extractor.go b/extractor.go
new file mode 100644 (file)
index 0000000..69d4b95
--- /dev/null
@@ -0,0 +1,30 @@
+package main
+
+import "regexp"
+
+
+func pathExtractor(input string) [][][]byte {
+    surroundRegex := "[^][ \\t:'\"]"
+    r := regexp.MustCompile("("+surroundRegex+"*[\\./]"+surroundRegex+"*)")
+    temp := [][][]byte{}
+    temp = r.FindAllSubmatch([]byte(input),-1)
+    return temp
+}
+
+func getAllMatches(input string) []string {
+    matches := [][][]byte{}
+    result := []string{}
+    s := string("")
+    matches = pathExtractor(input)
+    for _,match := range matches {
+        s = string(match[1])
+        if isDate(s) || isVersion(s) || isGitRange(s) || isGitInstruction(s) || containsInvalidString(s) || len(s)<=2 {
+            continue
+        }
+        if isGitPath(s) {
+            s = replaceGitPath(s)
+        }
+        result = append(result,s)
+    }
+    return result
+}
diff --git a/pe.go b/pe.go
new file mode 100644 (file)
index 0000000..a95a385
--- /dev/null
+++ b/pe.go
@@ -0,0 +1,18 @@
+package main
+
+import "os"
+import "bufio"
+import "fmt"
+
+func main() {
+    stdin := os.Stdin
+    if scanner := bufio.NewScanner(stdin); scanner != nil {
+        for scanner.Scan() {
+            matches := getAllMatches(scanner.Text())
+            for _,match := range matches {
+                fmt.Println(match)
+            }
+        }
+    }
+}
+
diff --git a/pe_test.go b/pe_test.go
new file mode 100644 (file)
index 0000000..378e79a
--- /dev/null
@@ -0,0 +1,65 @@
+package main
+
+import "testing"
+
+func TestGitIgnore(t *testing.T) {
+    output:=getAllMatches("?? alt/generateStore.php")
+    if output[0] != "alt/generateStore.php" {
+        t.Errorf("Doesnt match files", output[0])
+    }
+
+    output=getAllMatches("hello .gitignore")
+    if output[0] != ".gitignore" {
+        t.Errorf("Doesnt match hidden files", output[0])
+    }
+
+    output=getAllMatches(" mail@mail.com ")
+    if len(output) != 0 {
+        t.Errorf("Matches email adresses", output[0])
+    }
+
+    output=getAllMatches("v1.2")
+    if len(output) != 0 {
+        t.Errorf("Matches version number", output[0])
+    }
+
+    output=getAllMatches("obj.slice()")
+    if len(output) != 0 {
+        t.Errorf("Matches function call", output[0])
+    }
+
+    output=getAllMatches("~/www")
+    if len(output) == 0 || output[0] != "~/www" {
+        t.Errorf("Doesnt match home", output[0])
+    }
+
+    output=getAllMatches("origin/master")
+    if len(output) != 0 {
+        t.Errorf("Matches remote name", output[0])
+    }
+
+    output=getAllMatches("john doe (dead on 28/04/2014)")
+    if len(output) != 0 {
+        t.Errorf("Matches date", output[0])
+    }
+
+    output=getAllMatches("john doe ,dead on 28/04/2014")
+    if len(output) != 0 {
+        t.Errorf("Matches date", output[0])
+    }
+
+    output=getAllMatches(".gitignore , ~/www")
+    if len(output) != 2 {
+        t.Errorf("Doesnt match multi", output[0])
+    }
+
+    output=getAllMatches("var/")
+    if len(output) != 1 {
+        t.Errorf("Doesnt match dir", output[0])
+    }
+
+    output=getAllMatches("//")
+    if len(output) != 0 {
+        t.Errorf("Comment matches", output[0])
+    }
+}
diff --git a/validators.go b/validators.go
new file mode 100644 (file)
index 0000000..60811fc
--- /dev/null
@@ -0,0 +1,46 @@
+package main
+
+import "strings"
+import "regexp"
+
+func isGitRange (input string) bool {
+    r := regexp.MustCompile("[0-9a-f]{3,}\\.\\.[0-9a-f]{3,}")
+    return r.Match([]byte(input))
+}
+
+func isGitPath (input string) bool {
+    r := regexp.MustCompile("^[ab]/")
+    return r.Match([]byte(input))
+}
+
+func isDate (input string) bool {
+    r := regexp.MustCompile("^[0-9]+/[0-9]+/[0-9]+")
+    return r.Match([]byte(input))
+}
+
+func isGitInstruction (input string) bool {
+    r := regexp.MustCompile("\\.{3,}")
+    return r.Match([]byte(input))
+}
+
+func replaceGitPath (input string) string {
+    r := regexp.MustCompile("^[ab]/(.*)")
+    temp := [][]byte{}
+    temp = r.FindSubmatch([]byte(input))
+    return string(temp[1])
+}
+
+func isVersion (input string) bool {
+    r := regexp.MustCompile("[0-9x]\\.[0-9x]{1,2}(\\.[0-9x]{1,3})?")
+    return r.Match([]byte(input))
+}
+
+func containsInvalidString (input string) bool {
+    invalidStrings := []string{"(",")","@","origin/","{","}","<",">","$","*"}
+    for _,s := range invalidStrings {
+        if strings.Contains(input,s) {
+            return true
+        }
+    }
+    return false
+}