📄 editcmd.c
字号:
int w = strlen (query) + 7;
struct Dlg_head *raw_dlg = create_dlg (0, 0, 7, w, dialog_colors,
/* NLS ? */
raw_callback, "[Raw Key Query]",
"raw_key_input",
DLG_CENTER | DLG_TRYUP);
x_set_dialog_title (raw_dlg, heading);
raw_dlg->raw = 1; /* to return even a tab key */
if (cancel)
add_widget (raw_dlg, button_new (4, w / 2 - 5, B_CANCEL, NORMAL_BUTTON, "Cancel", 0, 0, 0));
add_widget (raw_dlg, label_new (3 - cancel, 2, query, 0));
add_widget (raw_dlg, input_new (3 - cancel, w - 5, INPUT_COLOR, 2, "", 0));
run_dlg (raw_dlg);
w = raw_dlg->ret_value;
destroy_dlg (raw_dlg);
if (cancel)
if (w == XCTRL ('g') || w == XCTRL ('c') || w == ESC_CHAR || w == B_CANCEL)
return 0;
/* hence ctrl-a (=B_CANCEL), ctrl-g, ctrl-c, and Esc are cannot returned */
return w;
}
#else
int edit_raw_key_query (char *heading, char *query, int cancel)
{
return CKeySymMod (CRawkeyQuery (0, 0, 0, heading, query));
}
#endif
/* creates a macro file if it doesn't exist */
static FILE *edit_open_macro_file (const char *r)
{
char *filename;
int file;
filename = catstrs (home_dir, MACRO_FILE, 0);
if ((file = open (filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1)
return 0;
close (file);
return fopen (filename, r);
}
#define MAX_MACROS 1024
static int saved_macro[MAX_MACROS + 1] =
{0, 0};
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.
*/
int macro_exists (int k)
{
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 */
int edit_delete_macro (WEdit * edit, int k)
{
struct macro macro[MAX_MACRO_LENGTH];
FILE *f, *g;
int s, i, n, j = 0;
if (saved_macros_loaded)
if ((j = macro_exists (k)) < 0)
return 0;
g = fopen (catstrs (home_dir, TEMP_FILE, 0), "w");
if (!g) {
/* This heads the delete macro error dialog box */
edit_error_dialog (_(" Delete macro "),
/* 'Open' = load temp file */
get_sys_error (_(" Error trying to open temp file ")));
return 1;
}
f = edit_open_macro_file ("r");
if (!f) {
/* This heads the delete macro error dialog box */
edit_error_dialog (_(" Delete macro "),
/* 'Open' = load temp file */
get_sys_error (_(" Error trying to open macro file ")));
fclose (g);
return 1;
}
for (;;) {
n = fscanf (f, _("key '%d 0': "), &s);
if (!n || n == EOF)
break;
n = 0;
while (fscanf (f, "%hd %hd, ", ¯o[n].command, ¯o[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);
if (rename (catstrs (home_dir, TEMP_FILE, 0), catstrs (home_dir, MACRO_FILE, 0)) == -1) {
/* This heads the delete macro error dialog box */
edit_error_dialog (_(" Delete macro "),
get_sys_error (_(" Error trying to overwrite macro file ")));
return 1;
}
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->force |= REDRAW_COMPLETELY;
edit_push_action (edit, KEY_PRESS + edit->start_display);
/* This heads the 'Macro' dialog box */
s = edit_raw_key_query (_(" Macro "),
/* Input line for a single key press follows the ':' */
_(" Press the macro's new hotkey: "), 1);
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
/* This heads the 'Save Macro' dialog box */
edit_error_dialog (_(" Save macro "), get_sys_error (_(" Error trying to open macro file ")));
}
return 0;
}
void edit_delete_macro_cmd (WEdit * edit)
{
int command;
#ifdef MIDNIGHT
command = CK_Macro (edit_raw_key_query (_(" Delete Macro "), _(" Press macro hotkey: "), 1));
#else
/* This heads the 'Delete Macro' dialog box */
command = CK_Macro (CKeySymMod (CRawkeyQuery (0, 0, 0, _(" Delete Macro "),
/* Input line for a single key press follows the ':' */
_(" Press macro hotkey: "))));
#endif
if (command == CK_Macro (0))
return;
edit_delete_macro (edit, command - 2000);
}
/* 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;
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, ", ¯o[*n].command, ¯o[*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
/* This heads the 'Load Macro' dialog box */
edit_error_dialog (_(" Load macro "),
get_sys_error (_(" Error trying to open macro file ")));
return 0;
}
/* }}} Macro stuff starts here */
/* returns 1 on success */
int edit_save_confirm_cmd (WEdit * edit)
{
char *f;
if (edit_confirm_save) {
#ifdef MIDNIGHT
f = catstrs (_(" Confirm save file? : "), edit->filename, " ", 0);
#else
f = catstrs (_(" Confirm save file? : "), edit->dir, edit->filename, " ", 0);
#endif
/* Buttons to 'Confirm save file' query */
if (edit_query_dialog2 (_(" Save file "), f, _("Save"), _("Cancel")))
return 0;
}
return edit_save_cmd (edit);
}
/* returns 1 on success */
int edit_save_cmd (WEdit * edit)
{
edit->force |= REDRAW_COMPLETELY;
if (!edit_save_file (edit, catstrs (edit->dir, edit->filename, 0)))
return edit_save_as_cmd (edit);
edit->modified = 0;
#ifdef MIDNIGHT
edit->delete_file = 0;
#endif
return 1;
}
/* returns 1 on success */
int edit_new_cmd (WEdit * edit)
{
edit->force |= REDRAW_COMPLETELY;
if (edit->modified)
if (edit_query_dialog2 (_(" Warning "), _(" Current text was modified without a file save. \n Continue discards these changes. "), _("Continue"), _("Cancel")))
return 0;
edit->modified = 0;
return edit_renew (edit); /* if this gives an error, something has really screwed up */
}
int edit_load_cmd (WEdit * edit)
{
char *exp;
edit->force |= REDRAW_COMPLETELY;
if (edit->modified)
if (edit_query_dialog2 (_(" Warning "), _(" Current text was modified without a file save. \n Continue discards these changes. "), _("Continue"), _("Cancel")))
return 0;
exp = edit_get_load_file (edit->dir, edit->filename, _(" Load "));
if (exp) {
if (!*exp) {
free (exp);
} else {
int file;
if ((file = open ((char *) exp, O_RDONLY, MY_O_TEXT)) != -1) {
close (file);
edit_reload (edit, exp, 0, "", 0);
edit_split_filename (edit, exp);
free (exp);
edit->modified = 0;
return 1;
} else {
free (exp);
/* Heads the 'Load' file dialog box */
edit_error_dialog (_(" Load "), get_sys_error (_(" Error trying to open file for reading ")));
}
}
}
return 0;
}
/*
if mark2 is -1 then marking is from mark1 to the cursor.
Otherwise its between the markers. This handles this.
Returns 1 if no text is marked.
*/
int eval_marks (WEdit * edit, long *start_mark, long *end_mark)
{
if (edit->mark1 != edit->mark2) {
if (edit->mark2 >= 0) {
*start_mark = min (edit->mark1, edit->mark2);
*end_mark = max (edit->mark1, edit->mark2);
} else {
*start_mark = min (edit->mark1, edit->curs1);
*end_mark = max (edit->mark1, edit->curs1);
edit->column2 = edit->curs_col;
}
return 0;
} else {
*start_mark = *end_mark = 0;
edit->column2 = edit->column1 = 0;
return 1;
}
}
/*Block copy, move and delete commands */
void edit_block_copy_cmd (WEdit * edit)
{
long start_mark, end_mark, current = edit->curs1;
long count;
char *copy_buf;
if (eval_marks (edit, &start_mark, &end_mark))
return;
copy_buf = malloc (end_mark - start_mark);
/* all that gets pushed are deletes hence little space is used on the stack */
edit_push_markers (edit);
count = start_mark;
while (count < end_mark) {
copy_buf[end_mark - count - 1] = edit_get_byte (edit, count);
count++;
}
while (count-- > start_mark) {
edit_insert_ahead (edit, copy_buf[end_mark - count - 1]);
}
free (copy_buf);
edit_scroll_screen_over_cursor (edit);
if (start_mark < current && end_mark > current)
edit_set_markers (edit, start_mark, end_mark + end_mark - start_mark, 0, 0);
edit->force |= REDRAW_PAGE;
}
void edit_block_move_cmd (WEdit * edit)
{
long count;
long current;
char *copy_buf;
long start_mark, end_mark;
if (eval_marks (edit, &start_mark, &end_mark))
return;
if (start_mark <= edit->curs1 && end_mark >= edit->curs1)
return;
if ((end_mark - start_mark) > option_max_undo / 2)
if (edit_query_dialog2 (_(" Warning "), _(" Block is large, you may not be able to undo this action. "), _("Continue"), _("Cancel")))
return;
copy_buf = malloc (end_mark - start_mark);
edit_push_markers (edit);
current = edit->curs1;
edit_cursor_move (edit, start_mark - edit->curs1);
edit_scroll_screen_over_cursor (edit);
count = start_mark;
while (count < end_mark) {
copy_buf[end_mark - count - 1] = edit_delete (edit);
count++;
}
edit_scroll_screen_over_cursor (edit);
edit_cursor_move (edit, current - edit->curs1
- (((current - edit->curs1) > 0) ? end_mark - start_mark : 0));
edit_scroll_screen_over_cursor (edit);
while (count-- > start_mark) {
edit_insert_ahead (edit, copy_buf[end_mark - count - 1]);
edit_set_markers (edit, edit->curs1, edit->curs1 + end_mark - start_mark, 0, 0);
}
edit_scroll_screen_over_cursor (edit);
free (copy_buf);
edit->force |= REDRAW_PAGE;
}
void edit_cursor_to_bol (WEdit * edit);
extern int column_highlighting;
void edit_delete_column_of_text (WEdit * edit)
{
long p, q, r, m1, m2;
int b, c, d, fin;
eval_marks (edit, &m1, &m2);
c = edit_move_forward3 (edit, edit_bol (edit, m1), 0, m1);
d = edit_move_forward3 (edit, edit_bol (edit, m2), 0, m2);
b = min (c, d);
c = max (c, d);
fin = 0;
while (!fin) {
eval_marks (edit, &m1, &m2);
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;
fin = 1;
}
edit_cursor_move (edit, p - edit->curs1);
while (p != q) { /* delete line between margins */
if (edit_get_byte (edit, edit->curs1) != '\n')
edit_delete (edit);
q--;
}
if (!fin) /* next line */
edit_cursor_move (edit, edit_move_forward (edit, edit->curs1, 1, 0) - edit->curs1);
}
}
/* returns 1 if canceelled by user */
int edit_block_delete_cmd (WEdit * edit)
{
long count;
long start_mark, end_mark;
if (eval_marks (edit, &start_mark, &end_mark)) {
start_mark = edit_bol (edit, edit->curs1);
end_mark = edit_eol (edit, edit->curs1) + 1;
}
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. "), _(" Continue "), _(" Cancel ")))
return 1;
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) {
edit_delete_column_of_text (edit);
} else {
while (count < end_mark) {
edit_delete (edit);
count++;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -