Index: /trunk/cli/index.ml
===================================================================
--- /trunk/cli/index.ml	(revision 3)
+++ /trunk/cli/index.ml	(revision 4)
@@ -1,54 +1,94 @@
 open Logarion
 
-let index print title authors locations peers dir =
-	let fname = Filename.concat dir "index.pck" in
-	let pck = match Header_pack.of_string @@ File_store.to_string fname with
-	| Error s -> failwith s
-	| Ok pck -> let info = Header_pack.{ pck.info with
-			title = if title <> "" then title else pck.info.title;
-			people = if authors <> ""
-				then (String_set.list_of_csv authors) else pck.info.people;
-			locations = if locations <> ""
-				then (String_set.list_of_csv locations) else pck.info.locations;
-		} in
-		Header_pack.{ info; fields;
-			texts = of_text_list @@ File_store.fold ~dir
-				(fun a (t,_) -> of_text a t) [];
-			peers = if peers <> ""
-				then (str_list @@ String_set.list_of_csv peers) else pck.peers;
-		}
+let text_editor name x =
+	let fname, out = Filename.open_temp_file name "" in
+	output_string out x; flush out;
+	let r = match Unix.system ("$EDITOR " ^ fname) with
+	| Unix.WEXITED 0 ->
+		let inp = open_in fname in 
+		let line = input_line inp in
+		close_in inp; line
+	| _ -> failwith "Failed launching editor to edit value" in
+	close_out out;
+	Unix.unlink fname;
+	r
+
+let text_editor_lines name x =
+	let fname, out = Filename.open_temp_file name "" in
+	List.iter (fun s -> output_string out (s ^ "\n")) x; flush out;
+	let r = match Unix.system ("$EDITOR " ^ fname) with
+	| Unix.WEXITED 0 ->
+		let inp = open_in fname in 
+		let lines =
+			let rec acc a =
+				try let a = String.trim (input_line inp) :: a in acc a
+				with End_of_file -> a in
+			acc [] in
+		close_in inp; lines
+	| _ -> failwith "Failed launching editor to edit value" in
+	close_out out;
+	Unix.unlink fname;
+	r
+
+let print_pack pck =
+	let s ss = String.concat "\n\t" ss in
+	let open Header_pack in
+	Printf.printf "Id: %s\nTitle: %s\nAuthors: %s\nLocations:\n\t%s\nPeers:\n\t%s\n"
+		pck.info.id pck.info.title (String.concat "," pck.info.people)
+		(s pck.info.locations) (s (to_str_list pck.peers))
+
+type t = { dir : string; index_path: string; pck : Header_pack.t }
+
+let index r print title auth locs peers =
+	let edit name index param = if print then index else match param with
+	| Some "$" -> text_editor name index | Some p -> p
+	| None -> index in
+	let edits name index param = if print then index else match param with
+	| Some "$" -> text_editor_lines name index | Some p -> String_set.list_of_csv p
+	| None -> index in
+	let edits_mp name index param = if print then index else match param with
+	| Some "$" -> Header_pack.str_list (text_editor_lines name (Header_pack.to_str_list index))
+	| Some p -> Header_pack.str_list (String_set.list_of_csv p)
+	| None -> index in
+	let info = Header_pack.{ r.pck.info with
+		title = edit "Title" r.pck.info.title title;
+		people = edits "People" r.pck.info.people auth;
+		locations = edits "Locations" r.pck.info.locations locs;
+	} in
+	let pack = Header_pack.{ info; fields;
+		texts = of_text_list @@ File_store.fold ~dir:r.dir (fun a (t,_) -> of_text a t) [];
+		peers = edits_mp "Peers" r.pck.peers peers;
+	} in
+	if print then print_pack pack
+	else (File_store.file r.index_path (Header_pack.string pack))
+
+let load dir =
+	let index_path = Filename.concat dir "index.pck" in
+	let pck = match Header_pack.of_string @@ File_store.to_string index_path with
+	| Error s -> failwith s | Ok pck -> pck 
 	| exception (Sys_error _) -> Header_pack.{
-		info = {
-			version = version; id = Id.generate (); title;
-			people = String_set.list_of_csv authors;
-			locations = String_set.list_of_csv locations };
+		info = { version = version; id = Id.generate (); title = ""; people = []; locations = [] };
 		fields;
 		texts = of_text_list @@ File_store.fold ~dir
 			(fun a (t,_) -> of_text a t) [];
-		peers = str_list @@ String_set.list_of_csv peers;
+		peers = Msgpck.of_list [];
 	} in
-	File_store.file fname (Header_pack.string pck);
-	let open Header_pack in
-	let s ss = String.concat "\n\t" ss in
-	if print then
-		Printf.printf "Title: %s\nAuthors: %s\nLocations:\n\t%s\nPeers:\n\t%s\n"
-			pck.info.title (String.concat "," pck.info.people)
-			(s pck.info.locations) (s (to_str_list pck.peers))
+	index { dir; index_path; pck }
 
 open Cmdliner
 let term =
-	let print = Arg.(value & flag & info ["print"] ~doc:"print info") in
-	let title= Arg.(value & opt string "" & info ["t"; "title"]
+	let print= Arg.(value & flag & info ["print"] ~doc:"print info") in
+	let title= Arg.(value & opt ~vopt:(Some "$") (some string) None & info ["t"; "title"]
 		~docv:"string" ~doc:"Title for index") in
-	let auth = Arg.(value & opt string "" & info ["a"; "authors"]
+	let auth = Arg.(value & opt ~vopt:(Some "$") (some string) None & info ["a"; "authors"]
 		~docv:"comma-separated names" ~doc:"Index authors") in
-	let locs = Arg.(value & opt string "" & info ["l"; "locations"]
+	let locs = Arg.(value & opt ~vopt:(Some "$") (some string) None & info ["l"; "locations"]
 		~docv:"comma-separated URLs" ~doc:"repository URLs") in
-	let peers= Arg.(value & opt string "" & info ["p"; "peers"]
+	let peers= Arg.(value & opt ~vopt:(Some "$") (some string) None & info ["p"; "peers"]
 		~docv:"comma-separated URLs" ~doc:"URLs to other known text repositories") in
-	let dir = Arg.(value & pos 0 string "." & info []
+	let dir  = Arg.(value & pos 0 string "." & info []
 		~docv:"directory to index") in
 	let doc = "Generate an index.pck for texts in a directory" in
-	Term.(const index $ print $ title $ auth $ locs $ peers $ dir),
+	Term.(const load $ dir $ print $ title $ auth $ locs $ peers),
 		Term.info "index" ~doc
 			~man:[ `S "DESCRIPTION"; `Pre "An index contains:\n
