aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2015-02-11 06:01:25 +0100
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2015-02-11 06:01:25 +0100
commitd24bc4a3670c253fad5bee380c35e8a45dd283a2 (patch)
tree03f8ca53f2adf741936c219e7af1539e62250738 /src
parenta2956aa85f1ba63dc45166d6418be8d50a298a10 (diff)
downloadsciteco-d24bc4a3670c253fad5bee380c35e8a45dd283a2.tar.gz
implemented support for different indention styles
* the ^I command was altered to insert indention characters rather than plain tabs always. * The <TAB> immediate editing command was added for all insertion arguments (I, ^I but also FR and FS) * documentation was extended for a discussion of indention
Diffstat (limited to 'src')
-rw-r--r--src/cmdline.cpp12
-rw-r--r--src/parser.cpp90
-rw-r--r--src/parser.h12
3 files changed, 92 insertions, 22 deletions
diff --git a/src/cmdline.cpp b/src/cmdline.cpp
index 39cec52..dc03d9c 100644
--- a/src/cmdline.cpp
+++ b/src/cmdline.cpp
@@ -219,7 +219,17 @@ process_edit_cmd(gchar key)
break;
case '\t':
- if (States::is_file()) {
+ if (States::is_insertion()) {
+ if (!interface.ssm(SCI_GETUSETABS)) {
+ gint len = interface.ssm(SCI_GETTABWIDTH);
+
+ len -= interface.ssm(SCI_GETCOLUMN,
+ interface.ssm(SCI_GETCURRENTPOS)) % len;
+
+ memset(insert, ' ', len);
+ insert[len] = '\0';
+ }
+ } else if (States::is_file()) {
*insert = '\0';
if (interface.popup_is_shown()) {
/* cycle through popup pages */
diff --git a/src/parser.cpp b/src/parser.cpp
index aa02164..ddf934b 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -58,6 +58,7 @@ namespace States {
StateScintilla_lParam scintilla_lparam;
StateInsert insert_building(true);
StateInsert insert_nobuilding(false);
+ StateInsertIndent insert_indent;
State *current = &start;
}
@@ -1647,6 +1648,7 @@ StateCondCommand::custom(gchar chr)
StateControl::StateControl() : State()
{
transitions['\0'] = this;
+ transitions['I'] = &States::insert_indent;
transitions['U'] = &States::ctlucommand;
transitions['^'] = &States::ascii;
}
@@ -1689,27 +1691,6 @@ StateControl::custom(gchar chr)
break;
/*
- * Alternatives: ^i, ^I, <CTRL/I>, <TAB>
- */
- /*$
- * [char,...]^I[text]$ -- Insert with leading TAB
- *
- * ^I (usually typed using the Tab key), is equivalent
- * to \(lq[char,...],9I[text]$\(rq.
- * In other words after all the chars on the stack have
- * been inserted into the buffer, a Tab-character is inserted
- * and then the optional <text> is inserted interactively.
- *
- * Like the I command, ^I has string building characters
- * \fBenabled\fP.
- */
- case 'I':
- BEGIN_EXEC(&States::insert_building);
- expressions.eval();
- expressions.push('\t');
- return &States::insert_building;
-
- /*
* Alternatives: ^[, <CTRL/[>, <ESC>
*/
/*$
@@ -2201,4 +2182,71 @@ StateInsert::done(const gchar *str)
return &States::start;
}
+/*
+ * Alternatives: ^i, ^I, <CTRL/I>, <TAB>
+ */
+/*$
+ * [char,...]^I[text]$ -- Insert with leading indention
+ *
+ * ^I (usually typed using the Tab key), first inserts
+ * all the chars on the stack into the buffer, then indention
+ * characters (one tab or multiple spaces) and eventually
+ * the optional <text> is inserted interactively.
+ * It is thus a derivate of the \fBI\fP (insertion) command.
+ *
+ * \*(ST uses Scintilla settings to determine the indention
+ * characters.
+ * If tab use is enabled with the \fBSCI_SETUSETABS\fP message,
+ * a single tab character is inserted.
+ * Tab use is enabled by default.
+ * Otherwise, a number of spaces is inserted up to the
+ * next tab stop so that the command's <text> argument
+ * is inserted at the beginning of the next tab stop.
+ * The size of the tab stops is configured by the
+ * \fBSCI_SETTABWIDTH\fP Scintilla message (8 by default).
+ * In combination with \*(ST's use of the tab key as an
+ * immediate editing command for all insertions, this
+ * implements support for different insertion styles.
+ * The Scintilla settings apply to the current Scintilla
+ * document and are thus local to the currently edited
+ * buffer or Q-Register.
+ *
+ * However for the same reason, the ^I command is not
+ * fully compatible with classic TECO which \fIalways\fP
+ * inserts a single tab character and should not be used
+ * for the purpose of inserting single tabs in generic
+ * macros.
+ * To insert a single tab character reliably, the idioms
+ * \(lq9I$\(rq or \(lqI^I$\(rq may be used.
+ *
+ * Like the I command, ^I has string building characters
+ * \fBenabled\fP.
+ */
+void
+StateInsertIndent::initial(void)
+{
+ StateInsert::initial();
+
+ interface.ssm(SCI_BEGINUNDOACTION);
+ if (interface.ssm(SCI_GETUSETABS)) {
+ interface.ssm(SCI_ADDTEXT, 1, (sptr_t)"\t");
+ } else {
+ gint len = interface.ssm(SCI_GETTABWIDTH);
+
+ len -= interface.ssm(SCI_GETCOLUMN,
+ interface.ssm(SCI_GETCURRENTPOS)) % len;
+
+ gchar spaces[len];
+
+ memset(spaces, ' ', sizeof(spaces));
+ interface.ssm(SCI_ADDTEXT, sizeof(spaces), (sptr_t)spaces);
+ }
+ interface.ssm(SCI_SCROLLCARET);
+ interface.ssm(SCI_ENDUNDOACTION);
+ ring.dirtify();
+
+ if (current_doc_must_undo())
+ interface.undo_ssm(SCI_UNDO);
+}
+
} /* namespace SciTECO */
diff --git a/src/parser.h b/src/parser.h
index 976b215..81099b9 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -243,6 +243,11 @@ protected:
State *done(const gchar *str);
};
+class StateInsertIndent : public StateInsert {
+protected:
+ void initial(void);
+};
+
namespace States {
extern StateStart start;
extern StateControl control;
@@ -254,6 +259,7 @@ namespace States {
extern StateScintilla_lParam scintilla_lparam;
extern StateInsert insert_building;
extern StateInsert insert_nobuilding;
+ extern StateInsertIndent insert_indent;
extern State *current;
@@ -264,6 +270,12 @@ namespace States {
}
static inline bool
+ is_insertion()
+ {
+ return dynamic_cast<StateInsert *>(current);
+ }
+
+ static inline bool
is_file()
{
return dynamic_cast<StateExpectFile *>(current);