aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSwissalpS <Luke@SwissalpS.ws>2020-06-26 02:10:03 +0200
committerSwissalpS <Luke@SwissalpS.ws>2020-06-26 02:10:03 +0200
commitf4c7a57ed2e8c4e5b6cc39786820d160c9baab14 (patch)
tree2e684d0e2dc56514bf94e0282e7afb1b1467211c
parent76144065f71d08ec5eb0ccc7309d847c871a3d11 (diff)
downloadlite-xl-plugins-f4c7a57ed2e8c4e5b6cc39786820d160c9baab14.tar.gz
lite-xl-plugins-f4c7a57ed2e8c4e5b6cc39786820d160c9baab14.zip
added basic drag and drop of selected text
TODO: use system DnD events and add drag image
-rw-r--r--README.md1
-rw-r--r--plugins/draganddropselectedtext.lua103
2 files changed, 104 insertions, 0 deletions
diff --git a/README.md b/README.md
index 4ca8550..3f26d59 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,7 @@ Plugin | Description
[`copyfilelocation`](plugins/copyfilelocation.lua?raw=1) | Copy file location to clipboard
[`datetimestamps`](plugins/datetimestamps.lua?raw=1) | Insert date-, time- and date-time-stamps
[`detectindent`](plugins/detectindent.lua?raw=1) | Automatically detects and uses the indentation size and tab type of a loaded file
+[`draganddropselectedtext`](plugins/draganddropselectedtext.lua?raw=1) | Provides basic drag and drop of selected text (in same document)
[`drawwhitespace`](plugins/drawwhitespace.lua?raw=1) | Draws tabs and spaces *([screenshot](https://user-images.githubusercontent.com/3920290/80573013-22ae5800-89f7-11ea-9895-6362a1c0abc7.png))*
[`eval`](plugins/eval.lua?raw=1) | Replaces selected Lua code with its evaluated result
[`exec`](plugins/exec.lua?raw=1) | Runs selected text through shell command and replaces with result
diff --git a/plugins/draganddropselectedtext.lua b/plugins/draganddropselectedtext.lua
new file mode 100644
index 0000000..984f209
--- /dev/null
+++ b/plugins/draganddropselectedtext.lua
@@ -0,0 +1,103 @@
+--[[
+ draganddropselectedtext.lua
+ provides basic drag and drop of selected text (in same document)
+ version: 20200626_013631
+ originally by SwissalpS
+
+ TODO: use OS drag and drop events
+ TODO: change mouse cursor when duplicating
+ TODO: add dragging image
+--]]
+local DocView = require "core.docview"
+local core = require "core"
+local keymap = require "core.keymap"
+
+-- helper function for on_mouse_pressed to determine if mouse down is in selection
+-- iLine is line number where mouse down happened
+-- iCol is column where mouse down happened
+-- iSelLine1 is line number where selection starts
+-- iSelCol1 is column where selection starts
+-- iSelLine2 is line number where selection ends
+-- iSelCol2 is column where selection ends
+local function isInSelection(iLine, iCol, iSelLine1, iSelCol1, iSelLine2, iSelCol2)
+ if iLine < iSelLine1 then return false end
+ if iLine > iSelLine2 then return false end
+ if (iLine == iSelLine1) and (iCol < iSelCol1) then return false end
+ if (iLine == iSelLine2) and (iCol > iSelCol2) then return false end
+ return true
+end -- isInSelection
+
+-- override DocView:on_mouse_moved
+local on_mouse_moved = DocView.on_mouse_moved
+function DocView:on_mouse_moved(x, y, ...)
+
+ -- make sure we only act if previously on_mouse_pressed was in selection
+ if self.bClickedIntoSelection then
+
+ -- check for modifier to duplicate
+ -- (may want to set a flag as this only needs to be done once)
+ -- TODO: make image to drag with and/or hand over to OS dnd event
+ if not keymap.modkeys['ctrl'] then
+ -- TODO: maybe check if moved at all and only delete then or
+ -- as some editors do, only when dropped. I do like it going
+ -- instantly as that reduces the travel-distance.
+ self.doc:delete_to(0)
+ --self.cursor = 'arrowWithPlus'
+ end
+ -- calculate line and column for current mouse position
+ local iLine, iCol = self:resolve_screen_position(x, y)
+ -- move text cursor
+ self.doc:set_selection(iLine, iCol)
+ -- update scroll position
+ self:scroll_to_line(iLine, true)
+
+ end -- if previously clicked into selection
+
+ -- hand off to 'old' on_mouse_moved()
+ return on_mouse_moved(self, x, y, ...)
+
+end -- DocView:on_mouse_moved
+
+-- override DocView:on_mouse_pressed
+local on_mouse_pressed = DocView.on_mouse_pressed
+function DocView:on_mouse_pressed(button, x, y, clicks)
+
+ -- no need to proceed if not left button or has no selection
+ if ('left' ~= button)
+ or not self.doc:has_selection() then
+ return on_mouse_pressed(self, button, x, y, clicks)
+ end
+ -- convert pixel coordinates to line and column coordinates
+ local iLine, iCol = self:resolve_screen_position(x, y)
+ -- get selection coordinates
+ local iSelLine1, iSelCol1, iSelLine2, iSelCol2 = self.doc:get_selection(true)
+ -- set flag for on_mouse_released and on_mouse_moved() methods to detect dragging
+ self.bClickedIntoSelection = isInSelection(iLine, iCol, iSelLine1, iSelCol1,
+ iSelLine2, iSelCol2)
+ if self.bClickedIntoSelection then
+ -- stash selection for inserting later
+ self.sDraggedText = self.doc:get_text(self.doc:get_selection())
+ else
+ -- let 'old' on_mouse_pressed() do whatever it needs to do
+ on_mouse_pressed(self, button, x, y, clicks)
+ end
+
+end -- DocView:on_mouse_pressed
+
+-- override DocView:on_mouse_released()
+local on_mouse_released = DocView.on_mouse_released
+function DocView:on_mouse_released(button)
+
+ if self.bClickedIntoSelection then
+ -- insert stashed selected text at current position
+ self.doc:text_input(self.sDraggedText)
+ -- unset stash and flag(s) TODO:
+ self.sDraggedText = ''
+ self.bClickedIntoSelection = nil
+ end
+
+ -- hand over to old handler
+ on_mouse_released(self, button)
+
+end -- DocView:on_mouse_released
+