forked from enlightenment/edi
search: Add project-wide search and replace feature.
This commit is contained in:
parent
5cefe27e48
commit
c826dee557
|
@ -17,3 +17,104 @@ edi_file_path_hidden(const char *path)
|
|||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
edi_file_text_replace(const char *path, const char *search, const char *replace)
|
||||
{
|
||||
char *map, *tempfilepath, *found;
|
||||
FILE *tempfile;
|
||||
Eina_File *f;
|
||||
unsigned long long len, idx;
|
||||
unsigned int slen;
|
||||
|
||||
f = eina_file_open(path, EINA_FALSE);
|
||||
if (!f) return;
|
||||
|
||||
map = eina_file_map_all(f, EINA_FILE_POPULATE);
|
||||
if (!map)
|
||||
{
|
||||
eina_file_close(f);
|
||||
return;
|
||||
}
|
||||
|
||||
len = eina_file_size_get(f);
|
||||
if (!len)
|
||||
{
|
||||
eina_file_close(f);
|
||||
return;
|
||||
}
|
||||
|
||||
tempfilepath = malloc(strlen(path)) + 5;
|
||||
sprintf(tempfilepath, "/tmp/%s.tmp", ecore_file_file_get(path));
|
||||
|
||||
tempfile = fopen(tempfilepath, "wb");
|
||||
if (!tempfile) goto done;
|
||||
|
||||
idx = 0;
|
||||
|
||||
found = strstr(&map[idx], search);
|
||||
if (!found)
|
||||
{
|
||||
fclose(tempfile);
|
||||
unlink(tempfilepath);
|
||||
goto done;
|
||||
}
|
||||
|
||||
slen = strlen(search);
|
||||
|
||||
while (idx < len)
|
||||
{
|
||||
if (!found || &map[idx] < found)
|
||||
{
|
||||
fprintf(tempfile, "%c", map[idx]);
|
||||
idx++;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(tempfile, "%s", replace);
|
||||
idx += slen;
|
||||
found = strstr(&map[idx], search);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(tempfile);
|
||||
ecore_file_mv(tempfilepath, path);
|
||||
done:
|
||||
eina_file_map_free(f, map);
|
||||
eina_file_close(f);
|
||||
}
|
||||
|
||||
static void
|
||||
_edi_file_text_replace_all(const char *directory, const char *search, const char *replace)
|
||||
{
|
||||
char *path, *file;
|
||||
Eina_List *files;
|
||||
|
||||
files = ecore_file_ls(directory);
|
||||
|
||||
EINA_LIST_FREE(files, file)
|
||||
{
|
||||
path = edi_path_append(directory, file);
|
||||
if (!edi_file_path_hidden(path))
|
||||
{
|
||||
if (ecore_file_is_dir(path))
|
||||
{
|
||||
_edi_file_text_replace_all(path, search, replace);
|
||||
}
|
||||
else
|
||||
{
|
||||
edi_file_text_replace(path, search, replace);
|
||||
}
|
||||
}
|
||||
free(path);
|
||||
free(file);
|
||||
}
|
||||
|
||||
if (files)
|
||||
eina_list_free(files);
|
||||
}
|
||||
|
||||
void
|
||||
edi_file_text_replace_all(const char *search, const char *replace)
|
||||
{
|
||||
_edi_file_text_replace_all(edi_project_get(), search, replace);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,27 @@ extern "C" {
|
|||
|
||||
Eina_Bool edi_file_path_hidden(const char *path);
|
||||
|
||||
/**
|
||||
* Replace all occurences of text within whole project.
|
||||
*
|
||||
* @param search The text to be replaced.
|
||||
* @param replace The text that will replace.
|
||||
*
|
||||
* @ingroup Lookup
|
||||
*/
|
||||
void edi_file_text_replace_all(const char *search, const char *replace);
|
||||
|
||||
/**
|
||||
* Replace all occurences of text within given file.
|
||||
*
|
||||
* @param path The path of the file to replace all occurences of the text.
|
||||
* @param search The text to be replaced.
|
||||
* @param replace The text that will replace.
|
||||
*
|
||||
* @ingroup Lookup
|
||||
*/
|
||||
void edi_file_text_replace(const char *path, const char *search, const char *replace);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -926,6 +926,13 @@ _edi_menu_find_project_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
|
|||
edi_mainview_project_search_popup_show();
|
||||
}
|
||||
|
||||
static void
|
||||
_edi_menu_find_replace_project_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
|
||||
void *event_info EINA_UNUSED)
|
||||
{
|
||||
edi_mainview_project_replace_popup_show();
|
||||
}
|
||||
|
||||
static void
|
||||
_edi_menu_findfile_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
|
||||
void *event_info EINA_UNUSED)
|
||||
|
@ -1137,6 +1144,7 @@ _edi_menu_setup(Evas_Object *win)
|
|||
elm_menu_item_add(menu, menu_it, "go-jump", _("Goto Line ..."), _edi_menu_goto_cb, NULL);
|
||||
elm_menu_item_separator_add(menu, menu_it);
|
||||
elm_menu_item_add(menu, menu_it, "edit-find", _("Find in project ..."), _edi_menu_find_project_cb, NULL);
|
||||
elm_menu_item_add(menu, menu_it, "edit-find-replace", _("Replace in project ..."), _edi_menu_find_replace_project_cb, NULL);
|
||||
|
||||
menu_it = elm_menu_item_add(menu, NULL, NULL, _("View"), NULL, NULL);
|
||||
elm_menu_item_add(menu, menu_it, "window-new", _("New Window"), _edi_menu_view_open_window_cb, NULL);
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
|
||||
#include "editor/edi_editor.h"
|
||||
#include "edi_content_provider.h"
|
||||
#include "../edi_searchpanel.h"
|
||||
#include "edi_searchpanel.h"
|
||||
#include "edi_file.h"
|
||||
|
||||
#include "edi_private.h"
|
||||
#include "edi_config.h"
|
||||
|
@ -465,6 +466,35 @@ edi_mainview_goto_popup_show()
|
|||
edi_mainview_panel_goto_popup_show(_current_panel);
|
||||
}
|
||||
|
||||
static void
|
||||
_edi_mainview_popup_message_close_cb(void *data EINA_UNUSED,
|
||||
Evas_Object *obj EINA_UNUSED,
|
||||
void *event_info EINA_UNUSED)
|
||||
{
|
||||
Evas_Object *popup = data;
|
||||
|
||||
evas_object_del(popup);
|
||||
}
|
||||
|
||||
static void
|
||||
_edi_mainview_popup_message_open(const char *message)
|
||||
{
|
||||
Evas_Object *popup, *button;
|
||||
|
||||
popup = elm_popup_add(_main_win);
|
||||
elm_object_part_text_set(popup, "title,text",
|
||||
message);
|
||||
|
||||
button = elm_button_add(popup);
|
||||
|
||||
elm_object_text_set(button, _("OK"));
|
||||
elm_object_part_content_set(popup, "button1", button);
|
||||
evas_object_smart_callback_add(button, "clicked",
|
||||
_edi_mainview_popup_message_close_cb, popup);
|
||||
|
||||
evas_object_show(popup);
|
||||
}
|
||||
|
||||
static void
|
||||
_edi_mainview_project_search_popup_cancel_cb(void *data EINA_UNUSED,
|
||||
Evas_Object *obj EINA_UNUSED,
|
||||
|
@ -482,7 +512,11 @@ _edi_mainview_project_search_cb(void *data,
|
|||
char *text;
|
||||
|
||||
text_markup = elm_object_text_get((Evas_Object *) data);
|
||||
if (!text_markup || !text_markup[0]) return;
|
||||
if (!text_markup || !text_markup[0])
|
||||
{
|
||||
_edi_mainview_popup_message_open(_("Please enter a valid search term."));
|
||||
return;
|
||||
}
|
||||
|
||||
text = elm_entry_markup_to_utf8(text_markup);
|
||||
|
||||
|
@ -517,6 +551,7 @@ edi_mainview_project_search_popup_show(void)
|
|||
_("Search for (whole project)"));
|
||||
|
||||
box = elm_box_add(popup);
|
||||
evas_object_show(box);
|
||||
sep = elm_separator_add(box);
|
||||
elm_separator_horizontal_set(sep, EINA_TRUE);
|
||||
evas_object_show(sep);
|
||||
|
@ -565,6 +600,127 @@ edi_mainview_project_search_popup_show(void)
|
|||
evas_object_show(popup);
|
||||
elm_object_focus_set(input, EINA_TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
_edi_mainview_project_replace_cb(void *data,
|
||||
Evas_Object *obj,
|
||||
void *event_info EINA_UNUSED)
|
||||
{
|
||||
const char *search_markup, *replace_markup;
|
||||
char *search, *replace;
|
||||
|
||||
search_markup = elm_object_text_get(evas_object_data_get(obj, "search"));
|
||||
if (!search_markup || !search_markup[0])
|
||||
{
|
||||
_edi_mainview_popup_message_open(_("Please enter a valid search string."));
|
||||
return;
|
||||
}
|
||||
|
||||
replace_markup = elm_object_text_get(data);
|
||||
if (!replace_markup || !replace_markup[0])
|
||||
{
|
||||
_edi_mainview_popup_message_open(_("Please enter a valid replace string."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(replace_markup, search_markup))
|
||||
{
|
||||
_edi_mainview_popup_message_open(_("Strings cannot match."));
|
||||
return;
|
||||
}
|
||||
|
||||
search = elm_entry_markup_to_utf8(search_markup);
|
||||
replace = elm_entry_markup_to_utf8(replace_markup);
|
||||
|
||||
edi_file_text_replace_all(search, replace);
|
||||
|
||||
free(search);
|
||||
free(replace);
|
||||
|
||||
evas_object_del(_edi_mainview_search_project_popup);
|
||||
}
|
||||
|
||||
void
|
||||
edi_mainview_project_replace_popup_show(void)
|
||||
{
|
||||
Evas_Object *popup, *table, *box, *label, *sep, *search, *replace, *button;
|
||||
|
||||
popup = elm_popup_add(_main_win);
|
||||
_edi_mainview_search_project_popup = popup;
|
||||
elm_object_part_text_set(popup, "title,text", _("Search & Replace"));
|
||||
|
||||
box = elm_box_add(popup);
|
||||
elm_object_content_set(popup, box);
|
||||
|
||||
sep = elm_separator_add(box);
|
||||
elm_separator_horizontal_set(sep, EINA_TRUE);
|
||||
evas_object_show(sep);
|
||||
elm_box_pack_end(box, sep);
|
||||
|
||||
label = elm_label_add(box);
|
||||
elm_object_text_set(label, _("Replace all occurences of text within the whole project."));
|
||||
evas_object_show(label);
|
||||
elm_box_pack_end(box, label);
|
||||
|
||||
sep = elm_separator_add(box);
|
||||
elm_separator_horizontal_set(sep, EINA_TRUE);
|
||||
evas_object_show(sep);
|
||||
elm_box_pack_end(box, sep);
|
||||
|
||||
table = elm_table_add(box);
|
||||
evas_object_size_hint_weight_set(table, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
evas_object_size_hint_align_set(table, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
evas_object_show(table);
|
||||
|
||||
label = elm_label_add(table);
|
||||
elm_object_text_set(label, _("Search: "));
|
||||
evas_object_show(label);
|
||||
elm_table_pack(table, label, 0, 0, 1, 1);
|
||||
|
||||
search = elm_entry_add(table);
|
||||
elm_entry_single_line_set(search, EINA_TRUE);
|
||||
elm_entry_scrollable_set(search, EINA_TRUE);
|
||||
evas_object_size_hint_weight_set(search, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
evas_object_size_hint_align_set(search, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
evas_object_show(search);
|
||||
elm_table_pack(table, search, 1, 0, 1, 1);
|
||||
|
||||
label = elm_label_add(table);
|
||||
elm_object_text_set(label, _("Replace: "));
|
||||
evas_object_show(label);
|
||||
elm_table_pack(table, label, 0, 1, 1, 1);
|
||||
|
||||
replace = elm_entry_add(table);
|
||||
elm_entry_single_line_set(replace, EINA_TRUE);
|
||||
elm_entry_scrollable_set(replace, EINA_TRUE);
|
||||
evas_object_size_hint_weight_set(replace, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
evas_object_size_hint_align_set(replace, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
evas_object_show(replace);
|
||||
elm_table_pack(table, replace, 1, 1, 1, 1);
|
||||
|
||||
elm_box_pack_end(box, table);
|
||||
|
||||
sep = elm_separator_add(box);
|
||||
elm_separator_horizontal_set(sep, EINA_TRUE);
|
||||
evas_object_show(sep);
|
||||
elm_box_pack_end(box, sep);
|
||||
|
||||
button = elm_button_add(popup);
|
||||
elm_object_text_set(button, _("Cancel"));
|
||||
elm_object_part_content_set(popup, "button1", button);
|
||||
evas_object_smart_callback_add(button, "clicked",
|
||||
_edi_mainview_project_search_popup_cancel_cb, NULL);
|
||||
|
||||
button = elm_button_add(popup);
|
||||
evas_object_data_set(button, "search", search);
|
||||
elm_object_text_set(button, _("Replace"));
|
||||
elm_object_part_content_set(popup, "button2", button);
|
||||
evas_object_smart_callback_add(button, "clicked",
|
||||
_edi_mainview_project_replace_cb, replace);
|
||||
|
||||
evas_object_show(popup);
|
||||
}
|
||||
|
||||
void
|
||||
edi_mainview_panel_remove(Edi_Mainview_Panel *panel)
|
||||
{
|
||||
|
|
|
@ -237,6 +237,14 @@ void edi_mainview_goto_popup_show();
|
|||
*/
|
||||
void edi_mainview_project_search_popup_show();
|
||||
|
||||
|
||||
/**
|
||||
* Present a popup to initiate a project-wide search and replace.
|
||||
*
|
||||
* @ingroup Content
|
||||
*/
|
||||
void edi_mainview_project_replace_popup_show();
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue