aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2012-11-13 09:46:41 +0100
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2012-11-13 09:46:41 +0100
commit3c395e56140c991ea776fedde0eaba230060c767 (patch)
tree82b629ddbfc6127b9f9e5f2b8745b5c35d4dc701
parent5db6dee299389eb3b939ca5d6ebfcefceb40c4c5 (diff)
downloadsciteco-3c395e56140c991ea776fedde0eaba230060c767.tar.gz
added EW...$ command
* EW$ saves file with its current filename * EW<filename>$ saves file with under the specified filename (Save As) * files are stored with absolute paths in the ring
-rw-r--r--cmdline.cpp3
-rw-r--r--parser.cpp3
-rw-r--r--qbuffers.cpp91
-rw-r--r--qbuffers.h38
4 files changed, 113 insertions, 22 deletions
diff --git a/cmdline.cpp b/cmdline.cpp
index a0c6fec..2f35c5d 100644
--- a/cmdline.cpp
+++ b/cmdline.cpp
@@ -100,7 +100,8 @@ process_edit_cmd(gchar key)
}
case '\t':
- if (States::current == &States::file ||
+ if (States::current == &States::editfile ||
+ States::current == &States::savefile ||
States::current == &States::loadqreg) {
gchar *new_chars = filename_complete(strings[0], escape_char);
if (new_chars)
diff --git a/parser.cpp b/parser.cpp
index 2e141f6..af691f0 100644
--- a/parser.cpp
+++ b/parser.cpp
@@ -892,7 +892,8 @@ StateControl::custom(gchar chr)
StateECommand::StateECommand() : State()
{
transitions['\0'] = this;
- transitions['B'] = &States::file;
+ transitions['B'] = &States::editfile;
+ transitions['W'] = &States::savefile;
transitions['Q'] = &States::eqcommand;
}
diff --git a/qbuffers.cpp b/qbuffers.cpp
index 3421d39..d0f11cf 100644
--- a/qbuffers.cpp
+++ b/qbuffers.cpp
@@ -1,5 +1,7 @@
-#include <bsd/sys/queue.h>
+#include <limits.h>
+#include <stdlib.h>
#include <string.h>
+#include <bsd/sys/queue.h>
#include <glib.h>
#include <glib/gprintf.h>
@@ -16,7 +18,9 @@
#include "qbuffers.h"
namespace States {
- StateFile file;
+ StateEditFile editfile;
+ StateSaveFile savefile;
+
StateEQCommand eqcommand;
StateLoadQReg loadqreg;
StateCtlUCommand ctlucommand;
@@ -189,13 +193,15 @@ Buffer::close(void)
Buffer *
Ring::find(const gchar *filename)
{
+ gchar *resolved = get_absolute_path(filename);
Buffer *cur;
LIST_FOREACH(cur, &head, buffers)
- if (!g_strcmp0(cur->filename, filename))
- return cur;
+ if (!g_strcmp0(cur->filename, resolved))
+ break;
- return NULL;
+ g_free(resolved);
+ return cur;
}
bool
@@ -239,6 +245,33 @@ Ring::edit(const gchar *filename)
return new_in_ring;
}
+bool
+Ring::save(const gchar *filename)
+{
+ const gchar *buffer;
+ gssize size;
+
+ if (!current)
+ return false;
+
+ if (!filename && !current->filename)
+ return false;
+
+ buffer = (const gchar *)editor_msg(SCI_GETCHARACTERPOINTER);
+ size = editor_msg(SCI_GETLENGTH);
+
+ if (!g_file_set_contents(filename ? : current->filename,
+ buffer, size, NULL))
+ return false;
+
+ if (filename) {
+ undo.push_str(current->filename);
+ current->set_filename(filename);
+ }
+
+ return true;
+}
+
void
Ring::close(void)
{
@@ -261,11 +294,42 @@ Ring::~Ring()
}
/*
+ * Auxiliary functions
+ */
+#ifdef __WIN32__
+
+gchar *
+get_absolute_path(const gchar *path)
+{
+ return path ? g_file_read_link(path, NULL) : NULL;
+}
+
+#else
+
+gchar *
+get_absolute_path(const gchar *path)
+{
+ gchar *resolved;
+
+ if (!path)
+ return NULL;
+
+ resolved = (gchar *)g_malloc(PATH_MAX);
+ if (!realpath(path, resolved)) {
+ g_free(resolved);
+ return NULL;
+ }
+ return resolved;
+}
+
+#endif
+
+/*
* Command states
*/
void
-StateFile::do_edit(const gchar *filename)
+StateEditFile::do_edit(const gchar *filename)
{
if (ring.current)
ring.undo_edit();
@@ -276,7 +340,7 @@ StateFile::do_edit(const gchar *filename)
}
void
-StateFile::initial(void)
+StateEditFile::initial(void)
{
gint64 id = expressions.pop_num_calc(1, -1);
@@ -292,7 +356,7 @@ StateFile::initial(void)
}
State *
-StateFile::done(const gchar *str)
+StateEditFile::done(const gchar *str)
{
BEGIN_EXEC(&States::start);
@@ -336,6 +400,17 @@ StateFile::done(const gchar *str)
}
State *
+StateSaveFile::done(const gchar *str)
+{
+ BEGIN_EXEC(&States::start);
+
+ if (!ring.save(*str ? str : NULL))
+ return NULL;
+
+ return &States::start;
+}
+
+State *
StateEQCommand::got_register(QRegister *reg)
{
BEGIN_EXEC(&States::loadqreg);
diff --git a/qbuffers.h b/qbuffers.h
index 79cd6ea..ca1ec32 100644
--- a/qbuffers.h
+++ b/qbuffers.h
@@ -14,6 +14,20 @@
#include "rbtree.h"
#include "parser.h"
+/*
+ * Auxiliary functions
+ */
+static inline bool
+is_glob_pattern(const gchar *str)
+{
+ return strchr(str, '*') || strchr(str, '?');
+}
+
+gchar *get_absolute_path(const gchar *path);
+
+/*
+ * Classes
+ */
class QRegister : public RBTree::RBEntry {
public:
gchar *name;
@@ -164,7 +178,7 @@ public:
set_filename(const gchar *filename)
{
g_free(Buffer::filename);
- Buffer::filename = filename ? g_strdup(filename) : NULL;
+ Buffer::filename = get_absolute_path(filename);
}
inline void
@@ -220,6 +234,8 @@ public:
current->undo_edit();
}
+ bool save(const gchar *filename);
+
void close(void);
inline void
undo_close(void)
@@ -232,7 +248,7 @@ public:
* Command states
*/
-class StateFile : public StateExpectString {
+class StateEditFile : public StateExpectString {
private:
void do_edit(const gchar *filename);
@@ -240,6 +256,11 @@ private:
State *done(const gchar *str);
};
+class StateSaveFile : public StateExpectString {
+private:
+ State *done(const gchar *str);
+};
+
class StateEQCommand : public StateExpectQReg {
private:
State *got_register(QRegister *reg);
@@ -286,7 +307,9 @@ private:
};
namespace States {
- extern StateFile file;
+ extern StateEditFile editfile;
+ extern StateSaveFile savefile;
+
extern StateEQCommand eqcommand;
extern StateLoadQReg loadqreg;
extern StateCtlUCommand ctlucommand;
@@ -298,13 +321,4 @@ namespace States {
extern StateCopyToQReg copytoqreg;
}
-/*
- * Auxiliary functions
- */
-static inline bool
-is_glob_pattern(const gchar *str)
-{
- return strchr(str, '*') || strchr(str, '?');
-}
-
#endif