diff options
-rw-r--r-- | cmdline.cpp | 3 | ||||
-rw-r--r-- | parser.cpp | 3 | ||||
-rw-r--r-- | qbuffers.cpp | 91 | ||||
-rw-r--r-- | qbuffers.h | 38 |
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) @@ -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); @@ -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 |