1 /* Copyright (c) 2006-2014 Jonas Fonseca <jonas.fonseca@gmail.com>
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU General Public License as
5 * published by the Free Software Foundation; either version 2 of
6 * the License, or (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
14 #include "tig/refdb.h"
15 #include "tig/options.h"
16 #include "tig/parse.h"
18 #include "tig/display.h"
19 #include "tig/prompt.h"
31 const char *last_file
;
35 #define grep_view_lineno(grep) ((grep)->lineno > 0 ? (grep)->lineno - 1 : 0)
37 static struct grep_line
*
38 grep_get_line(const struct line
*line
)
40 static struct grep_line grep_line
;
42 if (line
->type
== LINE_DEFAULT
)
45 grep_line
.file
= line
->type
== LINE_DELIMITER
? "" : get_path(line
->data
);
50 grep_get_column_data(struct view
*view
, const struct line
*line
, struct view_column_data
*column_data
)
52 struct grep_line
*grep
= grep_get_line(line
);
54 if (line
->type
== LINE_DELIMITER
)
57 if (*grep
->file
&& !grep
->lineno
) {
58 static struct view_column file_name_column
;
60 file_name_column
.type
= VIEW_COLUMN_FILE_NAME
;
61 file_name_column
.opt
.file_name
.show
= FILENAME_ALWAYS
;
63 column_data
->section
= &file_name_column
;
66 column_data
->line_number
= &grep
->lineno
;
67 column_data
->file_name
= grep
->file
;
68 column_data
->text
= grep
->text
;
73 grep_select(struct view
*view
, struct line
*line
)
75 struct grep_line
*grep
= grep_get_line(line
);
79 view
->env
->ref
[0] = 0;
80 string_ncopy(view
->env
->file
, grep
->file
, strlen(grep
->file
));
81 string_ncopy(view
->ref
, grep
->file
, strlen(grep
->file
));
84 static const char *grep_args
[] = {
85 "git", "grep", "--no-color", "-n", "-z", "--full-name", NULL
88 static const char **grep_argv
;
93 const char *argv
[SIZEOF_ARG
];
95 char *grep
= read_prompt("grep: ");
97 if (!grep
|| !argv_from_string_no_quotes(argv
, &argc
, grep
))
100 argv_free(grep_argv
);
101 return argv_append_array(&grep_argv
, argv
);
105 open_grep_view(struct view
*prev
)
107 struct view
*view
= &grep_view
;
108 bool in_grep_view
= prev
== view
;
110 if ((!prev
&& is_initial_view(view
)) || (view
->lines
&& !in_grep_view
)) {
111 open_view(prev
, view
, OPEN_DEFAULT
);
114 open_view(prev
, view
, OPEN_RELOAD
);
119 grep_open(struct view
*view
, enum open_flags flags
)
121 struct grep_state
*state
= view
->private;
122 const char **argv
= NULL
;
124 if (is_initial_view(view
)) {
125 grep_argv
= opt_cmdline_argv
;
126 opt_cmdline_argv
= NULL
;
129 if (!argv_append_array(&argv
, grep_args
) ||
130 !argv_append_array(&argv
, grep_argv
))
134 struct view_column
*column
= get_view_column(view
, VIEW_COLUMN_FILE_NAME
);
136 state
->no_file_group
= !column
|| column
->opt
.file_name
.show
!= FILENAME_NO
;
139 return begin_update(view
, NULL
, argv
, flags
);
143 grep_request(struct view
*view
, enum request request
, struct line
*line
)
145 struct grep_state
*state
= view
->private;
146 struct grep_line
*grep
= grep_get_line(line
);
147 struct view
*file_view
= &blob_view
;
157 if (file_view
->parent
== view
&& file_view
->prev
== view
&&
158 state
->last_file
== grep
->file
&& view_is_displayed(file_view
)) {
159 if (grep_view_lineno(grep
))
160 select_view_line(file_view
, grep_view_lineno(grep
));
163 const char *file_argv
[] = { repo
.cdup
, grep
->file
, NULL
};
165 clear_position(&file_view
->pos
);
166 view
->env
->lineno
= grep_view_lineno(grep
);
167 view
->env
->blob
[0] = 0;
168 open_argv(view
, file_view
, file_argv
, repo
.cdup
, OPEN_SPLIT
| OPEN_RELOAD
);
170 state
->last_file
= grep
->file
;
176 open_editor(grep
->file
, grep
->lineno
);
180 view
->env
->ref
[0] = 0;
181 view
->env
->lineno
= grep_view_lineno(grep
);
190 grep_read(struct view
*view
, char *data
)
192 struct grep_state
*state
= view
->private;
193 struct grep_line
*grep
;
200 state
->last_file
= NULL
;
204 if (!strcmp(data
, "--"))
205 return add_line_nodata(view
, LINE_DELIMITER
) != NULL
;
207 lineno
= io_memchr(&view
->io
, data
, 0);
208 text
= io_memchr(&view
->io
, lineno
, 0);
210 if (!lineno
|| !text
)
213 textlen
= strlen(text
);
215 file
= get_path(data
);
219 if (!state
->no_file_group
&& file
!= state
->last_file
&&
220 !add_line_text(view
, file
, LINE_FILE
))
223 line
= add_line_alloc(view
, &grep
, LINE_DEFAULT
, textlen
, FALSE
);
228 grep
->lineno
= atoi(lineno
);
229 strncpy(grep
->text
, text
, textlen
);
230 grep
->text
[textlen
] = 0;
231 view_column_info_update(view
, line
);
233 state
->last_file
= file
;
238 static struct view_ops grep_ops
= {
241 VIEW_REFRESH
| VIEW_GREP_LIKE
,
242 sizeof(struct grep_state
),
250 view_column_bit(FILE_NAME
) | view_column_bit(LINE_NUMBER
) |
251 view_column_bit(TEXT
),
252 grep_get_column_data
,
257 /* vim: set ts=8 sw=8 noexpandtab: */