2009-02-26 00:53:52 +03:00
/* editor high level editing commands
2001-08-24 22:23:17 +04:00
2007-09-25 19:33:35 +04:00
Copyright ( C ) 1996 , 1997 , 1998 , 2001 , 2002 , 2003 , 2004 , 2005 , 2006 ,
2007 Free Software Foundation , Inc .
2001-08-24 22:23:17 +04:00
Authors : 1996 , 1997 Paul Sheer
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
2005-05-27 07:35:10 +04:00
Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA
02110 - 1301 , USA .
2001-08-24 22:23:17 +04:00
*/
/* #define PIPE_BLOCKS_SO_READ_BYTE_BY_BYTE */
# include <config.h>
2005-09-07 12:54:11 +04:00
# include <assert.h>
2001-08-24 22:23:17 +04:00
# include <ctype.h>
2009-02-06 01:27:37 +03:00
2005-02-22 20:00:36 +03:00
# include <stdio.h>
# include <stdarg.h>
# include <sys/types.h>
# include <unistd.h>
# include <string.h>
# include <errno.h>
# include <sys/stat.h>
# include <stdlib.h>
# include "../src/global.h"
2009-01-24 23:51:29 +03:00
# include "../src/history.h"
2005-02-22 20:00:36 +03:00
2001-08-24 22:23:17 +04:00
# include "edit.h"
2003-04-02 23:36:10 +04:00
# include "editlock.h"
2001-08-24 22:23:17 +04:00
# include "editcmddef.h"
2002-11-29 06:01:06 +03:00
# include "edit-widget.h"
2009-04-29 17:13:12 +04:00
# include "editcmd_dialogs.h"
2009-03-02 17:43:22 +03:00
# include "../edit/etags.h"
2009-02-26 23:50:58 +03:00
# include "../src/panel.h"
2001-08-24 22:23:17 +04:00
2003-10-29 11:54:22 +03:00
# include "../src/tty.h" /* LINES */
# include "../src/widget.h" /* listbox_new() */
# include "../src/layout.h" /* clr_scr() */
2009-04-09 18:23:08 +04:00
# include "../src/main.h" /* mc_home source_codepage */
2003-10-29 11:54:22 +03:00
# include "../src/help.h" /* interactive_display() */
# include "../src/key.h" /* XCTRL */
# include "../src/wtools.h" /* message() */
# include "../src/charsets.h"
2005-07-20 15:56:30 +04:00
# include "../src/selcodepage.h"
2009-04-06 14:31:12 +04:00
# include "../src/strutil.h" /* utf string functions */
2001-08-24 22:23:17 +04:00
/* globals: */
/* search and replace: */
2003-10-15 01:48:40 +04:00
static int search_create_bookmark = 0 ;
2009-04-24 02:47:22 +04:00
/* static int search_in_all_charsets = 0; */
2001-08-24 22:23:17 +04:00
/* queries on a save */
int edit_confirm_save = 1 ;
2003-10-15 01:48:40 +04:00
static int edit_save_cmd ( WEdit * edit ) ;
static unsigned char * edit_get_block ( WEdit * edit , long start ,
long finish , int * l ) ;
2009-04-23 15:30:14 +04:00
static void
2009-04-24 02:47:22 +04:00
edit_search_cmd_search_create_bookmark ( WEdit * edit )
2001-08-24 22:23:17 +04:00
{
2009-04-23 15:30:14 +04:00
int found = 0 , books = 0 ;
int l = 0 , l_last = - 1 ;
long q = 0 ;
gsize len = 0 ;
2009-04-17 12:46:06 +04:00
2009-04-23 15:30:14 +04:00
for ( ; ; ) {
if ( ! mc_search_run ( edit - > search , ( void * ) edit , q , edit - > last_byte , & len ) )
break ;
found + + ;
l + = edit_count_lines ( edit , q , edit - > search - > normal_offset ) ;
if ( l ! = l_last ) {
book_mark_insert ( edit , l , BOOK_MARK_FOUND_COLOR ) ;
books + + ;
}
l_last = l ;
q = edit - > search - > normal_offset + 1 ;
}
2009-04-21 15:19:42 +04:00
2009-04-23 15:30:14 +04:00
if ( found ) {
/* in response to number of bookmarks added because of string being found %d times */
message ( D_NORMAL , _ ( " Search " ) , _ ( " %d items found, %d bookmarks added " ) , found , books ) ;
} else {
edit_error_dialog ( _ ( " Search " ) , _ ( " Search string not found " ) ) ;
}
2001-08-24 22:23:17 +04:00
}
2009-04-23 15:30:14 +04:00
static int
edit_search_cmd_callback ( const void * user_data , gsize char_offset )
2001-08-24 22:23:17 +04:00
{
2009-04-23 15:30:14 +04:00
return edit_get_byte ( ( WEdit * ) user_data , ( long ) char_offset ) ;
2001-08-24 22:23:17 +04:00
}
void edit_help_cmd ( WEdit * edit )
{
interactive_display ( NULL , " [Internal File Editor] " ) ;
edit - > force | = REDRAW_COMPLETELY ;
}
void edit_refresh_cmd ( WEdit * edit )
{
# ifndef HAVE_SLANG
clr_scr ( ) ;
do_refresh ( ) ;
# else
{
2002-07-14 21:56:47 +04:00
int color ;
edit_get_syntax_color ( edit , - 1 , & color ) ;
2001-08-24 22:23:17 +04:00
}
touchwin ( stdscr ) ;
2001-09-07 22:56:07 +04:00
# endif /* !HAVE_SLANG */
2001-08-24 22:23:17 +04:00
mc_refresh ( ) ;
doupdate ( ) ;
}
/* If 0 (quick save) then a) create/truncate <filename> file,
b ) save to < filename > ;
if 1 ( safe save ) then a ) save to < tempnam > ,
b ) rename < tempnam > to < filename > ;
if 2 ( do backups ) then a ) save to < tempnam > ,
b ) rename < filename > to < filename . backup_ext > ,
c ) rename < tempnam > to < filename > . */
2006-03-17 18:41:21 +03:00
/* returns 0 on error, -1 on abort */
2003-10-15 01:48:40 +04:00
static int
2002-12-15 21:55:53 +03:00
edit_save_file ( WEdit * edit , const char * filename )
2001-08-24 22:23:17 +04:00
{
char * p ;
2009-04-14 16:12:36 +04:00
gchar * tmp ;
2001-08-24 22:23:17 +04:00
long filelen = 0 ;
char * savename = 0 ;
2009-04-14 16:12:36 +04:00
gchar * real_filename ;
2006-03-17 18:41:21 +03:00
int this_save_mode , fd = - 1 ;
2001-08-24 22:23:17 +04:00
if ( ! filename )
return 0 ;
if ( ! * filename )
return 0 ;
2003-07-31 20:38:07 +04:00
if ( * filename ! = PATH_SEP & & edit - > dir ) {
2009-04-14 16:12:36 +04:00
real_filename = concat_dir_and_file ( edit - > dir , filename ) ;
} else {
real_filename = g_strdup ( filename ) ;
2003-07-31 20:38:07 +04:00
}
2006-03-17 18:41:21 +03:00
this_save_mode = option_save_mode ;
if ( this_save_mode ! = EDIT_QUICK_SAVE ) {
2009-04-14 16:12:36 +04:00
if ( ! vfs_file_is_local ( real_filename ) | |
( fd = mc_open ( real_filename , O_RDONLY | O_BINARY ) ) = = - 1 ) {
2006-03-17 18:41:21 +03:00
/*
* The file does not exists yet , so no safe save or
* backup are necessary .
*/
this_save_mode = EDIT_QUICK_SAVE ;
}
if ( fd ! = - 1 )
mc_close ( fd ) ;
}
if ( this_save_mode = = EDIT_QUICK_SAVE & &
! edit - > skip_detach_prompt ) {
int rv ;
struct stat sb ;
2009-04-14 16:12:36 +04:00
rv = mc_stat ( real_filename , & sb ) ;
2006-03-17 18:41:21 +03:00
if ( rv = = 0 & & sb . st_nlink > 1 ) {
rv = edit_query_dialog3 ( _ ( " Warning " ) ,
_ ( " File has hard-links. Detach before saving? " ) ,
_ ( " &Yes " ) , _ ( " &No " ) , _ ( " &Cancel " ) ) ;
switch ( rv ) {
case 0 :
this_save_mode = EDIT_SAFE_SAVE ;
/* fallthrough */
case 1 :
edit - > skip_detach_prompt = 1 ;
break ;
default :
2009-04-14 16:12:36 +04:00
g_free ( real_filename ) ;
2006-03-17 18:41:21 +03:00
return - 1 ;
}
}
2006-11-18 00:50:33 +03:00
/* Prevent overwriting changes from other editor sessions. */
if ( rv = = 0 & & edit - > stat1 . st_mtime ! = 0 & & edit - > stat1 . st_mtime ! = sb . st_mtime ) {
/* The default action is "Cancel". */
query_set_sel ( 1 ) ;
rv = edit_query_dialog2 (
_ ( " Warning " ) ,
_ ( " The file has been modified in the meantime. Save anyway? " ) ,
_ ( " &Yes " ) ,
_ ( " &Cancel " ) ) ;
2009-04-14 16:12:36 +04:00
if ( rv ! = 0 ) {
g_free ( real_filename ) ;
2006-11-18 00:50:33 +03:00
return - 1 ;
2009-04-14 16:12:36 +04:00
}
2006-11-18 00:50:33 +03:00
}
2001-08-24 22:23:17 +04:00
}
2002-12-18 23:04:39 +03:00
if ( this_save_mode ! = EDIT_QUICK_SAVE ) {
2004-08-30 03:27:40 +04:00
char * savedir , * saveprefix ;
const char * slashpos ;
2009-04-14 16:12:36 +04:00
slashpos = strrchr ( real_filename , PATH_SEP ) ;
2001-08-24 22:23:17 +04:00
if ( slashpos ) {
2009-04-14 16:12:36 +04:00
savedir = g_strdup ( real_filename ) ;
savedir [ slashpos - real_filename + 1 ] = ' \0 ' ;
2001-12-22 20:29:46 +03:00
} else
2009-02-06 15:01:28 +03:00
savedir = g_strdup ( " . " ) ;
2009-02-06 13:17:03 +03:00
saveprefix = concat_dir_and_file ( savedir , " cooledit " ) ;
2009-02-06 01:27:37 +03:00
g_free ( savedir ) ;
2002-12-15 21:55:53 +03:00
fd = mc_mkstemps ( & savename , saveprefix , NULL ) ;
2009-02-06 01:27:37 +03:00
g_free ( saveprefix ) ;
2009-04-14 16:12:36 +04:00
if ( ! savename ) {
g_free ( real_filename ) ;
2001-08-24 22:23:17 +04:00
return 0 ;
2009-04-14 16:12:36 +04:00
}
2002-05-13 20:53:51 +04:00
/* FIXME:
2005-02-07 10:31:19 +03:00
* Close for now because mc_mkstemps use pure open system call
2002-05-13 20:53:51 +04:00
* to create temporary file and it needs to be reopened by
2002-09-23 11:00:30 +04:00
* VFS - aware mc_open ( ) .
2002-05-13 20:53:51 +04:00
*/
2001-08-24 22:23:17 +04:00
close ( fd ) ;
2001-11-19 10:31:32 +03:00
} else
2009-04-14 16:12:36 +04:00
savename = g_strdup ( real_filename ) ;
2001-08-24 22:23:17 +04:00
2002-05-13 21:12:45 +04:00
mc_chown ( savename , edit - > stat1 . st_uid , edit - > stat1 . st_gid ) ;
2002-11-06 21:09:40 +03:00
mc_chmod ( savename , edit - > stat1 . st_mode ) ;
2002-05-13 21:12:45 +04:00
2002-12-15 21:55:53 +03:00
if ( ( fd =
mc_open ( savename , O_CREAT | O_WRONLY | O_TRUNC | O_BINARY ,
edit - > stat1 . st_mode ) ) = = - 1 )
2001-08-24 22:23:17 +04:00
goto error_save ;
/* pipe save */
2009-04-14 16:12:36 +04:00
if ( ( p = edit_get_write_filter ( savename , real_filename ) ) ) {
2001-08-24 22:23:17 +04:00
FILE * file ;
2002-05-13 20:53:51 +04:00
mc_close ( fd ) ;
2002-12-15 21:55:53 +03:00
file = ( FILE * ) popen ( p , " w " ) ;
2001-08-24 22:23:17 +04:00
if ( file ) {
filelen = edit_write_stream ( edit , file ) ;
# if 1
pclose ( file ) ;
# else
if ( pclose ( file ) ! = 0 ) {
2009-04-14 16:12:36 +04:00
tmp = g_strconcat ( _ ( " Error writing to pipe: " ) ,
p , " " , ( char * ) NULL ) ;
edit_error_dialog ( _ ( " Error " ) , tmp ) ;
g_free ( tmp ) ;
2009-02-06 01:27:37 +03:00
g_free ( p ) ;
2001-08-24 22:23:17 +04:00
goto error_save ;
}
# endif
} else {
2009-04-14 16:12:36 +04:00
tmp = g_strconcat ( _ ( " Cannot open pipe for writing: " ) ,
p , " " , ( char * ) NULL ) ;
2002-12-15 21:55:53 +03:00
edit_error_dialog ( _ ( " Error " ) ,
2009-04-14 16:12:36 +04:00
get_sys_error ( tmp ) ) ;
2009-02-06 01:27:37 +03:00
g_free ( p ) ;
2009-04-14 16:12:36 +04:00
g_free ( tmp ) ;
2001-08-24 22:23:17 +04:00
goto error_save ;
}
2009-02-06 01:27:37 +03:00
g_free ( p ) ;
2001-08-24 22:23:17 +04:00
} else {
long buf ;
buf = 0 ;
filelen = edit - > last_byte ;
while ( buf < = ( edit - > curs1 > > S_EDIT_BUF_SIZE ) - 1 ) {
2002-12-15 21:55:53 +03:00
if ( mc_write ( fd , ( char * ) edit - > buffers1 [ buf ] , EDIT_BUF_SIZE )
! = EDIT_BUF_SIZE ) {
2002-05-13 20:53:51 +04:00
mc_close ( fd ) ;
2001-08-24 22:23:17 +04:00
goto error_save ;
}
buf + + ;
}
2002-12-15 21:55:53 +03:00
if ( mc_write
( fd , ( char * ) edit - > buffers1 [ buf ] ,
edit - > curs1 & M_EDIT_BUF_SIZE ) ! =
( edit - > curs1 & M_EDIT_BUF_SIZE ) ) {
2001-08-24 22:23:17 +04:00
filelen = - 1 ;
} else if ( edit - > curs2 ) {
edit - > curs2 - - ;
buf = ( edit - > curs2 > > S_EDIT_BUF_SIZE ) ;
2002-12-15 21:55:53 +03:00
if ( mc_write
( fd ,
( char * ) edit - > buffers2 [ buf ] + EDIT_BUF_SIZE -
( edit - > curs2 & M_EDIT_BUF_SIZE ) - 1 ,
1 + ( edit - > curs2 & M_EDIT_BUF_SIZE ) ) ! =
1 + ( edit - > curs2 & M_EDIT_BUF_SIZE ) ) {
2001-08-24 22:23:17 +04:00
filelen = - 1 ;
} else {
while ( - - buf > = 0 ) {
2002-12-15 21:55:53 +03:00
if ( mc_write
( fd , ( char * ) edit - > buffers2 [ buf ] ,
EDIT_BUF_SIZE ) ! = EDIT_BUF_SIZE ) {
2001-08-24 22:23:17 +04:00
filelen = - 1 ;
break ;
}
}
}
edit - > curs2 + + ;
}
2002-05-13 20:53:51 +04:00
if ( mc_close ( fd ) )
2001-08-24 22:23:17 +04:00
goto error_save ;
2006-11-18 00:50:33 +03:00
/* Update the file information, especially the mtime. */
if ( mc_stat ( savename , & edit - > stat1 ) = = - 1 )
goto error_save ;
2001-08-24 22:23:17 +04:00
}
if ( filelen ! = edit - > last_byte )
goto error_save ;
2005-09-07 12:54:11 +04:00
if ( this_save_mode = = EDIT_DO_BACKUP ) {
assert ( option_backup_ext ! = NULL ) ;
2009-04-14 16:12:36 +04:00
tmp = g_strconcat ( real_filename , option_backup_ext , ( char * ) NULL ) ;
if ( mc_rename ( real_filename , tmp ) = = - 1 ) {
g_free ( tmp ) ;
2001-08-24 22:23:17 +04:00
goto error_save ;
2009-04-14 16:12:36 +04:00
}
2005-09-07 12:54:11 +04:00
}
2002-12-18 23:04:39 +03:00
if ( this_save_mode ! = EDIT_QUICK_SAVE )
2009-04-14 16:12:36 +04:00
if ( mc_rename ( savename , real_filename ) = = - 1 )
2001-08-24 22:23:17 +04:00
goto error_save ;
2009-02-06 01:27:37 +03:00
g_free ( savename ) ;
2009-04-14 16:12:36 +04:00
g_free ( real_filename ) ;
2001-08-24 22:23:17 +04:00
return 1 ;
error_save :
2002-12-18 23:04:39 +03:00
/* FIXME: Is this safe ?
* if ( this_save_mode ! = EDIT_QUICK_SAVE )
* mc_unlink ( savename ) ;
*/
2009-04-14 16:12:36 +04:00
g_free ( real_filename ) ;
2009-02-06 01:27:37 +03:00
g_free ( savename ) ;
2001-08-24 22:23:17 +04:00
return 0 ;
}
void menu_save_mode_cmd ( void )
{
# define DLG_X 38
# define DLG_Y 10
static char * str_result ;
static int save_mode_new ;
2004-08-29 22:45:56 +04:00
static const char * str [ ] =
2001-08-24 22:23:17 +04:00
{
N_ ( " Quick save " ) ,
N_ ( " Safe save " ) ,
N_ ( " Do backups --> " ) } ;
2009-04-29 17:13:12 +04:00
2001-08-24 22:23:17 +04:00
static QuickWidget widgets [ ] =
{
{ quick_button , 18 , DLG_X , 7 , DLG_Y , N_ ( " &Cancel " ) , 0 ,
2009-04-29 17:13:12 +04:00
B_CANCEL , 0 , 0 , NULL , NULL , NULL } ,
2002-10-22 02:26:39 +04:00
{ quick_button , 6 , DLG_X , 7 , DLG_Y , N_ ( " &OK " ) , 0 ,
2009-04-29 17:13:12 +04:00
B_ENTER , 0 , 0 , NULL , NULL , NULL } ,
2001-08-24 22:23:17 +04:00
{ quick_input , 23 , DLG_X , 5 , DLG_Y , 0 , 9 ,
2009-04-29 17:13:12 +04:00
0 , 0 , & str_result , " edit-backup-ext " , NULL , NULL } ,
2001-08-24 22:23:17 +04:00
{ quick_label , 22 , DLG_X , 4 , DLG_Y , N_ ( " Extension: " ) , 0 ,
2009-04-29 17:13:12 +04:00
0 , 0 , 0 , NULL , NULL , NULL } ,
2001-08-24 22:23:17 +04:00
{ quick_radio , 4 , DLG_X , 3 , DLG_Y , " " , 3 ,
2009-04-29 17:13:12 +04:00
0 , & save_mode_new , ( char * * ) str , NULL , NULL , NULL } ,
2004-08-15 22:24:06 +04:00
NULL_QuickWidget } ;
2001-08-24 22:23:17 +04:00
static QuickDialog dialog =
{ DLG_X , DLG_Y , - 1 , - 1 , N_ ( " Edit Save Mode " ) , " [Edit Save Mode] " ,
2004-08-16 02:55:17 +04:00
widgets , 0 } ;
2001-08-24 22:23:17 +04:00
static int i18n_flag = 0 ;
if ( ! i18n_flag ) {
2004-08-16 07:12:05 +04:00
size_t i ;
size_t maxlen = 0 ;
2001-08-24 22:23:17 +04:00
int dlg_x ;
2004-08-16 07:12:05 +04:00
size_t l1 ;
2001-08-24 22:23:17 +04:00
2003-06-02 22:39:44 +04:00
/* OK/Cancel buttons */
2009-04-06 14:31:12 +04:00
l1 = str_term_width1 ( _ ( widgets [ 0 ] . text ) ) + str_term_width1 ( _ ( widgets [ 1 ] . text ) ) + 5 ;
2001-08-24 22:23:17 +04:00
maxlen = max ( maxlen , l1 ) ;
2005-02-07 10:31:19 +03:00
2001-08-24 22:23:17 +04:00
for ( i = 0 ; i < 3 ; i + + ) {
str [ i ] = _ ( str [ i ] ) ;
2009-04-24 02:47:22 +04:00
maxlen = max ( maxlen , ( size_t ) str_term_width1 ( str [ i ] ) + 7 ) ;
2001-08-24 22:23:17 +04:00
}
i18n_flag = 1 ;
2009-04-06 14:31:12 +04:00
dlg_x = maxlen + str_term_width1 ( _ ( widgets [ 3 ] . text ) ) + 5 + 1 ;
widgets [ 2 ] . hotkey_pos = str_term_width1 ( _ ( widgets [ 3 ] . text ) ) ; /* input field length */
2001-08-24 22:23:17 +04:00
dlg_x = min ( COLS , dlg_x ) ;
dialog . xlen = dlg_x ;
i = ( dlg_x - l1 ) / 3 ;
widgets [ 1 ] . relative_x = i ;
2009-04-06 14:31:12 +04:00
widgets [ 0 ] . relative_x = i + str_term_width1 ( _ ( widgets [ 1 ] . text ) ) + i + 4 ;
2001-08-24 22:23:17 +04:00
widgets [ 2 ] . relative_x = widgets [ 3 ] . relative_x = maxlen + 2 ;
for ( i = 0 ; i < sizeof ( widgets ) / sizeof ( widgets [ 0 ] ) ; i + + )
widgets [ i ] . x_divisions = dlg_x ;
}
2005-09-07 12:54:11 +04:00
assert ( option_backup_ext ! = NULL ) ;
2001-08-24 22:23:17 +04:00
widgets [ 2 ] . text = option_backup_ext ;
widgets [ 4 ] . value = option_save_mode ;
if ( quick_dialog ( & dialog ) ! = B_ENTER )
return ;
option_save_mode = save_mode_new ;
2005-09-07 12:54:11 +04:00
2009-02-06 01:27:37 +03:00
g_free ( option_backup_ext ) ;
2005-09-07 12:54:11 +04:00
option_backup_ext = str_result ;
str_result = NULL ;
2001-08-24 22:23:17 +04:00
}
2002-12-15 05:40:38 +03:00
void
edit_set_filename ( WEdit * edit , const char * f )
2001-08-24 22:23:17 +04:00
{
2009-02-06 01:27:37 +03:00
g_free ( edit - > filename ) ;
2002-12-15 05:40:38 +03:00
if ( ! f )
f = " " ;
2009-02-06 01:40:32 +03:00
edit - > filename = g_strdup ( f ) ;
2003-07-31 20:38:07 +04:00
if ( edit - > dir = = NULL & & * f ! = PATH_SEP )
# ifdef USE_VFS
2009-02-06 01:40:32 +03:00
edit - > dir = g_strdup ( vfs_get_current_dir ( ) ) ;
2003-07-31 20:38:07 +04:00
# else
edit - > dir = g_get_current_dir ( ) ;
# endif
2001-08-24 22:23:17 +04:00
}
2001-12-22 20:29:46 +03:00
/* Here we want to warn the users of overwriting an existing file,
but only if they have made a change to the filename */
2001-08-24 22:23:17 +04:00
/* returns 1 on success */
2002-11-30 21:49:20 +03:00
int
edit_save_as_cmd ( WEdit * edit )
2001-08-24 22:23:17 +04:00
{
2002-11-30 21:49:20 +03:00
/* This heads the 'Save As' dialog box */
2003-07-31 20:32:30 +04:00
char * exp ;
2003-04-02 23:36:10 +04:00
int save_lock = 0 ;
2001-08-24 22:23:17 +04:00
int different_filename = 0 ;
2009-01-24 23:51:29 +03:00
exp = input_expand_dialog (
_ ( " Save As " ) , _ ( " Enter file name: " ) , MC_HISTORY_EDIT_SAVE_AS , edit - > filename ) ;
2001-08-24 22:23:17 +04:00
edit_push_action ( edit , KEY_PRESS + edit - > start_display ) ;
if ( exp ) {
if ( ! * exp ) {
2009-02-06 01:27:37 +03:00
g_free ( exp ) ;
2001-08-24 22:23:17 +04:00
edit - > force | = REDRAW_COMPLETELY ;
return 0 ;
} else {
2006-03-17 13:24:50 +03:00
int rv ;
2002-11-30 22:50:51 +03:00
if ( strcmp ( edit - > filename , exp ) ) {
2001-08-24 22:23:17 +04:00
int file ;
different_filename = 1 ;
2002-11-30 21:49:20 +03:00
if ( ( file = mc_open ( exp , O_RDONLY | O_BINARY ) ) ! = - 1 ) {
/* the file exists */
2002-05-13 20:53:51 +04:00
mc_close ( file ) ;
2002-11-30 21:49:20 +03:00
/* Overwrite the current file or cancel the operation */
if ( edit_query_dialog2
( _ ( " Warning " ) ,
_ ( " A file already exists with this name. " ) ,
2004-09-02 02:40:45 +04:00
_ ( " &Overwrite " ) , _ ( " &Cancel " ) ) ) {
2001-08-24 22:23:17 +04:00
edit - > force | = REDRAW_COMPLETELY ;
2009-02-06 01:27:37 +03:00
g_free ( exp ) ;
2001-08-24 22:23:17 +04:00
return 0 ;
}
}
2003-04-02 23:36:10 +04:00
save_lock = edit_lock_file ( exp ) ;
} else {
/* filenames equal, check if already locked */
if ( ! edit - > locked & & ! edit - > delete_file )
save_lock = edit_lock_file ( exp ) ;
2001-08-24 22:23:17 +04:00
}
2005-02-07 10:31:19 +03:00
2006-03-17 13:24:50 +03:00
rv = edit_save_file ( edit , exp ) ;
switch ( rv ) {
case 1 :
2003-04-02 23:36:10 +04:00
/* Succesful, so unlock both files */
2006-03-17 13:24:50 +03:00
if ( different_filename ) {
2003-04-02 23:36:10 +04:00
if ( save_lock )
edit_unlock_file ( exp ) ;
if ( edit - > locked )
edit - > locked = edit_unlock_file ( edit - > filename ) ;
} else {
if ( edit - > locked | | save_lock )
edit - > locked = edit_unlock_file ( edit - > filename ) ;
}
2005-02-07 10:31:19 +03:00
2002-12-15 05:40:38 +03:00
edit_set_filename ( edit , exp ) ;
2009-02-06 01:27:37 +03:00
g_free ( exp ) ;
2001-08-24 22:23:17 +04:00
edit - > modified = 0 ;
2002-11-30 21:49:20 +03:00
edit - > delete_file = 0 ;
2003-07-09 03:58:36 +04:00
if ( different_filename )
2005-07-24 17:37:58 +04:00
edit_load_syntax ( edit , NULL , option_syntax_type ) ;
2001-08-24 22:23:17 +04:00
edit - > force | = REDRAW_COMPLETELY ;
return 1 ;
2006-03-17 13:24:50 +03:00
default :
2006-03-17 18:41:21 +03:00
edit_error_dialog ( _ ( " Save As " ) ,
get_sys_error ( _
( " Cannot save file. " ) ) ) ;
/* fallthrough */
case - 1 :
2003-04-02 23:36:10 +04:00
/* Failed, so maintain modify (not save) lock */
if ( save_lock )
2006-03-17 13:24:50 +03:00
edit_unlock_file ( exp ) ;
2009-02-06 01:27:37 +03:00
g_free ( exp ) ;
2001-08-24 22:23:17 +04:00
edit - > force | = REDRAW_COMPLETELY ;
return 0 ;
}
}
}
edit - > force | = REDRAW_COMPLETELY ;
return 0 ;
}
/* {{{ Macro stuff starts here */
/* creates a macro file if it doesn't exist */
static FILE * edit_open_macro_file ( const char * r )
{
2009-04-14 16:12:36 +04:00
gchar * filename ;
FILE * fd ;
2001-08-24 22:23:17 +04:00
int file ;
2009-04-14 16:12:36 +04:00
filename = g_strconcat ( home_dir , PATH_SEP_STR MACRO_FILE , ( char * ) NULL ) ;
if ( ( file = open ( filename , O_CREAT | O_RDWR , S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ) ) = = - 1 ) {
g_free ( filename ) ;
2001-08-24 22:23:17 +04:00
return 0 ;
2009-04-14 16:12:36 +04:00
}
2001-08-24 22:23:17 +04:00
close ( file ) ;
2009-04-14 16:12:36 +04:00
fd = fopen ( filename , r ) ;
g_free ( filename ) ;
return fd ;
2001-08-24 22:23:17 +04:00
}
# define MAX_MACROS 1024
2001-11-19 10:31:32 +03:00
static int saved_macro [ MAX_MACROS + 1 ] ;
2001-08-24 22:23:17 +04:00
static int saved_macros_loaded = 0 ;
/*
This is just to stop the macro file be loaded over and over for keys
that aren ' t defined to anything . On slow systems this could be annoying .
*/
2002-11-13 07:32:00 +03:00
static int
macro_exists ( int k )
2001-08-24 22:23:17 +04:00
{
int i ;
for ( i = 0 ; i < MAX_MACROS & & saved_macro [ i ] ; i + + )
if ( saved_macro [ i ] = = k )
return i ;
return - 1 ;
}
/* returns 1 on error */
2002-11-13 07:32:00 +03:00
static int
edit_delete_macro ( WEdit * edit , int k )
2001-08-24 22:23:17 +04:00
{
2009-04-14 16:12:36 +04:00
gchar * tmp , * tmp2 ;
2001-08-24 22:23:17 +04:00
struct macro macro [ MAX_MACRO_LENGTH ] ;
FILE * f , * g ;
int s , i , n , j = 0 ;
2005-02-08 20:14:34 +03:00
( void ) edit ;
2001-08-24 22:23:17 +04:00
if ( saved_macros_loaded )
if ( ( j = macro_exists ( k ) ) < 0 )
return 0 ;
2009-04-14 16:12:36 +04:00
tmp = g_strconcat ( home_dir , PATH_SEP_STR TEMP_FILE , ( char * ) NULL ) ;
g = fopen ( tmp , " w " ) ;
g_free ( tmp ) ;
2001-08-24 22:23:17 +04:00
if ( ! g ) {
edit_error_dialog ( _ ( " Delete macro " ) ,
2002-12-08 12:27:18 +03:00
get_sys_error ( _ ( " Cannot open temp file " ) ) ) ;
2001-08-24 22:23:17 +04:00
return 1 ;
}
f = edit_open_macro_file ( " r " ) ;
if ( ! f ) {
edit_error_dialog ( _ ( " Delete macro " ) ,
2002-12-08 12:27:18 +03:00
get_sys_error ( _ ( " Cannot open macro file " ) ) ) ;
2001-08-24 22:23:17 +04:00
fclose ( g ) ;
return 1 ;
}
for ( ; ; ) {
n = fscanf ( f , ( " key '%d 0': " ) , & s ) ;
if ( ! n | | n = = EOF )
break ;
n = 0 ;
while ( fscanf ( f , " %hd %hd, " , & macro [ n ] . command , & macro [ n ] . ch ) )
n + + ;
fscanf ( f , " ; \n " ) ;
if ( s ! = k ) {
fprintf ( g , ( " key '%d 0': " ) , s ) ;
for ( i = 0 ; i < n ; i + + )
fprintf ( g , " %hd %hd, " , macro [ i ] . command , macro [ i ] . ch ) ;
fprintf ( g , " ; \n " ) ;
}
}
fclose ( f ) ;
fclose ( g ) ;
2009-04-14 16:12:36 +04:00
tmp = g_strconcat ( home_dir , PATH_SEP_STR TEMP_FILE , ( char * ) NULL ) ;
tmp2 = g_strconcat ( home_dir , PATH_SEP_STR MACRO_FILE , ( char * ) NULL ) ;
if ( rename ( tmp , tmp2 ) = = - 1 ) {
2001-08-24 22:23:17 +04:00
edit_error_dialog ( _ ( " Delete macro " ) ,
2002-12-08 12:27:18 +03:00
get_sys_error ( _ ( " Cannot overwrite macro file " ) ) ) ;
2009-04-14 16:12:36 +04:00
g_free ( tmp ) ;
g_free ( tmp2 ) ;
2001-08-24 22:23:17 +04:00
return 1 ;
}
2009-04-14 16:12:36 +04:00
g_free ( tmp ) ;
g_free ( tmp2 ) ;
2001-08-24 22:23:17 +04:00
if ( saved_macros_loaded )
memmove ( saved_macro + j , saved_macro + j + 1 , sizeof ( int ) * ( MAX_MACROS - j - 1 ) ) ;
return 0 ;
}
/* returns 0 on error */
int edit_save_macro_cmd ( WEdit * edit , struct macro macro [ ] , int n )
{
FILE * f ;
int s , i ;
edit_push_action ( edit , KEY_PRESS + edit - > start_display ) ;
2009-04-29 17:13:12 +04:00
s = editcmd_dialog_raw_key_query ( _ ( " Save macro " ) ,
2005-02-07 23:08:01 +03:00
_ ( " Press the macro's new hotkey: " ) , 1 ) ;
2001-08-24 22:23:17 +04:00
edit - > force | = REDRAW_COMPLETELY ;
if ( s ) {
if ( edit_delete_macro ( edit , s ) )
return 0 ;
f = edit_open_macro_file ( " a+ " ) ;
if ( f ) {
fprintf ( f , ( " key '%d 0': " ) , s ) ;
for ( i = 0 ; i < n ; i + + )
fprintf ( f , " %hd %hd, " , macro [ i ] . command , macro [ i ] . ch ) ;
fprintf ( f , " ; \n " ) ;
fclose ( f ) ;
if ( saved_macros_loaded ) {
for ( i = 0 ; i < MAX_MACROS & & saved_macro [ i ] ; i + + ) ;
saved_macro [ i ] = s ;
}
return 1 ;
} else
2002-12-08 12:27:18 +03:00
edit_error_dialog ( _ ( " Save macro " ) , get_sys_error ( _ ( " Cannot open macro file " ) ) ) ;
2001-08-24 22:23:17 +04:00
}
return 0 ;
}
void edit_delete_macro_cmd ( WEdit * edit )
{
int command ;
2009-04-29 17:13:12 +04:00
command = editcmd_dialog_raw_key_query ( _ ( " Delete macro " ) ,
2001-08-24 22:23:17 +04:00
_ ( " Press macro hotkey: " ) , 1 ) ;
if ( ! command )
return ;
edit_delete_macro ( edit , command ) ;
}
/* return 0 on error */
int edit_load_macro_cmd ( WEdit * edit , struct macro macro [ ] , int * n , int k )
{
FILE * f ;
int s , i = 0 , found = 0 ;
2005-02-08 20:14:34 +03:00
( void ) edit ;
2001-08-24 22:23:17 +04:00
if ( saved_macros_loaded )
if ( macro_exists ( k ) < 0 )
return 0 ;
if ( ( f = edit_open_macro_file ( " r " ) ) ) {
struct macro dummy ;
do {
int u ;
u = fscanf ( f , ( " key '%d 0': " ) , & s ) ;
if ( ! u | | u = = EOF )
break ;
if ( ! saved_macros_loaded )
saved_macro [ i + + ] = s ;
if ( ! found ) {
* n = 0 ;
while ( * n < MAX_MACRO_LENGTH & & 2 = = fscanf ( f , " %hd %hd, " , & macro [ * n ] . command , & macro [ * n ] . ch ) )
( * n ) + + ;
} else {
while ( 2 = = fscanf ( f , " %hd %hd, " , & dummy . command , & dummy . ch ) ) ;
}
fscanf ( f , " ; \n " ) ;
if ( s = = k )
found = 1 ;
} while ( ! found | | ! saved_macros_loaded ) ;
if ( ! saved_macros_loaded ) {
saved_macro [ i ] = 0 ;
saved_macros_loaded = 1 ;
}
fclose ( f ) ;
return found ;
} else
edit_error_dialog ( _ ( " Load macro " ) ,
2002-12-08 12:27:18 +03:00
get_sys_error ( _ ( " Cannot open macro file " ) ) ) ;
2001-08-24 22:23:17 +04:00
return 0 ;
}
/* }}} Macro stuff starts here */
/* returns 1 on success */
int edit_save_confirm_cmd ( WEdit * edit )
{
2009-04-15 00:41:41 +04:00
gchar * f = NULL ;
2001-08-24 22:23:17 +04:00
if ( edit_confirm_save ) {
2009-04-14 16:12:36 +04:00
f = g_strconcat ( _ ( " Confirm save file? : " ) , edit - > filename , " " , NULL ) ;
if ( edit_query_dialog2 ( _ ( " Save file " ) , f , _ ( " &Save " ) , _ ( " &Cancel " ) ) ) {
g_free ( f ) ;
2001-08-24 22:23:17 +04:00
return 0 ;
2009-04-14 16:12:36 +04:00
}
2009-04-15 00:41:41 +04:00
g_free ( f ) ;
2001-08-24 22:23:17 +04:00
}
return edit_save_cmd ( edit ) ;
}
/* returns 1 on success */
2003-10-15 01:48:40 +04:00
static int
edit_save_cmd ( WEdit * edit )
2001-08-24 22:23:17 +04:00
{
2003-04-02 23:36:10 +04:00
int res , save_lock = 0 ;
2005-02-07 10:31:19 +03:00
2003-04-02 23:36:10 +04:00
if ( ! edit - > locked & & ! edit - > delete_file )
save_lock = edit_lock_file ( edit - > filename ) ;
res = edit_save_file ( edit , edit - > filename ) ;
2005-02-07 10:31:19 +03:00
2003-04-02 23:36:10 +04:00
/* Maintain modify (not save) lock on failure */
2006-03-17 18:41:21 +03:00
if ( ( res > 0 & & edit - > locked ) | | save_lock )
2003-04-02 23:36:10 +04:00
edit - > locked = edit_unlock_file ( edit - > filename ) ;
2005-02-07 10:31:19 +03:00
2003-04-02 23:36:10 +04:00
/* On failure try 'save as', it does locking on its own */
2005-02-07 10:31:19 +03:00
if ( ! res )
2001-08-24 22:23:17 +04:00
return edit_save_as_cmd ( edit ) ;
edit - > force | = REDRAW_COMPLETELY ;
2006-03-17 18:41:21 +03:00
if ( res > 0 ) {
edit - > delete_file = 0 ;
edit - > modified = 0 ;
}
2001-08-24 22:23:17 +04:00
return 1 ;
}
/* returns 1 on success */
int edit_new_cmd ( WEdit * edit )
{
if ( edit - > modified ) {
2004-09-02 02:40:45 +04:00
if ( edit_query_dialog2 ( _ ( " Warning " ) , _ ( " Current text was modified without a file save. \n Continue discards these changes. " ) , _ ( " C&ontinue " ) , _ ( " &Cancel " ) ) ) {
2001-08-24 22:23:17 +04:00
edit - > force | = REDRAW_COMPLETELY ;
return 0 ;
}
}
edit - > force | = REDRAW_COMPLETELY ;
2003-04-02 23:36:10 +04:00
2001-08-24 22:23:17 +04:00
return edit_renew ( edit ) ; /* if this gives an error, something has really screwed up */
}
/* returns 1 on error */
2002-11-13 07:32:00 +03:00
static int
edit_load_file_from_filename ( WEdit * edit , char * exp )
2001-08-24 22:23:17 +04:00
{
2003-04-02 23:36:10 +04:00
int prev_locked = edit - > locked ;
2009-02-06 01:40:32 +03:00
char * prev_filename = g_strdup ( edit - > filename ) ;
2005-02-07 10:31:19 +03:00
2003-04-02 23:36:10 +04:00
if ( ! edit_reload ( edit , exp ) ) {
2009-02-06 01:27:37 +03:00
g_free ( prev_filename ) ;
2001-08-24 22:23:17 +04:00
return 1 ;
2003-04-02 23:36:10 +04:00
}
if ( prev_locked )
edit_unlock_file ( prev_filename ) ;
2009-02-06 01:27:37 +03:00
g_free ( prev_filename ) ;
2001-08-24 22:23:17 +04:00
return 0 ;
}
2002-11-30 21:49:20 +03:00
int
edit_load_cmd ( WEdit * edit )
2001-08-24 22:23:17 +04:00
{
char * exp ;
if ( edit - > modified ) {
2002-11-30 21:49:20 +03:00
if ( edit_query_dialog2
( _ ( " Warning " ) ,
_ ( " Current text was modified without a file save. \n "
2004-09-02 02:40:45 +04:00
" Continue discards these changes. " ) , _ ( " C&ontinue " ) ,
_ ( " &Cancel " ) ) ) {
2001-08-24 22:23:17 +04:00
edit - > force | = REDRAW_COMPLETELY ;
return 0 ;
}
}
2009-01-14 03:01:18 +03:00
exp = input_expand_dialog ( _ ( " Load " ) , _ ( " Enter file name: " ) ,
2009-01-24 23:51:29 +03:00
MC_HISTORY_EDIT_LOAD , edit - > filename ) ;
2001-08-24 22:23:17 +04:00
if ( exp ) {
if ( * exp )
edit_load_file_from_filename ( edit , exp ) ;
2009-02-06 01:27:37 +03:00
g_free ( exp ) ;
2001-08-24 22:23:17 +04:00
}
edit - > force | = REDRAW_COMPLETELY ;
return 0 ;
}
/*
if mark2 is - 1 then marking is from mark1 to the cursor .
Otherwise its between the markers . This handles this .
Returns 1 if no text is marked .
*/
int eval_marks ( WEdit * edit , long * start_mark , long * end_mark )
{
if ( edit - > mark1 ! = edit - > mark2 ) {
if ( edit - > mark2 > = 0 ) {
* start_mark = min ( edit - > mark1 , edit - > mark2 ) ;
* end_mark = max ( edit - > mark1 , edit - > mark2 ) ;
} else {
* start_mark = min ( edit - > mark1 , edit - > curs1 ) ;
* end_mark = max ( edit - > mark1 , edit - > curs1 ) ;
edit - > column2 = edit - > curs_col ;
}
return 0 ;
} else {
* start_mark = * end_mark = 0 ;
edit - > column2 = edit - > column1 = 0 ;
return 1 ;
}
}
# define space_width 1
2002-11-13 07:32:00 +03:00
static void
edit_insert_column_of_text ( WEdit * edit , unsigned char * data , int size , int width )
2001-08-24 22:23:17 +04:00
{
long cursor ;
int i , col ;
cursor = edit - > curs1 ;
col = edit_get_col ( edit ) ;
for ( i = 0 ; i < size ; i + + ) {
if ( data [ i ] = = ' \n ' ) { /* fill in and move to next line */
int l ;
long p ;
if ( edit_get_byte ( edit , edit - > curs1 ) ! = ' \n ' ) {
l = width - ( edit_get_col ( edit ) - col ) ;
while ( l > 0 ) {
edit_insert ( edit , ' ' ) ;
l - = space_width ;
}
}
for ( p = edit - > curs1 ; ; p + + ) {
2002-10-02 19:44:35 +04:00
if ( p = = edit - > last_byte ) {
edit_cursor_move ( edit , edit - > last_byte - edit - > curs1 ) ;
2001-08-24 22:23:17 +04:00
edit_insert_ahead ( edit , ' \n ' ) ;
2002-10-02 19:44:35 +04:00
p + + ;
break ;
}
2001-08-24 22:23:17 +04:00
if ( edit_get_byte ( edit , p ) = = ' \n ' ) {
p + + ;
break ;
}
}
edit_cursor_move ( edit , edit_move_forward3 ( edit , p , col , 0 ) - edit - > curs1 ) ;
l = col - edit_get_col ( edit ) ;
while ( l > = space_width ) {
edit_insert ( edit , ' ' ) ;
l - = space_width ;
}
continue ;
}
edit_insert ( edit , data [ i ] ) ;
}
edit_cursor_move ( edit , cursor - edit - > curs1 ) ;
}
2002-12-15 21:55:53 +03:00
void
edit_block_copy_cmd ( WEdit * edit )
2001-08-24 22:23:17 +04:00
{
long start_mark , end_mark , current = edit - > curs1 ;
2006-01-27 18:00:59 +03:00
int size ;
2001-08-24 22:23:17 +04:00
unsigned char * copy_buf ;
edit_update_curs_col ( edit ) ;
if ( eval_marks ( edit , & start_mark , & end_mark ) )
return ;
copy_buf = edit_get_block ( edit , start_mark , end_mark , & size ) ;
2002-12-15 21:55:53 +03:00
/* all that gets pushed are deletes hence little space is used on the stack */
2001-08-24 22:23:17 +04:00
edit_push_markers ( edit ) ;
if ( column_highlighting ) {
2002-12-15 21:55:53 +03:00
edit_insert_column_of_text ( edit , copy_buf , size ,
abs ( edit - > column2 - edit - > column1 ) ) ;
2001-08-24 22:23:17 +04:00
} else {
while ( size - - )
edit_insert_ahead ( edit , copy_buf [ size ] ) ;
}
2009-02-06 01:27:37 +03:00
g_free ( copy_buf ) ;
2001-08-24 22:23:17 +04:00
edit_scroll_screen_over_cursor ( edit ) ;
if ( column_highlighting ) {
edit_set_markers ( edit , 0 , 0 , 0 , 0 ) ;
edit_push_action ( edit , COLUMN_ON ) ;
column_highlighting = 0 ;
} else if ( start_mark < current & & end_mark > current )
2002-12-15 21:55:53 +03:00
edit_set_markers ( edit , start_mark ,
end_mark + end_mark - start_mark , 0 , 0 ) ;
2001-08-24 22:23:17 +04:00
edit - > force | = REDRAW_PAGE ;
}
2002-12-15 21:55:53 +03:00
void
edit_block_move_cmd ( WEdit * edit )
2001-08-24 22:23:17 +04:00
{
long count ;
long current ;
unsigned char * copy_buf ;
long start_mark , end_mark ;
int deleted = 0 ;
int x = 0 ;
if ( eval_marks ( edit , & start_mark , & end_mark ) )
return ;
if ( column_highlighting ) {
edit_update_curs_col ( edit ) ;
x = edit - > curs_col ;
if ( start_mark < = edit - > curs1 & & end_mark > = edit - > curs1 )
2002-12-15 21:55:53 +03:00
if ( ( x > edit - > column1 & & x < edit - > column2 )
| | ( x > edit - > column2 & & x < edit - > column1 ) )
2001-08-24 22:23:17 +04:00
return ;
} else if ( start_mark < = edit - > curs1 & & end_mark > = edit - > curs1 )
return ;
if ( ( end_mark - start_mark ) > option_max_undo / 2 )
2002-12-15 21:55:53 +03:00
if ( edit_query_dialog2
( _ ( " Warning " ) ,
_
( " Block is large, you may not be able to undo this action. " ) ,
2004-09-02 02:40:45 +04:00
_ ( " C&ontinue " ) , _ ( " &Cancel " ) ) )
2001-08-24 22:23:17 +04:00
return ;
edit_push_markers ( edit ) ;
current = edit - > curs1 ;
if ( column_highlighting ) {
int size , c1 , c2 , line ;
line = edit - > curs_line ;
if ( edit - > mark2 < 0 )
edit_mark_cmd ( edit , 0 ) ;
c1 = min ( edit - > column1 , edit - > column2 ) ;
c2 = max ( edit - > column1 , edit - > column2 ) ;
copy_buf = edit_get_block ( edit , start_mark , end_mark , & size ) ;
if ( x < c2 ) {
edit_block_delete_cmd ( edit ) ;
deleted = 1 ;
}
edit_move_to_line ( edit , line ) ;
2002-12-15 21:55:53 +03:00
edit_cursor_move ( edit ,
edit_move_forward3 ( edit ,
edit_bol ( edit , edit - > curs1 ) ,
x , 0 ) - edit - > curs1 ) ;
2001-08-24 22:23:17 +04:00
edit_insert_column_of_text ( edit , copy_buf , size , c2 - c1 ) ;
if ( ! deleted ) {
line = edit - > curs_line ;
edit_update_curs_col ( edit ) ;
x = edit - > curs_col ;
edit_block_delete_cmd ( edit ) ;
edit_move_to_line ( edit , line ) ;
2002-12-15 21:55:53 +03:00
edit_cursor_move ( edit ,
edit_move_forward3 ( edit ,
edit_bol ( edit ,
edit - > curs1 ) ,
x , 0 ) - edit - > curs1 ) ;
2001-08-24 22:23:17 +04:00
}
edit_set_markers ( edit , 0 , 0 , 0 , 0 ) ;
edit_push_action ( edit , COLUMN_ON ) ;
column_highlighting = 0 ;
} else {
2002-12-15 21:55:53 +03:00
copy_buf = g_malloc ( end_mark - start_mark ) ;
2001-08-24 22:23:17 +04:00
edit_cursor_move ( edit , start_mark - edit - > curs1 ) ;
edit_scroll_screen_over_cursor ( edit ) ;
count = start_mark ;
while ( count < end_mark ) {
2009-04-22 02:32:30 +04:00
copy_buf [ end_mark - count - 1 ] = edit_delete ( edit , 1 ) ;
2001-08-24 22:23:17 +04:00
count + + ;
}
edit_scroll_screen_over_cursor ( edit ) ;
2002-12-15 21:55:53 +03:00
edit_cursor_move ( edit ,
current - edit - > curs1 -
( ( ( current - edit - > curs1 ) >
0 ) ? end_mark - start_mark : 0 ) ) ;
2001-08-24 22:23:17 +04:00
edit_scroll_screen_over_cursor ( edit ) ;
while ( count - - > start_mark )
edit_insert_ahead ( edit , copy_buf [ end_mark - count - 1 ] ) ;
2002-12-15 21:55:53 +03:00
edit_set_markers ( edit , edit - > curs1 ,
edit - > curs1 + end_mark - start_mark , 0 , 0 ) ;
2001-08-24 22:23:17 +04:00
}
edit_scroll_screen_over_cursor ( edit ) ;
2009-02-06 01:27:37 +03:00
g_free ( copy_buf ) ;
2001-08-24 22:23:17 +04:00
edit - > force | = REDRAW_PAGE ;
}
2002-11-13 07:32:00 +03:00
static void
edit_delete_column_of_text ( WEdit * edit )
2001-08-24 22:23:17 +04:00
{
long p , q , r , m1 , m2 ;
int b , c , d ;
int n ;
eval_marks ( edit , & m1 , & m2 ) ;
n = edit_move_forward ( edit , m1 , 0 , m2 ) + 1 ;
c = edit_move_forward3 ( edit , edit_bol ( edit , m1 ) , 0 , m1 ) ;
d = edit_move_forward3 ( edit , edit_bol ( edit , m2 ) , 0 , m2 ) ;
b = min ( c , d ) ;
c = max ( c , d ) ;
while ( n - - ) {
r = edit_bol ( edit , edit - > curs1 ) ;
p = edit_move_forward3 ( edit , r , b , 0 ) ;
q = edit_move_forward3 ( edit , r , c , 0 ) ;
if ( p < m1 )
p = m1 ;
if ( q > m2 )
q = m2 ;
edit_cursor_move ( edit , p - edit - > curs1 ) ;
while ( q > p ) { /* delete line between margins */
if ( edit_get_byte ( edit , edit - > curs1 ) ! = ' \n ' )
2009-04-22 02:32:30 +04:00
edit_delete ( edit , 1 ) ;
2001-08-24 22:23:17 +04:00
q - - ;
}
if ( n ) /* move to next line except on the last delete */
edit_cursor_move ( edit , edit_move_forward ( edit , edit - > curs1 , 1 , 0 ) - edit - > curs1 ) ;
}
}
/* if success return 0 */
2003-10-15 01:48:40 +04:00
static int
2002-10-21 09:03:01 +04:00
edit_block_delete ( WEdit * edit )
2001-08-24 22:23:17 +04:00
{
long count ;
long start_mark , end_mark ;
if ( eval_marks ( edit , & start_mark , & end_mark ) )
return 0 ;
if ( column_highlighting & & edit - > mark2 < 0 )
edit_mark_cmd ( edit , 0 ) ;
2002-10-21 09:03:01 +04:00
if ( ( end_mark - start_mark ) > option_max_undo / 2 ) {
/* Warning message with a query to continue or cancel the operation */
if ( edit_query_dialog2
( _ ( " Warning " ) ,
_
( " Block is large, you may not be able to undo this action. " ) ,
2004-09-02 02:40:45 +04:00
_ ( " C&ontinue " ) , _ ( " &Cancel " ) ) ) {
2001-08-24 22:23:17 +04:00
return 1 ;
2002-10-21 09:03:01 +04:00
}
}
2001-08-24 22:23:17 +04:00
edit_push_markers ( edit ) ;
edit_cursor_move ( edit , start_mark - edit - > curs1 ) ;
edit_scroll_screen_over_cursor ( edit ) ;
count = start_mark ;
if ( start_mark < end_mark ) {
if ( column_highlighting ) {
if ( edit - > mark2 < 0 )
edit_mark_cmd ( edit , 0 ) ;
edit_delete_column_of_text ( edit ) ;
} else {
while ( count < end_mark ) {
2009-04-22 02:32:30 +04:00
edit_delete ( edit , 1 ) ;
2001-08-24 22:23:17 +04:00
count + + ;
}
}
}
edit_set_markers ( edit , 0 , 0 , 0 , 0 ) ;
edit - > force | = REDRAW_PAGE ;
return 0 ;
}
/* returns 1 if canceelled by user */
int edit_block_delete_cmd ( WEdit * edit )
{
long start_mark , end_mark ;
if ( eval_marks ( edit , & start_mark , & end_mark ) ) {
edit_delete_line ( edit ) ;
return 0 ;
}
return edit_block_delete ( edit ) ;
}
# define INPUT_INDEX 9
# define CONFIRM_DLG_WIDTH 79
# define CONFIRM_DLG_HEIGTH 6
2003-09-11 01:33:12 +04:00
# define B_REPLACE_ALL (B_USER+1)
# define B_REPLACE_ONE (B_USER+2)
# define B_SKIP_REPLACE (B_USER+3)
2001-08-24 22:23:17 +04:00
2002-11-13 07:32:00 +03:00
static int
edit_replace_prompt ( WEdit * edit , char * replace_text , int xpos , int ypos )
2001-08-24 22:23:17 +04:00
{
QuickWidget quick_widgets [ ] =
{
{ quick_button , 63 , CONFIRM_DLG_WIDTH , 3 , CONFIRM_DLG_HEIGTH , N_ ( " &Cancel " ) ,
2009-04-29 17:13:12 +04:00
0 , B_CANCEL , 0 , 0 , NULL , NULL , NULL } ,
2002-10-22 02:26:39 +04:00
{ quick_button , 50 , CONFIRM_DLG_WIDTH , 3 , CONFIRM_DLG_HEIGTH , N_ ( " O&ne " ) ,
2009-04-29 17:13:12 +04:00
0 , B_REPLACE_ONE , 0 , 0 , NULL , NULL , NULL } ,
2002-10-22 02:26:39 +04:00
{ quick_button , 37 , CONFIRM_DLG_WIDTH , 3 , CONFIRM_DLG_HEIGTH , N_ ( " A&ll " ) ,
2009-04-29 17:13:12 +04:00
0 , B_REPLACE_ALL , 0 , 0 , NULL , NULL , NULL } ,
2001-08-24 22:23:17 +04:00
{ quick_button , 21 , CONFIRM_DLG_WIDTH , 3 , CONFIRM_DLG_HEIGTH , N_ ( " &Skip " ) ,
2009-04-29 17:13:12 +04:00
0 , B_SKIP_REPLACE , 0 , 0 , NULL , NULL , NULL } ,
2001-08-24 22:23:17 +04:00
{ quick_button , 4 , CONFIRM_DLG_WIDTH , 3 , CONFIRM_DLG_HEIGTH , N_ ( " &Replace " ) ,
2009-04-29 17:13:12 +04:00
0 , B_ENTER , 0 , 0 , NULL , NULL , NULL } ,
2001-08-24 22:23:17 +04:00
{ quick_label , 2 , CONFIRM_DLG_WIDTH , 2 , CONFIRM_DLG_HEIGTH , 0 ,
2009-04-29 17:13:12 +04:00
0 , 0 , 0 , 0 , 0 , NULL , NULL } ,
2004-08-15 22:24:06 +04:00
NULL_QuickWidget } ;
2001-08-24 22:23:17 +04:00
2009-02-06 01:22:08 +03:00
GString * label_text = g_string_new ( _ ( " Replace with: " ) ) ;
if ( * replace_text ) {
size_t label_len ;
label_len = label_text - > len ;
g_string_append ( label_text , replace_text ) ;
2009-04-23 18:46:38 +04:00
g_string_append ( label_text , " ? " ) ;
2004-09-17 07:07:37 +04:00
}
2009-02-06 01:22:08 +03:00
quick_widgets [ 5 ] . text = label_text - > str ;
2001-08-24 22:23:17 +04:00
{
2005-02-07 23:32:17 +03:00
int retval ;
2001-08-24 22:23:17 +04:00
QuickDialog Quick_input =
{ CONFIRM_DLG_WIDTH , CONFIRM_DLG_HEIGTH , 0 , 0 , N_ ( " Confirm replace " ) ,
2004-08-16 02:55:17 +04:00
" [Input Line Keys] " , 0 /*quick_widgets */ , 0 } ;
2001-08-24 22:23:17 +04:00
Quick_input . widgets = quick_widgets ;
Quick_input . xpos = xpos ;
/* Sometimes menu can hide replaced text. I don't like it */
if ( ( edit - > curs_row > = ypos - 1 ) & & ( edit - > curs_row < = ypos + CONFIRM_DLG_HEIGTH - 1 ) )
ypos - = CONFIRM_DLG_HEIGTH ;
Quick_input . ypos = ypos ;
2004-09-19 21:23:52 +04:00
retval = quick_dialog ( & Quick_input ) ;
2009-02-06 01:22:08 +03:00
g_string_free ( label_text , TRUE ) ;
2004-09-19 21:23:52 +04:00
return retval ;
2001-08-24 22:23:17 +04:00
}
}
/* thanks to Liviu Daia <daia@stoilow.imar.ro> for getting this
( and the above ) routines to work properly - paul */
# define is_digit(x) ((x) >= '0' && (x) <= '9')
2009-04-23 18:28:07 +04:00
static char *
edit_replace_cmd__conv_to_display ( char * str )
{
GString * tmp ;
tmp = str_convert_to_display ( str ) ;
if ( tmp & & tmp - > len ) {
g_free ( str ) ;
str = tmp - > str ;
}
g_string_free ( tmp , FALSE ) ;
return str ;
}
static char *
edit_replace_cmd__conv_to_input ( char * str )
{
GString * tmp ;
tmp = str_convert_to_input ( str ) ;
if ( tmp & & tmp - > len ) {
g_free ( str ) ;
str = tmp - > str ;
}
g_string_free ( tmp , FALSE ) ;
return str ;
}
2001-08-24 22:23:17 +04:00
/* call with edit = 0 before shutdown to close memory leaks */
2002-10-31 02:56:49 +03:00
void
edit_replace_cmd ( WEdit * edit , int again )
2001-08-24 22:23:17 +04:00
{
2009-04-29 17:13:12 +04:00
/* 1 = search string, 2 = replace with */
2005-03-18 00:18:23 +03:00
static char * saved1 = NULL ; /* saved default[123] */
2004-12-03 00:02:07 +03:00
static char * saved2 = NULL ;
2005-03-18 00:18:23 +03:00
char * input1 = NULL ; /* user input from the dialog */
2004-12-03 00:02:07 +03:00
char * input2 = NULL ;
2009-04-23 18:46:38 +04:00
char * str_for_prompt_dialog = NULL ;
2001-08-24 22:23:17 +04:00
int replace_yes ;
long times_replaced = 0 , last_search ;
2009-04-23 18:46:38 +04:00
gboolean once_found = FALSE ;
2001-08-24 22:23:17 +04:00
if ( ! edit ) {
2009-02-06 01:27:37 +03:00
g_free ( saved1 ) , saved1 = NULL ;
g_free ( saved2 ) , saved2 = NULL ;
2001-08-24 22:23:17 +04:00
return ;
}
2004-12-03 00:02:07 +03:00
2001-08-24 22:23:17 +04:00
last_search = edit - > last_byte ;
edit - > force | = REDRAW_COMPLETELY ;
2005-03-18 00:18:23 +03:00
if ( again & & ! saved1 & & ! saved2 )
again = 0 ;
2001-08-24 22:23:17 +04:00
if ( again ) {
2009-02-06 01:40:32 +03:00
input1 = g_strdup ( saved1 ? saved1 : " " ) ;
input2 = g_strdup ( saved2 ? saved2 : " " ) ;
2001-08-24 22:23:17 +04:00
} else {
2009-04-23 18:28:07 +04:00
char * disp1 = edit_replace_cmd__conv_to_display ( g_strdup ( saved1 ? saved1 : " " ) ) ;
char * disp2 = edit_replace_cmd__conv_to_display ( g_strdup ( saved2 ? saved2 : " " ) ) ;
2004-12-03 00:02:07 +03:00
edit_push_action ( edit , KEY_PRESS + edit - > start_display ) ;
2009-04-29 17:13:12 +04:00
editcmd_dialog_replace_show ( edit , disp1 , disp2 , & input1 , & input2 ) ;
2001-08-24 22:23:17 +04:00
2009-02-06 01:27:37 +03:00
g_free ( disp1 ) ;
g_free ( disp2 ) ;
2001-08-24 22:23:17 +04:00
2009-04-29 17:13:12 +04:00
str_for_prompt_dialog = g_strdup ( input2 ) ;
2001-08-24 22:23:17 +04:00
2005-03-18 00:18:23 +03:00
if ( input1 = = NULL | | * input1 = = ' \0 ' ) {
edit - > force = REDRAW_COMPLETELY ;
goto cleanup ;
}
2001-08-24 22:23:17 +04:00
2009-04-29 17:13:12 +04:00
input1 = edit_replace_cmd__conv_to_input ( input1 ) ;
input2 = edit_replace_cmd__conv_to_input ( input2 ) ;
2009-02-06 15:01:28 +03:00
g_free ( saved1 ) , saved1 = g_strdup ( input1 ) ;
g_free ( saved2 ) , saved2 = g_strdup ( input2 ) ;
2009-04-23 18:28:07 +04:00
if ( edit - > search )
{
mc_search_free ( edit - > search ) ;
edit - > search = NULL ;
}
2005-03-18 00:18:23 +03:00
}
2001-08-24 22:23:17 +04:00
2009-04-23 18:28:07 +04:00
if ( ! edit - > search )
{
edit - > search = mc_search_new ( input1 , - 1 ) ;
if ( edit - > search = = NULL )
{
edit - > search_start = edit - > curs1 ;
return ;
}
2009-04-29 17:13:12 +04:00
edit - > search - > is_backward = edit - > replace_backwards ;
edit - > search - > search_type = edit - > search_type ;
edit - > search - > is_case_sentitive = edit - > replace_case ;
2009-04-23 18:28:07 +04:00
edit - > search - > search_fn = edit_search_cmd_callback ;
}
2002-10-31 02:56:49 +03:00
if ( edit - > found_len & & edit - > search_start = = edit - > found_start + 1
2009-04-29 17:13:12 +04:00
& & edit - > replace_backwards )
2001-08-24 22:23:17 +04:00
edit - > search_start - - ;
2002-10-31 02:56:49 +03:00
if ( edit - > found_len & & edit - > search_start = = edit - > found_start - 1
2009-04-29 17:13:12 +04:00
& & ! edit - > replace_backwards )
2001-08-24 22:23:17 +04:00
edit - > search_start + + ;
do {
2009-04-23 18:28:07 +04:00
gsize len = 0 ;
2001-08-24 22:23:17 +04:00
long new_start ;
2009-04-23 18:28:07 +04:00
if ( ! mc_search_run ( edit - > search , ( void * ) edit , edit - > search_start , last_search , & len ) )
{
2009-04-23 18:46:38 +04:00
if ( ! ( edit - > search - > error = = MC_SEARCH_E_OK | | ( once_found & & edit - > search - > error = = MC_SEARCH_E_NOTFOUND ) ) )
{
edit_error_dialog ( _ ( " Search " ) , edit - > search - > error_str ) ;
}
2001-08-24 22:23:17 +04:00
break ;
}
2009-04-23 18:46:38 +04:00
once_found = TRUE ;
2009-04-23 18:28:07 +04:00
new_start = edit - > search - > normal_offset ;
edit - > search_start = new_start = edit - > search - > normal_offset ;
2001-08-24 22:23:17 +04:00
/*returns negative on not found or error in pattern */
if ( edit - > search_start > = 0 ) {
2004-12-03 00:02:07 +03:00
int i ;
2001-08-24 22:23:17 +04:00
edit - > found_start = edit - > search_start ;
i = edit - > found_len = len ;
edit_cursor_move ( edit , edit - > search_start - edit - > curs1 ) ;
edit_scroll_screen_over_cursor ( edit ) ;
replace_yes = 1 ;
2009-04-29 17:13:12 +04:00
if ( edit - > replace_mode = = 0 ) {
2001-08-24 22:23:17 +04:00
int l ;
l = edit - > curs_row - edit - > num_widget_lines / 3 ;
if ( l > 0 )
edit_scroll_downward ( edit , l ) ;
if ( l < 0 )
edit_scroll_upward ( edit , - l ) ;
edit_scroll_screen_over_cursor ( edit ) ;
edit - > force | = REDRAW_PAGE ;
edit_render_keypress ( edit ) ;
/*so that undo stops at each query */
edit_push_key_press ( edit ) ;
2009-04-23 18:46:38 +04:00
switch ( edit_replace_prompt ( edit , str_for_prompt_dialog , /* and prompt 2/3 down */
2002-10-31 02:56:49 +03:00
( edit - > num_widget_columns -
CONFIRM_DLG_WIDTH ) / 2 ,
edit - > num_widget_lines * 2 /
3 ) ) {
2001-08-24 22:23:17 +04:00
case B_ENTER :
break ;
case B_SKIP_REPLACE :
replace_yes = 0 ;
break ;
case B_REPLACE_ALL :
2009-04-29 17:13:12 +04:00
edit - > replace_mode = 1 ;
2001-08-24 22:23:17 +04:00
break ;
case B_REPLACE_ONE :
break ;
case B_CANCEL :
replace_yes = 0 ;
break ;
}
}
if ( replace_yes ) { /* delete then insert new */
2009-04-29 19:45:21 +04:00
GString * repl_str , * tmp_str ;
tmp_str = g_string_new ( input2 ) ;
repl_str = mc_search_prepare_replace_str ( edit - > search , tmp_str ) ;
g_string_free ( tmp_str , TRUE ) ;
if ( edit - > search - > error ! = MC_SEARCH_E_OK )
{
edit_error_dialog ( _ ( " Replace " ) , edit - > search - > error_str ) ;
break ;
2001-08-24 22:23:17 +04:00
}
2009-04-29 19:45:21 +04:00
while ( i - - )
edit_delete ( edit , 1 ) ;
while ( + + i < repl_str - > len )
edit_insert ( edit , repl_str - > str [ i ] ) ;
g_string_free ( repl_str , TRUE ) ;
2001-08-24 22:23:17 +04:00
edit - > found_len = i ;
}
2002-10-31 02:56:49 +03:00
/* so that we don't find the same string again */
2009-04-29 17:13:12 +04:00
if ( edit - > replace_backwards ) {
2001-08-24 22:23:17 +04:00
last_search = edit - > search_start ;
edit - > search_start - - ;
} else {
edit - > search_start + = i ;
last_search = edit - > last_byte ;
}
edit_scroll_screen_over_cursor ( edit ) ;
} else {
2004-09-19 19:40:09 +04:00
const char * msg = _ ( " Replace " ) ;
2002-10-31 02:56:49 +03:00
/* try and find from right here for next search */
edit - > search_start = edit - > curs1 ;
2001-08-24 22:23:17 +04:00
edit_update_curs_col ( edit ) ;
edit - > force | = REDRAW_PAGE ;
edit_render_keypress ( edit ) ;
if ( times_replaced ) {
2009-01-10 16:13:56 +03:00
message ( D_NORMAL , msg , _ ( " %ld replacements made. " ) ,
2002-10-31 02:56:49 +03:00
times_replaced ) ;
2001-08-24 22:23:17 +04:00
} else
2005-05-20 23:27:45 +04:00
query_dialog ( msg , _ ( " Search string not found " ) ,
D_NORMAL , 1 , _ ( " &OK " ) ) ;
2009-04-29 17:13:12 +04:00
edit - > replace_mode = - 1 ;
2001-08-24 22:23:17 +04:00
}
2009-04-29 17:13:12 +04:00
} while ( edit - > replace_mode > 0 ) ;
2001-08-24 22:23:17 +04:00
edit - > force = REDRAW_COMPLETELY ;
edit_scroll_screen_over_cursor ( edit ) ;
2005-03-18 00:18:23 +03:00
cleanup :
2009-04-23 18:46:38 +04:00
g_free ( str_for_prompt_dialog ) ;
2009-02-06 01:27:37 +03:00
g_free ( input1 ) ;
g_free ( input2 ) ;
2001-08-24 22:23:17 +04:00
}
void edit_search_cmd ( WEdit * edit , int again )
{
2009-04-23 15:30:14 +04:00
char * search_string = NULL , * search_string_dup = NULL ;
2001-08-24 22:23:17 +04:00
2009-04-23 15:30:14 +04:00
gsize len = 0 ;
if ( ! edit )
2001-08-24 22:23:17 +04:00
return ;
2005-09-05 05:25:34 +04:00
2009-04-23 15:30:14 +04:00
if ( edit - > search ! = NULL )
search_string_dup = search_string = g_strndup ( edit - > search - > original , edit - > search - > original_len ) ;
if ( ! again )
{
2001-08-24 22:23:17 +04:00
# ifdef HAVE_CHARSET
2009-04-23 15:30:14 +04:00
GString * tmp ;
if ( search_string & & * search_string )
{
tmp = str_convert_to_display ( search_string ) ;
g_free ( search_string_dup ) ;
search_string_dup = NULL ;
if ( tmp & & tmp - > len )
search_string = search_string_dup = tmp - > str ;
2009-04-22 06:19:20 +04:00
g_string_free ( tmp , FALSE ) ;
2009-04-17 18:05:19 +04:00
}
2001-09-07 22:56:07 +04:00
# endif /* HAVE_CHARSET */
2009-04-29 17:13:12 +04:00
editcmd_dialog_search_show ( edit , & search_string ) ;
2001-08-24 22:23:17 +04:00
# ifdef HAVE_CHARSET
2009-04-23 15:30:14 +04:00
if ( search_string & & * search_string )
{
tmp = str_convert_to_input ( search_string ) ;
if ( tmp & & tmp - > len )
search_string = tmp - > str ;
2009-04-22 06:19:20 +04:00
g_string_free ( tmp , FALSE ) ;
2009-04-23 15:30:14 +04:00
if ( search_string_dup )
g_free ( search_string_dup ) ;
2009-04-17 18:05:19 +04:00
}
2001-09-07 22:56:07 +04:00
# endif /* HAVE_CHARSET */
2009-04-23 15:30:14 +04:00
2001-08-24 22:23:17 +04:00
edit_push_action ( edit , KEY_PRESS + edit - > start_display ) ;
2009-04-23 15:30:14 +04:00
if ( ! search_string )
{
edit - > force | = REDRAW_COMPLETELY ;
edit_scroll_screen_over_cursor ( edit ) ;
return ;
}
if ( edit - > search )
{
mc_search_free ( edit - > search ) ;
edit - > search = NULL ;
}
2001-08-24 22:23:17 +04:00
}
2009-04-23 15:30:14 +04:00
if ( ! edit - > search )
{
edit - > search = mc_search_new ( search_string , - 1 ) ;
if ( edit - > search = = NULL )
{
edit - > search_start = edit - > curs1 ;
return ;
}
2009-04-29 17:13:12 +04:00
edit - > search - > is_backward = edit - > replace_backwards ;
edit - > search - > search_type = edit - > search_type ;
2001-08-24 22:23:17 +04:00
2009-04-29 17:13:12 +04:00
edit - > search - > is_case_sentitive = edit - > replace_case ;
2009-04-23 15:30:14 +04:00
edit - > search - > search_fn = edit_search_cmd_callback ;
}
2001-08-24 22:23:17 +04:00
2009-04-23 15:30:14 +04:00
if ( search_create_bookmark )
{
2009-04-24 02:47:22 +04:00
edit_search_cmd_search_create_bookmark ( edit ) ;
2009-04-23 15:30:14 +04:00
}
else
{
2009-04-29 17:13:12 +04:00
if ( edit - > found_len & & edit - > search_start = = edit - > found_start + 1 & & edit - > replace_backwards )
2009-04-23 15:30:14 +04:00
edit - > search_start - - ;
2001-08-24 22:23:17 +04:00
2009-04-29 17:13:12 +04:00
if ( edit - > found_len & & edit - > search_start = = edit - > found_start - 1 & & ! edit - > replace_backwards )
2009-04-23 15:30:14 +04:00
edit - > search_start + + ;
2001-08-24 22:23:17 +04:00
2009-04-23 15:30:14 +04:00
if ( mc_search_run ( edit - > search , ( void * ) edit , edit - > search_start , edit - > last_byte , & len ) )
{
edit - > found_start = edit - > search_start = edit - > search - > normal_offset ;
edit - > found_len = len ;
edit_cursor_move ( edit , edit - > search_start - edit - > curs1 ) ;
edit_scroll_screen_over_cursor ( edit ) ;
2009-04-29 17:13:12 +04:00
if ( edit - > replace_backwards )
2009-04-23 15:30:14 +04:00
edit - > search_start - - ;
else
edit - > search_start + + ;
}
else
{
edit - > search_start = edit - > curs1 ;
edit_error_dialog ( _ ( " Search " ) , edit - > search - > error_str ) ;
2001-08-24 22:23:17 +04:00
}
}
2009-04-23 15:30:14 +04:00
2001-08-24 22:23:17 +04:00
edit - > force | = REDRAW_COMPLETELY ;
edit_scroll_screen_over_cursor ( edit ) ;
}
2003-07-21 07:54:47 +04:00
/*
* Check if it ' s OK to close the editor . If there are unsaved changes ,
* ask user . Return 1 if it ' s OK to exit , 0 to continue editing .
*/
int
edit_ok_to_exit ( WEdit * edit )
2001-08-24 22:23:17 +04:00
{
2003-07-21 07:54:47 +04:00
if ( ! edit - > modified )
return 1 ;
switch ( edit_query_dialog3
( _ ( " Quit " ) , _ ( " File was modified, Save with exit? " ) ,
2004-09-02 02:40:45 +04:00
_ ( " &Cancel quit " ) , _ ( " &Yes " ) , _ ( " &No " ) ) ) {
2003-07-21 07:54:47 +04:00
case 1 :
edit_push_markers ( edit ) ;
edit_set_markers ( edit , 0 , 0 , 0 , 0 ) ;
if ( ! edit_save_cmd ( edit ) )
return 0 ;
break ;
case 2 :
break ;
case 0 :
case - 1 :
return 0 ;
2001-08-24 22:23:17 +04:00
}
2003-07-21 07:54:47 +04:00
return 1 ;
2001-08-24 22:23:17 +04:00
}
2003-07-21 07:54:47 +04:00
2001-08-24 22:23:17 +04:00
# define TEMP_BUF_LEN 1024
2009-02-06 01:27:37 +03:00
/* Return a null terminated length of text. Result must be g_free'd */
2003-10-15 01:48:40 +04:00
static unsigned char *
2002-12-15 21:55:53 +03:00
edit_get_block ( WEdit * edit , long start , long finish , int * l )
2001-08-24 22:23:17 +04:00
{
unsigned char * s , * r ;
2002-12-15 21:55:53 +03:00
r = s = g_malloc ( finish - start + 1 ) ;
2001-08-24 22:23:17 +04:00
if ( column_highlighting ) {
* l = 0 ;
2002-12-15 21:55:53 +03:00
/* copy from buffer, excluding chars that are out of the column 'margins' */
while ( start < finish ) {
2001-08-24 22:23:17 +04:00
int c , x ;
2002-12-15 21:55:53 +03:00
x = edit_move_forward3 ( edit , edit_bol ( edit , start ) , 0 ,
start ) ;
2001-08-24 22:23:17 +04:00
c = edit_get_byte ( edit , start ) ;
if ( ( x > = edit - > column1 & & x < edit - > column2 )
2002-12-15 21:55:53 +03:00
| | ( x > = edit - > column2 & & x < edit - > column1 ) | | c = = ' \n ' ) {
2001-08-24 22:23:17 +04:00
* s + + = c ;
( * l ) + + ;
}
start + + ;
}
} else {
* l = finish - start ;
while ( start < finish )
* s + + = edit_get_byte ( edit , start + + ) ;
}
* s = 0 ;
return r ;
}
/* save block, returns 1 on success */
2002-09-23 10:54:50 +04:00
int
edit_save_block ( WEdit * edit , const char * filename , long start ,
long finish )
2001-08-24 22:23:17 +04:00
{
int len , file ;
2002-09-23 10:54:50 +04:00
if ( ( file =
2002-10-02 19:44:35 +04:00
mc_open ( filename , O_CREAT | O_WRONLY | O_TRUNC ,
2002-09-23 10:54:50 +04:00
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH | O_BINARY ) ) = = - 1 )
2001-08-24 22:23:17 +04:00
return 0 ;
if ( column_highlighting ) {
unsigned char * block , * p ;
int r ;
p = block = edit_get_block ( edit , start , finish , & len ) ;
while ( len ) {
2002-05-13 20:53:51 +04:00
r = mc_write ( file , p , len ) ;
2001-08-24 22:23:17 +04:00
if ( r < 0 )
break ;
p + = r ;
len - = r ;
}
2009-02-06 01:27:37 +03:00
g_free ( block ) ;
2001-08-24 22:23:17 +04:00
} else {
unsigned char * buf ;
int i = start , end ;
len = finish - start ;
2002-12-15 21:55:53 +03:00
buf = g_malloc ( TEMP_BUF_LEN ) ;
2001-08-24 22:23:17 +04:00
while ( start ! = finish ) {
end = min ( finish , start + TEMP_BUF_LEN ) ;
for ( ; i < end ; i + + )
buf [ i - start ] = edit_get_byte ( edit , i ) ;
2002-05-13 20:53:51 +04:00
len - = mc_write ( file , ( char * ) buf , end - start ) ;
2001-08-24 22:23:17 +04:00
start = end ;
}
2009-02-06 01:27:37 +03:00
g_free ( buf ) ;
2001-08-24 22:23:17 +04:00
}
2002-05-13 20:53:51 +04:00
mc_close ( file ) ;
2001-08-24 22:23:17 +04:00
if ( len )
return 0 ;
return 1 ;
}
/* copies a block to clipboard file */
static int edit_save_block_to_clip_file ( WEdit * edit , long start , long finish )
{
2009-04-14 16:12:36 +04:00
int ret ;
gchar * tmp ;
tmp = g_strconcat ( home_dir , PATH_SEP_STR CLIP_FILE , ( char * ) NULL ) ;
ret = edit_save_block ( edit , tmp , start , finish ) ;
g_free ( tmp ) ;
return ret ;
2001-08-24 22:23:17 +04:00
}
void edit_paste_from_history ( WEdit * edit )
{
2005-02-08 20:14:34 +03:00
( void ) edit ;
edit_error_dialog ( _ ( " Error " ) , _ ( " This function is not implemented. " ) ) ;
2001-08-24 22:23:17 +04:00
}
int edit_copy_to_X_buf_cmd ( WEdit * edit )
{
long start_mark , end_mark ;
if ( eval_marks ( edit , & start_mark , & end_mark ) )
return 0 ;
if ( ! edit_save_block_to_clip_file ( edit , start_mark , end_mark ) ) {
edit_error_dialog ( _ ( " Copy to clipboard " ) , get_sys_error ( _ ( " Unable to save to file. " ) ) ) ;
return 1 ;
}
edit_mark_cmd ( edit , 1 ) ;
return 0 ;
}
int edit_cut_to_X_buf_cmd ( WEdit * edit )
{
long start_mark , end_mark ;
if ( eval_marks ( edit , & start_mark , & end_mark ) )
return 0 ;
if ( ! edit_save_block_to_clip_file ( edit , start_mark , end_mark ) ) {
edit_error_dialog ( _ ( " Cut to clipboard " ) , _ ( " Unable to save to file. " ) ) ;
return 1 ;
}
edit_block_delete_cmd ( edit ) ;
edit_mark_cmd ( edit , 1 ) ;
return 0 ;
}
void edit_paste_from_X_buf_cmd ( WEdit * edit )
{
2009-04-14 16:12:36 +04:00
gchar * tmp ;
tmp = g_strconcat ( home_dir , PATH_SEP_STR CLIP_FILE , ( char * ) NULL ) ;
edit_insert_file ( edit , tmp ) ;
g_free ( tmp ) ;
2001-08-24 22:23:17 +04:00
}
2002-12-16 10:13:12 +03:00
/*
* Ask user for the line and go to that line .
* Negative numbers mean line from the end ( i . e . - 1 is the last line ) .
*/
void
edit_goto_cmd ( WEdit * edit )
2001-08-24 22:23:17 +04:00
{
char * f ;
2002-12-16 10:13:12 +03:00
static long line = 0 ; /* line as typed, saved as default */
long l ;
char * error ;
char s [ 32 ] ;
2009-02-06 01:49:00 +03:00
g_snprintf ( s , sizeof ( s ) , " %ld " , line ) ;
2009-01-24 23:51:29 +03:00
f = input_dialog ( _ ( " Goto line " ) , _ ( " Enter line: " ) , MC_HISTORY_EDIT_GOTO_LINE ,
2009-01-14 03:01:18 +03:00
line ? s : " " ) ;
2002-12-16 10:13:12 +03:00
if ( ! f )
return ;
if ( ! * f ) {
2009-02-06 01:27:37 +03:00
g_free ( f ) ;
2002-12-16 10:13:12 +03:00
return ;
}
l = strtol ( f , & error , 0 ) ;
if ( * error ) {
2009-02-06 01:27:37 +03:00
g_free ( f ) ;
2002-12-16 10:13:12 +03:00
return ;
2001-08-24 22:23:17 +04:00
}
2002-12-16 10:13:12 +03:00
line = l ;
if ( l < 0 )
l = edit - > total_lines + l + 2 ;
edit_move_display ( edit , l - edit - > num_widget_lines / 2 - 1 ) ;
edit_move_to_line ( edit , l - 1 ) ;
edit - > force | = REDRAW_COMPLETELY ;
2009-02-06 01:27:37 +03:00
g_free ( f ) ;
2001-08-24 22:23:17 +04:00
}
2002-12-16 10:13:12 +03:00
2002-11-30 21:49:20 +03:00
/* Return 1 on success */
int
edit_save_block_cmd ( WEdit * edit )
2001-08-24 22:23:17 +04:00
{
long start_mark , end_mark ;
2009-04-14 16:12:36 +04:00
char * exp , * tmp ;
2001-08-24 22:23:17 +04:00
if ( eval_marks ( edit , & start_mark , & end_mark ) )
return 1 ;
2009-04-14 16:12:36 +04:00
tmp = g_strconcat ( home_dir , PATH_SEP_STR CLIP_FILE , ( char * ) NULL ) ;
2002-11-30 21:49:20 +03:00
exp =
2009-01-14 03:01:18 +03:00
input_expand_dialog ( _ ( " Save Block " ) , _ ( " Enter file name: " ) ,
2009-01-24 23:51:29 +03:00
MC_HISTORY_EDIT_SAVE_BLOCK ,
2009-04-14 16:12:36 +04:00
tmp ) ;
g_free ( tmp ) ;
2001-08-24 22:23:17 +04:00
edit_push_action ( edit , KEY_PRESS + edit - > start_display ) ;
if ( exp ) {
if ( ! * exp ) {
2009-02-06 01:27:37 +03:00
g_free ( exp ) ;
2001-08-24 22:23:17 +04:00
return 0 ;
} else {
if ( edit_save_block ( edit , exp , start_mark , end_mark ) ) {
2009-02-06 01:27:37 +03:00
g_free ( exp ) ;
2001-08-24 22:23:17 +04:00
edit - > force | = REDRAW_COMPLETELY ;
return 1 ;
} else {
2009-02-06 01:27:37 +03:00
g_free ( exp ) ;
2002-11-30 21:49:20 +03:00
edit_error_dialog ( _ ( " Save Block " ) ,
get_sys_error ( _
2002-12-08 12:27:18 +03:00
( " Cannot save file. " ) ) ) ;
2001-08-24 22:23:17 +04:00
}
}
}
edit - > force | = REDRAW_COMPLETELY ;
return 0 ;
}
/* returns 1 on success */
2002-10-21 09:31:47 +04:00
int
edit_insert_file_cmd ( WEdit * edit )
2001-08-24 22:23:17 +04:00
{
2009-04-14 16:12:36 +04:00
gchar * tmp ;
char * exp ;
tmp = g_strconcat ( home_dir , PATH_SEP_STR CLIP_FILE , ( char * ) NULL ) ;
exp = input_expand_dialog ( _ ( " Insert File " ) , _ ( " Enter file name: " ) ,
2009-01-24 23:51:29 +03:00
MC_HISTORY_EDIT_INSERT_FILE ,
2009-04-14 16:12:36 +04:00
tmp ) ;
g_free ( tmp ) ;
2001-08-24 22:23:17 +04:00
edit_push_action ( edit , KEY_PRESS + edit - > start_display ) ;
if ( exp ) {
if ( ! * exp ) {
2009-02-06 01:27:37 +03:00
g_free ( exp ) ;
2001-08-24 22:23:17 +04:00
return 0 ;
} else {
if ( edit_insert_file ( edit , exp ) ) {
2009-02-06 01:27:37 +03:00
g_free ( exp ) ;
2001-08-24 22:23:17 +04:00
edit - > force | = REDRAW_COMPLETELY ;
return 1 ;
} else {
2009-02-06 01:27:37 +03:00
g_free ( exp ) ;
2002-10-21 09:31:47 +04:00
edit_error_dialog ( _ ( " Insert File " ) ,
get_sys_error ( _
2002-12-08 12:27:18 +03:00
( " Cannot insert file. " ) ) ) ;
2001-08-24 22:23:17 +04:00
}
}
}
edit - > force | = REDRAW_COMPLETELY ;
return 0 ;
}
/* sorts a block, returns -1 on system fail, 1 on cancel and 0 on success */
int edit_sort_cmd ( WEdit * edit )
{
static char * old = 0 ;
2009-04-14 16:12:36 +04:00
char * exp , * tmp ;
2001-08-24 22:23:17 +04:00
long start_mark , end_mark ;
int e ;
if ( eval_marks ( edit , & start_mark , & end_mark ) ) {
edit_error_dialog ( _ ( " Sort block " ) , _ ( " You must first highlight a block of text. " ) ) ;
return 0 ;
}
2009-04-14 16:12:36 +04:00
tmp = g_strconcat ( home_dir , PATH_SEP_STR BLOCK_FILE , ( char * ) NULL ) ;
edit_save_block ( edit , tmp , start_mark , end_mark ) ;
g_free ( tmp ) ;
2001-08-24 22:23:17 +04:00
2005-02-07 10:31:19 +03:00
exp = input_dialog ( _ ( " Run Sort " ) ,
2005-09-05 05:25:34 +04:00
_ ( " Enter sort options (see manpage) separated by whitespace: " ) ,
2009-01-24 23:51:29 +03:00
MC_HISTORY_EDIT_SORT , ( old ! = NULL ) ? old : " " ) ;
2001-08-24 22:23:17 +04:00
if ( ! exp )
return 1 ;
2009-02-06 01:27:37 +03:00
g_free ( old ) ;
2001-08-24 22:23:17 +04:00
old = exp ;
2009-04-14 16:12:36 +04:00
tmp = g_strconcat ( " sort " , exp , " " , home_dir , PATH_SEP_STR BLOCK_FILE , " > " , home_dir , PATH_SEP_STR TEMP_FILE , ( char * ) NULL ) ;
e = system ( tmp ) ;
g_free ( tmp ) ;
2001-08-24 22:23:17 +04:00
if ( e ) {
if ( e = = - 1 | | e = = 127 ) {
2005-02-07 10:31:19 +03:00
edit_error_dialog ( _ ( " Sort " ) ,
2002-12-08 12:27:18 +03:00
get_sys_error ( _ ( " Cannot execute sort command " ) ) ) ;
2001-08-24 22:23:17 +04:00
} else {
char q [ 8 ] ;
sprintf ( q , " %d " , e ) ;
2009-04-14 16:12:36 +04:00
tmp = g_strconcat ( _ ( " Sort returned non-zero: " ) , q , ( char * ) NULL ) ;
edit_error_dialog ( _ ( " Sort " ) , tmp ) ;
g_free ( tmp ) ;
2001-08-24 22:23:17 +04:00
}
return - 1 ;
}
edit - > force | = REDRAW_COMPLETELY ;
if ( edit_block_delete_cmd ( edit ) )
return 1 ;
2009-04-14 16:12:36 +04:00
tmp = g_strconcat ( home_dir , PATH_SEP_STR TEMP_FILE , ( char * ) NULL ) ;
edit_insert_file ( edit , tmp ) ;
g_free ( tmp ) ;
2001-08-24 22:23:17 +04:00
return 0 ;
}
2004-09-26 15:42:17 +04:00
/*
* Ask user for a command , execute it and paste its output back to the
* editor .
*/
2003-05-31 01:06:10 +04:00
int
edit_ext_cmd ( WEdit * edit )
{
2009-04-14 16:12:36 +04:00
char * exp , * tmp ;
2004-09-26 15:42:17 +04:00
int e ;
2003-05-31 01:06:10 +04:00
2004-09-26 15:42:17 +04:00
exp =
input_dialog ( _ ( " Paste output of external command " ) ,
2009-01-14 03:01:18 +03:00
_ ( " Enter shell command(s): " ) ,
2009-01-24 23:51:29 +03:00
MC_HISTORY_EDIT_PASTE_EXTCMD , NULL ) ;
2003-05-31 01:06:10 +04:00
2004-09-26 15:42:17 +04:00
if ( ! exp )
return 1 ;
2003-05-31 01:06:10 +04:00
2009-04-14 16:12:36 +04:00
tmp = g_strconcat ( exp , " > " , home_dir , PATH_SEP_STR TEMP_FILE , ( char * ) NULL ) ;
e = system ( tmp ) ;
g_free ( tmp ) ;
2009-02-06 01:27:37 +03:00
g_free ( exp ) ;
2003-05-31 01:06:10 +04:00
2004-09-26 15:42:17 +04:00
if ( e ) {
edit_error_dialog ( _ ( " External command " ) ,
get_sys_error ( _ ( " Cannot execute command " ) ) ) ;
return - 1 ;
2004-09-26 01:34:36 +04:00
}
2004-09-26 15:42:17 +04:00
2004-09-26 01:34:36 +04:00
edit - > force | = REDRAW_COMPLETELY ;
2009-04-14 16:12:36 +04:00
tmp = g_strconcat ( home_dir , PATH_SEP_STR TEMP_FILE , ( char * ) NULL ) ;
edit_insert_file ( edit , tmp ) ;
g_free ( tmp ) ;
2004-09-26 15:42:17 +04:00
return 0 ;
2003-05-31 01:06:10 +04:00
}
2001-08-24 22:23:17 +04:00
/* if block is 1, a block must be highlighted and the shell command
processes it . If block is 0 the shell command is a straight system
command , that just produces some output which is to be inserted */
2002-08-24 21:22:15 +04:00
void
2002-12-19 16:01:34 +03:00
edit_block_process_cmd ( WEdit * edit , const char * shell_cmd , int block )
2001-08-24 22:23:17 +04:00
{
long start_mark , end_mark ;
char buf [ BUFSIZ ] ;
FILE * script_home = NULL ;
FILE * script_src = NULL ;
FILE * block_file = NULL ;
2009-04-14 16:12:36 +04:00
gchar * o , * h , * b , * tmp ;
2002-12-19 16:01:34 +03:00
char * quoted_name = NULL ;
2002-08-19 04:33:08 +04:00
2009-04-14 16:12:36 +04:00
o = g_strconcat ( mc_home , shell_cmd , ( char * ) NULL ) ; /* original source script */
h = g_strconcat ( home_dir , PATH_SEP_STR EDIT_DIR , shell_cmd , ( char * ) NULL ) ; /* home script */
b = g_strconcat ( home_dir , PATH_SEP_STR BLOCK_FILE , ( char * ) NULL ) ; /* block file */
2002-08-19 04:33:08 +04:00
if ( ! ( script_home = fopen ( h , " r " ) ) ) {
if ( ! ( script_home = fopen ( h , " w " ) ) ) {
2009-04-14 16:12:36 +04:00
tmp = g_strconcat ( _ ( " Error creating script: " ) , h , ( char * ) NULL ) ;
edit_error_dialog ( " " , get_sys_error ( tmp ) ) ;
g_free ( tmp ) ;
goto edit_block_process_cmd__EXIT ;
2002-08-19 04:33:08 +04:00
}
if ( ! ( script_src = fopen ( o , " r " ) ) ) {
fclose ( script_home ) ;
unlink ( h ) ;
2009-04-14 16:12:36 +04:00
tmp = g_strconcat ( _ ( " Error reading script: " ) , o , ( char * ) NULL ) ;
edit_error_dialog ( " " , get_sys_error ( tmp ) ) ;
g_free ( tmp ) ;
goto edit_block_process_cmd__EXIT ;
2002-08-19 04:33:08 +04:00
}
while ( fgets ( buf , sizeof ( buf ) , script_src ) )
fputs ( buf , script_home ) ;
if ( fclose ( script_home ) ) {
2009-04-14 16:12:36 +04:00
tmp = g_strconcat ( _ ( " Error closing script: " ) , h , ( char * ) NULL ) ;
edit_error_dialog ( " " , get_sys_error ( tmp ) ) ;
g_free ( tmp ) ;
goto edit_block_process_cmd__EXIT ;
2002-08-19 04:33:08 +04:00
}
chmod ( h , 0700 ) ;
2009-04-14 16:12:36 +04:00
tmp = g_strconcat ( _ ( " Script created: " ) , h , ( char * ) NULL ) ;
edit_error_dialog ( " " , get_sys_error ( tmp ) ) ;
g_free ( tmp ) ;
2001-08-24 22:23:17 +04:00
}
2002-08-24 21:22:15 +04:00
open_error_pipe ( ) ;
2002-08-19 04:33:08 +04:00
if ( block ) { /* for marked block run indent formatter */
2001-08-24 22:23:17 +04:00
if ( eval_marks ( edit , & start_mark , & end_mark ) ) {
edit_error_dialog ( _ ( " Process block " ) ,
2002-08-19 04:33:08 +04:00
_
( " You must first highlight a block of text. " ) ) ;
2009-04-14 16:12:36 +04:00
goto edit_block_process_cmd__EXIT ;
2001-08-24 22:23:17 +04:00
}
2002-08-19 04:33:08 +04:00
edit_save_block ( edit , b , start_mark , end_mark ) ;
2002-12-19 16:01:34 +03:00
quoted_name = name_quote ( edit - > filename , 0 ) ;
2001-09-04 08:16:06 +04:00
/*
* Run script .
* Initial space is to avoid polluting bash history .
* Arguments :
2003-06-02 22:39:44 +04:00
* $ 1 - name of the edited file ( to check its extension etc ) .
2001-09-04 08:16:06 +04:00
* $ 2 - file containing the current block .
2002-09-02 03:20:37 +04:00
* $ 3 - file where error messages should be put
* ( for compatibility with old scripts ) .
2001-09-04 08:16:06 +04:00
*/
2009-04-14 16:12:36 +04:00
tmp = g_strconcat ( " " , home_dir , PATH_SEP_STR EDIT_DIR , shell_cmd , " " , quoted_name ,
" " , home_dir , PATH_SEP_STR BLOCK_FILE " /dev/null " , ( char * ) NULL ) ;
system ( tmp ) ;
g_free ( tmp ) ;
2001-09-04 08:16:06 +04:00
} else {
/*
* No block selected , just execute the command for the file .
* Arguments :
* $ 1 - name of the edited file .
*/
2009-04-14 16:12:36 +04:00
tmp = g_strconcat ( " " , home_dir , PATH_SEP_STR EDIT_DIR , shell_cmd , " " ,
quoted_name , ( char * ) NULL ) ;
system ( tmp ) ;
g_free ( tmp ) ;
2001-08-24 22:23:17 +04:00
}
2009-02-06 01:27:37 +03:00
g_free ( quoted_name ) ;
2009-01-10 16:13:56 +03:00
close_error_pipe ( D_NORMAL , NULL ) ;
2002-08-24 21:22:15 +04:00
2001-08-24 22:23:17 +04:00
edit_refresh_cmd ( edit ) ;
edit - > force | = REDRAW_COMPLETELY ;
2002-08-19 04:33:08 +04:00
/* insert result block */
2001-08-24 22:23:17 +04:00
if ( block ) {
2002-08-24 21:22:15 +04:00
if ( edit_block_delete_cmd ( edit ) )
2009-04-14 16:12:36 +04:00
goto edit_block_process_cmd__EXIT ;
2002-08-24 21:22:15 +04:00
edit_insert_file ( edit , b ) ;
2001-08-24 22:23:17 +04:00
if ( ( block_file = fopen ( b , " w " ) ) )
fclose ( block_file ) ;
2009-04-14 16:12:36 +04:00
goto edit_block_process_cmd__EXIT ;
2001-08-24 22:23:17 +04:00
}
2009-04-14 16:12:36 +04:00
edit_block_process_cmd__EXIT :
g_free ( b ) ;
g_free ( h ) ;
g_free ( o ) ;
2001-08-24 22:23:17 +04:00
return ;
}
/* prints at the cursor */
/* returns the number of chars printed */
int edit_print_string ( WEdit * e , const char * s )
{
int i = 0 ;
while ( s [ i ] )
edit_execute_cmd ( e , - 1 , ( unsigned char ) s [ i + + ] ) ;
e - > force | = REDRAW_COMPLETELY ;
edit_update_screen ( e ) ;
return i ;
}
static void pipe_mail ( WEdit * edit , char * to , char * subject , char * cc )
{
FILE * p = 0 ;
char * s ;
2002-12-18 23:04:39 +03:00
to = name_quote ( to , 0 ) ;
subject = name_quote ( subject , 0 ) ;
cc = name_quote ( cc , 0 ) ;
2004-09-24 18:57:57 +04:00
s = g_strconcat ( " mail -s " , subject , * cc ? " -c " : " " , cc , " " , to , ( char * ) NULL ) ;
2009-02-06 01:27:37 +03:00
g_free ( to ) ;
g_free ( subject ) ;
g_free ( cc ) ;
2001-08-24 22:23:17 +04:00
if ( s ) {
p = popen ( s , " w " ) ;
2009-02-06 01:27:37 +03:00
g_free ( s ) ;
2001-08-24 22:23:17 +04:00
}
if ( p ) {
long i ;
for ( i = 0 ; i < edit - > last_byte ; i + + )
fputc ( edit_get_byte ( edit , i ) , p ) ;
pclose ( p ) ;
}
}
# define MAIL_DLG_HEIGHT 12
void edit_mail_dialog ( WEdit * edit )
{
char * tmail_to ;
char * tmail_subject ;
char * tmail_cc ;
static char * mail_cc_last = 0 ;
static char * mail_subject_last = 0 ;
static char * mail_to_last = 0 ;
QuickDialog Quick_input =
{ 50 , MAIL_DLG_HEIGHT , - 1 , 0 , N_ ( " Mail " ) ,
2004-08-16 02:55:17 +04:00
" [Input Line Keys] " , 0 , 0 } ;
2001-08-24 22:23:17 +04:00
QuickWidget quick_widgets [ ] =
{
{ quick_button , 6 , 10 , 9 , MAIL_DLG_HEIGHT , N_ ( " &Cancel " ) , 0 , B_CANCEL , 0 ,
2009-04-29 17:13:12 +04:00
0 , NULL , NULL , NULL } ,
2002-10-22 02:26:39 +04:00
{ quick_button , 2 , 10 , 9 , MAIL_DLG_HEIGHT , N_ ( " &OK " ) , 0 , B_ENTER , 0 ,
2009-04-29 17:13:12 +04:00
0 , NULL , NULL , NULL } ,
2001-08-24 22:23:17 +04:00
{ quick_input , 3 , 50 , 8 , MAIL_DLG_HEIGHT , " " , 44 , 0 , 0 ,
2009-04-29 17:13:12 +04:00
0 , " mail-dlg-input " , NULL , NULL } ,
2001-08-24 22:23:17 +04:00
{ quick_label , 2 , 50 , 7 , MAIL_DLG_HEIGHT , N_ ( " Copies to " ) , 0 , 0 , 0 ,
2009-04-29 17:13:12 +04:00
0 , 0 , NULL , NULL } ,
2001-08-24 22:23:17 +04:00
{ quick_input , 3 , 50 , 6 , MAIL_DLG_HEIGHT , " " , 44 , 0 , 0 ,
2009-04-29 17:13:12 +04:00
0 , " mail-dlg-input-2 " , NULL , NULL } ,
2001-08-24 22:23:17 +04:00
{ quick_label , 2 , 50 , 5 , MAIL_DLG_HEIGHT , N_ ( " Subject " ) , 0 , 0 , 0 ,
2009-04-29 17:13:12 +04:00
0 , 0 , NULL , NULL } ,
2001-08-24 22:23:17 +04:00
{ quick_input , 3 , 50 , 4 , MAIL_DLG_HEIGHT , " " , 44 , 0 , 0 ,
2009-04-29 17:13:12 +04:00
0 , " mail-dlg-input-3 " , NULL , NULL } ,
2001-08-24 22:23:17 +04:00
{ quick_label , 2 , 50 , 3 , MAIL_DLG_HEIGHT , N_ ( " To " ) , 0 , 0 , 0 ,
2009-04-29 17:13:12 +04:00
0 , 0 , NULL , NULL } ,
2001-08-24 22:23:17 +04:00
{ quick_label , 2 , 50 , 2 , MAIL_DLG_HEIGHT , N_ ( " mail -s <subject> -c <cc> <to> " ) , 0 , 0 , 0 ,
2009-04-29 17:13:12 +04:00
0 , 0 , NULL , NULL } ,
2004-08-15 22:24:06 +04:00
NULL_QuickWidget } ;
2001-08-24 22:23:17 +04:00
quick_widgets [ 2 ] . str_result = & tmail_cc ;
quick_widgets [ 2 ] . text = mail_cc_last ? mail_cc_last : " " ;
quick_widgets [ 4 ] . str_result = & tmail_subject ;
quick_widgets [ 4 ] . text = mail_subject_last ? mail_subject_last : " " ;
quick_widgets [ 6 ] . str_result = & tmail_to ;
quick_widgets [ 6 ] . text = mail_to_last ? mail_to_last : " " ;
Quick_input . widgets = quick_widgets ;
if ( quick_dialog ( & Quick_input ) ! = B_CANCEL ) {
2009-02-06 01:27:37 +03:00
g_free ( mail_cc_last ) ;
g_free ( mail_subject_last ) ;
g_free ( mail_to_last ) ;
2003-11-03 21:59:50 +03:00
mail_cc_last = tmail_cc ;
mail_subject_last = tmail_subject ;
mail_to_last = tmail_to ;
2001-08-24 22:23:17 +04:00
pipe_mail ( edit , mail_to_last , mail_subject_last , mail_cc_last ) ;
}
}
2002-01-21 20:49:57 +03:00
/*******************/
/* Word Completion */
/*******************/
/* find first character of current word */
static int edit_find_word_start ( WEdit * edit , long * word_start , int * word_len )
{
int i , c , last ;
2005-02-07 10:31:19 +03:00
2002-01-21 20:49:57 +03:00
/* return if at begin of file */
if ( edit - > curs1 < = 0 )
return 0 ;
c = ( unsigned char ) edit_get_byte ( edit , edit - > curs1 - 1 ) ;
/* return if not at end or in word */
if ( isspace ( c ) | | ! ( isalnum ( c ) | | c = = ' _ ' ) )
2005-02-07 10:31:19 +03:00
return 0 ;
2002-01-21 20:49:57 +03:00
/* search start of word to be completed */
for ( i = 2 ; ; i + + ) {
/* return if at begin of file */
2005-02-07 10:31:19 +03:00
if ( edit - > curs1 - i < 0 )
2002-01-21 20:49:57 +03:00
return 0 ;
2005-02-07 10:31:19 +03:00
2002-01-21 20:49:57 +03:00
last = c ;
c = ( unsigned char ) edit_get_byte ( edit , edit - > curs1 - i ) ;
if ( ! ( isalnum ( c ) | | c = = ' _ ' ) ) {
/* return if word starts with digit */
if ( isdigit ( last ) )
return 0 ;
* word_start = edit - > curs1 - ( i - 1 ) ; /* start found */
* word_len = i - 1 ;
break ;
}
}
/* success */
return 1 ;
}
/* (re)set search parameters to the given values */
2009-04-29 17:13:12 +04:00
static void edit_set_search_parameters ( WEdit * edit , int replace_mode , int rb , int rc )
2002-01-21 20:49:57 +03:00
{
2009-04-29 17:13:12 +04:00
edit - > replace_mode = replace_mode ;
edit - > replace_backwards = rb ;
edit - > replace_case = rc ;
2002-01-21 20:49:57 +03:00
}
2002-11-11 11:06:01 +03:00
# define MAX_WORD_COMPLETIONS 100 /* in listbox */
2002-01-21 20:49:57 +03:00
2002-11-30 20:41:07 +03:00
/* collect the possible completions */
static int
edit_collect_completions ( WEdit * edit , long start , int word_len ,
char * match_expr , struct selection * compl ,
int * num )
2002-01-21 20:49:57 +03:00
{
2009-04-23 15:30:14 +04:00
int len = 0 , max_len = 0 , i , skip ;
2005-05-11 03:04:32 +04:00
unsigned char * bufpos ;
2002-01-21 20:49:57 +03:00
2009-04-24 02:47:22 +04:00
( void ) match_expr ;
2002-11-30 20:41:07 +03:00
/* collect max MAX_WORD_COMPLETIONS completions */
while ( * num < MAX_WORD_COMPLETIONS ) {
/* get next match */
2009-04-24 02:47:22 +04:00
/*
start =
edit_find ( start - 1 , ( unsigned char * ) match_expr , & len ,
edit - > last_byte , edit_get_byte_ptr , ( void * ) edit , 0 ) ;
*/
2009-04-23 15:30:14 +04:00
start = - 1 ;
2002-11-30 20:41:07 +03:00
/* not matched */
2002-01-21 20:49:57 +03:00
if ( start < 0 )
break ;
2002-11-30 20:41:07 +03:00
/* add matched completion if not yet added */
bufpos =
& edit - >
buffers1 [ start > > S_EDIT_BUF_SIZE ] [ start & M_EDIT_BUF_SIZE ] ;
2002-01-21 20:49:57 +03:00
skip = 0 ;
for ( i = 0 ; i < * num ; i + + ) {
2002-11-30 20:41:07 +03:00
if ( strncmp
2005-05-11 03:04:32 +04:00
( ( char * ) & compl [ i ] . text [ word_len ] ,
( char * ) & bufpos [ word_len ] , max ( len ,
compl [ i ] . len ) -
word_len ) = = 0 ) {
2002-01-21 20:49:57 +03:00
skip = 1 ;
2002-11-30 20:41:07 +03:00
break ; /* skip it, already added */
2002-01-21 20:49:57 +03:00
}
}
if ( skip )
continue ;
2002-11-30 20:41:07 +03:00
compl [ * num ] . text = g_malloc ( len + 1 ) ;
2002-01-21 20:49:57 +03:00
compl [ * num ] . len = len ;
for ( i = 0 ; i < len ; i + + )
compl [ * num ] . text [ i ] = * ( bufpos + i ) ;
compl [ * num ] . text [ i ] = ' \0 ' ;
( * num ) + + ;
2002-11-30 20:41:07 +03:00
/* note the maximal length needed for the completion dialog */
2002-01-21 20:49:57 +03:00
if ( len > max_len )
max_len = len ;
}
2002-11-30 20:41:07 +03:00
return max_len ;
2002-01-21 20:49:57 +03:00
}
2002-11-30 20:41:07 +03:00
/*
* Complete current word using regular expression search
* backwards beginning at the current cursor position .
*/
void
edit_complete_word_cmd ( WEdit * edit )
2002-01-21 20:49:57 +03:00
{
int word_len = 0 , i , num_compl = 0 , max_len ;
long word_start = 0 ;
2005-05-11 03:04:32 +04:00
unsigned char * bufpos ;
2003-11-24 23:27:34 +03:00
char * match_expr ;
2002-11-30 20:41:07 +03:00
struct selection compl [ MAX_WORD_COMPLETIONS ] ; /* completions */
/* don't want to disturb another search */
2009-04-29 17:13:12 +04:00
int old_replace_mode = edit - > replace_mode ;
int old_rb = edit - > replace_backwards ;
int old_rc = edit - > replace_case ;
2002-01-21 20:49:57 +03:00
2002-11-30 20:41:07 +03:00
/* search start of word to be completed */
2002-01-21 20:49:57 +03:00
if ( ! edit_find_word_start ( edit , & word_start , & word_len ) )
return ;
2002-11-30 20:41:07 +03:00
/* prepare match expression */
2002-01-21 20:49:57 +03:00
bufpos = & edit - > buffers1 [ word_start > > S_EDIT_BUF_SIZE ]
2002-11-30 20:41:07 +03:00
[ word_start & M_EDIT_BUF_SIZE ] ;
2009-02-26 00:53:52 +03:00
match_expr = g_strdup_printf ( " %.*s[a-zA-Z_0-9]+ " , word_len , bufpos ) ;
2002-11-30 20:41:07 +03:00
/* init search: backward, regexp, whole word, case sensitive */
2009-04-29 17:13:12 +04:00
edit_set_search_parameters ( edit , 0 , 1 , 1 ) ;
2002-01-21 20:49:57 +03:00
2002-11-30 20:41:07 +03:00
/* collect the possible completions */
/* start search from curs1 down to begin of file */
max_len =
edit_collect_completions ( edit , word_start , word_len , match_expr ,
( struct selection * ) & compl , & num_compl ) ;
2002-01-21 20:49:57 +03:00
if ( num_compl > 0 ) {
2002-11-30 20:41:07 +03:00
/* insert completed word if there is only one match */
2002-01-21 20:49:57 +03:00
if ( num_compl = = 1 ) {
for ( i = word_len ; i < compl [ 0 ] . len ; i + + )
edit_insert ( edit , * ( compl [ 0 ] . text + i ) ) ;
2002-11-30 20:41:07 +03:00
}
/* more than one possible completion => ask the user */
2002-01-21 20:49:57 +03:00
else {
2002-11-30 20:41:07 +03:00
/* !!! usually only a beep is expected and when <ALT-TAB> is !!! */
/* !!! pressed again the selection dialog pops up, but that !!! */
/* !!! seems to require a further internal state !!! */
/*beep (); */
/* let the user select the preferred completion */
2009-04-29 17:13:12 +04:00
editcmd_dialog_completion_show ( edit , max_len , word_len ,
2002-11-30 20:41:07 +03:00
( struct selection * ) & compl ,
num_compl ) ;
2002-01-21 20:49:57 +03:00
}
}
2002-11-30 20:41:07 +03:00
2009-02-06 01:27:37 +03:00
g_free ( match_expr ) ;
2002-11-30 20:41:07 +03:00
/* release memory before return */
2002-01-21 20:49:57 +03:00
for ( i = 0 ; i < num_compl ; i + + )
2009-02-06 01:27:37 +03:00
g_free ( compl [ i ] . text ) ;
2002-01-21 20:49:57 +03:00
2002-11-30 20:41:07 +03:00
/* restore search parameters */
2009-04-29 17:13:12 +04:00
edit_set_search_parameters ( edit , old_replace_mode , old_rb , old_rc ) ;
2002-01-21 20:49:57 +03:00
}
2005-07-20 15:56:30 +04:00
void
edit_select_codepage_cmd ( WEdit * edit )
{
# ifdef HAVE_CHARSET
do_select_codepage ( ) ;
2009-04-17 01:28:02 +04:00
if ( get_codepage_id ( source_codepage ) )
edit - > utf8 = str_isutf8 ( get_codepage_id ( source_codepage ) ) ;
2005-07-20 15:56:30 +04:00
edit - > force = REDRAW_COMPLETELY ;
edit_refresh_cmd ( edit ) ;
# endif
}
void
edit_insert_literal_cmd ( WEdit * edit )
{
int char_for_insertion =
2009-04-29 17:13:12 +04:00
editcmd_dialog_raw_key_query ( _ ( " Insert Literal " ) ,
2005-07-20 15:56:30 +04:00
_ ( " Press any key: " ) , 0 ) ;
edit_execute_key_command ( edit , - 1 ,
ascii_alpha_to_cntrl ( char_for_insertion ) ) ;
}
void
edit_execute_macro_cmd ( WEdit * edit )
{
int command =
2009-04-29 17:13:12 +04:00
CK_Macro ( editcmd_dialog_raw_key_query
2005-07-20 15:56:30 +04:00
( _ ( " Execute Macro " ) , _ ( " Press macro hotkey: " ) ,
1 ) ) ;
if ( command = = CK_Macro ( 0 ) )
command = CK_Insert_Char ;
edit_execute_key_command ( edit , command , - 1 ) ;
}
void
edit_begin_end_macro_cmd ( WEdit * edit )
{
int command ;
/* edit is a pointer to the widget */
if ( edit ) {
command =
edit - > macro_i <
0 ? CK_Begin_Record_Macro : CK_End_Record_Macro ;
edit_execute_key_command ( edit , command , - 1 ) ;
}
}
2009-02-26 00:53:52 +03:00
int
edit_load_forward_cmd ( WEdit * edit )
{
if ( edit - > modified ) {
if ( edit_query_dialog2
( _ ( " Warning " ) ,
_ ( " Current text was modified without a file save. \n "
" Continue discards these changes. " ) , _ ( " C&ontinue " ) ,
_ ( " &Cancel " ) ) ) {
edit - > force | = REDRAW_COMPLETELY ;
return 0 ;
}
}
if ( edit_stack_iterator + 1 < MAX_HISTORY_MOVETO ) {
if ( edit_history_moveto [ edit_stack_iterator + 1 ] . line < 1 ) {
return 1 ;
}
edit_stack_iterator + + ;
if ( edit_history_moveto [ edit_stack_iterator ] . filename ) {
edit_reload_line ( edit , edit_history_moveto [ edit_stack_iterator ] . filename ,
edit_history_moveto [ edit_stack_iterator ] . line ) ;
return 0 ;
} else {
return 1 ;
}
} else {
return 1 ;
}
}
int
edit_load_back_cmd ( WEdit * edit )
{
if ( edit - > modified ) {
if ( edit_query_dialog2
( _ ( " Warning " ) ,
_ ( " Current text was modified without a file save. \n "
" Continue discards these changes. " ) , _ ( " C&ontinue " ) ,
_ ( " &Cancel " ) ) ) {
edit - > force | = REDRAW_COMPLETELY ;
return 0 ;
}
}
if ( edit_stack_iterator > 0 ) {
edit_stack_iterator - - ;
if ( edit_history_moveto [ edit_stack_iterator ] . filename ) {
edit_reload_line ( edit , edit_history_moveto [ edit_stack_iterator ] . filename ,
edit_history_moveto [ edit_stack_iterator ] . line ) ;
return 0 ;
} else {
return 1 ;
}
} else {
return 1 ;
}
}
void
edit_get_match_keyword_cmd ( WEdit * edit )
{
2009-03-04 23:10:55 +03:00
int word_len = 0 ;
int num_def = 0 ;
int max_len = 0 ;
2009-04-24 02:47:22 +04:00
int i ;
2009-02-26 00:53:52 +03:00
long word_start = 0 ;
unsigned char * bufpos ;
char * match_expr ;
2009-02-26 23:50:58 +03:00
char * path = NULL ;
char * ptr = NULL ;
char * tagfile = NULL ;
2009-03-05 13:27:45 +03:00
etags_hash_t def_hash [ MAX_DEFINITIONS ] ;
2009-02-26 00:53:52 +03:00
2009-04-24 02:47:22 +04:00
for ( i = 0 ; i < MAX_DEFINITIONS ; i + + ) {
2009-02-26 00:53:52 +03:00
def_hash [ i ] . filename = NULL ;
}
/* search start of word to be completed */
if ( ! edit_find_word_start ( edit , & word_start , & word_len ) )
return ;
/* prepare match expression */
bufpos = & edit - > buffers1 [ word_start > > S_EDIT_BUF_SIZE ]
[ word_start & M_EDIT_BUF_SIZE ] ;
match_expr = g_strdup_printf ( " %.*s " , word_len , bufpos ) ;
2009-03-06 18:28:54 +03:00
ptr = g_get_current_dir ( ) ;
path = g_strconcat ( ptr , G_DIR_SEPARATOR_S , ( char * ) NULL ) ;
g_free ( ptr ) ;
2009-02-26 00:53:52 +03:00
2009-03-06 18:28:54 +03:00
/* Recursive search file 'TAGS' in parent dirs */
2009-03-02 17:43:22 +03:00
do {
ptr = g_path_get_dirname ( path ) ;
g_free ( path ) ; path = ptr ;
2009-03-06 18:28:54 +03:00
g_free ( tagfile ) ;
tagfile = g_build_filename ( path , TAGS_NAME , ( char * ) NULL ) ;
2009-03-02 17:43:22 +03:00
if ( exist_file ( tagfile ) )
break ;
} while ( strcmp ( path , G_DIR_SEPARATOR_S ) ! = 0 ) ;
if ( tagfile ) {
2009-03-06 18:28:54 +03:00
num_def = etags_set_definition_hash ( tagfile , path , match_expr , ( etags_hash_t * ) & def_hash ) ;
2009-03-02 17:43:22 +03:00
g_free ( tagfile ) ;
}
2009-02-26 23:50:58 +03:00
g_free ( path ) ;
2009-03-02 17:43:22 +03:00
2009-03-06 18:28:54 +03:00
max_len = MAX_WIDTH_DEF_DIALOG ;
2009-02-26 00:53:52 +03:00
word_len = 0 ;
if ( num_def > 0 ) {
2009-04-29 17:13:12 +04:00
editcmd_dialog_select_definition_show ( edit , match_expr , max_len , word_len ,
2009-03-05 13:27:45 +03:00
( etags_hash_t * ) & def_hash ,
2009-02-26 00:53:52 +03:00
num_def ) ;
}
g_free ( match_expr ) ;
}