Re: [code] [textadept] Working with clipboard

From: Mitchell <m.att.foicica.com>
Date: Tue, 17 Sep 2019 12:16:01 -0400 (EDT)

Hi Qwerky,

On Sun, 15 Sep 2019, Qwerky wrote:

> Hi Mitchell,
>
> On 2019-09-15 13:35, Mitchell wrote:
>> Hi Qwerky,
>>
>> On Sun, 15 Sep 2019, Qwerky wrote:
>>
>>> Hi Mitchell,
>>>
>>> On 2019-09-15 09:08, Mitchell wrote:
>>>> Hi Qwerky,
>>>>
>>>> On Sat, 14 Sep 2019, Qwerky wrote:
>>>>
>>>>> Hi Mitchell,
>>>>>
>>>>> What is needed to make use of buffer.copy_text(), to write text to the
>>>>> clipboard?  I've used `cliptext = ui.clipboard_text` to read the
>>>>> clipboard
>>>>> text to a string, and then `for line in cliptext:gmatch('.-\n') do` to
>>>>> read
>>>>> the lines of text from the string into a table.
>>>>>
>>>>> After that, `cliptext = table.concat(cliplines, '\n')` to join the table
>>>>> lines, and `buffer.copy_text(cliptext)` to write that string back to the
>>>>> clipboard.
>>>>>
>>>>> Although this text looks the same on the clipboard, when it is pasted
>>>>> into
>>>>> some other text, the result is not the same as pasting the original
>>>>> clipboard
>>>>> text into some other text.  Specifically, when the original text is
>>>>> rectangular, and is pasted into some other text, it pastes each line
>>>>> into
>>>>> succeeding lines of the other text.  But after the above operation, the
>>>>> text
>>>>> is pasted as a group of lines at a single place, rather than individual
>>>>> lines
>>>>> going into succeeding lines of the receiving text.
>>>>>
>>>>> How can I keep the text rectangular after writing it back to the
>>>>> clipboard?
>>>>
>>>> This is not possible with Scintilla, unfortunately. You cannot put
>>>> rectangular or multi-selected text on the clipboard. Only Scintilla can
>>>> do
>>>> it. It's like a one-way thing.
>>>>
>>>> Cheers,
>>>> Mitchell
>>>
>>> Hmm... blocked at every turn.  But wait, I'm not sure that the problem
>>> lies
>>> with putting the text on the clipboard, but rather with /reading it back/
>>> in
>>> a rectangular format (see my earlier follow-up to this thread, about
>>> `buffer.selection_is_rectangle`).  I'll quote it here:
>>>
>>> "My working theory is that `buffer.selection_is_rectangle`, which is
>>> read-only, is used to keep track of whether or not the selection is
>>> rectangular, and controls how the text is pasted.  And further, that it is
>>> being reset by `buffer.copy_text()`, so that even though the text was
>>> originally selected as rectangular, after using `buffer.copy_text()`, it
>>> will
>>> always be pasted as stream.  Since `buffer.selection_is_rectangle` is
>>> read-only, I'm not sure how to work around this.  Does this theory sound
>>> correct?"
>>>
>>> When I modify the clipboard text in a Lua module, as described above, and
>>> then paste it into text in a different text editor, it can be made to
>>> appear
>>> correctly (depends on the text editor, and upon its settings). It seems to
>>> me that Scintilla is keeping track of the clipboard contents, and will
>>> paste
>>> back as rectangular only when it believes it has put rectangular data
>>> there.
>>> Also, I think it must be monitoring the clipboard, and becomes aware when
>>> another application places something on the clipboard, in which case it
>>> won't
>>> paste back as rectangular (or as line), but only as stream.
>>>
>>> So whether the limitation is in writing or reading the clipboard, the end
>>> result (and perhaps the answer as well) may be the same: Scintilla won't
>>> allow it!
>>
>> Think about it for a minute: clipboard text is just a sequence of bytes to
>> pass between applications. It is up to the applications how they want to
>> interpret it. Scintilla doesn't try to do anything fancy. Its documentation
>> states how it outputs rectangular selections and multiple selections on the
>> clipboard. It is then up to clients or external applications to figure out
>> what to do with it.
>>
>> The same idea applies to incoming clipboard text. Just because there is a
>> rectangular or multiple selection in play when text is pasted doesn't mean
>> Scintilla should try and be "smart" about what to do with said text.
>> Incoming text with newlines could legitimately not be a rectangular
>> selection, even if there is one currently.
>>
>>> This is a real blow, as this issue with rectangular selections is the last
>>> major obstacle that I have with Scintilla.  And just when I thought I had
>>> a
>>> solution (by padding the rectangle in a module), it is blocked again.
>>
>> You could try writing your own Lua code that interprets your clipboard text
>> in a special way, determines rectangular selection bounds, and then pastes
>> as you expect. I think this is kind of what Scintilla expects client
>> applications to do, as clipboard formats are not standardized, as I alluded
>> to above.
>>
>>> Well, I've posted on the Scintilla list, and we'll see what Neil says
>>> about
>>> it in October, when he gets back.  If there are any other Textadept users
>>> who
>>> would like this feature, you may wish to add your voice as well.
>>>
>>> Thanks for you help, Mitchell.  Hopefully a solution will arrive.
>>>
>>> Oh, a thought just came up: `buffer.selection_is_rectangle` is read-only
>>> in
>>> Textadept (and presumably so is its counterpart in Scintilla). Would you
>>> be
>>> able to make it read/write, which may help?
>>
>> Making it writable will not help. Scintilla just does not interpret text
>> put on the clipboard for a reason.
>>
>> Cheers,
>> Mitchell
>
> Although I do agree mostly with what you wrote, Scintilla does interpret
> /it's own/ rectangular selections and pastes them back as rectangular.  I
> thought that perhaps Scintilla's counterpart of
> `buffer.selection_is_rectangle` is what it uses to make that determination. 
> However, if you say that that is not the case, so be it.
>
> As to writing Lua code to handle it, I am quite willing to give it a shot. 
> I've already figured out how to read/pad/write the clipboard data to make it
> a proper rectangle.  But I'm not sure how to /paste/ that data into a
> Textadept buffer, which I suppose would need to be done line-by-line--any
> pointers along those lines would be appreciated.

You could try to use `buffer.rectangular_selection_{anchor,caret}` to determine the row and column extents of the rectangular selection, then iterate over those lines, using `buffer:set_target_range()` and `buffer:replace_target()` coupled with your text to paste. Wrap all of this in `buffer:{begin,end}_undo_action()` of course. Then re-bind the `buffer.paste` key to a custom function that checks for a rectangular selection on the clipboard or whatever, and if so, call your custom function. Otherwise call `buffer:paste()`.

This is off the top of my head and might need some tweaking.

Cheers,
Mitchell

-- 
You are subscribed to code.att.foicica.com.
To change subscription settings, send an e-mail to code+help.att.foicica.com.
To unsubscribe, send an e-mail to code+unsubscribe.att.foicica.com.
Received on Tue 17 Sep 2019 - 12:16:01 EDT

This archive was generated by hypermail 2.2.0 : Wed 18 Sep 2019 - 06:32:41 EDT