Source file cmd__tools__emacs_grep.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
module Path_display_mode = struct
type t =
| Absolute
| Relative_to_repo_root
| Relative_to_cwd
[@@deriving enumerate]
let to_string = function
| Absolute -> "absolute"
| Relative_to_repo_root -> "relative-to-repo-root"
| Relative_to_cwd -> "relative-to-cwd"
;;
end
let loc_to_string loc ~repo_root ~below ~path_display_mode =
let loc = (Loc.to_lexbuf_loc loc).start in
let fname = Vcs.Path_in_repo.v loc.pos_fname in
let path =
match (path_display_mode : Path_display_mode.t) with
| Absolute ->
(Vcs.Repo_root.append repo_root fname |> Absolute_path.to_string) [@coverage off]
| Relative_to_cwd ->
(match
Relative_path.chop_prefix (Vcs.Path_in_repo.to_relative_path fname) ~prefix:below
with
| Some path -> Printf.sprintf "./%s" (Relative_path.to_string path)
| None -> Printf.sprintf "./%s" (Vcs.Path_in_repo.to_string fname))
| Relative_to_repo_root -> Printf.sprintf "./%s" (Vcs.Path_in_repo.to_string fname)
in
Printf.sprintf "%s:%d:" path loc.pos_lnum
;;
let to_string t ~repo_root ~below ~path_display_mode =
String.concat
~sep:"\n"
[ loc_to_string (Cr_comment.whole_loc t) ~repo_root ~below ~path_display_mode
; Cr_comment.reindented_content t
; ""
]
;;
let output_one ~include_delim cr ~oc ~repo_root ~below ~path_display_mode =
let str = to_string cr ~repo_root ~below ~path_display_mode in
let nl = if include_delim then "\n" else "" in
Out_channel.output_string oc (Printf.sprintf "%s%s" nl str)
;;
let output_list crs ~oc ~repo_root ~below ~path_display_mode =
let crs = Cr_comment.sort crs in
let include_delim = ref false in
List.iter crs ~f:(fun cr ->
output_one ~include_delim:!include_delim cr ~oc ~repo_root ~below ~path_display_mode;
include_delim := true)
;;
let main =
Command.make
~summary:"A util used by the emacs crs-grep-mode."
~readme:(fun () ->
{|
This command is a building block to the emacs $(b,crs-grep-mode).
It first locates the repository in which the command is launched and then grep-finds all CRs located in listed-files located in the subtree whose root is the current working directory of the command.
It then prints these CRs to $(b,stdout), displaying paths using a syntax that facilitate the integration with emacs grep-mode.
By default the file paths are displayed relative to the command's $(b,cwd).
|})
(let open Command.Std in
let+ path_display_mode =
Arg.named_with_default
[ "path-display-mode" ]
(Param.enumerated (module Path_display_mode))
~docv:"MODE"
~doc:"Specify how the paths are displayed."
~default:Relative_to_cwd
and+ filters = Common_helpers.filters in
let cwd = Unix.getcwd () |> Absolute_path.v in
let { Enclosing_repo.vcs_kind = _; repo_root; vcs } =
Common_helpers.find_enclosing_repo ~from:cwd
in
let below =
Common_helpers.relativize ~repo_root ~cwd ~path:(Relative_path.empty :> Fpath.t)
in
let crs =
let all_crs = Crs_parser.grep ~vcs ~repo_root ~below in
match filters with
| `Default -> all_crs
| `Supplied filters ->
List.filter all_crs ~f:(fun cr ->
List.exists filters ~f:(fun filter -> Cr_comment.Filter.matches filter ~cr))
in
output_list
crs
~oc:Out_channel.stdout
~repo_root
~below:(Vcs.Path_in_repo.to_relative_path below)
~path_display_mode)
;;