Skip to content

Commit

Permalink
Fix cursor flickering on log viewer (#2118)
Browse files Browse the repository at this point in the history
  • Loading branch information
fox0430 authored Jul 27, 2024
1 parent 849bd03 commit 0d395b7
Show file tree
Hide file tree
Showing 11 changed files with 339 additions and 116 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.. _#2118: https://github.com/fox0430/moe/pull/2118

Fixed
.....

- `#2118`_ Fix cursor flickering on log viewer

41 changes: 10 additions & 31 deletions src/moepkg/editorstatus.nim
Original file line number Diff line number Diff line change
Expand Up @@ -648,11 +648,6 @@ proc updateStatusLine(status: var EditorStatus) =
isActiveWindow,
status.settings)

proc initLogViewerHighlight(buffer: seq[Runes]): Highlight =
if buffer.len > 0:
const EmptyReservedWord: seq[ReservedWord] = @[]
return buffer.initHighlight(EmptyReservedWord, SourceLanguage.langNone)

proc isInitialized(t: LspClientTable, langId: string): bool {.inline.} =
t.contains(langId) and t[langId].isInitialized

Expand Down Expand Up @@ -741,6 +736,7 @@ proc updateSyntaxHighlightings(status: EditorStatus) =
n.currentLine)
elif b.isLogViewerMode:
b.highlight = initLogViewerHighlight(b.buffer.toSeqRunes)
b.isUpdate = false
elif b.isDiffViewerMode:
b.highlight = initDiffViewerHighlight(b.buffer.toRunes)
elif b.isUpdate:
Expand Down Expand Up @@ -785,26 +781,14 @@ proc updateSyntaxHighlightings(status: EditorStatus) =
# Send a textDocument/codeLens request to the LSP server.
client.sendLspCodeLens(b)

proc updateLogViewerEditorBuffer*(b: var BufferStatus) =
## Update the logviewer buffer for editor logs.

let log = getMessageLog()
if log.len > 0 and log[0].len > 0:
b.buffer = log.toGapBuffer

proc updateLogViewerLspBuffer*(b: var BufferStatus, log: LspLog) =
## Update the logviewer buffer for LSP logs.

if log.len > 0:
b.buffer = initGapBuffer(@[ru""])

for l in log:
b.buffer.add toRunes(fmt"{$l.timestamp} -- {$l.kind}")

let lines = l.message.pretty.splitLines.toSeqRunes
for line in lines: b.buffer.add line

b.buffer.add ru""
template updateLogViewerBuffer(b: var BufferStatus) =
case b.logContent:
of editor:
b.buffer = initEditorLogViewrBuffer().toGapBuffer
of lsp:
if status.lspClients.contains(b.logLspLangId):
b.buffer = initLspLogViewrBuffer(status.lspClients[b.logLspLangId].log)
.toGapBuffer

proc updateSelectedArea(b: var BufferStatus, windowNode: var WindowNode) =
if b.isVisualLineMode:
Expand Down Expand Up @@ -892,12 +876,7 @@ proc update*(status: var EditorStatus) =
settings.filer.showIcons).toGapBuffer
elif b.isLogViewerMode:
# Update the logviewer mode buffer.
case b.logContent:
of editor:
b.updateLogViewerEditorBuffer
of lsp:
if status.lspClients.contains(b.logLspLangId):
b.updateLogViewerLspBuffer(status.lspClients[b.logLspLangId].log)
b.updateLogViewerBuffer

elif b.isDebugMode:
# Update the debug mode buffer.
Expand Down
11 changes: 8 additions & 3 deletions src/moepkg/exmode.nim
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,16 @@ proc openEditorLogViewer(status: var EditorStatus) =
status.moveNextWindow

discard status.addNewBufferInCurrentWin(Mode.logviewer)
status.resize

currentBufStatus.logContent = LogContentKind.editor

status.changeCurrentBuffer(status.bufStatus.high)

let buf = initEditorLogViewrBuffer()
currentBufStatus.buffer = buf.toGapBuffer
currentBufStatus.highlight = buf.initLogViewerHighlight

status.resize

proc openLspLogViewer(status: var EditorStatus) =
## Open a new log viewe for LSP logs.

Expand All @@ -228,13 +232,14 @@ proc openLspLogViewer(status: var EditorStatus) =
status.moveNextWindow

discard status.addNewBufferInCurrentWin(Mode.logviewer)
status.resize

status.changeCurrentBuffer(status.bufStatus.high)

currentBufStatus.logContent = LogContentKind.lsp
currentBufStatus.logLspLangId = langId

status.resize

proc openBufferManager(status: var EditorStatus) =
status.changeMode(currentBufStatus.prevMode)

Expand Down
2 changes: 2 additions & 0 deletions src/moepkg/highlight.nim
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import syntax/highlite
import lsp/[semantictoken, protocol/types]
import unicodeext, color, independentutils, ui

export SourceLanguage

type
ColorSegment* = object
firstRow*, firstColumn*, lastRow*, lastColumn*: int
Expand Down
55 changes: 54 additions & 1 deletion src/moepkg/logviewerutils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,66 @@
# #
#[############################################################################]#

import ui, unicodeext
import std/[json, strformat, strutils, times]

import lsp/client
import ui, unicodeext, messagelog, highlight

type
LogContentKind* = enum
editor
lsp

proc countLogLine[T](buf: T): int =
## `buf` is `seq[Runes]`, `GapBuffer[T]` or etc

if buf.len == 1 and buf[0].len == 0: return 0

result = 1
for i in 0 .. buf.high:
# Count empty lines after log lines.
if buf[i].len == 0: result.inc

proc initEditorLogViewrBuffer*(): seq[Runes] =
let log = getMessageLog()

if log.len == 0:
return @[ru""]

for i, l in log:
result.add l
if i < log.high:
result.add ru""

proc initLspLogViewrBuffer*(log: LspLog): seq[Runes] =
if log.len == 0:
return @[ru""]

for i in 0 .. log.high:
result.add toRunes(fmt"{$log[i].timestamp} -- {$log[i].kind}")

let lines = log[i].message.pretty.splitLines.toSeqRunes
for i in 0 .. lines.high: result.add lines[i]

if i < log.high: result.add ru""

proc initLogViewerHighlight*(buffer: seq[Runes]): Highlight =
## TODO: Move to highlight module?

if buffer.len > 0:
const EmptyReservedWord: seq[ReservedWord] = @[]
return buffer.initHighlight(EmptyReservedWord, SourceLanguage.langNone)

proc isUpdateEditorLogViwer*[T](buf: var T): bool {.inline.} =
## `buf` is `seq[Runes]`, `GapBuffer[T]` or etc

return messageLogLen() > buf.countLogLine

proc isUpdateLspLogViwer*[T](buf: var T, log: var LspLog): bool {.inline.} =
## `buf` is `seq[Runes]`, `GapBuffer[T]` or etc

log.len > buf.countLogLine

proc isLogViewerCommand*(command: Runes): InputState =
result = InputState.Invalid

Expand Down
21 changes: 20 additions & 1 deletion src/moepkg/mainloop.nim
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ import editorstatus, bufferstatus, windownode, unicodeext, gapbuffer, ui,
debugmode, commandline, search, commandlineutils, popupwindow, messages,
filermodeutils, editor, registers, exmodeutils, movement, searchutils,
independentutils, viewhighlight, completion, completionwindow,
worddictionary, referencesmode, callhierarchyviewer, editorview
worddictionary, referencesmode, callhierarchyviewer, editorview,
logviewerutils

type
BeforeLine = object
Expand Down Expand Up @@ -847,6 +848,20 @@ proc sendLspRequests(status: var EditorStatus) =
currentMainWindowNode.bufferPosition)
if err.isErr: error fmt"lsp: {err.error}"

template isUpdateEditorLogViwer(status: var EditorStatus): bool =
currentBufStatus.logContent == LogContentKind.editor and
currentBufStatus.buffer.isUpdateEditorLogViwer

template isUpdateLspLogViwer(status: var EditorStatus): bool =
currentBufStatus.logContent == LogContentKind.lsp and
status.lspClients.contains(currentBufStatus.logLspLangId) and
currentBufStatus.buffer.isUpdateLspLogViwer(
status.lspClients[currentBufStatus.logLspLangId].log)

template isUpdateLogViwer(status: var EditorStatus): bool =
status.isUpdateEditorLogViwer or
status.isUpdateLspLogViwer

proc editorMainLoop*(status: var EditorStatus) =
## Get keys, exec commands and update view.

Expand Down Expand Up @@ -875,6 +890,10 @@ proc editorMainLoop*(status: var EditorStatus) =
key = currentMainWindowNode.getKey(Timeout)

status.runBackgroundTasks

if currentBufStatus.isLogViewerMode and status.isUpdateLogViwer:
currentBufStatus.isUpdate = true

if status.bufStatus.isUpdate:
break

Expand Down
5 changes: 5 additions & 0 deletions src/moepkg/messagelog.nim
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,8 @@ proc getMessageLog*(): seq[Runes] =
proc clearMessageLog*() =
## Clear all message.
messageLog = @[]

proc messageLogLen*(): int =
## Returns the number of lines in the log.

messageLog.len
50 changes: 43 additions & 7 deletions tests/texmode.nim
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#[###################### GNU General Public License 3.0 ######################]#
# #
# Copyright (C) 2017─2023 Shuhei Nogawa #
# Copyright (C) 2017─2024 Shuhei Nogawa #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
Expand All @@ -26,7 +26,7 @@ import moepkg/syntax/highlite
import moepkg/lsp/client
import moepkg/[ui, editorstatus, gapbuffer, unicodeext, bufferstatus, settings,
windownode, helputils, backgroundprocess, quickrunutils,
exmodeutils]
exmodeutils, messagelog, logviewerutils]

import utils

Expand Down Expand Up @@ -525,17 +525,55 @@ suite "Ex mode: Open buffer manager":
const Command = @[ru"buf"]
status.exModeCommand(Command)

suite "Ex mode: Open editor log viewer":
suite "Ex mode: Open Editor log viewer":
test "Empty":
var status = initEditorStatus()
assert status.addNewBufferInCurrentWin.isOk

status.resize(100, 100)
status.update

clearMessageLog()

const Command = @[ru"log"]
status.exModeCommand(Command)

status.update

check status.mainWindow.numOfMainWindow == 2
check currentMainWindowNode.view.height > 1

check currentBufStatus.isReadonly
check currentBufStatus.logContent == LogContentKind.editor
check currentBufStatus.buffer.toSeqRunes == @[""].toSeqRunes

test "Basic":
var status = initEditorStatus()
discard status.addNewBufferInCurrentWin.get
assert status.addNewBufferInCurrentWin.isOk

status.resize(100, 100)
status.update

addMessageLog "line1"
addMessageLog "line2"

const Command = @[ru"log"]
status.exModeCommand(Command)

status.update

check status.mainWindow.numOfMainWindow == 2
check currentMainWindowNode.view.height > 1

check currentBufStatus.isReadonly
check currentBufStatus.logContent == LogContentKind.editor
check currentBufStatus.buffer.toSeqRunes == @[
"line1",
"",
"line2"
]
.toSeqRunes

suite "Ex mode: Open LSP log viewer":
var status: EditorStatus

Expand Down Expand Up @@ -602,7 +640,6 @@ suite "Ex mode: Open LSP log viewer":
check currentMainWindowNode.view.height > 1

check currentBufStatus.buffer.toSeqRunes == @[
"",
$status.lspClients["nim"].log[0].timestamp & " -- " & "request",
"{",
""" "message1": "message1"""",
Expand All @@ -611,8 +648,7 @@ suite "Ex mode: Open LSP log viewer":
$status.lspClients["nim"].log[1].timestamp & " -- " & "response",
"{",
""" "message2": "message2"""",
"}",
""
"}"
].toSeqRunes

suite "Ex mode: Highlight pair of paren settig command":
Expand Down
Loading

0 comments on commit 0d395b7

Please sign in to comment.