diff options
author | Martijn Laan <1092369+martijnlaan@users.noreply.github.com> | 2024-06-20 08:23:46 +1000 |
---|---|---|
committer | Martijn Laan <1092369+martijnlaan@users.noreply.github.com> | 2024-06-20 08:23:46 +1000 |
commit | 4040c66fc31c7e537d063c65ed1e734e974250c2 (patch) | |
tree | a19d212bcf90ba998d282f047741bc214598c64e | |
parent | eee34c2c5053450ec48aea8a9cbff4d5dd140b55 (diff) | |
download | scintilla-mirror-4040c66fc31c7e537d063c65ed1e734e974250c2.tar.gz |
Feature [feature-requests:#1518]. Cherry pick SCI_CUTALLOWLINE from isscint.
-rw-r--r-- | call/ScintillaCall.cxx | 4 | ||||
-rw-r--r-- | doc/ScintillaDoc.html | 7 | ||||
-rw-r--r-- | doc/ScintillaHistory.html | 5 | ||||
-rw-r--r-- | include/Scintilla.h | 1 | ||||
-rw-r--r-- | include/Scintilla.iface | 3 | ||||
-rw-r--r-- | include/ScintillaCall.h | 1 | ||||
-rw-r--r-- | include/ScintillaMessages.h | 1 | ||||
-rw-r--r-- | src/Editor.cxx | 67 | ||||
-rw-r--r-- | src/Editor.h | 3 | ||||
-rw-r--r-- | test/simpleTests.py | 13 | ||||
-rw-r--r-- | win32/ScintillaWin.cxx | 2 |
11 files changed, 89 insertions, 18 deletions
diff --git a/call/ScintillaCall.cxx b/call/ScintillaCall.cxx index 78100e774..d6c9ece4d 100644 --- a/call/ScintillaCall.cxx +++ b/call/ScintillaCall.cxx @@ -2711,6 +2711,10 @@ void ScintillaCall::CopyAllowLine() { Call(Message::CopyAllowLine); } +void ScintillaCall::CutAllowLine() { + Call(Message::CutAllowLine); +} + void *ScintillaCall::CharacterPointer() { return reinterpret_cast<void *>(Call(Message::GetCharacterPointer)); } diff --git a/doc/ScintillaDoc.html b/doc/ScintillaDoc.html index 5417fa8dd..ed8db883d 100644 --- a/doc/ScintillaDoc.html +++ b/doc/ScintillaDoc.html @@ -1852,6 +1852,7 @@ struct Sci_TextToFindFull { <a class="message" href="#SCI_COPYRANGE">SCI_COPYRANGE(position start, position end)</a><br /> <a class="message" href="#SCI_COPYTEXT">SCI_COPYTEXT(position length, const char *text)</a><br /> <a class="message" href="#SCI_COPYALLOWLINE">SCI_COPYALLOWLINE</a><br /> + <a class="message" href="#SCI_CUTALLOWLINE">SCI_CUTALLOWLINE</a><br /> <a class="message" href="#SCI_SETPASTECONVERTENDINGS">SCI_SETPASTECONVERTENDINGS(bool convert)</a><br /> <a class="message" href="#SCI_GETPASTECONVERTENDINGS">SCI_GETPASTECONVERTENDINGS → bool</a><br /> <a class="message" href="#SCI_REPLACERECTANGULAR">SCI_REPLACERECTANGULAR(position length, const char *text)</a><br /> @@ -1863,6 +1864,7 @@ struct Sci_TextToFindFull { <b id="SCI_CLEAR">SCI_CLEAR</b><br /> <b id="SCI_CANPASTE">SCI_CANPASTE → bool</b><br /> <b id="SCI_COPYALLOWLINE">SCI_COPYALLOWLINE</b><br /> + <b id="SCI_CUTALLOWLINE">SCI_CUTALLOWLINE</b><br /> These commands perform the standard tasks of cutting and copying data to the clipboard, pasting from the clipboard into the document, and clearing the document. <code>SCI_CANPASTE</code> returns non-zero if the document isn't read-only and if the selection @@ -1882,6 +1884,11 @@ struct Sci_TextToFindFull { is added to the clipboard which is then used in <code>SCI_PASTE</code> to paste the whole line before the current line.</p> + <p><code>SCI_CUTALLOWLINE</code> works the same as SCI_CUT except that if the + selection is empty then the current line is cut. On Windows, an extra "MSDEVLineSelect" marker + is added to the clipboard which is then used in <code>SCI_PASTE</code> to paste + the whole line before the current line.</p> + <b id="SCI_COPYRANGE">SCI_COPYRANGE(position start, position end)</b><br /> <b id="SCI_COPYTEXT">SCI_COPYTEXT(position length, const char *text)</b><br /> <p><code>SCI_COPYRANGE</code> copies a range of text from the document to diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 3bf4c94fb..4b0358ed4 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -580,6 +580,7 @@ <td>Chengzhi Li</td> <td>Gary James</td> <td>Tsuyoshi Miyake</td> + <td>Martijn Laan</td> </tr> </table> <h2>Releases</h2> @@ -591,6 +592,10 @@ Released 23 April 2024. </li> <li> + SCI_CUTALLOWLINE added which is similar to SCI_COPYALLOWLINE but also deletes the copied text. + <a href="https://sourceforge.net/p/scintilla/feature-requests/1518/">Feature #1518</a>. + </li> + <li> Increase maximum zoom set interactively to +60 points. <a href="https://sourceforge.net/p/scintilla/feature-requests/1517/">Feature #1517</a>. </li> diff --git a/include/Scintilla.h b/include/Scintilla.h index 75583a824..b51c8c2ab 100644 --- a/include/Scintilla.h +++ b/include/Scintilla.h @@ -976,6 +976,7 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define SCI_SETLAYOUTTHREADS 2775 #define SCI_GETLAYOUTTHREADS 2776 #define SCI_COPYALLOWLINE 2519 +#define SCI_CUTALLOWLINE 2810 #define SCI_GETCHARACTERPOINTER 2520 #define SCI_GETRANGEPOINTER 2643 #define SCI_GETGAPPOSITION 2644 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 72d2a7d41..bba11003b 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -2657,6 +2657,9 @@ get int GetLayoutThreads=2776(,) # Copy the selection, if selection empty copy the line with the caret fun void CopyAllowLine=2519(,) +# Cut the selection, if selection empty cut the line with the caret +fun void CutAllowLine=2810(,) + # Compact the document buffer and return a read-only pointer to the # characters in the document. get pointer GetCharacterPointer=2520(,) diff --git a/include/ScintillaCall.h b/include/ScintillaCall.h index 2f2e4f0cb..5db9c38d7 100644 --- a/include/ScintillaCall.h +++ b/include/ScintillaCall.h @@ -723,6 +723,7 @@ public: void SetLayoutThreads(int threads); int LayoutThreads(); void CopyAllowLine(); + void CutAllowLine(); void *CharacterPointer(); void *RangePointer(Position start, Position lengthRange); Position GapPosition(); diff --git a/include/ScintillaMessages.h b/include/ScintillaMessages.h index a00ed44b4..a2e91c92f 100644 --- a/include/ScintillaMessages.h +++ b/include/ScintillaMessages.h @@ -637,6 +637,7 @@ enum class Message { SetLayoutThreads = 2775, GetLayoutThreads = 2776, CopyAllowLine = 2519, + CutAllowLine = 2810, GetCharacterPointer = 2520, GetRangePointer = 2643, GetGapPosition = 2644, diff --git a/src/Editor.cxx b/src/Editor.cxx index 1bcaca2ef..12150dcda 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -2267,6 +2267,21 @@ void Editor::CopyAllowLine() { CopyToClipboard(selectedText); } +void Editor::CutAllowLine() { + if (sel.Empty()) { + pdoc->CheckReadOnly(); + if (!pdoc->IsReadOnly()) { + SelectionText selectedText; + if (CopyLineRange(&selectedText, false)) { + CopyToClipboard(selectedText); + LineDelete(); + } + } + } else { + Cut(); + } +} + void Editor::Cut() { pdoc->CheckReadOnly(); if (!pdoc->IsReadOnly() && !SelectionContainsProtected()) { @@ -2959,6 +2974,7 @@ void Editor::NotifyMacroRecord(Message iMessage, uptr_t wParam, sptr_t lParam) { case Message::PageDownRectExtend: case Message::SelectionDuplicate: case Message::CopyAllowLine: + case Message::CutAllowLine: case Message::VerticalCentreCaret: case Message::MoveSelectedLinesUp: case Message::MoveSelectedLinesDown: @@ -3081,6 +3097,13 @@ void Editor::ChangeCaseOfSelection(CaseMapping caseMapping) { } } +void Editor::LineDelete() { + const Sci::Line line = pdoc->SciLineFromPosition(sel.MainCaret()); + const Sci::Position start = pdoc->LineStart(line); + const Sci::Position end = pdoc->LineStart(line + 1); + pdoc->DeleteChars(start, end - start); +} + void Editor::LineTranspose() { const Sci::Line line = pdoc->SciLineFromPosition(sel.MainCaret()); if (line > 0) { @@ -3991,12 +4014,8 @@ int Editor::KeyCommand(Message iMessage) { SetLastXChosen(); } break; - case Message::LineDelete: { - const Sci::Line line = pdoc->SciLineFromPosition(sel.MainCaret()); - const Sci::Position start = pdoc->LineStart(line); - const Sci::Position end = pdoc->LineStart(line + 1); - pdoc->DeleteChars(start, end - start); - } + case Message::LineDelete: + LineDelete(); break; case Message::LineTranspose: LineTranspose(); @@ -4316,20 +4335,29 @@ std::string Editor::RangeText(Sci::Position start, Sci::Position end) const { return std::string(); } +bool Editor::CopyLineRange(SelectionText *ss, bool allowProtected) { + const Sci::Line currentLine = pdoc->SciLineFromPosition(sel.MainCaret()); + const Sci::Position start = pdoc->LineStart(currentLine); + const Sci::Position end = pdoc->LineEnd(currentLine); + + if (allowProtected || !RangeContainsProtected(start, end)) { + std::string text = RangeText(start, end); + if (pdoc->eolMode != EndOfLine::Lf) + text.push_back('\r'); + if (pdoc->eolMode != EndOfLine::Cr) + text.push_back('\n'); + ss->Copy(text, pdoc->dbcsCodePage, + vs.styles[StyleDefault].characterSet, false, true); + return true; + } else { + return false; + } +} + void Editor::CopySelectionRange(SelectionText *ss, bool allowLineCopy) { if (sel.Empty()) { if (allowLineCopy) { - const Sci::Line currentLine = pdoc->SciLineFromPosition(sel.MainCaret()); - const Sci::Position start = pdoc->LineStart(currentLine); - const Sci::Position end = pdoc->LineEnd(currentLine); - - std::string text = RangeText(start, end); - if (pdoc->eolMode != EndOfLine::Lf) - text.push_back('\r'); - if (pdoc->eolMode != EndOfLine::Cr) - text.push_back('\n'); - ss->Copy(text, pdoc->dbcsCodePage, - vs.styles[StyleDefault].characterSet, false, true); + CopyLineRange(ss); } } else { std::string text; @@ -6183,6 +6211,11 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) { CopyAllowLine(); break; + case Message::CutAllowLine: + CutAllowLine(); + SetLastXChosen(); + break; + case Message::VerticalCentreCaret: VerticalCentreCaret(); break; diff --git a/src/Editor.h b/src/Editor.h index dfc25d72d..50aa9a660 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -436,6 +436,7 @@ protected: // ScintillaBase subclass needs access to much of Editor void PasteRectangular(SelectionPosition pos, const char *ptr, Sci::Position len); virtual void Copy() = 0; void CopyAllowLine(); + void CutAllowLine(); virtual bool CanPaste(); virtual void Paste() = 0; void Clear(); @@ -481,6 +482,7 @@ protected: // ScintillaBase subclass needs access to much of Editor enum class CaseMapping { same, upper, lower }; virtual std::string CaseMapString(const std::string &s, CaseMapping caseMapping); void ChangeCaseOfSelection(CaseMapping caseMapping); + void LineDelete(); void LineTranspose(); void LineReverse(); void Duplicate(bool forLine); @@ -515,6 +517,7 @@ protected: // ScintillaBase subclass needs access to much of Editor virtual void CopyToClipboard(const SelectionText &selectedText) = 0; std::string RangeText(Sci::Position start, Sci::Position end) const; + bool CopyLineRange(SelectionText *ss, bool allowProtected=true); void CopySelectionRange(SelectionText *ss, bool allowLineCopy=false); void CopyRangeToClipboard(Sci::Position start, Sci::Position end); void CopyText(size_t length, const char *text); diff --git a/test/simpleTests.py b/test/simpleTests.py index 900f97faf..afd7de328 100644 --- a/test/simpleTests.py +++ b/test/simpleTests.py @@ -581,6 +581,19 @@ class TestSimple(unittest.TestCase): self.ed.EOLMode = lineEndType self.assertEqual(self.ed.Contents(), b"a1\na1\nb2") + def testCutAllowLine(self): + lineEndType = self.ed.EOLMode + self.ed.EOLMode = self.ed.SC_EOL_LF + self.ed.AddText(5, b"a1\nb2") + self.ed.SetSel(1,1) + self.ed.CutAllowLine() + # Clipboard = "a1\n" + self.assertEqual(self.ed.CanPaste(), 1) + self.ed.SetSel(0, 0) + self.ed.Paste() + self.ed.EOLMode = lineEndType + self.assertEqual(self.ed.Contents(), b"a1\nb2") + def testDuplicate(self): self.ed.AddText(3, b"1b2") self.ed.SetSel(1,2) diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index decf0e8f6..31d1d826f 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -595,7 +595,7 @@ ScintillaWin::ScintillaWin(HWND hwnd) { cfColumnSelect = RegisterClipboardType(L"MSDEVColumnSelect"); cfBorlandIDEBlockType = RegisterClipboardType(L"Borland IDE Block Type"); - // Likewise for line-copy (copies a full line when no text is selected) + // Likewise for line-copy or line-cut (copies or cuts a full line when no text is selected) cfLineSelect = RegisterClipboardType(L"MSDEVLineSelect"); cfVSLineTag = RegisterClipboardType(L"VisualStudioEditorOperationsLineCutCopyClipboardTag"); hrOle = E_FAIL; |