⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 editcmd.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
/* editor high level editing commands.

   Copyright (C) 1996, 1997 the Free Software Foundation

   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
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */

/* #define PIPE_BLOCKS_SO_READ_BYTE_BY_BYTE */

#include <config.h>
#ifdef OS2_NT
#include <io.h>
#include <fcntl.h>
#endif
#include <ctype.h>
#include "edit.h"
#include "editcmddef.h"

#ifndef MIDNIGHT
#include <X11/Xatom.h>
#include "loadfile.h"
#endif

/* globals: */

/* search and replace: */
int replace_scanf = 0;
int replace_regexp = 0;
int replace_all = 0;
int replace_prompt = 1;
int replace_whole = 0;
int replace_case = 0;
int replace_backwards = 0;

/* queries on a save */
#ifdef MIDNIGHT
int edit_confirm_save = 1;
#else
int edit_confirm_save = 0;
#endif

#define NUM_REPL_ARGS 16
#define MAX_REPL_LEN 1024

#ifdef MIDNIGHT

static inline int my_lower_case (int c)
{
    return tolower(c);
}

char *strcasechr (const char *s, int c)
{
    for (; my_lower_case ((int) *s) != my_lower_case (c); ++s)
	if (*s == '\0')
	    return 0;
    return (char *)s;
}


#include "../src/mad.h"

#ifndef HAVE_MEMMOVE
/* for Christophe */
static void *memmove (void *dest, const void *src, size_t n)
{
    char *t, *s;

    if (dest <= src) {
	t = (char *) dest;
	s = (char *) src;
	while (n--)
	    *t++ = *s++;
    } else {
	t = (char *) dest + n;
	s = (char *) src + n;
	while (n--)
	    *--t = *--s;
    }
    return dest;
}
#endif

/* #define itoa MY_itoa  <---- this line is now in edit.h */
char *itoa (int i)
{
    static char t[14];
    char *s = t + 13;
    int j = i;
    *s-- = 0;
    do {
	*s-- = i % 10 + '0';
    } while ((i = i / 10));
    if (j < 0)
	*s-- = '-';
    return ++s;
}

/*
   This joins strings end on end and allocates memory for the result.
   The result is later automatically free'd and must not be free'd
   by the caller.
 */
char *catstrs (const char *first,...)
{
    static char *stacked[16] =
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    static int i = 0;
    va_list ap;
    int len;
    char *data;

    if (!first)
	return 0;

    len = strlen (first);
    va_start (ap, first);

    while ((data = va_arg (ap, char *)) != 0)
	 len += strlen (data);

    len++;

    i = (i + 1) % 16;
    if (stacked[i])
	free (stacked[i]);

    stacked[i] = malloc (len);
    va_end (ap);
    va_start (ap, first);
    strcpy (stacked[i], first);
    while ((data = va_arg (ap, char *)) != 0)
	 strcat (stacked[i], data);
    va_end (ap);

    return stacked[i];
}
#endif

#ifdef MIDNIGHT

void edit_help_cmd (WEdit * edit)
{
    char *hlpdir = concat_dir_and_file (mc_home, "mc.hlp");
    interactive_display (hlpdir, "[Internal File Editor]");
    free (hlpdir);
    edit->force |= REDRAW_COMPLETELY;
}

void edit_refresh_cmd (WEdit * edit)
{
#ifndef HAVE_SLANG
    clr_scr();
    do_refresh();
#else
    {
	int fg, bg;
	edit_get_syntax_color (edit, -1, &fg, &bg);
    }
    touchwin(stdscr);
#endif
    mc_refresh();
    doupdate();
}

#else

void edit_help_cmd (WEdit * edit)
{
}

void edit_refresh_cmd (WEdit * edit)
{
}

void CRefreshEditor (WEdit * edit)
{
    edit_refresh_cmd (edit);
}

#endif

#ifndef MIDNIGHT

/* three argument open */
int my_open (const char *pathname, int flags,...)
{
    int file;
    va_list ap;

    file = open ((char *) pathname, O_RDONLY);
    if (file < 0 && (flags & O_CREAT)) {	/* must it be created ? */
	mode_t mode;
	va_start(ap, flags);
	mode = va_arg(ap, mode_t);
	va_end(ap);
	return creat ((char *) pathname, mode);
    }
    close (file);
    return open ((char *) pathname, flags);
}

#define open my_open

#endif

/* "Oleg Yu. Repin" <repin@ssd.sscc.ru> added backup filenames
    ...thanks -paul */

/*  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>. */

/* returns 0 on error */
int edit_save_file (WEdit * edit, const char *filename)
{
    long buf;
    long filelen = 0;
    int file;
    char *savename = (char *) filename;
    int this_save_mode;

    if ((file = open (savename, O_WRONLY)) == -1) {
	this_save_mode = 0;		/* the file does not exists yet, so no safe save or backup necessary */
    } else {
	close (file);
	this_save_mode = option_save_mode;
    }

    if (this_save_mode > 0) {
	char *savedir = ".", *slashpos = strrchr (filename, '/');
	if (slashpos != 0) {
	    savedir = strdup (filename);
	    if (savedir == 0)
		return 0;
	    savedir[slashpos - filename + 1] = '\0';
	}
#ifdef HAVE_MAD
	savename = strdup (tempnam (savedir, "cooledit"));
#else
	savename = tempnam (savedir, "cooledit");
#endif
	if (slashpos)
	    free (savedir);
	if (!savename)
	    return 0;
    }
    if ((file = open (savename, O_CREAT | O_WRONLY | O_TRUNC | MY_O_TEXT, edit->stat.st_mode)) == -1) {
	if (this_save_mode > 0)
	    free (savename);
	return 0;
    }
    chown (savename, edit->stat.st_uid, edit->stat.st_gid);
    buf = 0;
    while (buf <= (edit->curs1 >> S_EDIT_BUF_SIZE) - 1) {
	filelen += write (file, (char *) edit->buffers1[buf], EDIT_BUF_SIZE);
	buf++;
    }
    filelen += write (file, (char *) edit->buffers1[buf], edit->curs1 & M_EDIT_BUF_SIZE);

    if (edit->curs2) {
	edit->curs2--;
	buf = (edit->curs2 >> S_EDIT_BUF_SIZE);
	filelen += write (file, (char *) edit->buffers2[buf] + EDIT_BUF_SIZE - (edit->curs2 & M_EDIT_BUF_SIZE) - 1, 1 + (edit->curs2 & M_EDIT_BUF_SIZE));
	buf--;
	while (buf >= 0) {
	    filelen += write (file, (char *) edit->buffers2[buf], EDIT_BUF_SIZE);
	    buf--;
	}
	edit->curs2++;
    }
    close (file);

    if (filelen == edit->last_byte) {
	if (this_save_mode == 2) {
	    if (rename (filename, catstrs (filename, option_backup_ext, 0)) == -1) {	/* catstrs free's automatically */
		free (savename);
		return 0;
	    }
	}
	if (this_save_mode > 0) {
	    if (rename (savename, filename) == -1) {
		free (savename);
		return 0;
	    }
	    free (savename);
	}
	return 1;
    } else {
	if (this_save_mode > 0)
	    free (savename);
	return 0;
    }
}

#ifdef MIDNIGHT
/*
   I changed this from Oleg's original routine so
   that option_backup_ext works with coolwidgets as well. This
   does mean there is a memory leak - paul.
 */
void menu_save_mode_cmd (void)
{
#define DLG_X 36
#define DLG_Y 10
    static char *str_result;
    static int save_mode_new;
    static char *str[] =
    {
	"Quick save ",
	"Safe save ",
	"Do backups -->"};
    static QuickWidget widgets[] =
    {
	{quick_button, 18, DLG_X, 7, DLG_Y, "&Cancel", 0,
	 B_CANCEL, 0, 0, XV_WLAY_DONTCARE, "c"},
	{quick_button, 6, DLG_X, 7, DLG_Y, "&Ok", 0,
	 B_ENTER, 0, 0, XV_WLAY_DONTCARE, "o"},
	{quick_input, 23, DLG_X, 5, DLG_Y, 0, 9,
	 0, 0, &str_result, XV_WLAY_DONTCARE, "i"},
	{quick_label, 22, DLG_X, 4, DLG_Y, "Extension:", 0,
	 0, 0, 0, XV_WLAY_DONTCARE, "savemext"},
	{quick_radio, 4, DLG_X, 3, DLG_Y, "", 3,
	 0, &save_mode_new, str, XV_WLAY_DONTCARE, "t"},
	{0}};
    static QuickDialog dialog =
/* NLS ? */
    {DLG_X, DLG_Y, -1, -1, " Edit Save Mode ", "[Edit Save Mode]",
     "esm", widgets};

    widgets[2].text = option_backup_ext;
    widgets[4].value = option_save_mode;
    if (quick_dialog (&dialog) != B_ENTER)
	return;
    option_save_mode = save_mode_new;
    option_backup_ext = str_result;	/* this is a memory leak */
    option_backup_ext_int = 0;
    str_result[min (strlen (str_result), sizeof (int))] = '\0';
    memcpy ((char *) &option_backup_ext_int, str_result, strlen (option_backup_ext));
}

#endif

#ifdef MIDNIGHT

void edit_split_filename (WEdit * edit, char *f)
{
    if (edit->filename)
	free (edit->filename);
    edit->filename = strdup (f);
    if (edit->dir)
	free (edit->dir);
    edit->dir = strdup ("");
}

#else

void edit_split_filename (WEdit * edit, char *longname)
{
    char *exp, *p;
    exp = canonicalize_pathname (longname);	/* this ensures a full path */
    if (edit->filename)
	free (edit->filename);
    if (edit->dir)
	free (edit->dir);
    p = strrchr (exp, '/');
    edit->filename = strdup (++p);
    *p = 0;
    edit->dir = strdup (exp);
    free (exp);
}

#endif

/*  here we want to warn the user of overwriting an existing file, but only if they
   have made a change to the filename */
/* returns 1 on success */
int edit_save_as_cmd (WEdit * edit)
{
/* This heads the 'Save As' dialog box */
    char *exp = edit_get_save_file (edit->dir, edit->filename, _(" Save As "));
    int different_filename = 0;
    edit_push_action (edit, KEY_PRESS + edit->start_display);
    edit->force |= REDRAW_COMPLETELY;

    if (exp) {
	if (!*exp) {
	    free (exp);
	    return 0;
	} else {
	    if (strcmp(catstrs (edit->dir, edit->filename, 0), exp)) {
		int file;
		different_filename = 1;
		if ((file = open ((char *) exp, O_RDONLY)) != -1) {	/* the file exists */
		    close (file);
		    if (edit_query_dialog2 (_(" Warning "),
		    _(" A file already exists with this name. "),
/* Push buttons to over-write the current file, or cancel the operation */
		    _("Overwrite"), _("Cancel")))
			return 0;
		}
	    }
	    if (edit_save_file (edit, exp)) {
		edit_split_filename (edit, exp);
		free (exp);
		edit->modified = 0;
#ifdef MIDNIGHT
	        edit->delete_file = 0;
#endif
		if (different_filename && !edit->explicit_syntax)
		    edit_load_syntax (edit, 0, 0);
		return 1;
	    } else {
		free (exp);
		edit_error_dialog (_(" Save as "), get_sys_error (_(" Error trying to save file. ")));
		return 0;
	    }
	}
    } else
	return 0;
}

/* {{{ Macro stuff starts here */

#ifdef MIDNIGHT
int raw_callback (struct Dlg_head *h, int key, int Msg)
{
    switch (Msg) {
    case DLG_DRAW:
	attrset (REVERSE_COLOR);
	dlg_erase (h);
	draw_box (h, 1, 1, h->lines - 2, h->cols - 2);

	attrset (COLOR_HOT_NORMAL);
	dlg_move (h, 1, 2);
	printw (h->title);
	break;

    case DLG_KEY:
	h->running = 0;
	h->ret_value = key;
	return 1;
    }
    return 0;
}

/* gets a raw key from the keyboard. Passing cancel = 1 draws
   a cancel button thus allowing c-c etc.. Alternatively, cancel = 0
   will return the next key pressed */
int edit_raw_key_query (char *heading, char *query, int cancel)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -