Skip to content

Commit

Permalink
update win_extmarks handling
Browse files Browse the repository at this point in the history
  • Loading branch information
yatli committed Sep 18, 2021
1 parent 5c78e92 commit aa1273f
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 28 deletions.
47 changes: 41 additions & 6 deletions ViewModels/GridViewModel.fs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ module private GridViewModelHelper =

open GridViewModelHelper

type TrackedGridPosition =
{
mutable trow: int
mutable tcol: int
}

[<Struct>]
type GridDrawOperation =
| Scroll of int * int * int * int * int * int
Expand Down Expand Up @@ -214,7 +220,7 @@ and GridViewModel(_gridid: int, ?_parent: GridViewModel, ?_gridsize: GridSize) a
#endif
clearBuffer preserveContent

let putBuffer (M: ReadOnlyMemory<_>) =
let putBuffer (M: ReadOnlyMemory<GridLine>) =
//if _gridid = 1 then
// trace _gridid "putBuffer"
for line in M.Span do
Expand All @@ -228,22 +234,36 @@ and GridViewModel(_gridid: int, ?_parent: GridViewModel, ?_gridsize: GridSize) a
for _i = 1 to rep do
m_gridbuffer.[row, col].hlid <- hlid
m_gridbuffer.[row, col].text <- cell.text
for m in m_gridbuffer.[row, col].marks do
m_extmarks.Remove m.mark |> ignore
m_gridbuffer.[row, col].marks <- []
col <- col + 1
markDirty { row = row; col = line.col_start; height = 1; width = col - line.col_start }

let clearMarks() =
for _,cell,_ in m_extmarks.Values do
cell.marks <- []
m_extmarks.Clear()
#if DEBUG
trace _gridid $"clearMarks"
#endif

let putExtmarks (M: Extmark[]) =
#if DEBUG
trace _gridid $"putExtmarks:\n%A{M}"
#endif
let rec rm (l: Extmark list) (id: int) =
match l with
| [] -> []
| {mark = mark} :: rest when mark = id -> rm rest id
| x :: rest -> x :: (rm rest id)
for mark in M do
let { mark = id; startRow = row; col = col } = mark
let { mark = id; row = row; col = col } = mark
match m_extmarks.TryGetValue id with
| true, (mark, cell, r, c) ->
| true, (_, cell, _) ->
cell.marks <- rm cell.marks id
| _ -> ()
m_extmarks.[id] <- (mark, m_gridbuffer.[row, col], row, col)
m_extmarks.[id] <- (mark, m_gridbuffer.[row, col], { trow = row; tcol = col })
m_gridbuffer.[row, col].marks <- mark :: m_gridbuffer.[row, col].marks

let changeMode (name: string) (index: int) =
Expand Down Expand Up @@ -299,9 +319,23 @@ and GridViewModel(_gridid: int, ?_parent: GridViewModel, ?_gridsize: GridSize) a
trace _gridid "scroll: %A %A %A %A %A %A" top bot left right rows cols
#endif

// copies the line from src to dst, and then refill the dst with "new cells"
let copy src dst =
if src >= 0 && src < m_gridsize.rows && dst >= 0 && dst < m_gridsize.rows then
GridBufferCell.MoveLine m_gridbuffer src dst left right
for c = left to right - 1 do
// since the "dst" line will be overwritten, we may say it's really new cells...
let dst_cell = m_gridbuffer.[dst,c]
let src_cell = m_gridbuffer.[src,c]
m_gridbuffer.[dst,c] <- src_cell
m_gridbuffer.[src,c] <- dst_cell
// update src row marks -> dst row
for m in src_cell.marks do
let _,_,pos = m_extmarks.[m.mark]
pos.trow <- dst
// remove dst row marks
for m in dst_cell.marks do
m_extmarks.Remove m.mark |> ignore
dst_cell.marks <- []

if rows > 0 then
for i = top + rows to bot do
Expand Down Expand Up @@ -426,6 +460,7 @@ and GridViewModel(_gridid: int, ?_parent: GridViewModel, ?_gridsize: GridSize) a
| WinExternalPos(_,win) -> setWinExternalPos win
| WinViewport(id, win, top, bot, row, col, lc) -> setWinViewport win top bot row col lc
| WinExtmarks(win, marks) -> if win = m_winhnd then putExtmarks marks
| WinExtmarksClear(win) -> if win = m_winhnd then clearMarks()
| x -> trace _gridid "unimplemented command: %A" x

let fontConfig() =
Expand Down Expand Up @@ -748,7 +783,7 @@ and GridViewModel(_gridid: int, ?_parent: GridViewModel, ?_gridsize: GridSize) a
member __.FindTargetWidget (r: int) (c: int) =
let placements = getGuiWidgetPlacements m_bufnr
m_extmarks.Values
|> Seq.tryPick(fun ({ns = ns; mark = mark},cell,cr,cc) ->
|> Seq.tryPick(fun ({ns = ns; mark = mark},cell,{trow=cr;tcol=cc}) ->
if ns <> guiwidgetNamespace || not(cell.ContainsMark mark) then None else
match placements.TryGetValue mark with
| false, _ -> None
Expand Down
3 changes: 2 additions & 1 deletion Views/Grid.xaml.fs
Original file line number Diff line number Diff line change
Expand Up @@ -354,11 +354,12 @@ type Grid() as this =
let view_top,view_bot,cur_row,line_count =
let top,bot,row,_,lc = vm.ScrollbarData
float top, float bot, float row, float lc
use _mainClipclip = ctx.PushClip(Rect(vm_x, vm_y, vm_w, vm_h))

// gui widgets
do
let placements = getGuiWidgetPlacements vm.BufNr
for ({ns = ns; mark = mark}, cell, r, c) in vm.Extmarks.Values do
for ({ns = ns; mark = mark}, cell, {trow=r;tcol=c}) in vm.Extmarks.Values do
// if cell.marks does not have this mark, it means cell has scrolled out of view.
if ns = guiwidgetNamespace && cell.ContainsMark mark then
match (placements.TryGetValue mark) with
Expand Down
25 changes: 13 additions & 12 deletions def.fs
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,7 @@ type Extmark =
{
ns: int
mark: int
startRow: int
endRow: int
row: int
col: int
}

Expand Down Expand Up @@ -369,6 +368,7 @@ type RedrawCommand =
/// watch for a specific namespace `ns_id`. `start_row`, `end_row` and
/// `start_col` are relative to the window.
| WinExtmarks of win: int * marks: Extmark[]
| WinExtmarksClear of win: int
/// Display messages on `grid`. The grid will be displayed at `row` on the
/// default grid (grid=1), covering the full column width. `scrolled`
/// indicates whether the message area has been scrolled to cover other
Expand Down Expand Up @@ -673,18 +673,18 @@ let parse_int_singleton =
-> Some(i)
| _ -> None

let parse_extmark =
function
| ObjArray [| Integer32 a; Integer32 b; Integer32 c; Integer32 d; Integer32 e |]
-> Some({ns = a; mark = b; startRow = c; endRow = d; col = e})
| _ -> None

let parse_win_extmarks =
let parse_win_extmarks_1 =
function
| ObjArray [| (Integer32 win); ObjArray(PX(parse_extmark)data) |]
-> Some(WinExtmarks(win, data))
| ObjArray [| Integer32 a; Integer32 b; Integer32 c; Integer32 d; Integer32 e |]
-> Some(a,{ns=b;mark=c;row=d;col=e})
| _ -> None

let parse_win_extmarks_2 (tuples: (int*Extmark)[]) =
tuples
|> Array.groupBy fst
|> Array.map(fun (win, marks) ->
WinExtmarks(win, marks |> Array.map snd))

let unwrap_multi xs =
match xs with
| [| one |] -> one
Expand Down Expand Up @@ -725,7 +725,8 @@ let parse_redrawcmd (x: obj) =
| C("win_scroll_over_reset", _) -> WinScrollOverReset
| C("win_close", PX(parse_int_singleton)ids) -> ids |> Array.map(WinClose) |> unwrap_multi
| C("win_viewport", PX(parse_win_viewport)cmds) -> unwrap_multi cmds
| C("win_extmarks", PX(parse_win_extmarks)cmds) -> unwrap_multi cmds
| C("win_extmarks", PX(parse_win_extmarks_1)cmds) -> cmds |> parse_win_extmarks_2 |> unwrap_multi
| C1("win_extmarks_clear", PX(Integer32)ids) -> ids |> Array.map(WinExtmarksClear) |> unwrap_multi
| C1("msg_set_pos", [|
(Integer32 grid); (Integer32 row)
(Bool scrolled); (String sep_char) |]) -> MsgSetPos(grid, row,scrolled, sep_char)
Expand Down
3 changes: 2 additions & 1 deletion model.fs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ module private ModelImpl =
| PopupMenuSelect _ | PopupMenuHide _
| Busy _ | Mouse _
| ModeChange _ | GridCursorGoto _
| WinExtmarks _ -> broadcast cmd
| WinExtmarks _
| WinExtmarksClear _ -> broadcast cmd
// Unicast
| GridClear id | GridScroll(id,_,_,_,_,_,_)
| WinClose id | WinHide(id)
Expand Down
8 changes: 0 additions & 8 deletions ui.fs
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,6 @@ type GridBufferCell =
|> List.exists (fun (x: Extmark) -> x.mark = markid)
static member CreateGrid r c =
Array2D.init r c (fun _ _ -> { text = Rune.empty; hlid = 0; marks = [] })
// copies the line from src to dst, and then refill the dst with "new cells"
static member MoveLine (grid: GridBufferCell[,]) src dst left right =
for c = left to right - 1 do
// since the "dst" line will be overwritten, we may say it's really new cells...
let tmp = grid.[dst,c]
grid.[dst,c] <- grid.[src,c]
grid.[src,c] <- tmp
tmp.marks <- []

[<Struct>]
type GridSize =
Expand Down

0 comments on commit aa1273f

Please sign in to comment.