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
*/
2009-02-07 00:09:50 +03:00
/** \file
* \ brief Source : editor high level editing commands
* \ author Paul Sheer
* \ date 1996 , 1997
*/
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>
2009-02-06 02:30:45 +03:00
# include <fcntl.h>
2005-02-22 20:00:36 +03:00
# include "../src/global.h"
2009-08-16 19:27:33 +04:00
# include "../src/tty/tty.h"
2009-05-08 14:01:05 +04:00
# include "../src/tty/key.h" /* XCTRL */
# include "../src/history.h"
2003-10-29 11:54:22 +03:00
# 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/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 */
2009-08-12 17:47:52 +04:00
# include "../src/mcconfig/mcconfig.h"
2003-10-15 01:48:40 +04:00
2009-06-19 14:36:36 +04:00
# include "../edit/edit-impl.h"
2009-05-07 23:06:05 +04:00
# include "../edit/edit.h"
# include "../edit/editlock.h"
2009-07-05 19:04:42 +04:00
# include "../src/cmddef.h"
2009-05-07 23:06:05 +04:00
# include "../edit/edit-widget.h"
# include "../edit/editcmd_dialogs.h"
# include "../edit/etags.h"
2001-08-24 22:23:17 +04:00
/* globals: */
/* search and replace: */
2009-08-22 16:56:06 +04:00
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 ;
2001-08-24 22:23:17 +04:00
2009-08-22 16:56:06 +04:00
search_create_bookmark = 0 ;
book_mark_flush ( edit , - 1 ) ;
2009-04-23 15:30:14 +04:00
for ( ; ; ) {
if ( ! mc_search_run ( edit - > search , ( void * ) edit , q , edit - > last_byte , & len ) )
break ;
2009-08-22 16:56:06 +04:00
if ( found = = 0 )
edit - > search_start = edit - > search - > normal_offset ;
2009-04-23 15:30:14 +04:00
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 ;
}
2001-08-24 22:23:17 +04:00
2009-08-22 16:56:06 +04:00
if ( found = = 0 ) {
2009-04-23 15:30:14 +04:00
edit_error_dialog ( _ ( " Search " ) , _ ( " Search string not found " ) ) ;
2009-08-22 16:56:06 +04:00
} else {
edit_cursor_move ( edit , edit - > search_start - edit - > curs1 ) ;
edit_scroll_screen_over_cursor ( edit ) ;
2009-04-23 15:30:14 +04:00
}
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 )
2002-08-21 03:18:36 +04:00
{
2009-04-23 15:30:14 +04:00
return edit_get_byte ( ( WEdit * ) user_data , ( long ) char_offset ) ;
2002-08-21 03:18:36 +04:00
}
2001-08-24 22:23:17 +04:00
void edit_help_cmd ( WEdit * edit )
{
interactive_display ( NULL , " [Internal File Editor] " ) ;
edit - > force | = REDRAW_COMPLETELY ;
}
2009-08-16 19:27:33 +04:00
void
edit_refresh_cmd ( WEdit * edit )
2001-08-24 22:23:17 +04:00
{
2009-06-05 19:17:18 +04:00
# ifdef HAVE_SLANG
2009-08-16 19:27:33 +04:00
int color ;
edit_get_syntax_color ( edit , - 1 , & color ) ;
2009-06-02 08:55:07 +04:00
tty_touch_screen ( ) ;
2009-08-16 19:27:33 +04:00
mc_refresh ( ) ;
2009-06-05 19:17:18 +04:00
# else
2009-08-16 19:27:33 +04:00
clr_scr ( ) ;
2009-06-05 19:17:18 +04:00
repaint_screen ( ) ;
# endif /* !HAVE_SLANG */
2009-08-14 18:46:44 +04:00
tty_keypad ( TRUE ) ;
2001-08-24 22:23:17 +04:00
}
/* 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
2009-08-29 16:22:39 +04: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 ) {
2009-08-29 16:22:39 +04:00
filelen = edit_write_stream ( edit , file ) ;
2001-08-24 22:23:17 +04:00
# 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 ) ;
2009-08-29 16:22:39 +04:00
} else if ( edit - > lb = = LB_ASIS ) { /* do not change line breaks */
2001-08-24 22:23:17 +04:00
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 ;
2009-08-29 14:45:50 +04:00
} else { /* change line breaks */
FILE * file ;
mc_close ( fd ) ;
file = ( FILE * ) fopen ( savename , " w " ) ;
if ( file ) {
2009-08-29 16:22:39 +04:00
filelen = edit_write_stream ( edit , file ) ;
2009-08-29 14:45:50 +04:00
fclose ( file ) ;
} else {
2009-08-29 16:22:39 +04:00
char * msg ;
msg = g_strdup_printf ( _ ( " Cannot open file for writing: %s " ) , savename ) ;
edit_error_dialog ( _ ( " Error " ) , msg ) ;
g_free ( msg ) ;
2009-08-29 14:45:50 +04:00
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 ;
}
2009-07-30 13:59:29 +04:00
void
menu_save_mode_cmd ( void )
2001-08-24 22:23:17 +04:00
{
2009-07-30 13:59:29 +04:00
/* diaog sizes */
const int DLG_X = 38 ;
const int DLG_Y = 10 ;
char * str_result ;
const char * str [ ] =
2001-08-24 22:23:17 +04:00
{
N_ ( " Quick save " ) ,
N_ ( " Safe save " ) ,
2009-07-30 13:59:29 +04:00
N_ ( " Do backups --> " )
} ;
2009-04-29 17:13:12 +04:00
2009-07-30 13:59:29 +04:00
QuickWidget widgets [ ] =
2001-08-24 22:23:17 +04:00
{
2009-07-30 13:59:29 +04:00
/* 0 */ QUICK_BUTTON ( 18 , DLG_X , 7 , DLG_Y , N_ ( " &Cancel " ) , B_CANCEL , NULL ) ,
/* 1 */ QUICK_BUTTON ( 6 , DLG_X , 7 , DLG_Y , N_ ( " &OK " ) , B_ENTER , NULL ) ,
/* 2 */ QUICK_INPUT ( 23 , DLG_X , 5 , DLG_Y , option_backup_ext , 9 , 0 , " edit-backup-ext " , & str_result ) ,
/* 3 */ QUICK_LABEL ( 22 , DLG_X , 4 , DLG_Y , N_ ( " Extension: " ) ) ,
/* 4 */ QUICK_RADIO ( 4 , DLG_X , 3 , DLG_Y , 3 , str , & option_save_mode ) ,
QUICK_END
} ;
QuickDialog dialog =
{
DLG_X , DLG_Y , - 1 , - 1 , N_ ( " Edit Save Mode " ) ,
" [Edit Save Mode] " , widgets , FALSE
} ;
size_t i ;
size_t maxlen = 0 ;
int dlg_x ;
size_t l1 , w0 , w1 , w3 ;
assert ( option_backup_ext ! = NULL ) ;
2001-08-24 22:23:17 +04:00
2009-07-30 13:59:29 +04:00
/* OK/Cancel buttons */
w0 = str_term_width1 ( _ ( widgets [ 0 ] . u . button . text ) ) + 2 ;
w1 = str_term_width1 ( _ ( widgets [ 1 ] . u . button . text ) ) + 4 ; /* default batton */
2001-08-24 22:23:17 +04:00
2009-07-30 13:59:29 +04:00
w3 = str_term_width1 ( _ ( widgets [ 3 ] . u . label . text ) ) ;
2001-08-24 22:23:17 +04:00
2009-07-30 13:59:29 +04:00
maxlen = l1 = w0 + w1 + 6 ;
2001-08-24 22:23:17 +04:00
2009-07-30 13:59:29 +04:00
for ( i = 0 ; i < 3 ; i + + ) {
# ifdef ENABLE_NLS
str [ i ] = _ ( str [ i ] ) ;
# endif
maxlen = max ( maxlen , ( size_t ) str_term_width1 ( str [ i ] ) + 7 ) ;
2001-08-24 22:23:17 +04:00
}
2009-07-30 13:59:29 +04:00
dlg_x = maxlen + w3 + 5 + 2 ;
widgets [ 2 ] . u . input . len = w3 ; /* input field length */
dlg_x = min ( COLS , dlg_x ) ;
dialog . xlen = dlg_x ;
widgets [ 0 ] . relative_x = dlg_x * 2 / 3 - w0 / 2 ;
widgets [ 1 ] . relative_x = dlg_x / 3 - w1 / 2 ;
widgets [ 2 ] . relative_x = widgets [ 3 ] . relative_x = maxlen + 3 ;
2005-09-07 12:54:11 +04:00
2009-07-30 13:59:29 +04:00
for ( i = 0 ; i < sizeof ( widgets ) / sizeof ( widgets [ 0 ] ) ; i + + )
widgets [ i ] . x_divisions = dlg_x ;
if ( quick_dialog ( & dialog ) ! = B_CANCEL ) {
g_free ( option_backup_ext ) ;
option_backup_ext = str_result ;
}
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
}
2009-08-29 16:22:39 +04:00
2009-08-29 14:45:50 +04:00
static char *
2009-08-29 16:22:39 +04:00
edit_get_save_file_as ( WEdit * edit )
2009-08-29 14:45:50 +04:00
{
# define DLG_WIDTH 64
# define DLG_HEIGHT 14
2009-07-30 13:59:29 +04:00
static LineBreaks cur_lb = LB_ASIS ;
2009-08-29 16:22:39 +04:00
char * filename = edit - > filename ;
2009-09-30 03:09:54 +04:00
const char * lb_names [ LB_NAMES ] =
2009-08-29 14:45:50 +04:00
{
2009-08-29 16:22:39 +04:00
N_ ( " &Do not change " ) ,
N_ ( " &Unix format (LF) " ) ,
N_ ( " &Windows/DOS format (CR LF) " ) ,
2009-09-02 09:17:30 +04:00
N_ ( " &Macintosh format (CR) " )
2009-08-29 14:45:50 +04:00
} ;
QuickWidget quick_widgets [ ] =
{
2009-07-30 13:59:29 +04:00
QUICK_BUTTON ( 6 , 10 , DLG_HEIGHT - 3 , DLG_HEIGHT , N_ ( " &Cancel " ) , B_CANCEL , NULL ) ,
QUICK_BUTTON ( 2 , 10 , DLG_HEIGHT - 3 , DLG_HEIGHT , N_ ( " &OK " ) , B_ENTER , NULL ) ,
2009-09-30 03:09:54 +04:00
QUICK_RADIO ( 5 , DLG_WIDTH , DLG_HEIGHT - 8 , DLG_HEIGHT , LB_NAMES , lb_names , ( int * ) & cur_lb ) ,
2009-07-30 13:59:29 +04:00
QUICK_LABEL ( 3 , DLG_WIDTH , DLG_HEIGHT - 9 , DLG_HEIGHT , N_ ( " Change line breaks to: " ) ) ,
QUICK_INPUT ( 3 , DLG_WIDTH , DLG_HEIGHT - 11 , DLG_HEIGHT , filename , DLG_WIDTH - 6 , 0 , " save-as " , & filename ) ,
QUICK_LABEL ( 2 , DLG_WIDTH , DLG_HEIGHT - 12 , DLG_HEIGHT , N_ ( " Enter file name: " ) ) ,
QUICK_END
2009-08-29 14:45:50 +04:00
} ;
QuickDialog Quick_options =
{
2009-07-30 13:59:29 +04:00
DLG_WIDTH , DLG_HEIGHT , - 1 , - 1 ,
N_ ( " Save As " ) , " [Save File As] " ,
quick_widgets , FALSE
2009-08-29 14:45:50 +04:00
} ;
2009-07-30 13:59:29 +04:00
if ( quick_dialog ( & Quick_options ) ! = B_CANCEL ) {
2009-08-29 16:22:39 +04:00
edit - > lb = cur_lb ;
2009-08-29 14:45:50 +04:00
return filename ;
}
return NULL ;
# undef DLG_WIDTH
# undef DLG_HEIGHT
}
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-08-29 16:22:39 +04:00
exp = edit_get_save_file_as ( edit ) ;
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 ;
}
2009-08-18 23:28:59 +04:00
} else {
edit - > stat1 . st_mode | = S_IWUSR ;
2001-08-24 22:23:17 +04:00
}
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
2009-08-09 20:05:52 +04:00
if ( different_filename )
{
/*
* Allow user to write into saved ( under another name ) file
* even if original file had r / o user permissions .
*/
edit - > stat1 . st_mode | = S_IWRITE ;
}
2009-08-29 16:22:39 +04:00
rv = edit_save_file ( edit , exp ) ;
2006-03-17 13:24:50 +03:00
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-08-29 16:22:39 +04:00
if ( edit - > lb ! = LB_ASIS )
2009-08-29 14:45:50 +04:00
edit_reload ( 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-06-14 19:18:27 +04:00
filename = concat_dir_and_file ( home_dir , EDIT_MACRO_FILE ) ;
2009-04-14 16:12:36 +04:00
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-06-14 19:18:27 +04:00
tmp = concat_dir_and_file ( home_dir , EDIT_TEMP_FILE ) ;
2009-04-14 16:12:36 +04:00
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-06-14 19:18:27 +04:00
tmp = concat_dir_and_file ( home_dir , EDIT_TEMP_FILE ) ;
tmp2 = concat_dir_and_file ( home_dir , EDIT_MACRO_FILE ) ;
2009-04-14 16:12:36 +04:00
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 ) ;
2009-08-29 16:22:39 +04:00
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 ;
}
2009-05-21 09:13:12 +04:00
static void
edit_load_syntax_file ( WEdit * edit )
{
char * extdir ;
int dir = 0 ;
if ( geteuid ( ) = = 0 ) {
dir = query_dialog ( _ ( " Syntax file edit " ) ,
_ ( " Which syntax file you want to edit? " ) , D_NORMAL , 2 ,
_ ( " &User " ) , _ ( " &System Wide " ) ) ;
}
2009-06-12 15:36:30 +04:00
extdir = concat_dir_and_file ( mc_home , " syntax " PATH_SEP_STR " Syntax " ) ;
if ( ! exist_file ( extdir ) ) {
g_free ( extdir ) ;
extdir = concat_dir_and_file ( mc_home_alt , " syntax " PATH_SEP_STR " Syntax " ) ;
}
2009-05-21 09:13:12 +04:00
if ( dir = = 0 ) {
char * buffer ;
2009-06-14 19:18:27 +04:00
buffer = concat_dir_and_file ( home_dir , EDIT_SYNTAX_FILE ) ;
2009-05-21 09:13:12 +04:00
check_for_default ( extdir , buffer ) ;
edit_load_file_from_filename ( edit , buffer ) ;
g_free ( buffer ) ;
} else if ( dir = = 1 )
edit_load_file_from_filename ( edit , extdir ) ;
g_free ( extdir ) ;
}
static void
edit_load_menu_file ( WEdit * edit )
{
char * buffer ;
char * menufile ;
int dir = 0 ;
dir = query_dialog (
_ ( " Menu edit " ) ,
_ ( " Which menu file do you want to edit? " ) , D_NORMAL ,
geteuid ( ) ? 2 : 3 , _ ( " &Local " ) , _ ( " &User " ) , _ ( " &System Wide " )
) ;
2009-06-14 19:18:27 +04:00
menufile = concat_dir_and_file ( mc_home , EDIT_GLOBAL_MENU ) ;
2009-05-21 09:13:12 +04:00
2009-05-22 18:14:47 +04:00
if ( ! exist_file ( menufile ) ) {
g_free ( menufile ) ;
2009-06-14 19:18:27 +04:00
menufile = concat_dir_and_file ( mc_home_alt , EDIT_GLOBAL_MENU ) ;
2009-05-22 18:14:47 +04:00
}
2009-05-21 09:13:12 +04:00
switch ( dir ) {
case 0 :
2009-06-14 19:18:27 +04:00
buffer = g_strdup ( EDIT_LOCAL_MENU ) ;
2009-05-21 09:13:12 +04:00
check_for_default ( menufile , buffer ) ;
chmod ( buffer , 0600 ) ;
break ;
case 1 :
2009-06-14 19:18:27 +04:00
buffer = concat_dir_and_file ( home_dir , EDIT_HOME_MENU ) ;
2009-05-21 09:13:12 +04:00
check_for_default ( menufile , buffer ) ;
break ;
case 2 :
2009-06-14 19:18:27 +04:00
buffer = concat_dir_and_file ( mc_home , EDIT_GLOBAL_MENU ) ;
2009-05-22 18:14:47 +04:00
if ( ! exist_file ( buffer ) ) {
g_free ( buffer ) ;
2009-06-14 19:18:27 +04:00
buffer = concat_dir_and_file ( mc_home_alt , EDIT_GLOBAL_MENU ) ;
2009-05-22 18:14:47 +04:00
}
2009-05-21 09:13:12 +04:00
break ;
default :
g_free ( menufile ) ;
return ;
}
edit_load_file_from_filename ( edit , buffer ) ;
g_free ( buffer ) ;
g_free ( menufile ) ;
}
2002-11-30 21:49:20 +03:00
int
2009-05-21 09:13:12 +04:00
edit_load_cmd ( WEdit * edit , edit_current_file_t what )
2001-08-24 22:23:17 +04:00
{
char * exp ;
2009-05-21 09:13:12 +04:00
if ( edit - > modified
& & ( edit_query_dialog2
2002-11-30 21:49:20 +03:00
( _ ( " Warning " ) ,
_ ( " Current text was modified without a file save. \n "
2009-05-21 09:13:12 +04:00
" Continue discards these changes. " ) ,
_ ( " C&ontinue " ) , _ ( " &Cancel " ) ) = = 1 ) ) {
2001-08-24 22:23:17 +04:00
edit - > force | = REDRAW_COMPLETELY ;
return 0 ;
}
2009-05-21 09:13:12 +04:00
switch ( what ) {
case EDIT_FILE_COMMON :
exp = input_expand_dialog ( _ ( " Load " ) , _ ( " Enter file name: " ) ,
MC_HISTORY_EDIT_LOAD , edit - > filename ) ;
2001-08-24 22:23:17 +04:00
2009-05-21 09:13:12 +04:00
if ( exp ) {
if ( * exp )
edit_load_file_from_filename ( edit , exp ) ;
g_free ( exp ) ;
}
break ;
case EDIT_FILE_SYNTAX :
edit_load_syntax_file ( edit ) ;
break ;
case EDIT_FILE_MENU :
edit_load_menu_file ( edit ) ;
break ;
default :
break ;
2001-08-24 22:23:17 +04:00
}
2009-05-21 09:13:12 +04:00
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 ) ;
2009-08-15 02:51:39 +04:00
edit - > column2 = edit - > curs_col + edit - > over_col ;
2001-08-24 22:23:17 +04:00
}
return 0 ;
} else {
* start_mark = * end_mark = 0 ;
edit - > column2 = edit - > column1 = 0 ;
return 1 ;
}
}
# define space_width 1
2009-06-16 23:47:20 +04:00
void
2002-11-13 07:32:00 +03:00
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 ) ;
}
2009-06-16 23:47:20 +04:00
# define TEMP_BUF_LEN 1024
int
edit_insert_column_of_text_from_file ( WEdit * edit , int file )
{
long cursor ;
int i , col ;
int blocklen = - 1 , width ;
unsigned char * data ;
cursor = edit - > curs1 ;
col = edit_get_col ( edit ) ;
data = g_malloc ( TEMP_BUF_LEN ) ;
while ( ( blocklen = mc_read ( file , ( char * ) data , TEMP_BUF_LEN ) ) > 0 ) {
for ( width = 0 ; width < blocklen ; width + + ) {
if ( data [ width ] = = ' \n ' )
break ;
}
for ( i = 0 ; i < blocklen ; 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 + + ) {
if ( p = = edit - > last_byte ) {
edit_cursor_move ( edit , edit - > last_byte - edit - > curs1 ) ;
edit_insert_ahead ( edit , ' \n ' ) ;
p + + ;
break ;
}
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 ) ;
g_free ( data ) ;
edit - > force | = REDRAW_PAGE ;
return blocklen ;
}
2001-08-24 22:23:17 +04:00
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 ) ;
2009-08-20 17:12:02 +04:00
b = max ( min ( c , d ) , min ( edit - > column1 , edit - > column2 ) ) ;
c = max ( c , d + edit - > over_col ) ;
2001-08-24 22:23:17 +04:00
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
2009-04-30 13:35:24 +04:00
static gboolean
editcmd_find ( WEdit * edit , gsize * len )
2001-08-24 22:23:17 +04:00
{
2009-08-19 23:36:23 +04:00
off_t search_start = edit - > search_start ;
off_t search_end ;
long start_mark = 0 ;
long end_mark = edit - > last_byte ;
int mark_res = 0 ;
if ( edit - > only_in_selection ) {
mark_res = eval_marks ( edit , & start_mark , & end_mark ) ;
if ( mark_res ! = 0 ) {
edit - > search - > error = MC_SEARCH_E_NOTFOUND ;
edit - > search - > error_str = g_strdup ( _ ( " Search string not found " ) ) ;
return FALSE ;
}
if ( edit - > replace_backwards ) {
if ( search_start > end_mark | | search_start < = start_mark ) {
search_start = end_mark ;
}
} else {
if ( search_start < start_mark | | search_start > = end_mark ) {
search_start = start_mark ;
}
}
2009-08-24 10:58:38 +04:00
} else {
if ( edit - > replace_backwards )
end_mark = max ( 1 , edit - > curs1 ) - 1 ;
2009-08-19 23:36:23 +04:00
}
2009-04-30 13:35:24 +04:00
if ( edit - > replace_backwards ) {
2009-08-19 23:36:23 +04:00
search_end = end_mark ;
while ( ( int ) search_start > = start_mark ) {
if ( search_end > search_start + edit - > search - > original_len
& & mc_search_is_fixed_search_str ( edit - > search ) ) {
search_end = search_start + edit - > search - > original_len ;
}
if ( mc_search_run ( edit - > search , ( void * ) edit , search_start , search_end , len )
& & edit - > search - > normal_offset = = search_start ) {
return TRUE ;
}
search_start - - ;
}
edit - > search - > error_str = g_strdup ( _ ( " Search string not found " ) ) ;
2009-04-30 13:35:24 +04:00
} else {
2009-08-19 23:36:23 +04:00
return mc_search_run ( edit - > search , ( void * ) edit , search_start , end_mark , len ) ;
2001-08-24 22:23:17 +04:00
}
2009-04-30 13:35:24 +04:00
return FALSE ;
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')
2004-12-01 03:55:17 +03:00
2009-04-23 18:28:07 +04:00
static char *
edit_replace_cmd__conv_to_display ( char * str )
2001-08-24 22:23:17 +04:00
{
2009-05-07 13:20:34 +04:00
# ifdef HAVE_CHARSET
2009-04-23 18:28:07 +04:00
GString * tmp ;
tmp = str_convert_to_display ( str ) ;
2001-08-24 22:23:17 +04:00
2009-04-23 18:28:07 +04:00
if ( tmp & & tmp - > len ) {
g_free ( str ) ;
str = tmp - > str ;
2001-08-24 22:23:17 +04:00
}
2009-04-23 18:28:07 +04:00
g_string_free ( tmp , FALSE ) ;
return str ;
2009-05-07 13:20:34 +04:00
# else
return g_strdup ( str ) ;
# endif
2001-08-24 22:23:17 +04:00
}
2009-04-23 18:28:07 +04:00
static char *
edit_replace_cmd__conv_to_input ( char * str )
2001-08-24 22:23:17 +04:00
{
2009-05-07 13:20:34 +04:00
# ifdef HAVE_CHARSET
2009-04-23 18:28:07 +04:00
GString * tmp ;
tmp = str_convert_to_input ( str ) ;
2001-10-20 11:20:30 +04:00
2009-04-23 18:28:07 +04:00
if ( tmp & & tmp - > len ) {
g_free ( str ) ;
str = tmp - > str ;
2001-08-24 22:23:17 +04:00
}
2009-04-23 18:28:07 +04:00
g_string_free ( tmp , FALSE ) ;
return str ;
2009-05-07 13:20:34 +04:00
# else
return g_strdup ( str ) ;
# endif
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 ;
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
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
2009-08-04 22:53:41 +04:00
if ( edit - > search ) {
2009-04-23 18:28:07 +04:00
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-08-04 22:53:41 +04:00
if ( ! edit - > search ) {
2009-04-23 18:28:07 +04:00
edit - > search = mc_search_new ( input1 , - 1 ) ;
2009-08-04 22:53:41 +04:00
if ( edit - > search = = NULL ) {
2009-04-23 18:28:07 +04:00
edit - > search_start = edit - > curs1 ;
return ;
2001-08-24 22:23:17 +04:00
}
2009-04-29 17:13:12 +04:00
edit - > search - > search_type = edit - > search_type ;
2009-04-30 17:58:28 +04:00
edit - > search - > is_all_charsets = edit - > all_codepages ;
2009-04-29 17:13:12 +04:00
edit - > search - > is_case_sentitive = edit - > replace_case ;
2009-08-22 15:06:01 +04:00
edit - > search - > whole_words = edit - > whole_words ;
2009-04-23 18:28:07 +04:00
edit - > search - > search_fn = edit_search_cmd_callback ;
2001-08-24 22:23:17 +04:00
}
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
2009-08-04 22:53:41 +04:00
if ( ! editcmd_find ( edit , & len ) ) {
if ( ! ( edit - > search - > error = = MC_SEARCH_E_OK | |
( once_found & & edit - > search - > error = = MC_SEARCH_E_NOTFOUND ) ) ) {
2009-04-23 18:46:38 +04:00
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 ) {
2009-06-30 15:10:42 +04:00
guint i ;
2004-12-03 00:02:07 +03:00
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-07-14 17:37:49 +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-07-14 17:37:49 +04:00
/* and prompt 2/3 down */
switch ( editcmd_dialog_replace_prompt_show ( edit , input1 , input2 , - 1 , - 1 ) ) {
2001-08-24 22:23:17 +04:00
case B_ENTER :
2009-07-14 17:37:49 +04:00
replace_yes = 1 ;
2001-08-24 22:23:17 +04:00
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_CANCEL :
replace_yes = 0 ;
2009-07-14 17:37:49 +04:00
edit - > replace_mode = - 1 ;
2001-08-24 22:23:17 +04:00
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-07-14 17:37:49 +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-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-08-04 22:53:41 +04:00
if ( edit - > search ! = NULL ) {
search_string = g_strndup ( edit - > search - > original , edit - > search - > original_len ) ;
search_string_dup = search_string ;
} else {
GList * history ;
history = history_get ( MC_HISTORY_SHARED_SEARCH ) ;
if ( history ! = NULL & & history - > data ! = NULL ) {
search_string_dup = search_string = ( char * ) g_strdup ( history - > data ) ;
history = g_list_first ( history ) ;
g_list_foreach ( history , ( GFunc ) g_free , NULL ) ;
g_list_free ( history ) ;
}
edit - > search_start = edit - > curs1 ;
}
2001-08-24 22:23:17 +04:00
2009-08-04 22:53:41 +04:00
if ( ! again ) {
2001-08-24 22:23:17 +04:00
# ifdef HAVE_CHARSET
2009-04-23 15:30:14 +04:00
GString * tmp ;
2009-08-04 22:53:41 +04:00
if ( search_string & & * search_string ) {
2009-04-23 15:30:14 +04:00
tmp = str_convert_to_display ( search_string ) ;
2001-08-24 22:23:17 +04:00
2009-04-23 15:30:14 +04:00
g_free ( search_string_dup ) ;
search_string_dup = NULL ;
2001-08-24 22:23:17 +04:00
2009-04-23 15:30:14 +04:00
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-08-04 22:53:41 +04:00
if ( search_string & & * search_string ) {
2009-04-23 15:30:14 +04:00
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 */
2001-08-24 22:23:17 +04:00
edit_push_action ( edit , KEY_PRESS + edit - > start_display ) ;
2009-08-04 22:53:41 +04:00
if ( ! search_string ) {
2009-04-23 15:30:14 +04:00
edit - > force | = REDRAW_COMPLETELY ;
edit_scroll_screen_over_cursor ( edit ) ;
return ;
}
2001-08-24 22:23:17 +04:00
2009-08-04 22:53:41 +04:00
if ( edit - > search ) {
2009-04-23 15:30:14 +04:00
mc_search_free ( edit - > search ) ;
edit - > search = NULL ;
}
2001-08-24 22:23:17 +04:00
}
2009-08-04 22:53:41 +04:00
if ( ! edit - > search ) {
2009-04-23 15:30:14 +04:00
edit - > search = mc_search_new ( search_string , - 1 ) ;
2009-08-04 22:53:41 +04:00
if ( edit - > search = = NULL ) {
2009-04-23 15:30:14 +04:00
edit - > search_start = edit - > curs1 ;
return ;
}
2009-04-29 17:13:12 +04:00
edit - > search - > search_type = edit - > search_type ;
2009-04-30 17:58:28 +04:00
edit - > search - > is_all_charsets = edit - > all_codepages ;
2009-04-29 17:13:12 +04:00
edit - > search - > is_case_sentitive = edit - > replace_case ;
2009-08-22 15:06:01 +04:00
edit - > search - > whole_words = edit - > whole_words ;
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-08-04 22:53:41 +04:00
if ( search_create_bookmark ) {
2009-04-24 02:47:22 +04:00
edit_search_cmd_search_create_bookmark ( edit ) ;
2009-08-04 22:53:41 +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-30 13:35:24 +04:00
2009-08-04 22:53:41 +04:00
if ( editcmd_find ( edit , & len ) ) {
2009-04-23 15:30:14 +04:00
edit - > found_start = edit - > search_start = edit - > search - > normal_offset ;
edit - > found_len = len ;
2009-08-24 10:58:38 +04:00
edit - > over_col = 0 ;
2009-04-23 15:30:14 +04:00
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 + + ;
2009-08-04 22:53:41 +04:00
} else {
2009-04-23 15:30:14 +04:00
edit - > search_start = edit - > curs1 ;
2009-05-05 17:19:32 +04:00
if ( edit - > search - > error_str )
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
}
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 ) {
int r ;
2009-06-16 23:47:20 +04:00
r = mc_write ( file , VERTICAL_MAGIC , sizeof ( VERTICAL_MAGIC ) ) ;
if ( r > 0 ) {
unsigned char * block , * p ;
p = block = edit_get_block ( edit , start , finish , & len ) ;
while ( len ) {
r = mc_write ( file , p , len ) ;
if ( r < 0 )
break ;
p + = r ;
len - = r ;
}
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 ;
2009-06-14 19:18:27 +04:00
tmp = concat_dir_and_file ( home_dir , EDIT_CLIP_FILE ) ;
2009-04-14 16:12:36 +04:00
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 ;
2009-06-14 19:18:27 +04:00
tmp = concat_dir_and_file ( home_dir , EDIT_CLIP_FILE ) ;
2009-04-14 16:12:36 +04:00
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 ;
2009-06-14 19:18:27 +04:00
2001-08-24 22:23:17 +04:00
if ( eval_marks ( edit , & start_mark , & end_mark ) )
return 1 ;
2009-06-14 19:18:27 +04:00
tmp = concat_dir_and_file ( home_dir , EDIT_CLIP_FILE ) ;
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 ;
2009-06-14 19:18:27 +04:00
tmp = concat_dir_and_file ( home_dir , EDIT_CLIP_FILE ) ;
2009-04-14 16:12:36 +04:00
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-06-14 19:18:27 +04:00
tmp = concat_dir_and_file ( home_dir , EDIT_BLOCK_FILE ) ;
2009-04-14 16:12:36 +04:00
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-06-14 19:18:27 +04:00
tmp = g_strconcat ( " sort " , exp , " " , home_dir , PATH_SEP_STR EDIT_BLOCK_FILE , " > " ,
home_dir , PATH_SEP_STR EDIT_TEMP_FILE , ( char * ) NULL ) ;
2009-04-14 16:12:36 +04:00
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-06-14 19:18:27 +04:00
tmp = concat_dir_and_file ( home_dir , EDIT_TEMP_FILE ) ;
2009-04-14 16:12:36 +04:00
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-06-14 19:18:27 +04:00
tmp = g_strconcat ( exp , " > " , home_dir , PATH_SEP_STR EDIT_TEMP_FILE , ( char * ) NULL ) ;
2009-04-14 16:12:36 +04:00
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-06-14 19:18:27 +04:00
tmp = concat_dir_and_file ( home_dir , EDIT_TEMP_FILE ) ;
2009-04-14 16:12:36 +04:00
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-06-14 19:18:27 +04:00
o = g_strconcat ( mc_home , shell_cmd , ( char * ) NULL ) ; /* original source script */
2009-04-14 16:12:36 +04:00
h = g_strconcat ( home_dir , PATH_SEP_STR EDIT_DIR , shell_cmd , ( char * ) NULL ) ; /* home script */
2009-06-14 19:18:27 +04:00
b = concat_dir_and_file ( home_dir , EDIT_BLOCK_FILE ) ; /* 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 " ) ) ) {
2009-05-21 02:01:10 +04:00
o = g_strconcat ( mc_home_alt , shell_cmd , ( char * ) NULL ) ;
if ( ! ( script_src = fopen ( o , " r " ) ) ) {
fclose ( script_home ) ;
unlink ( h ) ;
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 ,
2009-06-14 19:18:27 +04:00
" " , home_dir , PATH_SEP_STR EDIT_BLOCK_FILE " /dev/null " , ( char * ) NULL ) ;
2009-04-14 16:12:36 +04:00
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 ;
QuickWidget quick_widgets [ ] =
{
2009-07-30 13:59:29 +04:00
/* 0 */ QUICK_BUTTON ( 6 , 10 , 9 , MAIL_DLG_HEIGHT , N_ ( " &Cancel " ) , B_CANCEL , NULL ) ,
/* 1 */ QUICK_BUTTON ( 2 , 10 , 9 , MAIL_DLG_HEIGHT , N_ ( " &OK " ) , B_ENTER , NULL ) ,
/* 2 */ QUICK_INPUT ( 3 , 50 , 8 , MAIL_DLG_HEIGHT , " " , 44 , 0 , " mail-dlg-input " , & tmail_cc ) ,
/* 3 */ QUICK_LABEL ( 2 , 50 , 7 , MAIL_DLG_HEIGHT , N_ ( " Copies to " ) ) ,
/* 4 */ QUICK_INPUT ( 3 , 50 , 6 , MAIL_DLG_HEIGHT , " " , 44 , 0 , " mail-dlg-input-2 " , & tmail_subject ) ,
/* 5 */ QUICK_LABEL ( 2 , 50 , 5 , MAIL_DLG_HEIGHT , N_ ( " Subject " ) ) ,
/* 6 */ QUICK_INPUT ( 3 , 50 , 4 , MAIL_DLG_HEIGHT , " " , 44 , 0 , " mail-dlg-input-3 " , & tmail_to ) ,
/* 7 */ QUICK_LABEL ( 2 , 50 , 3 , MAIL_DLG_HEIGHT , N_ ( " To " ) ) ,
/* 8 */ QUICK_LABEL ( 2 , 50 , 2 , MAIL_DLG_HEIGHT , N_ ( " mail -s <subject> -c <cc> <to> " ) ) ,
QUICK_END
} ;
QuickDialog Quick_input =
{
50 , MAIL_DLG_HEIGHT , - 1 , - 1 , N_ ( " Mail " ) ,
" [Input Line Keys] " , quick_widgets , FALSE
} ;
quick_widgets [ 2 ] . u . input . text = mail_cc_last ? mail_cc_last : " " ;
quick_widgets [ 4 ] . u . input . text = mail_subject_last ? mail_subject_last : " " ;
quick_widgets [ 6 ] . u . input . text = mail_to_last ? mail_to_last : " " ;
2001-08-24 22:23:17 +04:00
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 */
/*******************/
2009-06-29 15:14:25 +04:00
static gboolean is_break_char ( char c )
{
return ( isspace ( c ) | | strchr ( " {}[]()<>=|/ \\ !?~' \" ,.;:#$%^&* " , c ) ) ;
}
2002-01-21 20:49:57 +03:00
/* find first character of current word */
2009-09-30 03:09:54 +04:00
static int edit_find_word_start ( WEdit * edit , long * word_start , gsize * word_len )
2002-01-21 20:49:57 +03:00
{
2009-09-30 03:09:54 +04:00
int c , last ;
gsize i ;
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 */
2009-06-29 15:14:25 +04:00
if ( is_break_char ( 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 ) ;
2009-06-29 15:14:25 +04:00
if ( is_break_char ( c ) ) {
2002-01-21 20:49:57 +03:00
/* 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 ;
}
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 */
2009-09-30 03:09:54 +04:00
static gsize
edit_collect_completions ( WEdit * edit , long start , gsize word_len ,
2002-11-30 20:41:07 +03:00
char * match_expr , struct selection * compl ,
2009-09-30 03:09:54 +04:00
gsize * num )
2002-01-21 20:49:57 +03:00
{
2009-05-29 18:42:26 +04:00
gsize len = 0 ;
2009-08-29 16:22:39 +04:00
gsize max_len = 0 ;
gsize i ;
int skip ;
2009-05-29 18:42:26 +04:00
GString * temp ;
mc_search_t * srch ;
2009-08-12 17:47:52 +04:00
long last_byte ;
Ticket #1486: Editor completion is confusing
Editor completion became really confusing in 4.7.0-pre1:
1. The list is populated with words from the entire file. This is arguably
better than the old style, which scanned only up to the cursor. But the number
of suggestions are limited, and if you have a bigger file, some words won't
make it in the list. Besides, I somehow liked the old way.
2. Suggestions do not end on a word boundary. This may or may be not useful; but
it just increases the list of suggestions, which slows the user. In the end, it
beats the purpose of completions.
3. It completes the word I am currently editing. That's smart. :)
4. The suggestions are displayed in the order in which they were found from the
beginning of the file. This is my main gripe, because when using the editor for
coding, it is better to have suggestions based on the distance to the cursor.
Closer means higher. When writing a function, I am mainly interested in the
variable names I recently used.
5. Sometimes, it does not work at all, but I haven't investigated the bug. :(
Signed-off-by: Slava Zanko <slavazanko@gmail.com>
2009-08-12 16:58:48 +04:00
2009-05-29 18:42:26 +04:00
srch = mc_search_new ( match_expr , - 1 ) ;
if ( srch = = NULL )
return 0 ;
2009-08-12 17:47:52 +04:00
if ( mc_config_get_bool ( mc_main_config , CONFIG_APP_SECTION , " editor_wordcompletion_collect_entire_file " , 0 ) ) {
last_byte = edit - > last_byte ;
} else {
last_byte = start ;
}
2009-05-29 18:42:26 +04:00
srch - > search_type = MC_SEARCH_T_REGEX ;
srch - > is_case_sentitive = TRUE ;
srch - > search_fn = edit_search_cmd_callback ;
2002-01-21 20:49:57 +03:00
2002-11-30 20:41:07 +03:00
/* collect max MAX_WORD_COMPLETIONS completions */
Ticket #1486: Editor completion is confusing
Editor completion became really confusing in 4.7.0-pre1:
1. The list is populated with words from the entire file. This is arguably
better than the old style, which scanned only up to the cursor. But the number
of suggestions are limited, and if you have a bigger file, some words won't
make it in the list. Besides, I somehow liked the old way.
2. Suggestions do not end on a word boundary. This may or may be not useful; but
it just increases the list of suggestions, which slows the user. In the end, it
beats the purpose of completions.
3. It completes the word I am currently editing. That's smart. :)
4. The suggestions are displayed in the order in which they were found from the
beginning of the file. This is my main gripe, because when using the editor for
coding, it is better to have suggestions based on the distance to the cursor.
Closer means higher. When writing a function, I am mainly interested in the
variable names I recently used.
5. Sometimes, it does not work at all, but I haven't investigated the bug. :(
Signed-off-by: Slava Zanko <slavazanko@gmail.com>
2009-08-12 16:58:48 +04:00
start = - 1 ;
while ( 1 ) {
2002-11-30 20:41:07 +03:00
/* get next match */
Ticket #1486: Editor completion is confusing
Editor completion became really confusing in 4.7.0-pre1:
1. The list is populated with words from the entire file. This is arguably
better than the old style, which scanned only up to the cursor. But the number
of suggestions are limited, and if you have a bigger file, some words won't
make it in the list. Besides, I somehow liked the old way.
2. Suggestions do not end on a word boundary. This may or may be not useful; but
it just increases the list of suggestions, which slows the user. In the end, it
beats the purpose of completions.
3. It completes the word I am currently editing. That's smart. :)
4. The suggestions are displayed in the order in which they were found from the
beginning of the file. This is my main gripe, because when using the editor for
coding, it is better to have suggestions based on the distance to the cursor.
Closer means higher. When writing a function, I am mainly interested in the
variable names I recently used.
5. Sometimes, it does not work at all, but I haven't investigated the bug. :(
Signed-off-by: Slava Zanko <slavazanko@gmail.com>
2009-08-12 16:58:48 +04:00
if ( mc_search_run ( srch , ( void * ) edit , start + 1 , last_byte , & len ) = = FALSE )
2002-01-21 20:49:57 +03:00
break ;
2009-05-29 18:42:26 +04:00
start = srch - > normal_offset ;
2002-11-30 20:41:07 +03:00
/* add matched completion if not yet added */
2009-05-29 18:42:26 +04:00
temp = g_string_new ( " " ) ;
2009-05-29 19:08:57 +04:00
for ( i = 0 ; i < len ; i + + ) {
skip = edit_get_byte ( edit , start + i ) ;
if ( isspace ( skip ) )
continue ;
g_string_append_c ( temp , skip ) ;
}
2009-05-29 18:42:26 +04:00
2002-01-21 20:49:57 +03:00
skip = 0 ;
2009-05-29 18:42:26 +04:00
2009-08-29 16:22:39 +04:00
for ( i = 0 ; i < ( gsize ) * num ; i + + ) {
2002-11-30 20:41:07 +03:00
if ( strncmp
2009-05-29 18:42:26 +04:00
(
( char * ) & compl [ i ] . text [ word_len ] ,
( char * ) & temp - > str [ word_len ] ,
2009-08-29 16:22:39 +04:00
max ( len , compl [ i ] . len ) - ( gsize ) word_len
2009-05-29 18:42:26 +04:00
) = = 0 ) {
Ticket #1486: Editor completion is confusing
Editor completion became really confusing in 4.7.0-pre1:
1. The list is populated with words from the entire file. This is arguably
better than the old style, which scanned only up to the cursor. But the number
of suggestions are limited, and if you have a bigger file, some words won't
make it in the list. Besides, I somehow liked the old way.
2. Suggestions do not end on a word boundary. This may or may be not useful; but
it just increases the list of suggestions, which slows the user. In the end, it
beats the purpose of completions.
3. It completes the word I am currently editing. That's smart. :)
4. The suggestions are displayed in the order in which they were found from the
beginning of the file. This is my main gripe, because when using the editor for
coding, it is better to have suggestions based on the distance to the cursor.
Closer means higher. When writing a function, I am mainly interested in the
variable names I recently used.
5. Sometimes, it does not work at all, but I haven't investigated the bug. :(
Signed-off-by: Slava Zanko <slavazanko@gmail.com>
2009-08-12 16:58:48 +04:00
struct selection this = compl [ i ] ;
for ( + + i ; i < * num ; i + + ) {
compl [ i - 1 ] = compl [ i ] ;
}
compl [ * num - 1 ] = this ;
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
}
}
2009-05-29 18:42:26 +04:00
if ( skip ) {
g_string_free ( temp , TRUE ) ;
2002-01-21 20:49:57 +03:00
continue ;
2009-05-29 18:42:26 +04:00
}
Ticket #1486: Editor completion is confusing
Editor completion became really confusing in 4.7.0-pre1:
1. The list is populated with words from the entire file. This is arguably
better than the old style, which scanned only up to the cursor. But the number
of suggestions are limited, and if you have a bigger file, some words won't
make it in the list. Besides, I somehow liked the old way.
2. Suggestions do not end on a word boundary. This may or may be not useful; but
it just increases the list of suggestions, which slows the user. In the end, it
beats the purpose of completions.
3. It completes the word I am currently editing. That's smart. :)
4. The suggestions are displayed in the order in which they were found from the
beginning of the file. This is my main gripe, because when using the editor for
coding, it is better to have suggestions based on the distance to the cursor.
Closer means higher. When writing a function, I am mainly interested in the
variable names I recently used.
5. Sometimes, it does not work at all, but I haven't investigated the bug. :(
Signed-off-by: Slava Zanko <slavazanko@gmail.com>
2009-08-12 16:58:48 +04:00
if ( * num = = MAX_WORD_COMPLETIONS & & MAX_WORD_COMPLETIONS ) {
g_free ( compl [ 0 ] . text ) ;
for ( i = 1 ; i < * num ; i + + ) {
compl [ i - 1 ] = compl [ i ] ;
}
( * num ) - - ;
}
2009-08-13 16:47:11 +04:00
# ifdef HAVE_CHARSET
{
GString * recoded ;
recoded = str_convert_to_display ( temp - > str ) ;
2002-01-21 20:49:57 +03:00
2009-08-13 16:47:11 +04:00
if ( recoded & & recoded - > len ) {
g_string_free ( temp , TRUE ) ;
temp = recoded ;
} else
g_string_free ( recoded , TRUE ) ;
}
# endif
2009-05-29 18:42:26 +04:00
compl [ * num ] . text = temp - > str ;
2009-05-29 19:08:57 +04:00
compl [ * num ] . len = temp - > len ;
2002-01-21 20:49:57 +03:00
( * num ) + + ;
2009-08-13 16:47:11 +04:00
start + = len ;
2009-05-29 18:42:26 +04:00
g_string_free ( temp , FALSE ) ;
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 ;
}
2009-05-29 18:42:26 +04:00
mc_search_free ( srch ) ;
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
{
2009-09-30 03:09:54 +04:00
gsize i , max_len , word_len = 0 , num_compl = 0 ;
2002-01-21 20:49:57 +03:00
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 */
/* 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-08-13 16:47:11 +04:00
/* match_expr = g_strdup_printf ("\\b%.*s[a-zA-Z_0-9]+", word_len, bufpos); */
match_expr = g_strdup_printf ( " (^| \\ s+| \\ b)%.*s[^ \\ s \\ .= \\ + \\ [ \\ ] \\ ( \\ ) \\ , \\ ; \\ : \\ \" \\ ' \\ - \\ ? \\ / \\ | \\ \\ \\ { \\ } \\ * \\ & \\ ^ \\ %% \\ $#@ \\ !]+ " , word_len , bufpos ) ;
2009-06-18 17:20:15 +04:00
2002-11-30 20:41:07 +03:00
/* collect the possible completions */
2009-05-29 18:42:26 +04:00
/* start search from begin to end of file */
2002-11-30 20:41:07 +03:00
max_len =
Ticket #1486: Editor completion is confusing
Editor completion became really confusing in 4.7.0-pre1:
1. The list is populated with words from the entire file. This is arguably
better than the old style, which scanned only up to the cursor. But the number
of suggestions are limited, and if you have a bigger file, some words won't
make it in the list. Besides, I somehow liked the old way.
2. Suggestions do not end on a word boundary. This may or may be not useful; but
it just increases the list of suggestions, which slows the user. In the end, it
beats the purpose of completions.
3. It completes the word I am currently editing. That's smart. :)
4. The suggestions are displayed in the order in which they were found from the
beginning of the file. This is my main gripe, because when using the editor for
coding, it is better to have suggestions based on the distance to the cursor.
Closer means higher. When writing a function, I am mainly interested in the
variable names I recently used.
5. Sometimes, it does not work at all, but I haven't investigated the bug. :(
Signed-off-by: Slava Zanko <slavazanko@gmail.com>
2009-08-12 16:58:48 +04:00
edit_collect_completions ( edit , word_start , word_len , match_expr ,
2002-11-30 20:41:07 +03:00
( 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 !!! */
2009-05-31 16:23:10 +04:00
/*tty_beep (); */
2002-11-30 20:41:07 +03:00
/* 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 */
2009-09-30 03:09:54 +04: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
}
2005-07-20 15:56:30 +04:00
void
edit_select_codepage_cmd ( WEdit * edit )
{
# ifdef HAVE_CHARSET
2009-08-13 09:59:31 +04:00
const char * cp_id = NULL ;
2009-06-14 19:05:57 +04:00
if ( do_select_codepage ( ) ) {
2009-06-16 11:32:59 +04:00
cp_id = get_codepage_id ( source_codepage > = 0 ?
source_codepage : display_codepage ) ;
2009-08-13 09:59:31 +04:00
if ( cp_id ! = NULL ) {
GIConv conv ;
conv = str_crt_conv_from ( cp_id ) ;
if ( conv ! = INVALID_CONV ) {
if ( edit - > converter ! = str_cnv_from_term )
str_close_conv ( edit - > converter ) ;
edit - > converter = conv ;
}
}
2009-06-14 19:05:57 +04:00
if ( cp_id ! = NULL )
edit - > utf8 = str_isutf8 ( cp_id ) ;
}
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-09-30 03:09:54 +04:00
gsize word_len = 0 , max_len = 0 ;
2009-03-04 23:10:55 +03:00
int num_def = 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 ) ;
}
2009-03-23 01:53:21 +03:00
void
edit_move_block_to_right ( WEdit * edit )
{
long start_mark , end_mark ;
long cur_bol , start_bol ;
if ( eval_marks ( edit , & start_mark , & end_mark ) )
return ;
start_bol = edit_bol ( edit , start_mark ) ;
cur_bol = edit_bol ( edit , end_mark - 1 ) ;
do {
edit_cursor_move ( edit , cur_bol - edit - > curs1 ) ;
if ( option_fill_tabs_with_spaces ) {
if ( option_fake_half_tabs ) {
insert_spaces_tab ( edit , 1 ) ;
} else {
insert_spaces_tab ( edit , 0 ) ;
}
} else {
edit_insert ( edit , ' \t ' ) ;
}
edit_cursor_move ( edit , edit_bol ( edit , cur_bol ) - edit - > curs1 ) ;
if ( cur_bol = = 0 ) {
break ;
}
cur_bol = edit_bol ( edit , cur_bol - 1 ) ;
} while ( cur_bol > = start_bol ) ;
edit - > force | = REDRAW_PAGE ;
}
void
edit_move_block_to_left ( WEdit * edit )
{
long start_mark , end_mark ;
long cur_bol , start_bol ;
int i , del_tab_width ;
int next_char ;
if ( eval_marks ( edit , & start_mark , & end_mark ) )
return ;
start_bol = edit_bol ( edit , start_mark ) ;
cur_bol = edit_bol ( edit , end_mark - 1 ) ;
do {
edit_cursor_move ( edit , cur_bol - edit - > curs1 ) ;
if ( option_fake_half_tabs ) {
del_tab_width = HALF_TAB_SIZE ;
} else {
del_tab_width = option_tab_spacing ;
}
next_char = edit_get_byte ( edit , edit - > curs1 ) ;
if ( next_char = = ' \t ' ) {
2009-05-07 14:23:32 +04:00
edit_delete ( edit , 1 ) ;
2009-03-23 01:53:21 +03:00
} else if ( next_char = = ' ' ) {
for ( i = 1 ; i < = del_tab_width ; i + + ) {
if ( next_char = = ' ' ) {
2009-05-07 14:23:32 +04:00
edit_delete ( edit , 1 ) ;
2009-03-23 01:53:21 +03:00
}
next_char = edit_get_byte ( edit , edit - > curs1 ) ;
}
}
if ( cur_bol = = 0 ) {
break ;
}
cur_bol = edit_bol ( edit , cur_bol - 1 ) ;
} while ( cur_bol > = start_bol ) ;
edit - > force | = REDRAW_PAGE ;
}