Browse Source

Add command to edit and add (simultaneously) items to launch in rc file

 - Generalise Remove_command module
 - Update TODO, CHANGELOG
Leo 10 years ago
parent
commit
0c656838b1
5 changed files with 135 additions and 19 deletions
  1. 2 1
      CHANGELOG.md
  2. 6 4
      TODO.md
  3. 10 2
      src/command_def.ml
  4. 95 0
      src/edit_command.ml
  5. 22 12
      src/remove_command.ml

+ 2 - 1
CHANGELOG.md

@@ -3,8 +3,9 @@
 ## v0.2.1
 ## v0.2.1
  + Add new command line option:
  + Add new command line option:
    + “-c file” allow to read configuration from custom file.
    + “-c file” allow to read configuration from custom file.
+   + “-m n” allow to edit and add (simultaneously) items to launch in rc file.
  + Improve “-l”: now display a “\*” next to current state.
  + Improve “-l”: now display a “\*” next to current state.
- + Code clean up (Types in records)
+ + Code clean up (Types in records) and code factoring.
 
 
 ## v0.2.0
 ## v0.2.0
  + Add new command line option.
  + Add new command line option.

+ 6 - 4
TODO.md

@@ -2,18 +2,20 @@
 
 
 ## Users idees
 ## Users idees
 
 
-    + Use commands with “--” insthead of “-”.
-    + Add confirmation on delete.
-    + Add undo command ?
-    + Show help in context
+ + Add confirmation on delete.
+ + Add undo command ?
+ + Show help in context
         + When all has been launched, explain how to reset.
         + When all has been launched, explain how to reset.
 
 
     **Feel free to add things here (and make a pull request).
     **Feel free to add things here (and make a pull request).
     Or send an email to the author !**
     Or send an email to the author !**
 
 
 ## Major issue
 ## Major issue
+ + Make multiple tmp file really working by using checksum for rc file.
 
 
 ## Short term
 ## Short term
+ + Use a dedicated module, for user messages. Allow to print in color and to set
+   verbsity level (maybe also script output, in JSON format)
 
 
 ### Configuration value
 ### Configuration value
  + Make displaying command before launching configurable
  + Make displaying command before launching configurable

+ 10 - 2
src/command_def.ml

@@ -67,6 +67,10 @@ let args =
     +> flag "-n" no_arg
     +> flag "-n" no_arg
     ~aliases:["-number" ; "--number"]
     ~aliases:["-number" ; "--number"]
     ~doc:" Display current state of the program"
     ~doc:" Display current state of the program"
+    (* Flag to edit the nth command *)
+    +> flag "-m" no_arg
+    ~aliases:["-modify" ; "--modify"]
+    ~doc:"[n] Edit the nth command of the rc file."
 
 
     +> anon (maybe ("Command number" %: int)))
     +> anon (maybe ("Command number" %: int)))
 ;;
 ;;
@@ -79,11 +83,13 @@ let commands =
     ~readme:(fun () -> "See https://gitlab.com/WzukW/oclaunch for help.")
     ~readme:(fun () -> "See https://gitlab.com/WzukW/oclaunch for help.")
     args
     args
 
 
-    (fun rc_file_name reset_tmp list_commands add delete number num_cmd () ->
+    (fun rc_file_name reset_tmp list_commands add delete number modify num_cmd () ->
        (* Use given rc file, should run the nth argument if present *)
        (* Use given rc file, should run the nth argument if present *)
        Const.rc_file := rc_file_name;
        Const.rc_file := rc_file_name;
        (* Obtain data from rc_file *)
        (* Obtain data from rc_file *)
        let rc_content = File_com.init_rc () in
        let rc_content = File_com.init_rc () in
+       (* A default number, corresponding to first item *)
+       let default_n = (Option.value ~default:0 num_cmd) in
        (* First try to list *)
        (* First try to list *)
        if list_commands then List_rc.run ~rc:rc_content
        if list_commands then List_rc.run ~rc:rc_content
        (* To add command to rc file *)
        (* To add command to rc file *)
@@ -93,7 +99,9 @@ let commands =
        (* To print current state *)
        (* To print current state *)
        else if number then State.print_current ()
        else if number then State.print_current ()
        (* Reset to a value *)
        (* Reset to a value *)
-       else if reset_tmp then Tmp_file.reset (Option.value ~default:0 num_cmd)
+       else if reset_tmp then Tmp_file.reset default_n
+       (* Edit the nth command *)
+       else if modify then Edit_command.run ~rc:rc_content default_n
        (* Else: Run the nth command *)
        (* Else: Run the nth command *)
        else Default.run ~rc:rc_content num_cmd
        else Default.run ~rc:rc_content num_cmd
     )
     )

+ 95 - 0
src/edit_command.ml

@@ -0,0 +1,95 @@
+(******************************************************************************)
+(* Copyright © Joly Clément, 2014-2015                                        *)
+(*                                                                            *)
+(*  leowzukw@vmail.me                                                         *)
+(*                                                                            *)
+(*  Ce logiciel est un programme informatique servant à exécuter              *)
+(*  automatiquement des programmes à l'ouverture du terminal.                 *)
+(*                                                                            *)
+(*  Ce logiciel est régi par la licence CeCILL soumise au droit français et   *)
+(*  respectant les principes de diffusion des logiciels libres. Vous pouvez   *)
+(*  utiliser, modifier et/ou redistribuer ce programme sous les conditions    *)
+(*  de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA    *)
+(*  sur le site "http://www.cecill.info".                                     *)
+(*                                                                            *)
+(*  En contrepartie de l'accessibilité au code source et des droits de copie, *)
+(*  de modification et de redistribution accordés par cette licence, il n'est *)
+(*  offert aux utilisateurs qu'une garantie limitée.  Pour les mêmes raisons, *)
+(*  seule une responsabilité restreinte pèse sur l'auteur du programme,  le   *)
+(*  titulaire des droits patrimoniaux et les concédants successifs.           *)
+(*                                                                            *)
+(*  A cet égard  l'attention de l'utilisateur est attirée sur les risques     *)
+(*  associés au chargement,  à l'utilisation,  à la modification et/ou au     *)
+(*  développement et à la reproduction du logiciel par l'utilisateur étant    *)
+(*  donné sa spécificité de logiciel libre, qui peut le rendre complexe à     *)
+(*  manipuler et qui le réserve donc à des développeurs et des professionnels *)
+(*  avertis possédant  des  connaissances  informatiques approfondies.  Les   *)
+(*  utilisateurs sont donc invités à charger  et  tester  l'adéquation  du    *)
+(*  logiciel à leurs besoins dans des conditions permettant d'assurer la      *)
+(*  sécurité de leurs systèmes et ou de leurs données et, plus généralement,  *)
+(*  à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.        *)
+(*                                                                            *)
+(*  Le fait que vous puissiez accéder à cet en-tête signifie que vous avez    *)
+(*  pris connaissance de la licence CeCILL, et que vous en avez accepté les   *)
+(*  termes.                                                                   *)
+(******************************************************************************)
+
+open Core.Std;;
+
+(* Module to edit command without editing the rc file directly *)
+
+(* Function to create a new list augmented by some commands *)
+(* TODO Factorise this *)
+let new_list current_list position new_items =
+    (* If a number is given, add commands after position n by
+    splitting the list and concatenating all. List.split_n works like this :
+        * #let l1 = [1;2;3;4;5;6] in
+        * # List.split_n l1 2;;
+        * - : int list * int list = ([1; 2], [3; 4; 5; 6]) *)
+    let l_begin,l_end = List.split_n current_list position in
+    List.concat [ l_begin ; new_items ; l_end ]
+;;
+
+
+
+(* Function which get the nth element, put it in afile, let the user edit it,
+ * and then remplace with the new result *)
+let run ~(rc:File_com.t) position =
+    (* Current list of commands *)
+    let current_list = rc.Settings_t.progs in
+
+    (* Creating tmp file *)
+    let tmp_filename = [
+        "/tmp/oc_edit_" ;
+        (Int.to_string (Random.int 10000)) ;
+        ".txt" ;
+    ] in
+    let tmp_edit = String.concat tmp_filename in
+    (* Remove item to be edited *)
+    let original_command,shorter_list = Remove_command.remove current_list
+    position in
+    Out_channel.write_all tmp_edit original_command;
+
+
+    (* Edit file *)
+    let edit = String.concat [ Const.editor ; " " ; tmp_edit ] in
+    Sys.command edit
+    |> (function
+        0 -> ()
+        | n -> printf "Error while running %s: error code %i" edit n);
+
+    (* Reading and applying the result *)
+    let new_commands = In_channel.read_lines tmp_edit in
+    let cmd_list = new_list shorter_list position new_commands in
+    let updated_rc = { rc with Settings_t.progs = cmd_list} in
+    File_com.write updated_rc;
+    (* Display the result *)
+    printf "'%s' -> '%s'\n\n" original_command
+        (List.fold
+            ~f:(fun accum item -> String.concat [ accum ; item ; "\n" ])
+            ~init:""
+            new_commands);
+    let reread_rc = File_com.init_rc () in
+    (* Display new rc file *)
+    List_rc.run ~rc:reread_rc
+;;

+ 22 - 12
src/remove_command.ml

@@ -38,6 +38,26 @@ open Core.Std;;
 
 
 (* Module to remove commands without editing the rc file directly *)
 (* Module to remove commands without editing the rc file directly *)
 
 
+(* Function remove nth command in the rc_file, returning the removed one and the
+ * new list *)
+let remove current_list n =
+    let removed = ref "" in
+    (* The list without the nth item *)
+    let new_list = List.filteri current_list ~f:(fun i _ ->
+        if i <> n then
+            (* If it is not nth, return true *)
+            true
+        else
+            begin
+                (* If it is nth, ie the command to be removed, store it and return
+                 * false, to remove the corresponding item *)
+                removed := List.nth_exn current_list i;
+                false
+            end
+    ) in
+    ( !removed, new_list )
+;;
+
 (* Function which add the commands (one per line) ridden on stdin to the rc
 (* Function which add the commands (one per line) ridden on stdin to the rc
  * file, and then display th new configuration *)
  * file, and then display th new configuration *)
 let run ~(rc:File_com.t) n_to_remove =
 let run ~(rc:File_com.t) n_to_remove =
@@ -47,18 +67,8 @@ let run ~(rc:File_com.t) n_to_remove =
     let nth = Option.value n_to_remove
     let nth = Option.value n_to_remove
         ~default:((List.length actual_list) - 1) in
         ~default:((List.length actual_list) - 1) in
     (* Remove the nth command, after display it *)
     (* Remove the nth command, after display it *)
-    let new_list = List.filteri actual_list ~f:(fun i _ ->
-        if i <> nth then
-            (* If it is not nth, return true *)
-            true
-        else
-            begin
-                (* If it is nth, ie the command to be removed, print if and return
-                 * false *)
-                printf "Removing: %s\n\n" (List.nth_exn actual_list i);
-                false
-            end
-    ) in
+    let removed,new_list = remove actual_list nth in
+    printf "Removing: %s\n\n" removed;
     (* Write new list to rc file *)
     (* Write new list to rc file *)
     let updated_rc = { rc with Settings_t.progs = new_list } in
     let updated_rc = { rc with Settings_t.progs = new_list } in
     File_com.write updated_rc;
     File_com.write updated_rc;