aboutsummaryrefslogtreecommitdiff
path: root/mark.c
diff options
context:
space:
mode:
Diffstat (limited to 'mark.c')
-rw-r--r--mark.c152
1 files changed, 104 insertions, 48 deletions
diff --git a/mark.c b/mark.c
index 858209605948..b15ff0f12a9d 100644
--- a/mark.c
+++ b/mark.c
@@ -27,7 +27,6 @@ struct mark
* because we don't want to create an ifile until the
* user explicitly requests the file (by name or mark).
*/
- char m_letter; /* Associated character */
IFILE m_ifile; /* Input file being marked */
char *m_filename; /* Name of the input file */
struct scrpos m_scrpos; /* Position of the mark */
@@ -39,12 +38,14 @@ struct mark
* The final one is lmark, for the "last mark"; addressed by the apostrophe.
*/
#define NMARKS ((2*26)+2) /* a-z, A-Z, mousemark, lastmark */
-#define NUMARKS ((2*26)+1) /* user marks (not lastmark) */
-#define MOUSEMARK (NMARKS-2)
+#define NUMARKS (NMARKS-1) /* user marks (not lastmark) */
#define LASTMARK (NMARKS-1)
+#define MOUSEMARK (LASTMARK-1)
static struct mark marks[NMARKS];
-public int marks_modified = 0;
-
+public lbool marks_modified = FALSE;
+#if CMD_HISTORY
+static struct mark file_marks[NMARKS];
+#endif
/*
* Initialize a mark struct.
@@ -69,17 +70,23 @@ public void init_mark(void)
for (i = 0; i < NMARKS; i++)
{
- char letter;
- switch (i) {
- case MOUSEMARK: letter = '#'; break;
- case LASTMARK: letter = '\''; break;
- default: letter = (char) ((i < 26) ? 'a'+i : 'A'+i-26); break;
- }
- marks[i].m_letter = letter;
cmark(&marks[i], NULL_IFILE, NULL_POSITION, -1);
+#if CMD_HISTORY
+ cmark(&file_marks[i], NULL_IFILE, NULL_POSITION, -1);
+#endif
}
}
+static void mark_clear(struct mark *m)
+{
+ m->m_scrpos.pos = NULL_POSITION;
+}
+
+static lbool mark_is_set(struct mark *m)
+{
+ return m->m_scrpos.pos != NULL_POSITION;
+}
+
/*
* Set m_ifile and clear m_filename.
*/
@@ -102,22 +109,47 @@ static void mark_get_ifile(struct mark *m)
}
/*
- * Return the user mark struct identified by a character.
+ * Return the letter associated with a mark index.
*/
-static struct mark * getumark(char c)
+static char mark_letter(int index)
+{
+ switch (index) {
+ case LASTMARK: return '\'';
+ case MOUSEMARK: return '#';
+ default: return (char) ((index < 26) ? 'a'+index : 'A'+index-26);
+ }
+}
+
+/*
+ * Return the mark table index identified by a character.
+ */
+static int mark_index(char c)
{
- PARG parg;
if (c >= 'a' && c <= 'z')
- return (&marks[c-'a']);
+ return c-'a';
if (c >= 'A' && c <= 'Z')
- return (&marks[c-'A'+26]);
+ return c-'A'+26;
if (c == '\'')
- return (&marks[LASTMARK]);
+ return LASTMARK;
if (c == '#')
- return (&marks[MOUSEMARK]);
- parg.p_char = (char) c;
- error("Invalid mark letter %c", &parg);
- return (NULL);
+ return MOUSEMARK;
+ return -1;
+}
+
+/*
+ * Return the user mark struct identified by a character.
+ */
+static struct mark * getumark(char c)
+{
+ int index = mark_index(c);
+ if (index < 0 || index >= NUMARKS)
+ {
+ PARG parg;
+ parg.p_char = (char) c;
+ error("Invalid mark letter %c", &parg);
+ return NULL;
+ }
+ return &marks[index];
}
/*
@@ -172,7 +204,7 @@ static struct mark * getmark(char c)
m = getumark(c);
if (m == NULL)
break;
- if (m->m_scrpos.pos == NULL_POSITION)
+ if (!mark_is_set(m))
{
error("Mark not set", NULL_PARG);
return (NULL);
@@ -185,7 +217,7 @@ static struct mark * getmark(char c)
/*
* Is a mark letter invalid?
*/
-public int badmark(char c)
+public lbool badmark(char c)
{
return (getmark(c) == NULL);
}
@@ -204,11 +236,13 @@ public void setmark(char c, int where)
get_scrpos(&scrpos, where);
if (scrpos.pos == NULL_POSITION)
{
- bell();
+ lbell();
return;
}
cmark(m, curr_ifile, scrpos.pos, scrpos.ln);
- marks_modified = 1;
+ marks_modified = TRUE;
+ if (perma_marks && autosave_action('m'))
+ save_cmdhist();
}
/*
@@ -223,11 +257,13 @@ public void clrmark(char c)
return;
if (m->m_scrpos.pos == NULL_POSITION)
{
- bell();
+ lbell();
return;
}
m->m_scrpos.pos = NULL_POSITION;
- marks_modified = 1;
+ marks_modified = TRUE;
+ if (perma_marks && autosave_action('m'))
+ save_cmdhist();
}
/*
@@ -243,7 +279,7 @@ public void lastmark(void)
if (scrpos.pos == NULL_POSITION)
return;
cmark(&marks[LASTMARK], curr_ifile, scrpos.pos, scrpos.ln);
- marks_modified = 1;
+ marks_modified = TRUE;
}
/*
@@ -264,7 +300,7 @@ public void gomark(char c)
* set it to the beginning of the current file.
* {{ Couldn't we instead set marks[LASTMARK] in edit()? }}
*/
- if (m == &marks[LASTMARK] && m->m_scrpos.pos == NULL_POSITION)
+ if (m == &marks[LASTMARK] && !mark_is_set(m))
cmark(m, curr_ifile, ch_zero(), jump_sline);
mark_get_ifile(m);
@@ -316,14 +352,11 @@ public char posmark(POSITION pos)
/* Only user marks */
for (i = 0; i < NUMARKS; i++)
{
- if (marks[i].m_ifile == curr_ifile && marks[i].m_scrpos.pos == pos)
- {
- if (i < 26) return (char) ('a' + i);
- if (i < 26*2) return (char) ('A' + (i - 26));
- return '#';
- }
+ struct mark *m = &marks[i];
+ if (m->m_ifile == curr_ifile && m->m_scrpos.pos == pos)
+ return mark_letter(i);
}
- return 0;
+ return '\0';
}
/*
@@ -335,7 +368,7 @@ public void unmark(IFILE ifile)
for (i = 0; i < NMARKS; i++)
if (marks[i].m_ifile == ifile)
- marks[i].m_scrpos.pos = NULL_POSITION;
+ mark_clear(&marks[i]);
}
/*
@@ -364,22 +397,44 @@ public void mark_check_ifile(IFILE ifile)
#if CMD_HISTORY
/*
+ * Initialize a mark struct, including the filename.
+ */
+static void cmarkf(struct mark *m, IFILE ifile, POSITION pos, int ln, constant char *filename)
+{
+ cmark(m, ifile, pos, ln);
+ m->m_filename = (filename == NULL) ? NULL : save(filename);
+}
+
+/*
* Save marks to history file.
*/
public void save_marks(FILE *fout, constant char *hdr)
{
int i;
- if (!perma_marks)
- return;
+ if (perma_marks)
+ {
+ /* Copy active marks to file_marks. */
+ for (i = 0; i < NMARKS; i++)
+ {
+ struct mark *m = &marks[i];
+ if (mark_is_set(m))
+ cmarkf(&file_marks[i], m->m_ifile, m->m_scrpos.pos, m->m_scrpos.ln, m->m_filename);
+ }
+ }
+ /*
+ * Save file_marks to the history file.
+ * These may have been read from the history file at startup
+ * (in restore_mark), or copied from the active marks above.
+ */
fprintf(fout, "%s\n", hdr);
for (i = 0; i < NMARKS; i++)
{
constant char *filename;
- struct mark *m = &marks[i];
+ struct mark *m = &file_marks[i];
char pos_str[INT_STRLEN_BOUND(m->m_scrpos.pos) + 2];
- if (m->m_scrpos.pos == NULL_POSITION)
+ if (!mark_is_set(m))
continue;
postoa(m->m_scrpos.pos, pos_str, 10);
filename = m->m_filename;
@@ -387,7 +442,7 @@ public void save_marks(FILE *fout, constant char *hdr)
filename = get_real_filename(m->m_ifile);
if (strcmp(filename, "-") != 0)
fprintf(fout, "m %c %d %s %s\n",
- m->m_letter, m->m_scrpos.ln, pos_str, filename);
+ mark_letter(i), m->m_scrpos.ln, pos_str, filename);
}
}
@@ -396,7 +451,7 @@ public void save_marks(FILE *fout, constant char *hdr)
*/
public void restore_mark(constant char *line)
{
- struct mark *m;
+ int index;
int ln;
POSITION pos;
@@ -404,8 +459,8 @@ public void restore_mark(constant char *line)
if (*line++ != 'm')
return;
skip_whitespace;
- m = getumark(*line++);
- if (m == NULL)
+ index = mark_index(*line++);
+ if (index < 0)
return;
skip_whitespace;
ln = lstrtoic(line, &line, 10);
@@ -420,8 +475,9 @@ public void restore_mark(constant char *line)
if (pos < 0)
return;
skip_whitespace;
- cmark(m, NULL_IFILE, pos, ln);
- m->m_filename = save(line);
+ /* Save in both active marks table and file_marks table. */
+ cmarkf(&marks[index], NULL_IFILE, pos, ln, line);
+ cmarkf(&file_marks[index], NULL_IFILE, pos, ln, line);
}
#endif /* CMD_HISTORY */