--- /dev/null
+USING: help.syntax help.markup kernel prettyprint sequences strings words math ;
+IN: ctags.etags
+
+ARTICLE: "etags" "Etags file"
+{ $emphasis "Etags" } " generates a index file of every factor word in etags format as supported by emacs and other editors. More information can be found at " { $url "http://en.wikipedia.org/wiki/Ctags#Etags_2" } "."
+{ $subsection etags }
+{ $subsection etags-write }
+{ $subsection etag-strings }
+{ $subsection etag-header }
+
+HELP: etags ( path -- )
+{ $values { "path" string } }
+{ $description "Generates a index file in etags format and stores in " { $snippet "path" } "." }
+{ $examples
+ { $unchecked-example
+ "USING: ctags.etags ;"
+ "\"ETAGS\" etags"
+ ""
+ }
+} ;
+
+HELP: etags-write ( alist path -- )
+{ $values { "alist" sequence }
+ { "path" string } }
+{ $description "Stores a " { $snippet "alist" } " in " { $snippet "path" } ". " { $snippet "alist" } " must be an association list with etags format: its key must be a resource path and its value a vector, containing pairs of words and lines" }
+{ $examples
+ { $unchecked-example
+ "USING: kernel etags.ctags ;"
+ "{ { \"resource:extra/unix/unix.factor\" V{ { dup2 91 } } } } \"ETAGS\" etags-write"
+ ""
+ }
+} ;
+
+HELP: etag-strings ( alist -- seq )
+{ $values { "alist" sequence }
+ { "seq" sequence } }
+{ $description "Converts an " { $snippet "alist" } " with etag format (a path as key and a vector containing word/line pairs) in a " { $snippet "seq" } " of strings." }
+
+ABOUT: "etags"
\ No newline at end of file
USING: kernel ctags ctags.etags tools.test io.backend sequences arrays prettyprint hashtables assocs ;
IN: ctags.etags.tests
+! etag-at
+[ t ]
+[
+ V{ }
+ "path" H{ } clone etag-at =
+] unit-test
-[ H{ { "path" V{ if { "path" 1 } } } } ]
-[ H{ } clone dup V{ if { "path" 1 } } "path" rot set-at ] unit-test
-
-[ { "path" V{ if { "path" 1 } } } ]
-[ H{ } clone dup { "path" V{ if { "path" 1 } } } "path" rot set-at "path" swap at ] unit-test
-
-
-[ V{ if { "path" 1 } } ]
-[ "path" H{ { "path" V{ if { "path" 1 } } } } at ] unit-test
-
-[ "path" ] [ { if { "path" 1 } } ctag-path ] unit-test
-
-[ V{ } ]
-[ "path" H{ } clone etag-at ] unit-test
-
-[ V{ if { "path" 1 } } ]
-[ "path" H{ { "path" V{ if { "path" 1 } } } } etag-at ] unit-test
-
-[ { if 28 } ]
-[ { if { "resource:core/kernel/kernel.factor" 28 } } etag-pair ] unit-test
+[ t ]
+[
+ V{ if { "path" 1 } }
+ "path" H{ { "path" V{ if { "path" 1 } } } } etag-at =
+] unit-test
-[ V{ } ] [ { if { "path" 1 } } H{ } clone etag-vector ] unit-test
+! etag-vector
+[ t ]
+[
+ V{ }
+ { if { "path" 1 } } H{ } clone etag-vector =
+] unit-test
-[ V{ if { "path" 1 } } ]
-[ { if { "path" 1 } }
+[ t ]
+[
+ V{ if { "path" 1 } }
+ { if { "path" 1 } }
{ { "path" V{ if { "path" 1 } } } } >hashtable
- etag-vector
+ etag-vector =
] unit-test
-[ H{ { "path" V{ { if 1 } } } } ]
-[ { if { "path" 1 } } H{ } clone [ etag-add ] keep ] unit-test
+! etag-pair
+[ t ]
+[
+ { if 28 }
+ { if { "resource:core/kernel/kernel.factor" 28 } } etag-pair =
+] unit-test
-[ H{ { "path" V{ { if 1 } } } } ]
-[ { { if { "path" 1 } } } etag-hash ] unit-test
+! etag-add
+[ t ]
+[
+ H{ { "path" V{ { if 1 } } } }
+ { if { "path" 1 } } H{ } clone [ etag-add ] keep =
+] unit-test
-[ "if\7f28,704" ]
-[ "resource:core/kernel/kernel.factor" file>lines { if 28 } etag ] unit-test
+! etag-hash
+[ t ]
+[
+ H{ { "path" V{ { if 1 } } } }
+ { { if { "path" 1 } } } etag-hash =
+] unit-test
-! [ V{ "\f" "resource:core/kernel/kernel.factor,22" "if\7f28,704" "unless\7f31,755" } ]
-! [ { { "resource:core/kernel/kernel.factor"
-! V{ { if 28 }
-! { unless 31 } } } } etag-strings ] unit-test
+! line-bytes (note that for each line implicit \n is counted)
+[ t ]
+[
+ 17
+ { "1234567890" "12345" } 2 lines>bytes =
+] unit-test
+
+! etag
+[ t ]
+[
+ "if\7f2,11"
+ { "1234567890" "12345" } { if 2 } etag =
+] unit-test
+! etag-length
+[ t ]
+[
+ 14
+ V{ "if\7f2,11" "if\7f2,11" } etag-length =
+] unit-test
: lines>bytes ( seq n -- bytes )
head 0 [ length 1+ + ] reduce ;
-: file>lines ( resource -- lines )
+: file>lines ( path -- lines )
ascii file-lines ;
: etag ( lines seq -- str )
: etag-length ( vector -- n )
0 [ length + ] reduce ;
-: <header> ( n path -- str )
+: (etag-header) ( n path -- str )
[
%
1 CHAR: , <string> %
] "" make ;
: etag-header ( vec1 n resource -- vec2 )
- normalize-path <header> prefix
+ normalize-path (etag-header) prefix
1 HEX: 0c <string> prefix ;
: etag-strings ( alist -- seq )