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
) {
55 static struct view_column separator_column
;
57 separator_column
.type
= VIEW_COLUMN_TEXT
;
58 column_data
->section
= &separator_column
;
59 column_data
->text
= "--";
63 if (*grep
->file
&& !grep
->lineno
) {
64 static struct view_column file_name_column
;
66 file_name_column
.type
= VIEW_COLUMN_FILE_NAME
;
67 file_name_column
.opt
.file_name
.display
= FILENAME_ALWAYS
;
69 column_data
->section
= &file_name_column
;
72 column_data
->line_number
= &grep
->lineno
;
73 column_data
->file_name
= grep
->file
;
74 column_data
->text
= grep
->text
;
79 grep_select(struct view
*view
, struct line
*line
)
81 struct grep_line
*grep
= grep_get_line(line
);
85 view
->env
->ref
[0] = 0;
86 string_ncopy(view
->env
->file
, grep
->file
, strlen(grep
->file
));
87 string_ncopy(view
->ref
, grep
->file
, strlen(grep
->file
));
90 static const char *grep_args
[] = {
91 "git", "grep", "--no-color", "-n", "-z", "--full-name", NULL
94 static const char **grep_argv
;
99 const char *argv
[SIZEOF_ARG
];
101 char *grep
= read_prompt("grep: ");
103 if (!grep
|| !argv_from_string_no_quotes(argv
, &argc
, grep
))
106 argv_free(grep_argv
);
107 return argv_append_array(&grep_argv
, argv
);
111 open_grep_view(struct view
*prev
)
113 struct view
*view
= &grep_view
;
114 bool in_grep_view
= prev
== view
;
116 if ((!prev
&& is_initial_view(view
)) || (view
->lines
&& !in_grep_view
)) {
117 open_view(prev
, view
, OPEN_DEFAULT
);
120 open_view(prev
, view
, OPEN_RELOAD
);
125 grep_open(struct view
*view
, enum open_flags flags
)
127 struct grep_state
*state
= view
->private;
128 const char **argv
= NULL
;
130 if (is_initial_view(view
)) {
131 grep_argv
= opt_cmdline_argv
;
132 opt_cmdline_argv
= NULL
;
135 if (!argv_append_array(&argv
, grep_args
) ||
136 !argv_append_array(&argv
, grep_argv
))
140 struct view_column
*column
= get_view_column(view
, VIEW_COLUMN_FILE_NAME
);
142 state
->no_file_group
= !column
|| column
->opt
.file_name
.display
!= FILENAME_NO
;
145 return begin_update(view
, NULL
, argv
, flags
);
149 grep_request(struct view
*view
, enum request request
, struct line
*line
)
151 struct grep_state
*state
= view
->private;
152 struct grep_line
*grep
= grep_get_line(line
);
153 struct view
*file_view
= &blob_view
;
163 if (file_view
->parent
== view
&& file_view
->prev
== view
&&
164 state
->last_file
== grep
->file
&& view_is_displayed(file_view
)) {
165 if (grep_view_lineno(grep
))
166 select_view_line(file_view
, grep_view_lineno(grep
));
169 const char *file_argv
[] = { repo
.cdup
, grep
->file
, NULL
};
171 clear_position(&file_view
->pos
);
172 view
->env
->lineno
= grep_view_lineno(grep
);
173 view
->env
->blob
[0] = 0;
174 open_argv(view
, file_view
, file_argv
, repo
.cdup
, OPEN_SPLIT
| OPEN_RELOAD
);
176 state
->last_file
= grep
->file
;
182 open_editor(grep
->file
, grep
->lineno
);
186 view
->env
->ref
[0] = 0;
187 view
->env
->lineno
= grep_view_lineno(grep
);
196 grep_read(struct view
*view
, struct buffer
*buf
)
198 struct grep_state
*state
= view
->private;
199 struct grep_line
*grep
;
206 state
->last_file
= NULL
;
210 if (!strcmp(buf
->data
, "--"))
211 return add_line_nodata(view
, LINE_DELIMITER
) != NULL
;
213 lineno
= io_memchr(buf
, buf
->data
, 0);
214 text
= io_memchr(buf
, lineno
, 0);
216 if (!lineno
|| !text
)
219 textlen
= strlen(text
);
221 file
= get_path(buf
->data
);
225 if (!state
->no_file_group
&& file
!= state
->last_file
&&
226 !add_line_text(view
, file
, LINE_FILE
))
229 line
= add_line_alloc(view
, &grep
, LINE_DEFAULT
, textlen
, FALSE
);
234 grep
->lineno
= atoi(lineno
);
235 strncpy(grep
->text
, text
, textlen
);
236 grep
->text
[textlen
] = 0;
237 view_column_info_update(view
, line
);
239 state
->last_file
= file
;
244 static struct view_ops grep_ops
= {
247 VIEW_REFRESH
| VIEW_GREP_LIKE
,
248 sizeof(struct grep_state
),
256 view_column_bit(FILE_NAME
) | view_column_bit(LINE_NUMBER
) |
257 view_column_bit(TEXT
),
258 grep_get_column_data
,
263 /* vim: set ts=8 sw=8 noexpandtab: */