Closed Gavin-Holt closed 1 month ago
I'm using the following in my init.lua for lazy line selection:
function selectLineUp(bp)
if not bp.Cursor:HasSelection() then
bp:EndOfLine()
bp:SelectToStartOfLine()
else
bp:SelectUp()
bp:SelectToStartOfLine()
end
end
function selectLineDown(bp)
if not bp.Cursor:HasSelection() then
bp:StartOfLine()
bp:SelectDown()
else
bp:SelectDown()
end
end
I have Ctrl-Shift-Up
and Ctrl-Shift-Down
bound to these functions:
"CtrlShiftDown": "lua:initlua.selectLineDown",
"CtrlShiftUp": "lua:initlua.selectLineUp",
So in particular you could use these to quickly select a few whole lines via Ctrl-Shift-Up
or Ctrl-Shift-Down
(i.e. in whatever direction you like) and then duplicate them via Ctrl-D
.
Hi,
Many thanks for sharing your functions - taking this as inspiration - and combining with https://github.com/zyedidia/micro/issues/2583, I have written a SelectBlock
function:
function editor_SelectBlock(Current)
-- Extend the selection to include the whole of any line selected
if editor.HasSelection(Current) then
if Current.Cursor.CurSelection[1]:LessThan(-Current.Cursor.CurSelection[2]) then
-- forward -> backward
-- Extend selection to end
Current:SelectToEndOfLine()
-- Get EOL Character
Current:SelectRight()
-- Swap to end of selection
editor_SwapAnchor(Current)
-- Extend selection to begining of line
Current:SelectToStartOfLine()
else
-- backward -> forward
-- Extend selection to begining of line
Current:SelectToStartOfLine()
-- Swap to end of selection
editor_SwapAnchor(Current)
-- Extend selection to end
Current:SelectToEndOfLine()
-- Get EOL Character
Current:SelectRight()
end
else
Current.Cursor:SelectLine()
end
return true
end
This can be called before duplicateline
to achieve block duplication:
"CtrlD": "lua:initlua.editor_GetBlock, duplicateline"
Unfortunately these manipulations change the current selection (so you can't make multiple copies).
I will leave this open as I still feel duplicateline
is an irregular command and better solution should be found.
Kind Regards Gavin Holt
I guess we can close this now as there is a work-around.
Kind Regards Gavin Holt
Hi,
After downloading the new binary today, my selectblock
function no longer works. I suspect this is a result of Fix Deselect() after mouse selection https://github.com/zyedidia/micro/commit/3f810c24d231daaee00239a919feb415e864653f or Fix cursor moving down when selection exist https://github.com/zyedidia/micro/pull/3091
This function is only used to extend the selection before using the DuplicateLine
action, to cope with with partly selected lines and I have it bound to Ctrl+D
:
"CtrlD": "lua:initlua.selectblock,DuplicateLine,EndOfLine",
It fails only when the lazy selection if from the bottom upwards!
Generally Micro will act upon partly selected lines (top down or bottom up) for all the following :
DuplicateLine
remains an outlier, and my work-around no longer works!
Not wanting to upset the current users of DuplicateLine
could we have a DuplicateLines
action which acts on all partly selected lines?
Kind Regards Gavin Holt
PS. Naming things is hard: given a free hand I would rename DuplicateLine
action to Duplicate
(a method to duplicate selection, or current line if no selection, without using the clipboard), and that would allow a more logical use for DuplicateLine
(duplicate all partly selected lines or current line if no selection, without using the clipboard).
After downloading the new binary today, my
selectblock
function no longer works. I suspect this is a result of Fix Deselect() after mouse selection 3f810c2 or Fix cursor moving down when selection exist #3091
Yes, we changed the behavior to always ignore the direction of selection. First, to make it at least consistent (and to fix bugs caused by its inconsistency), second, because apparently some users even prefer this ignore-direction-of-selection behavior.
You can use something like this now:
function selectblock(bp)
if bp.Cursor:HasSelection() then
local lastY = bp.Cursor.CurSelection[2].Y
bp:StartOfLine()
while bp.Cursor.Loc.Y <= lastY do
bp:SelectDown()
end
end
end
PS. Naming things is hard: given a free hand I would rename
DuplicateLine
action toDuplicate
(a method to duplicate selection, or current line if no selection, without using the clipboard), and that would allow a more logical use forDuplicateLine
(duplicate all partly selected lines or current line if no selection, without using the clipboard).
I'm thinking about the same. We may clean up and unify things by changing behavior of some action without changing behavior of the default keys bound to them (so that the change would not affect most users): bind Ctrl-c to Copy|CopyLine
, Ctrl-x to Cut|CutLine
, Ctrl-d to Duplicate|DuplicateLine
. The Copy
, Cut
and Duplicate
actions would return false if there is no selection, and the *Line
variants would operate on whole lines, not just the selection.
I'm thinking about the same. We may clean up and unify things by changing behavior of some action without changing behavior of the default keys bound to them (so that the change would not affect most users): bind Ctrl-c to
Copy|CopyLine
, Ctrl-x toCut|CutLine
, Ctrl-d toDuplicate|DuplicateLine
. TheCopy
,Cut
andDuplicate
actions would return false if there is no selection, and the*Line
variants would operate on whole lines, not just the selection.
Implemented in #3335. With this PR you will probably not need your selectblock
any longer.
Hi
I have been giving more thought to duplicate
and have written a function to deal with three situations:
All of these situations leave the cursor position/selection unchanged, and therefore can be repeated for multiple duplication.
My Lua function satisfies my needs, but would be better as a built in action
- to work with multiple cursors.
function duplicate(Current)
if Current.Cursor:HasSelection() then
if Current.Cursor.CurSelection[1].Y == Current.Cursor.CurSelection[2].Y then
-- Selection on a single line - therefore:
-- Duplicate selection with padding
-- Insert after last character
-- Maintain original selection
local sel = Current.Cursor:GetSelection() -- BYTES
sel = util.String(sel) -- String
sel = sel.." " -- Add right padding as likely a word
local nextcharLOC = buffer.Loc(Current.Cursor.CurSelection[2].X+1, Current.Cursor.CurSelection[2].Y)
-- If I don't increment X the inserted text expands the current selection!
Current.Buf:Insert(nextcharLOC, sel)
return true
else
-- Multiline selection - therefore:
-- Get all part selected lines
-- Insert after last line
-- Maintain original selection
local block = ""
local top = math.min(Current.Cursor.CurSelection[1].Y,Current.Cursor.CurSelection[2].Y)
local bottom = math.max(Current.Cursor.CurSelection[1].Y,Current.Cursor.CurSelection[2].Y)
for i=top, bottom,1 do
block = block..Current.Buf:Line(i).."\n"
end
local nextlineLOC = buffer.Loc(0,bottom+1)
Current.Buf:Insert(nextlineLOC, block)
return true
end
else
-- Nil selection - therefore:
-- Duplicate current line
-- Insert after current line
-- Maintain cursor position
local sel = Current.Buf:Line(Current.Cursor.Y).."\n"
local nextlineLOC = buffer.Loc(0,Current.Cursor.Y+1)
Current.Buf:Insert(nextlineLOC, sel)
return true
end
end
Kind Regards Gavin Holt
Hi
My name is Gavin, and I am a lazy line selector.
I have tried to go straight, but lack the willpower to make pinpoint accurate line selections.
I blame a troubled relationship with the mouse, we never bonded, and I have no love for the little rodent.
My condition is so bad, that sometimes my lazy line selection is backwards - from bottom up!
Thankfully, there is a near perfect solution, the micro editor.
Micro will act upon partially selected lines:
MoveLinesDown
MoveLinesUp
IndentSelection
OutSelection
lua:comment.comment
Textfilter
SpawnMultiCursorSelect
The only irregular command I have discovered so far is
DuplicateLine
, and it trips me up hourly. With no selection, the current line is duplicated. However, with any text selected - only that text is duplicated (see https://github.com/zyedidia/micro/pull/416).To duplicate a set of lines, I have to make a pinpoint selection, remembering to include the end-of-line character (not selected with a simple shift end!).
I guess many users will be accustomed to the default behaviour, and it would be unfair for my affliction to inconvenience the majority of law-abiding precision line selectors.
My ideal solution would be a pair of functions
DuplicateLinesBelow
andDuplicateLinesAbove
, which would make copies of the current lazy line selections above or below AND leave my selection (and clipboard) unchanged. e.g.Before
DuplicateLinesBelow
:After
DuplicateLinesBelow
:I am not good at manipulating bp.Cursor.Loc, so a Lua solution is beyond my abilities.
Any help for an incurable lazy line selector would be welcome.
Kind Regards Gavin Holt
OS: Windows 10 Version: 2.0.13 Commit hash: https://github.com/zyedidia/micro/commit/68d88b571de6dca9fb8f03e2a3caafa2287c38d4 Compiled on December 12, 2023