aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/qregisters.cpp
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2015-06-02 15:38:00 +0200
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2015-06-02 15:38:00 +0200
commit02d414b3ab447e637fef776e387aa5a07293738a (patch)
tree60d5db01e9e0cc15f1f8e84abb14138cb0ca54a3 /src/qregisters.cpp
parent6c62ccc436d972a872616c187d460ed61c8bc0d2 (diff)
downloadsciteco-02d414b3ab447e637fef776e387aa5a07293738a.tar.gz
added <FG> command and special Q-Register "$" to set and get the current working directory
* FG stands for "Folder Go" * FG behaves similar to a Unix shell `cd`. Without arguments, it changes to the $HOME directory. * The $HOME directory was previously only used by $SCITECOCONFIG on Unix. Now it is documented on its own, since the HOME directory should also be configurable on Windows - e.g. to adapt SciTECO to a MinGW or Cygwin installation. HOME is initialized just like the other environment variables. This also means that now, the $HOME Q-Register is always defined and can be used by platform-agnostic macros. * FG uses a new kind of tab-completion: for directories only. It would be annoying to complete the FG command after every directory, so this tab-completion does not close the command automatically. Theoretically, it would be possible to close the command after completing a directory with no subdirectories, but this is not supported currently. * Filename arguments are no longer completed with " " if {} escaping is in place as this brings no benefit. Instead no completion character is inserted for this escape mode. * "$" was mapped to the current directory to support an elegant way to insert/get the current directory. Also this allows the idiom "[$ FG...new_dir...$ ]$" for changing the current directory temporarily. * The Q-Register stack was extended to support restoring the string part of special Q-Registers (that overwrite the default functionality) when using the "[$" and "]$" commands. * fixed minor typos (american spelling)
Diffstat (limited to 'src/qregisters.cpp')
-rw-r--r--src/qregisters.cpp118
1 files changed, 109 insertions, 9 deletions
diff --git a/src/qregisters.cpp b/src/qregisters.cpp
index e792fc0..d924b25 100644
--- a/src/qregisters.cpp
+++ b/src/qregisters.cpp
@@ -36,6 +36,7 @@
#include "expressions.h"
#include "document.h"
#include "ring.h"
+#include "ioview.h"
#include "error.h"
#include "qregisters.h"
@@ -204,6 +205,15 @@ QRegisterData::get_character(gint position)
}
void
+QRegisterData::undo_exchange_string(QRegisterData &reg)
+{
+ if (must_undo)
+ string.undo_exchange();
+ if (reg.must_undo)
+ reg.string.undo_exchange();
+}
+
+void
QRegister::edit(void)
{
if (QRegisters::current)
@@ -368,11 +378,7 @@ QRegisterBufferInfo::get_string(void)
* This does not change the size of the string, so
* get_string_size() still works.
*/
-#if G_DIR_SEPARATOR != '/'
- g_strdelimit(str, G_DIR_SEPARATOR_S, '/');
-#endif
-
- return str;
+ return normalize_path(str);
}
gsize
@@ -407,6 +413,102 @@ QRegisterBufferInfo::edit(void)
QRegisters::view.undo_ssm(SCI_UNDO);
}
+void
+QRegisterWorkingDir::set_string(const gchar *str, gsize len)
+{
+ /* str is not null-terminated */
+ gchar *dir = g_strndup(str, len);
+ int ret = g_chdir(dir);
+
+ g_free(dir);
+
+ if (ret)
+ /* FIXME: Is errno usable on Windows here? */
+ throw Error("Cannot change working directory "
+ "to \"%.*s\"", len, str);
+}
+
+void
+QRegisterWorkingDir::undo_set_string(void)
+{
+ /* passes ownership of string to undo token object */
+ undo.push(new UndoTokenChangeDir(g_get_current_dir()));
+}
+
+gchar *
+QRegisterWorkingDir::get_string(void)
+{
+ /*
+ * On platforms with a default non-forward-slash directory
+ * separator (i.e. Windows), Buffer::filename will have
+ * the wrong separator.
+ * To make the life of macros that evaluate "$" easier,
+ * the directory separators are normalized to "/" here.
+ * This does not change the size of the string, so
+ * get_string_size() still works.
+ */
+ return normalize_path(g_get_current_dir());
+}
+
+gsize
+QRegisterWorkingDir::get_string_size(void)
+{
+ gchar *str = g_get_current_dir();
+ gsize len = strlen(str);
+
+ g_free(str);
+ return len;
+}
+
+gint
+QRegisterWorkingDir::get_character(gint position)
+{
+ gchar *str = QRegisterWorkingDir::get_string();
+ gint ret = -1;
+
+ if (position >= 0 &&
+ position < (gint)strlen(str))
+ ret = str[position];
+
+ g_free(str);
+ return ret;
+}
+
+void
+QRegisterWorkingDir::edit(void)
+{
+ gchar *str;
+
+ QRegister::edit();
+
+ QRegisters::view.ssm(SCI_BEGINUNDOACTION);
+ str = QRegisterWorkingDir::get_string();
+ QRegisters::view.ssm(SCI_SETTEXT, 0, (sptr_t)str);
+ g_free(str);
+ QRegisters::view.ssm(SCI_ENDUNDOACTION);
+
+ QRegisters::view.undo_ssm(SCI_UNDO);
+}
+
+void
+QRegisterWorkingDir::exchange_string(QRegisterData &reg)
+{
+ gchar *own_str = QRegisterWorkingDir::get_string();
+ gchar *other_str = reg.get_string();
+
+ QRegisterData::set_string(other_str);
+ g_free(other_str);
+ reg.set_string(own_str);
+ g_free(own_str);
+}
+
+void
+QRegisterWorkingDir::undo_exchange_string(QRegisterData &reg)
+{
+ QRegisterWorkingDir::undo_set_string();
+ reg.undo_set_string();
+}
+
QRegisterTable::QRegisterTable(bool _undo) : RBTree(), must_undo(_undo)
{
/* general purpose registers */
@@ -495,10 +597,8 @@ QRegisterStack::pop(QRegister &reg)
reg.set_integer(entry->get_integer());
/* exchange document ownership between Stack entry and Q-Register */
- if (reg.must_undo)
- reg.string.undo_exchange();
- entry->string.undo_exchange();
- entry->string.exchange(reg.string);
+ reg.undo_exchange_string(*entry);
+ reg.exchange_string(*entry);
SLIST_REMOVE_HEAD(&head, entries);
/* pass entry ownership to undo stack */