aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2024-07-27 12:35:18 +1000
committerNeil <nyamatongwe@gmail.com>2024-07-27 12:35:18 +1000
commit76ef74bc44e201562320906ca18d3add7084ff8b (patch)
tree6f8ea39c723a28fb9d355eb7894833689a05c68e
parent12edbfc7840bc4c56d1a7933e587694e9c774aee (diff)
downloadscintilla-mirror-76ef74bc44e201562320906ca18d3add7084ff8b.tar.gz
Feature [feature-requests:#1530]. SCI_SETCOPYSEPARATOR sets string to separate
parts of multiple selection when copied.
-rw-r--r--call/ScintillaCall.cxx12
-rw-r--r--doc/ScintillaDoc.html7
-rw-r--r--doc/ScintillaHistory.html12
-rw-r--r--include/Scintilla.h2
-rw-r--r--include/Scintilla.iface6
-rw-r--r--include/ScintillaCall.h3
-rw-r--r--include/ScintillaMessages.h2
-rw-r--r--src/EditModel.h1
-rw-r--r--src/Editor.cxx17
-rw-r--r--test/simpleTests.py19
10 files changed, 74 insertions, 7 deletions
diff --git a/call/ScintillaCall.cxx b/call/ScintillaCall.cxx
index 8f48a5256..4cb1f19d4 100644
--- a/call/ScintillaCall.cxx
+++ b/call/ScintillaCall.cxx
@@ -2723,6 +2723,18 @@ void ScintillaCall::CutAllowLine() {
Call(Message::CutAllowLine);
}
+void ScintillaCall::SetCopySeparator(const char *separator) {
+ CallString(Message::SetCopySeparator, 0, separator);
+}
+
+int ScintillaCall::CopySeparator(char *separator) {
+ return static_cast<int>(CallPointer(Message::GetCopySeparator, 0, separator));
+}
+
+std::string ScintillaCall::CopySeparator() {
+ return CallReturnString(Message::GetCopySeparator, 0);
+}
+
void *ScintillaCall::CharacterPointer() {
return reinterpret_cast<void *>(Call(Message::GetCharacterPointer));
}
diff --git a/doc/ScintillaDoc.html b/doc/ScintillaDoc.html
index eab747f1f..0e0300d95 100644
--- a/doc/ScintillaDoc.html
+++ b/doc/ScintillaDoc.html
@@ -1858,6 +1858,8 @@ struct Sci_TextToFindFull {
<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 &rarr; bool</a><br />
+ <a class="message" href="#SCI_SETCOPYSEPARATOR">SCI_SETCOPYSEPARATOR(&lt;unused&gt;, const char *separator)</a><br />
+ <a class="message" href="#SCI_GETCOPYSEPARATOR">SCI_GETCOPYSEPARATOR(&lt;unused&gt;, char *separator) &rarr; int</a><br />
<a class="message" href="#SCI_REPLACERECTANGULAR">SCI_REPLACERECTANGULAR(position length, const char *text)</a><br />
</code>
@@ -1905,6 +1907,11 @@ struct Sci_TextToFindFull {
<a class="seealso" href="#SCI_SETEOLMODE">SCI_SETEOLMODE</a>.
Defaults to true.</p>
+ <p><b id="SCI_SETCOPYSEPARATOR">SCI_SETCOPYSEPARATOR(&lt;unused&gt;, const char *separator)</b><br />
+ <b id="SCI_GETCOPYSEPARATOR">SCI_GETCOPYSEPARATOR(&lt;unused&gt;, char *separator) &rarr; int</b><br />
+ When a multiple selection is copied, this string property is added between each part.
+ Defaults to empty.</p>
+
<p><b id="SCI_REPLACERECTANGULAR">SCI_REPLACERECTANGULAR(position length, const char *text)</b><br/>
Replaces the selected text or empty selection with the given text.
The insertion is performed similarly to rectangular pastes: new lines in the given text are interpreted as
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html
index dc011dda7..520760784 100644
--- a/doc/ScintillaHistory.html
+++ b/doc/ScintillaHistory.html
@@ -586,6 +586,18 @@
</table>
<h2>Releases</h2>
<h3>
+ <a href="https://www.scintilla.org/scintilla552.zip">Release 5.5.2</a>
+ </h3>
+ <ul>
+ <li>
+ Released 22 July 2024.
+ </li>
+ <li>
+ Add SCI_SETCOPYSEPARATOR for separator between parts of a multiple selection when copied to the clipboard.
+ <a href="https://sourceforge.net/p/scintilla/feature-requests/1530/">Feature #1530</a>.
+ </li>
+ </ul>
+ <h3>
<a href="https://www.scintilla.org/scintilla551.zip">Release 5.5.1</a>
</h3>
<ul>
diff --git a/include/Scintilla.h b/include/Scintilla.h
index 8ef2532c2..719b44afd 100644
--- a/include/Scintilla.h
+++ b/include/Scintilla.h
@@ -980,6 +980,8 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP
#define SCI_GETLAYOUTTHREADS 2776
#define SCI_COPYALLOWLINE 2519
#define SCI_CUTALLOWLINE 2810
+#define SCI_SETCOPYSEPARATOR 2811
+#define SCI_GETCOPYSEPARATOR 2812
#define SCI_GETCHARACTERPOINTER 2520
#define SCI_GETRANGEPOINTER 2643
#define SCI_GETGAPPOSITION 2644
diff --git a/include/Scintilla.iface b/include/Scintilla.iface
index 85ab84324..195c87d37 100644
--- a/include/Scintilla.iface
+++ b/include/Scintilla.iface
@@ -2668,6 +2668,12 @@ fun void CopyAllowLine=2519(,)
# Cut the selection, if selection empty cut the line with the caret
fun void CutAllowLine=2810(,)
+# Set the string to separate parts when copying a multiple selection.
+set void SetCopySeparator=2811(, string separator)
+
+# Get the string to separate parts when copying a multiple selection.
+get int GetCopySeparator=2812(, stringresult separator)
+
# 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 201e31ecc..6212a42cd 100644
--- a/include/ScintillaCall.h
+++ b/include/ScintillaCall.h
@@ -726,6 +726,9 @@ public:
int LayoutThreads();
void CopyAllowLine();
void CutAllowLine();
+ void SetCopySeparator(const char *separator);
+ int CopySeparator(char *separator);
+ std::string CopySeparator();
void *CharacterPointer();
void *RangePointer(Position start, Position lengthRange);
Position GapPosition();
diff --git a/include/ScintillaMessages.h b/include/ScintillaMessages.h
index ccaa2a8d6..cac6d9d62 100644
--- a/include/ScintillaMessages.h
+++ b/include/ScintillaMessages.h
@@ -640,6 +640,8 @@ enum class Message {
GetLayoutThreads = 2776,
CopyAllowLine = 2519,
CutAllowLine = 2810,
+ SetCopySeparator = 2811,
+ GetCopySeparator = 2812,
GetCharacterPointer = 2520,
GetRangePointer = 2643,
GetGapPosition = 2644,
diff --git a/src/EditModel.h b/src/EditModel.h
index 025c54389..e36d26fb1 100644
--- a/src/EditModel.h
+++ b/src/EditModel.h
@@ -36,6 +36,7 @@ public:
bool hasFocus;
Selection sel;
bool primarySelection;
+ std::string copySeparator;
Scintilla::IMEInteraction imeInteraction;
Scintilla::Bidirectional bidirectional;
diff --git a/src/Editor.cxx b/src/Editor.cxx
index 681c0914a..390c83898 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -4361,10 +4361,12 @@ void Editor::CopySelectionRange(SelectionText *ss, bool allowLineCopy) {
std::vector<SelectionRange> rangesInOrder = sel.RangesCopy();
if (sel.selType == Selection::SelTypes::rectangle)
std::sort(rangesInOrder.begin(), rangesInOrder.end());
- for (const SelectionRange &current : rangesInOrder) {
- text.append(RangeText(current.Start().Position(), current.End().Position()));
- if (sel.selType == Selection::SelTypes::rectangle) {
- text.append(pdoc->EOLString());
+ const std::string_view separator = (sel.selType == Selection::SelTypes::rectangle) ? pdoc->EOLString() : copySeparator;
+ for (size_t part = 0; part < rangesInOrder.size(); part++) {
+ text.append(RangeText(rangesInOrder[part].Start().Position(), rangesInOrder[part].End().Position()));
+ if ((sel.selType == Selection::SelTypes::rectangle) || (part < rangesInOrder.size() - 1)) {
+ // Append unless simple selection or last part of multiple selection
+ text.append(separator);
}
}
ss->Copy(text, pdoc->dbcsCodePage,
@@ -6215,6 +6217,13 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
SetLastXChosen();
break;
+ case Message::GetCopySeparator:
+ return StringResult(lParam, copySeparator.c_str());
+
+ case Message::SetCopySeparator:
+ copySeparator = ConstCharPtrFromSPtr(lParam);
+ break;
+
case Message::VerticalCentreCaret:
VerticalCentreCaret();
break;
diff --git a/test/simpleTests.py b/test/simpleTests.py
index 4f5b7251a..1ca5b76cb 100644
--- a/test/simpleTests.py
+++ b/test/simpleTests.py
@@ -1974,9 +1974,7 @@ class TestMultiSelection(unittest.TestCase):
self.assertEqual(self.ed.Contents(), result)
def testMultipleCopy(self):
- self.ed.ClearAll()
- t = b"abc\n123\nxyz"
- self.ed.AddText(len(t), t)
+ self.ed.SetContents(b"abc\n123\nxyz")
self.ed.SetSelection(4, 5) # 1
self.ed.AddSelection(1, 3) # bc
self.ed.AddSelection(10, 11) # z
@@ -1986,6 +1984,21 @@ class TestMultiSelection(unittest.TestCase):
self.ed.Paste()
self.assertEqual(self.ed.Contents(), b"1bcz")
+ def testCopySeparator(self):
+ self.assertEqual(self.ed.GetCopySeparator(), b"")
+ self.ed.CopySeparator = b"_"
+ self.assertEqual(self.ed.GetCopySeparator(), b"_")
+ self.ed.SetContents(b"abc\n123\nxyz")
+ self.ed.SetSelection(4, 5) # 1
+ self.ed.AddSelection(1, 3) # bc
+ self.ed.AddSelection(10, 11) # z
+ self.ed.Copy()
+ self.ed.ClearAll()
+ self.ed.Paste()
+ # 1,bc,z separated by _
+ self.assertEqual(self.ed.Contents(), b"1_bc_z")
+ self.ed.CopySeparator = b""
+
def testPasteConversion(self):
# Test that line ends are converted to current mode
self.ed.SetSelection(0, 11)