commit b55e85b730136a073724c9f149ebe174ce27eefa
parent de8e7863fbf29ee41290753a3657f96a675e4f23
Author: Rafael Garcia <rafael.garcia.gallego@gmail.com>
Date: Wed, 10 Aug 2011 03:33:07 +0200
Autoindent is back (start sandy with -a), now using a awk one liner rather than hardcode in C; can also be set/unset. Helper functions moved to the config file for now.
Diffstat:
5 files changed, 45 insertions(+), 19 deletions(-)
diff --git a/README b/README
@@ -28,6 +28,7 @@ Use the following syntax:
sandy [-r] [-S | -s SYNTAX] [-t TABSTOP] [File]
Where:
+-a starts with autoindent
-r opens the file read-only
-S use no syntax colors at all.
-s SYNTAX lets you specify the syntax colors for this file
diff --git a/TODO b/TODO
@@ -2,7 +2,6 @@ In no particular order, at sandy.c:
- Update manpage
- Create m_*vline
- Bracket matching?
-- Autoindenting?
- Number modifier?
- Smart end? is it really needed?
- BUG: high CPU usage on continuous resize
diff --git a/config.def.h b/config.def.h
@@ -20,6 +20,11 @@ static const char spcstr[2] = { ' ', 0 };
static const char nlstr[1] = { 0 };
#endif
+/* Helper config functions, not used in main code */
+static void f_moveb(const Arg*);
+static void f_pipeb(const Arg*);
+static void f_pipelines(const Arg*);
+
/* Args to f_spawn */
#define PROMPT(prompt, default, cmd) { .v = (const char *[]){ "/bin/sh", "-c", \
"dmenu -v >/dev/null 2>&1 || DISPLAY=\"\";"\
@@ -99,12 +104,14 @@ static const Key stdkeys[] = {
{ .keyv.c = CONTROL('H'), { t_sel, t_rw, 0, 0 }, f_delete, { .m = m_tosel } },
{ .keyv.c = CONTROL('H'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_prevchar } },
{ .keyv.c = CONTROL('I'), { t_rw, 0, 0, 0 }, f_insert, { .v = "\t" } },
+{ .keyv.c = CONTROL('J'), { t_rw, t_ai, 0, 0 }, f_pipeb, { .v = "awk 'BEGIN{ l=\"\\n\" } ; { if(match($0, \"^[\t ]+[^\t ]\")) l=substr($0, RSTART, RLENGTH-1); else l=\"\"; if(FNR==NR && $0 ~ /^[\t ]+$/) print \"\" ; else print }; END{ ORS=\"\"; print l }'" } } ,
{ .keyv.c = CONTROL('J'), { t_rw, 0, 0, 0 }, f_insert, { .v = "\n" } },
{ .keyv.c = CONTROL('J'), { 0, 0, 0, 0 }, f_move, { .m = m_nextline } },
{ .keyv.c = CONTROL('K'), { t_eol, t_rw, 0, 0 }, f_delete, { .m = m_nextchar } },
{ .keyv.c = CONTROL('K'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_eol } },
{ .keyv.c = CONTROL('L'), { 0, 0, 0, 0 }, f_center, { 0 } },
{ .keyv.c = META('l'), { t_sel, t_rw, 0, 0 }, f_pipe, { .v = "tr [A-Z] [a-z]" } },
+{ .keyv.c = CONTROL('M'), { t_rw, t_ai, 0, 0 }, f_pipeb, { .v = "awk 'BEGIN{ l=\"\\n\" } ; { if(match($0, \"^[\t ]+[^\t ]\")) l=substr($0, RSTART, RLENGTH-1); else l=\"\"; if(FNR==NR && $0 ~ /^[\t ]+$/) print \"\" ; else print }; END{ ORS=\"\"; print l }'" } } ,
{ .keyv.c = CONTROL('M'), { t_rw, 0, 0, 0 }, f_insert, { .v = "\n" } },
{ .keyv.c = CONTROL('M'), { 0, 0, 0, 0 }, f_move, { .m = m_nextline } },
{ .keyv.c = CONTROL('N'), { 0, 0, 0, 0 }, f_move, { .m = m_nextline } },
@@ -156,6 +163,7 @@ static const Command cmds[] = { /* if(arg == 0) arg.v=regex_match */
{"^offset (.*)$", { 0, 0, 0 }, f_offset, { 0 } },
{"^set icase$", { 0, 0, 0 }, f_toggle, { .i = S_CaseIns } },
{"^set ro$", { 0, 0, 0 }, f_toggle, { .i = S_Readonly } },
+{"^set ai$", { 0, 0, 0 }, f_toggle, { .i = S_AutoIndent } },
{"^q$", { t_mod, 0, 0 }, f_toggle, { .i = S_Warned } },
{"^q$", { 0, 0, 0 }, f_toggle, { .i = S_Running } },
{"^q!$", { 0, 0, 0 }, f_toggle, { .i = S_Running } },
@@ -291,3 +299,24 @@ static const short bgcolors[LastBG] = {
[SelBG] = COLOR_YELLOW,
};
+/* Helper config functions implementation */
+void /* Move cursor as per arg->m, then cancel selection */
+f_moveb(const Arg *arg) {
+ fsel=fcur=arg->m(fcur);
+}
+
+void /* Pipe selection from bol, then cancel selection */
+f_pipeb(const Arg *arg) {
+ i_sortpos(&fsel, &fcur);
+ fsel.o=0;
+ f_pipe(arg);
+ fsel=fcur;
+}
+
+void /* Pipe full lines including the selection */
+f_pipelines(const Arg *arg) {
+ f_extsel(&(const Arg){ .i = ExtLines });
+ i_pipetext(arg->v);
+ statusflags|=S_Modified;
+ lastaction=LastPipe;
+}
diff --git a/sandy.1 b/sandy.1
@@ -3,7 +3,7 @@
sandy \- simple ncurses text editor
.SH SYNOPSIS
.B sandy
-.RB [ \-hruS ]
+.RB [ \-ahruS ]
.RB [ \-t
.IR tabstop ]
.RB [ \-s
@@ -16,6 +16,9 @@ commands. A small degree of external control can be achieved by writing to a
named pipe.
.SH OPTIONS
.TP
+.B \-a
+Autoindents text while editing.
+.TP
.B \-h
Prints usage information to stderr, then exits.
.TP
diff --git a/sandy.c b/sandy.c
@@ -127,6 +127,7 @@ enum { /* To use in statusflags */
S_NeedResize = 1<<7,
S_Warned = 1<<8,
S_GroupUndo = 1<<9,
+ S_AutoIndent = 1<<10,
};
enum { /* To use in Undo.flags */
@@ -185,10 +186,8 @@ static void f_insert(const Arg*);
static void f_line(const Arg*);
static void f_mark(const Arg*);
static void f_move(const Arg*);
-static void f_moveb(const Arg*);
static void f_offset(const Arg*);
static void f_pipe(const Arg*);
-static void f_pipelines(const Arg*);
static void f_pipero(const Arg*);
static void f_repeat(const Arg*);
static void f_save(const Arg*);
@@ -233,6 +232,7 @@ static void i_usage(void);
static bool i_writefile(char*);
/* t_* functions to know whether to process an action or keybinding */
+static bool t_ai(void);
static bool t_bol(void);
static bool t_eol(void);
static bool t_mod(void);
@@ -363,11 +363,6 @@ f_move(const Arg *arg) {
fcur=arg->m(fcur);
}
-void /* Move cursor as per arg->m, then copy at selection */
-f_moveb(const Arg *arg) {
- fsel=fcur=arg->m(fcur);
-}
-
void /* Got to atoi(arg->v) position in the current line */
f_offset(const Arg *arg) {
fcur.o=atoi(arg->v);
@@ -382,14 +377,6 @@ f_pipe(const Arg *arg) {
lastaction=LastPipe;
}
-void /* Pipe full lines including the selection through arg->v external command. Your responsibility: call only if t_rw() */
-f_pipelines(const Arg *arg) {
- f_extsel(&(const Arg){ .i = ExtLines });
- i_pipetext(arg->v);
- statusflags|=S_Modified;
- lastaction=LastPipe;
-}
-
void /* Pipe selection through arg->v external command but do not update text on screen */
f_pipero(const Arg *arg) {
char oldsf=statusflags;
@@ -1405,12 +1392,13 @@ i_update(void) {
else {
statusflags&=~S_Warned; /* Reset warning */
snprintf(buf, 4, "%ld%%", (100*ncur)/nlst);
- snprintf(title, BUFSIZ, "%s [%s]%s%s%s %ld,%d %s",
+ snprintf(title, BUFSIZ, "%s [%s]%s%s%s%s %ld,%d %s",
(filename == NULL?"<No file>":filename),
(syntx>=0 ? syntaxes[syntx].name : "none"),
(t_mod()?"[+]":""),
(!t_rw()?"[RO]":""),
(statusflags&S_CaseIns?"[icase]":""),
+ (statusflags&S_AutoIndent?"[ai]":""),
ncur, (int)fcur.o,
(scrline==fstline?
(nlst<lines3?"All":"Top"):
@@ -1439,7 +1427,7 @@ i_update(void) {
void /* Print help, die */
i_usage(void) {
fputs("sandy - simple editor\n", stderr);
- i_die("usage: sandy [-r] [-u] [-t TABSTOP] [-s SYNTAX] [file | -]\n");
+ i_die("usage: sandy [-a] [-r] [-u] [-t TABSTOP] [-s SYNTAX] [file | -]\n");
}
bool /* Write buffer to disk */
@@ -1625,6 +1613,10 @@ m_tosel(Filepos pos) {
/* T_* FUNCTIONS
Used to test for conditions, take no arguments and return bool. */
+bool /* TRUE is autoindent is on */
+t_ai(void) {
+ return (statusflags & S_AutoIndent);
+}
bool /* TRUE at the beginning of line */
t_bol(void) {
@@ -1678,6 +1670,8 @@ main(int argc, char **argv){
for(i = 1; i < argc && argv[i][0] == '-' && argv[i][1] != '\0'; i++) {
if(!strcmp(argv[i], "-r")) {
statusflags|=S_Readonly;
+ } else if(!strcmp(argv[i], "-a")) {
+ statusflags|=S_AutoIndent;
} else if(!strcmp(argv[i], "-t")) {
if(++i < argc) {
tabstop=atoi(argv[i]);