This allows for external editing of ERT insets. Original patch
by Georg Baum. Updated to 2.4dev by Riki Heck.

(cherry picked from commit f17f5617e0)
This commit is contained in:
Richard Heck 2018-04-01 22:40:00 -04:00 committed by Richard Kimberly Heck
parent 99d025e2da
commit 26d4b5bb47
6 changed files with 113 additions and 1 deletions

View File

@ -664,6 +664,9 @@ Menuset
Menu "context-ert"
# repeat 1 is added as a work-around to not indicate this action as toggable
Item "Wrap by Preview|y" "command-sequence repeat 1;inset-toggle;char-forward;char-backward;char-forward-select;preview-insert;char-backward;char-backward;inset-toggle"
Separator
Item "Edit Externally...|x" "inset-edit"
Item "End Editing Externally...|e" "inset-end-edit"
End
#

View File

@ -479,6 +479,9 @@ enum FuncCode
LFUN_BUFFER_ANONYMIZE, // sanda, 20180201
LFUN_GRAPHICS_UNIFY, // sanda, 20180207
LFUN_MASTER_BUFFER_EXPORT, // rkh, 20180417
LFUN_LAYOUT_TOGGLE, // lasgouttes 20180514
// 375
LFUN_INSET_END_EDIT, // gb/rkh, 20180605
LFUN_LASTACTION // end of the table
};

View File

@ -2014,6 +2014,11 @@ void LyXAction::init()
* \var lyx::FuncCode lyx::LFUN_INSET_EDIT
* \li Action: Edit the inset at cursor with an external application,
if one is attributed.
If the inset is file based, the referenced file is edited.
Otherwise, the inset contents is written to a temporary file,
the inset is locked, and the temporary file is edited.
In this case, #LFUN_INSET_END_EDIT must be called to overtake
the changes and unlock the inset after editing is finished.
* \li Syntax: inset-edit [<INSET_PARAMS>]
* \li Params: <INSET_PARAMS>: Parameters for the inset. \n
Currently only the filename will be considered.
@ -2023,6 +2028,17 @@ void LyXAction::init()
{ LFUN_INSET_EDIT, "inset-edit", ReadOnly | AtPoint, Edit },
/*!
* \var lyx::FuncCode lyx::LFUN_INSET_END_EDIT
* \li Action: End editing the inset at cursor with an external application.
* This replaces the inset contents with the contents of the
* temporary file, deletes the file and unlocks the inset.
* \li Syntax: inset-end-edit
* \li Origin: gb, 11 Oct 2015
* \endvar
*/
{ LFUN_INSET_END_EDIT, "inset-end-edit", ReadOnly | AtPoint, Edit },
/*!
* \var lyx::FuncCode lyx::LFUN_INSET_END
* \li Action: Move the cursor to the end of the current inset if it

View File

@ -453,6 +453,7 @@ Inset * InsetCollapsible::editXY(Cursor & cur, int x, int y)
{
//lyxerr << "InsetCollapsible: edit xy" << endl;
if (geometry(cur.bv()) == ButtonOnly
|| !editable()
|| (view_[&cur.bv()].button_dim_.contains(x, y)
&& geometry(cur.bv()) != NoButton))
return this;

View File

@ -17,7 +17,9 @@
#include "BufferParams.h"
#include "BufferView.h"
#include "Cursor.h"
#include "CutAndPaste.h"
#include "DispatchResult.h"
#include "Format.h"
#include "FuncRequest.h"
#include "FuncStatus.h"
#include "Language.h"
@ -29,8 +31,11 @@
#include "Paragraph.h"
#include "TextClass.h"
#include "support/docstream.h"
#include "support/FileName.h"
#include "support/gettext.h"
#include "support/lstrings.h"
#include "support/TempFile.h"
#include <sstream>
@ -46,6 +51,21 @@ InsetERT::InsetERT(Buffer * buf, CollapseStatus status)
}
// Do not copy the temp file on purpose: If a copy of an inset which is
// currently being edited is made, then we simply copy the current contents.
InsetERT::InsetERT(InsetERT const & that) : InsetCollapsible(that)
{}
InsetERT & InsetERT::operator=(InsetERT const & that)
{
if (&that == this)
return *this;
tempfile_.reset();
return *this;
}
void InsetERT::write(ostream & os) const
{
os << "ERT" << "\n";
@ -109,6 +129,40 @@ int InsetERT::docbook(odocstream & os, OutputParams const &) const
void InsetERT::doDispatch(Cursor & cur, FuncRequest & cmd)
{
switch (cmd.action()) {
case LFUN_INSET_EDIT: {
cur.push(*this);
text().selectAll(cur);
string const format =
cur.buffer()->params().documentClass().outputFormat();
string const ext = theFormats().extension(format);
tempfile_.reset(new TempFile("ert_editXXXXXX." + ext));
FileName const tempfilename = tempfile_->name();
string const name = tempfilename.toFilesystemEncoding();
ofdocstream os(name.c_str());
os << cur.selectionAsString(false);
os.close();
// Since we lock the inset while the external file is edited,
// we need to move the cursor outside and clear any selection inside
cur.clearSelection();
cur.pop();
cur.leaveInset(*this);
theFormats().edit(buffer(), tempfilename, format);
break;
}
case LFUN_INSET_END_EDIT: {
FileName const tempfilename = tempfile_->name();
docstring const s = tempfilename.fileContents("UTF-8");
cur.recordUndoInset(this);
cur.push(*this);
text().selectAll(cur);
cap::replaceSelection(cur);
cur.text()->insertStringAsLines(cur, s, cur.current_font);
// FIXME it crashes without this
cur.fixIfBroken();
tempfile_.reset();
cur.pop();
break;
}
case LFUN_INSET_MODIFY:
if (cmd.getArg(0) == "ert") {
cur.recordUndoInset(this);
@ -128,6 +182,12 @@ bool InsetERT::getStatus(Cursor & cur, FuncRequest const & cmd,
FuncStatus & status) const
{
switch (cmd.action()) {
case LFUN_INSET_EDIT:
status.setEnabled(tempfile_ == 0);
return true;
case LFUN_INSET_END_EDIT:
status.setEnabled(tempfile_ != 0);
return true;
case LFUN_INSET_MODIFY:
if (cmd.getArg(0) == "ert") {
status.setEnabled(true);
@ -141,6 +201,22 @@ bool InsetERT::getStatus(Cursor & cur, FuncRequest const & cmd,
}
bool InsetERT::editable() const
{
if (tempfile_)
return false;
return InsetCollapsible::editable();
}
bool InsetERT::descendable(BufferView const & bv) const
{
if (tempfile_)
return false;
return InsetCollapsible::descendable(bv);
}
docstring const InsetERT::buttonLabel(BufferView const & bv) const
{
if (decoration() == InsetLayout::CLASSIC)

View File

@ -15,7 +15,6 @@
#include "InsetCollapsible.h"
namespace lyx {
/** A collapsible text inset for LaTeX insertions.
@ -29,10 +28,18 @@ namespace lyx {
class Language;
namespace support {
class TempFile;
}
class InsetERT : public InsetCollapsible {
public:
///
InsetERT(Buffer *, CollapseStatus status = Open);
///
InsetERT(InsetERT const &);
///
InsetERT & operator=(InsetERT const &);
///
static CollapseStatus string2params(std::string const &);
///
@ -62,12 +69,18 @@ private:
void doDispatch(Cursor & cur, FuncRequest & cmd);
///
bool getStatus(Cursor & cur, FuncRequest const & cmd, FuncStatus &) const;
///
bool editable() const;
///
bool descendable(BufferView const &) const;
///
Inset * clone() const { return new InsetERT(*this); }
///
docstring const buttonLabel(BufferView const & bv) const;
///
bool allowSpellCheck() const { return false; }
///
unique_ptr<support::TempFile> tempfile_;
};