From c759ab0f803be663f681bc670fc4824d4e9bb470 Mon Sep 17 00:00:00 2001 From: fox0430 Date: Wed, 13 Dec 2023 09:02:38 +0900 Subject: [PATCH] Chnaged: `#1965`_ Rewrite clipboard --- documents/configfile.md | 4 +- example/moerc.toml | 3 +- src/moepkg/clipboard.nim | 119 +++++++++------- src/moepkg/configmode.nim | 12 +- src/moepkg/init.nim | 3 +- src/moepkg/registers.nim | 9 +- src/moepkg/settings.nim | 55 ++++---- src/moepkg/unicodeext.nim | 12 ++ tests/tclipboard.nim | 283 ++++++++++++++++---------------------- tests/tconfigmode.nim | 18 +-- tests/teditor.nim | 48 +++---- tests/tregisters.nim | 33 +---- tests/tsettings.nim | 40 ++++-- tests/utils.nim | 95 +++++++++++++ 14 files changed, 403 insertions(+), 331 deletions(-) create mode 100644 tests/utils.nim diff --git a/documents/configfile.md b/documents/configfile.md index 1b4271b08..7f5388bec 100644 --- a/documents/configfile.md +++ b/documents/configfile.md @@ -152,10 +152,10 @@ enable Set clipboard tool for Linux (string) default is xsel -`xsel` or `xclip` or `wl-clipboard`. +`xsel`, `xclip`, `wl-clipboard`, `wsl-default`, `macOS-default`. ``` -toolOnLinux +tool ``` ### TabLine table diff --git a/example/moerc.toml b/example/moerc.toml index 049ddfbe7..b15b3cb7c 100644 --- a/example/moerc.toml +++ b/example/moerc.toml @@ -49,9 +49,10 @@ liveReloadOfFile = false colorMode = "24bit" [Clipboard] + enable = true -# toolOnLinux = "xsel" +tool = "xsel" [BuildOnSave] diff --git a/src/moepkg/clipboard.nim b/src/moepkg/clipboard.nim index 54d832780..c9a33d8ad 100644 --- a/src/moepkg/clipboard.nim +++ b/src/moepkg/clipboard.nim @@ -19,69 +19,94 @@ import std/[os, osproc, strformat, strutils] import pkg/results -import independentutils, platform, settings, unicodeext +import independentutils, settings, unicodeext -proc linesToStrings(lines: seq[Runes]): string = +proc linesToString(lines: Runes | seq[Runes]): string = result = lines.toString result.stripLineEnd +proc genHereDocument(cmd, delimiterStr, buf: string): string {.inline.} = + cmd & + " <<" & + "'" & + delimiterStr & + "'" & + "\n" & + buf & + "\n" & + delimiterStr & + "\n" + +proc xselCopyCommand(delimiterStr, buf: string): string {.inline.} = + genHereDocument("xsel", delimiterStr, buf) + +proc xclipCopyCommand(delimiterStr, buf: string): string {.inline.} = + genHereDocument("xclip", delimiterStr, buf) + +proc wlClipboardCopyComand(delimiterStr, buf: string): string {.inline.} = + genHereDocument("wl-copy", delimiterStr, buf) + +proc wslDefaultCopyCommand(delimiterStr, buf: string): string {.inline.} = + genHereDocument("clip.exe", delimiterStr, buf) + +proc macOsDefaultCopyCommand(delimiterStr, buf: string): string {.inline.} = + genHereDocument("pbcopy", delimiterStr, buf) + +proc xselPasteCommand(): string {.inline.} = "xsel -o" + +proc xclipPasteCommand(): string {.inline.} = "xclip -o" + +proc wlClipboardPasteCommand(): string {.inline.} = "wl-paste" + +proc wslDefaultPasteCommand(): string {.inline.} = + "powershell.exe -Command Get-Clipboard" + +proc macOsDefaultPasteCommand(): string {.inline.} = "pbpaste" + proc sendToClipboard*( - buffer: seq[Runes], - tool: ClipboardTool) = + buffer: Runes | seq[Runes], + tool: ClipboardTool): Result[(), string] = ## Send the buffer to the OS clipboard (xclip, xsel, etc). - if buffer.len < 1: return + if buffer.isEmpty: return let - str = linesToStrings(buffer) - delimiterStr = genDelimiterStr(str) - - case currentPlatform: - of linux: - let cmd = - if tool == ClipboardTool.xclip: - "xclip -r <<" & "'" & delimiterStr & "'" & "\n" & str & "\n" & delimiterStr & "\n" - elif tool == ClipboardTool.xsel: - "xsel <<" & "'" & delimiterStr & "'" & "\n" & str & "\n" & delimiterStr & "\n" - elif tool == ClipboardTool.wlClipboard: - "wl-copy <<" & "'" & delimiterStr & "'" & "\n" & str & "\n" & delimiterStr & "\n" - else: - "" - - if cmd.len > 0: - discard execShellCmd(cmd) - of wsl: - let cmd = "clip.exe <<" & "'" & delimiterStr & "'" & "\n" & str & "\n" & delimiterStr & "\n" - discard execShellCmd(cmd) - of mac: - let cmd = "pbcopy <<" & "'" & delimiterStr & "'" & "\n" & str & "\n" & delimiterStr & "\n" - discard execShellCmd(cmd) - else: - discard - -proc sendToClipboard*(buffer: Runes, tool: ClipboardTool) {.inline.} = - ## Send the buffer to the OS clipboard (xclip, xsel, etc). - - sendToClipboard(@[buffer], tool) - -proc getBufferFromClipboard*(tool: ClipboardTool): Result[Runes, string] = - ## Return the buffer from the OS clipboard. + buf = linesToString(buffer) + delimiterStr = genDelimiterStr(buf) + cmd = + case tool: + of xsel: xselCopyCommand(delimiterStr, buf) + of xclip: xclipCopyCommand(delimiterStr, buf) + of wlClipboard: wlClipboardCopyComand(delimiterStr, buf) + of wslDefault: wslDefaultCopyCommand(delimiterStr, buf) + of macOsDefault: macOsDefaultCopyCommand(delimiterStr, buf) - if tool == ClipboardTool.none: return + if execShellCmd(cmd) != 0: + return Result[(), string].err "Error: Clipboard: copy failed" + + return Result[(), string].ok () + +proc getFromClipboard*(tool: ClipboardTool): Result[Runes, string] = + ## Return the buffer from the OS clipboard. let cmd = case tool: - of xsel: "xsel -o" - of xclip: "xclip -o" - of wlClipboard: "wl-paste" - of wslDefault: "powershell.exe -Command Get-Clipboard" - of macOsDefault: "pbpaste" - else: "" + of xsel: xselPasteCommand() + of xclip: xclipPasteCommand() + of wlClipboard: wlClipboardPasteCommand() + of wslDefault: wslDefaultPasteCommand() + of macOsDefault: macOsDefaultPasteCommand() let cmdResult = execCmdEx(cmd) if cmdResult.exitCode != 0: - return Result[Runes, string].err fmt"clipboard: Failed to get clipboard buffer: {$cmdResult}" + return Result[Runes, string].err fmt"Error: Clipboard: Failed to get clipboard buffer: {$cmdResult}" var buf = cmdResult.output - buf.stripLineEnd + case tool: + of wlClipboard, wslDefault: + # Remove two newlines. + for i in 0 .. 1: buf.stripLineEnd + else: + buf.stripLineEnd + return Result[Runes, string].ok buf.toRunes diff --git a/src/moepkg/configmode.nim b/src/moepkg/configmode.nim index d07228182..a55e0e0b1 100644 --- a/src/moepkg/configmode.nim +++ b/src/moepkg/configmode.nim @@ -298,7 +298,7 @@ proc getClipboardTableSettingsValues( result = @[ru "true", ru "false"] else: result = @[ru "false", ru "true"] - of "toolOnLinux": + of "tool": for toolName in ClipboardTool: if $toolName == "wlClipboard": result.add ru "wl-clipboard" @@ -776,9 +776,9 @@ proc changeClipBoardTableSettings( case settingName: of "enable": settings.enable = parseBool(settingVal) - of "toolOnLinux": + of "tool": let name = if settingVal == "wl-clipboard": "wlClipboard" else: settingVal - settings.toolOnLinux = parseEnum[ClipboardTool](name) + settings.tool = parseEnum[ClipboardTool](name) else: discard @@ -1181,7 +1181,7 @@ proc getSettingType(table, name: string): SettingType = case name: of "enable": result = SettingType.bool - of "toolOnLinux": + of "tool": result = SettingType.enums else: result = SettingType.none @@ -1886,8 +1886,8 @@ proc initClipBoardTableBuffer(settings: ClipboardSettings): seq[Runes] = case $name: of "enable": result.add(ru nameStr & space & $settings.enable) - of "toolOnLinux": - result.add(ru nameStr & space & $settings.toolOnLinux) + of "tool": + result.add(ru nameStr & space & $settings.tool) proc initBuildOnSaveTableBuffer(settings: BuildOnSaveSettings): seq[Runes] = result.add(ru"BuildOnSave") diff --git a/src/moepkg/init.nim b/src/moepkg/init.nim index b3aa89a03..fc9d84e61 100644 --- a/src/moepkg/init.nim +++ b/src/moepkg/init.nim @@ -136,7 +136,8 @@ proc initEditor*(): EditorStatus = result.initSidebar - result.registers.setClipBoardTool(result.settings.clipboard.toolOnLinux) + if result.settings.clipboard.enable: + result.registers.setClipBoardTool(result.settings.clipboard.tool) disableControlC() catchTerminalResize() diff --git a/src/moepkg/registers.nim b/src/moepkg/registers.nim index ba92d2efb..1c41f9a7d 100644 --- a/src/moepkg/registers.nim +++ b/src/moepkg/registers.nim @@ -114,9 +114,8 @@ proc initRegisters*(): Registers = proc setClipboardTool*(r: var Registers, tool: ClipboardTool) {.inline.} = ## Set the clipboard tool for Linux and init the clipboard register. - if tool != ClipboardTool.none: - r.clipboardTool = some(tool) - r.clipboard = initClipBoardRegister(now()) + r.clipboardTool = some(tool) + r.clipboard = initClipBoardRegister(now()) proc isNamedRegisterName*(c: char): bool {.inline.} = c in Letters @@ -167,7 +166,7 @@ proc setNoNamedRegister*( r.noNamed.set(buffer) if r.clipboardTool.isSome: - buffer.sendToClipboard(r.clipboardTool.get) + discard buffer.sendToClipboard(r.clipboardTool.get) proc set( r: var NumberRegisters, @@ -308,7 +307,7 @@ proc trySetClipBoardRegister(r: var Registers): bool = if r.clipboardTool.isSome: # Check the OS clipboard and update clipboard and no named registers. - let buf = getBufferFromClipboard(r.clipboardTool.get) + let buf = getFromClipboard(r.clipboardTool.get) if buf.isOk and buf.get.len > 0: let lines = buf.get.splitLines if r.isUpdateClipBoardRegister(lines): diff --git a/src/moepkg/settings.nim b/src/moepkg/settings.nim index c72476d6e..23cfb8698 100644 --- a/src/moepkg/settings.nim +++ b/src/moepkg/settings.nim @@ -34,7 +34,6 @@ type VSCode ClipboardTool* = enum - none xsel xclip wlClipboard @@ -202,7 +201,7 @@ type ClipboardSettings* = object enable*: bool - toolOnLinux*: ClipboardTool + tool*: ClipboardTool GitSettings* = object showChangedLine*: bool @@ -412,9 +411,8 @@ proc initPersistSettings(): PersistSettings = result.searchHistoryLimit = 1000 result.cursorPosition = true -# Automatically set the clipboard tool on GNU/Linux -proc autoSetClipboardTool(): ClipboardTool = - result = ClipboardTool.none +proc autoSetClipboardTool(): Option[ClipboardTool] = + ## Automatically set the clipboard tool for your environment. case currentPlatform: of linux: @@ -422,7 +420,7 @@ proc autoSetClipboardTool(): ClipboardTool = if execCmdExNoOutput("xset q") == 0: if execCmdExNoOutput("xsel --version") == 0: - result = ClipboardTool.xsel + result = some(ClipboardTool.xsel) elif execCmdExNoOutput("xclip -version") == 0: let (output, _) = execCmdEx("xclip -version") # Check xclip version @@ -430,16 +428,18 @@ proc autoSetClipboardTool(): ClipboardTool = lines = output.splitLines versionStr = (strutils.splitWhitespace(lines[0]))[2] if parseFloat(versionStr) >= 0.13: - result = ClipboardTool.xclip + result = some(ClipboardTool.xclip) elif execCmdExNoOutput("wl-copy -v") == 0: - result = ClipboardTool.wlClipboard + result = some(ClipboardTool.wlClipboard) + of mac: + result = some(ClipboardTool.macOsDefault) else: - discard + result = none(ClipboardTool) proc initClipboardSettings(): ClipboardSettings = - result.toolOnLinux = autoSetClipboardTool() - - if ClipboardTool.none != result.toolOnLinux: + let tool = autoSetClipboardTool() + if tool.isSome: + result.tool = tool.get result.enable = true proc initGitSettings(): GitSettings = @@ -1195,17 +1195,19 @@ proc parseClipboardTable( if clipboardConfigs.contains("enable"): s.clipboard.enable = clipboardConfigs["enable"].getBool - if clipboardConfigs.contains("toolOnLinux"): - let str = clipboardConfigs["toolOnLinux"].getStr + if clipboardConfigs.contains("tool"): + let str = clipboardConfigs["tool"].getStr case str: - of "xsel": - s.clipboard.toolOnLinux = ClipboardTool.xsel of "xclip": - s.clipboard.toolOnLinux = ClipboardTool.xclip + s.clipboard.tool = ClipboardTool.xclip of "wl-clipboard": - s.clipboard.toolOnLinux = ClipboardTool.wlClipboard + s.clipboard.tool = ClipboardTool.wlClipboard + of "wsl-default": + s.clipboard.tool = ClipboardTool.wslDefault + of "macOS-default": + s.clipboard.tool = ClipboardTool.macOsDefault else: - s.clipboard.toolOnLinux = ClipboardTool.xsel + s.clipboard.tool = ClipboardTool.xsel proc parseTabLineTable(s: var EditorSettings, tablineConfigs: TomlValueRef) = if tablineConfigs.contains("allBuffer"): @@ -1892,18 +1894,17 @@ proc validateStandardTable(table: TomlValueRef): Option[InvalidItem] = return some(InvalidItem(name: $key, val: $val)) proc validateClipboardTable(table: TomlValueRef): Option[InvalidItem] = + template isValidTool(s: string): bool = + s in [ "xclip", "xsel", "wl-clipboard", "wsl-defaut", "macOS-default"] + for key, val in table.getTable: case key: of "enable": if not (val.kind == TomlValueKind.Bool): return some(InvalidItem(name: $key, val: $val)) - of "toolOnLinux": - if not ( - (val.kind == TomlValueKind.String) and - (val.getStr == "none" or - val.getStr == "xclip" or - val.getStr == "xsel" or - val.getStr == "wl-clipboard")): return some(InvalidItem(name: $key, val: $val)) + of "tool": + if not (val.kind == TomlValueKind.String and val.getStr.isValidTool): + return some(InvalidItem(name: $key, val: $val)) else: return some(InvalidItem(name: $key, val: $val)) @@ -2415,7 +2416,7 @@ proc genTomlConfigStr*(settings: EditorSettings): string = result.addLine fmt "[Clipboard]" result.addLine fmt "enable = {$settings.clipboard.enable}" - result.addLine fmt "toolOnLinux = \"{$settings.clipboard.toolOnLinux}\"" + result.addLine fmt "tool = \"{$settings.clipboard.tool}\"" result.addLine "" diff --git a/src/moepkg/unicodeext.nim b/src/moepkg/unicodeext.nim index 133d710ef..c4d41c7b9 100644 --- a/src/moepkg/unicodeext.nim +++ b/src/moepkg/unicodeext.nim @@ -285,6 +285,8 @@ proc startsWith*(r1: Runes, r2: Runes | Rune): bool {.inline.} = proc endsWith*(r1: Runes, r2: Runes | Rune): bool {.inline.} = endsWith($r1, $r2) +proc toString*(runes: Runes): string {.inline.} = $runes + proc toString*(lines: seq[Runes]): string = for i, runes in lines: result &= $runes & '\n' @@ -625,3 +627,13 @@ proc maxLen*(lines: seq[Runes]): int {.inline.} = proc maxHigh*(lines: seq[Runes]): int {.inline.} = lines.mapIt(it.high).max + +proc removeNewLineAtEnd*(runes: Runes): Runes = + result = runes + + var countNewline = 0 + for i in countdown(runes.high, 0): + if runes[i] in [ru'\n', ru'\r']: countNewline.inc + else: break + + if countNewline > 0: return result[0 .. countNewline] diff --git a/tests/tclipboard.nim b/tests/tclipboard.nim index 6a0c32dc9..626a0bffa 100644 --- a/tests/tclipboard.nim +++ b/tests/tclipboard.nim @@ -17,171 +17,128 @@ # # #[############################################################################]# -import std/[unittest, osproc] +import std/[unittest, osproc, strformat, strutils] +import pkg/results import moepkg/[settings, unicodeext, clipboard] +import utils import moepkg/platform {.all.} import moepkg/independentutils {.all.} -proc isXAvailable(): bool {.inline.} = - execCmdExNoOutput("xset q") == 0 - -proc isXselAvailable(): bool {.inline.} = - isXAvailable() and execCmdExNoOutput("xsel --version") == 0 - -proc isXclipAvailable(): bool {.inline.} = - isXAvailable() and execCmdExNoOutput("xclip -version") == 0 - -if isXselAvailable(): - suite "Clipboard: Send to clipboad (xsel)": - test "Send string to clipboard 1 (xsel)": - const - Buffer = @["Clipboard test"].toSeqRunes - Tool = ClipboardTool.xsel - - sendToClipboard(Buffer, Tool) - - let p = initPlatform() - if p == Platforms.linux or p == Platforms.wsl: - let - cmd = - if p == Platforms.linux: - execCmdEx("xsel -o") - else: - # On the WSL - execCmdEx("powershell.exe -Command Get-Clipboard") - (output, exitCode) = cmd - - check exitCode == 0 - if p == Platforms.linux: - check output[0 .. output.high - 1] == $Buffer[0] - else: - # On the WSL - check output[0 .. output.high - 2] == $Buffer[0] - - test "Send string to clipboard 1 (xclip)": - const - Buffer = @["Clipboard test"].toSeqRunes - Tool = ClipboardTool.xclip - - sendToClipboard(Buffer, Tool) - - let p = initPlatform() - if p == Platforms.linux or p == Platforms.wsl: - let - cmd = - if p == Platforms.linux: - execCmdEx("xclip -o") - else: - # On the WSL - execCmdEx("powershell.exe -Command Get-Clipboard") - (output, exitCode) = cmd - - check exitCode == 0 - if p == Platforms.linux: - check output[0 .. output.high - 1] == $Buffer[0] - else: - # On the WSL - check output[0 .. output.high - 2] == $Buffer[0] - - test "Send string to clipboard 2 (xsel)": - const - Buffer = @["`````"].toSeqRunes - Tool = ClipboardTool.xsel - - sendToClipboard(Buffer, Tool) - - let p = initPlatform() - if p == Platforms.linux or p == Platforms.wsl: - let - cmd = - if p == Platforms.linux: - execCmdEx("xsel -o") - else: - # On the WSL - execCmdEx("powershell.exe -Command Get-Clipboard") - (output, exitCode) = cmd - - check exitCode == 0 - if p == Platforms.linux: - check output[0 .. output.high - 1] == $Buffer[0] - else: - # On the WSL - check output[0 .. output.high - 2] == $Buffer[0] - -if isXclipAvailable(): - suite "Clipboard: Send string to clipboard (xclip)": - test "Send string to clipboard (xclip)": - const - Buffer = @["`````"].toSeqRunes - Tool = ClipboardTool.xclip - - sendToClipboard(Buffer, Tool) - - let p = initPlatform() - if p == Platforms.linux or p == Platforms.wsl: - let - cmd = - if p == Platforms.linux: - execCmdEx("xclip -o") - else: - # On the WSL - execCmdEx("powershell.exe -Command Get-Clipboard") - (output, exitCode) = cmd - - check exitCode == 0 - if p == Platforms.linux: - check output[0 .. output.high - 1] == $Buffer[0] - else: - # On the WSL - check output[0 .. output.high - 2] == $Buffer[0] - - test "Send string to clipboard 2 (xsel)": - const - Buffer = @["$Clipboard test"].toSeqRunes - Tool = ClipboardTool.xsel - - sendToClipboard(Buffer, Tool) - - let p = initPlatform() - if p == Platforms.linux or p == Platforms.wsl: - let - cmd = - if p == Platforms.linux: - execCmdEx("xsel -o") - else: - # On the WSL - execCmdEx("powershell.exe -Command Get-Clipboard") - (output, exitCode) = cmd - - check exitCode == 0 - if p == Platforms.linux: - check output[0 .. output.high - 1] == $Buffer[0] - else: - # On the WSL - check output[0 .. output.high - 2] == $Buffer[0] - - test "Send string to clipboard 3 (xclip)": - const - Buffer = @["$Clipboard test"].toSeqRunes - Tool = ClipboardTool.xclip - - sendToClipboard(Buffer, Tool) - - let p = initPlatform() - if p == Platforms.linux or p == Platforms.wsl: - let - cmd = - if p == Platforms.linux: - execCmdEx("xclip -o") - else: - # On the WSL - execCmdEx("powershell.exe -Command Get-Clipboard") - (output, exitCode) = cmd - - check exitCode == 0 - if p == Platforms.linux: - check output[0 .. output.high - 1] == $Buffer[0] - else: - # On the WSL - check output[0 .. output.high - 2] == $Buffer[0] +proc removeLineEnd(buf: string, tool: ClipboardTool): string = + case tool: + of wslDefault, wlClipboard: + result = buf + for i in 0 .. 1: + # Remove two newlines. + result.stripLineEnd + else: + return buf.removeLineEnd + +template isToolAvailable(tool: ClipboardTool): bool = + case tool: + of xsel: isXselAvailable() + of xclip: isXclipAvailable() + of wlClipboard: isWlClipboardAvailable() + of wslDefault: isWsl() + else: false + +template getClipboardBuffer(tool: ClipboardTool): string = + case tool: + of xsel: getXselBuffer() + of xclip: getXclipBuffer() + of wlClipboard: getWlClipboardBuffer() + of wslDefault: getWslDefaultBuffer() + else: "" + +template clearClipboard(tool: ClipboardTool) = + case tool + of xsel: assert clearXsel() + of xclip: assert clearXclip() + of wlClipboard: assert clearWlClipboard() + of wslDefault: assert clearWslDefaultClipboard() + else: assert false + +template runClipboardSendTests(tool: ClipboardTool) = + test "Runes": + if not isToolAvailable(tool): + skip() + else: + clearClipboard(tool) + + const Buffer = ru"abc" + check sendToClipboard(Buffer, tool).isOk + + let buf = getClipboardBuffer(tool).removeLineEnd(tool) + check buf == $Buffer + + test "Lines": + if not isToolAvailable(tool): + skip() + else: + clearClipboard(tool) + + const Buffer = @["abc", "def"].toSeqRunes + check sendToClipboard(Buffer, tool).isOk + + let buf = getClipboardBuffer(tool).removeLineEnd(tool) + check buf == Buffer.toString.removeLineEnd + + test "Only back quotes": + if not isToolAvailable(tool): + skip() + else: + const Buffer = @["`````"].toSeqRunes + check sendToClipboard(Buffer, tool).isOk + + let buf = getClipboardBuffer(tool).removeLineEnd(tool) + check buf == Buffer.toString.removeLineEnd + +template runClipboardGetTests(tool: ClipboardTool) = + test "Runes": + if not isToolAvailable(tool): + skip() + else: + clearClipboard(tool) + + const Buffer = ru"abc" + assert sendToClipboard(Buffer, tool).isOk + + let buf = getFromClipboard(tool).get + check buf == Buffer + + test "Lines": + if not isToolAvailable(tool): + skip() + else: + clearClipboard(tool) + + const Buffer = @["abc", "def"].toSeqRunes + assert sendToClipboard(Buffer, tool).isOk + + let buf = getFromClipboard(tool).get + check buf == "abc\ndef".toRunes + +suite fmt"clipboard: Send to clipboad (xsel)": + runClipboardSendTests(ClipboardTool.xsel) + +suite fmt"clipboard: Send to clipboad (xclip)": + runClipboardSendTests(ClipboardTool.xclip) + +suite fmt"clipboard: Send to clipboad (wl-clipboard)": + runClipboardSendTests(ClipboardTool.wlClipboard) + +suite fmt"clipboard: Send to clipboad (WSL)": + runClipboardSendTests(ClipboardTool.wslDefault) + +suite fmt"clipboard: Get from clipboad (xsel)": + runClipboardGetTests(ClipboardTool.xsel) + +suite fmt"clipboard: Get from clipboad (xclip)": + runClipboardGetTests(ClipboardTool.xclip) + +suite fmt"clipboard: Get from clipboad (wl-clipboad)": + runClipboardGetTests(ClipboardTool.wlClipboard) + +suite fmt"clipboard: Get from clipboad (WSL)": + runClipboardGetTests(ClipboardTool.wslDefault) diff --git a/tests/tconfigmode.nim b/tests/tconfigmode.nim index 3adbbe3df..c1dbfb56d 100644 --- a/tests/tconfigmode.nim +++ b/tests/tconfigmode.nim @@ -17,7 +17,7 @@ # # #[############################################################################]# -import std/[unittest, strformat, os] +import std/[unittest, strformat, os, options] import pkg/results import moepkg/[unicodeext, editorstatus, bufferstatus, color, ui, rgb, theme] @@ -71,13 +71,13 @@ suite "Config mode: Init buffer": test "Init ClipBoard table buffer": var status = initEditorStatus() status.settings.clipboard.enable = true - status.settings.clipboard.toolOnLinux = ClipboardTool.none + status.settings.clipboard.tool = ClipboardTool.xsel let buffer = status.settings.clipboard.initClipBoardTableBuffer const Sample = @[ "ClipBoard", " enable true", - " toolOnLinux none"].toSeqRunes + " toolOnLinux xsel"].toSeqRunes for index, line in buffer: check Sample[index] == line @@ -862,14 +862,14 @@ suite "Config mode: Get ClipBoard table setting values": checkBoolSettingValue(default, values) - test "Get toolOnLinux value": + test "Get tool value (none)": var status = initEditorStatus() - status.settings.clipboard.toolOnLinux = ClipboardTool.none + status.settings.clipboard.tool = ClipboardTool.xsel let clipboardSettings = status.settings.clipboard - const Name = "toolOnLinux" + const Name = "tool" let - default = clipboardSettings.toolOnLinux + default = clipboardSettings.tool values = clipboardSettings.getClipboardTableSettingsValues(Name) check $default == $values[0] @@ -1850,9 +1850,9 @@ suite "Config mode: Chaging ClipBoard table settings": clipboardSettings = settings.clipboard let val = ClipboardTool.xclip - clipboardSettings.changeClipBoardTableSettings("toolOnLinux", $val) + clipboardSettings.changeClipBoardTableSettings("tool", $val) - check val == clipboardSettings.toolOnLinux + check val == clipboardSettings.tool test "Set invalid value": var diff --git a/tests/teditor.nim b/tests/teditor.nim index cff053e8a..ac6510993 100644 --- a/tests/teditor.nim +++ b/tests/teditor.nim @@ -22,13 +22,10 @@ import pkg/results import moepkg/[independentutils, gapbuffer, unicodeext, bufferstatus, editorstatus, settings, registers, windownode] import moepkg/syntax/highlite +import utils import moepkg/editor {.all.} import moepkg/ui {.all.} -import moepkg/platform {.all.} - -proc isXselAvailable(): bool {.inline.} = - execCmdExNoOutput("xset q") == 0 and execCmdExNoOutput("xsel --version") == 0 proc sourceLangToStr(lang: SourceLanguage): string = case lang: @@ -1723,10 +1720,13 @@ suite "Editor: pasteBeforeCursor": check currentMainWindowNode.currentLine == 1 check currentMainWindowNode.currentColumn == 0 -if isXselAvailable(): - suite "Editor: Yank characters": +suite "Editor: Yank characters": + test "Yank a string with name in the empty line": + if not isXselAvailable(): + skip() + else: + assert clearXsel() - test "Yank a string with name in the empty line": var status = initEditorStatus() discard status.addNewBufferInCurrentWin.get currentBufStatus.buffer = initGapBuffer(@[ru ""]) @@ -1749,9 +1749,13 @@ if isXselAvailable(): check status.registers.getNoNamedRegister.buffer == @[""].toSeqRunes check not status.registers.getNoNamedRegister.isLine -if isXselAvailable(): - suite "Editor: Yank words": - test "Yank a word": +suite "Editor: Yank words": + test "Yank a word": + if not isXselAvailable(): + skip() + else: + assert clearXsel() + var status = initEditorStatus() discard status.addNewBufferInCurrentWin.get currentBufStatus.buffer = initGapBuffer(@[ru "abc def"]) @@ -1768,26 +1772,10 @@ if isXselAvailable(): check status.registers.getNoNamedRegister.buffer == @["abc "].toSeqRunes check not status.registers.getNoNamedRegister.isLine - # Check clipboad - let p = initPlatform() - if p == Platforms.linux or p == Platforms.wsl: - let - cmd = - if p == Platforms.linux: - execCmdEx("xsel -o") - else: - # On the WSL - execCmdEx("powershell.exe -Command Get-Clipboard") - (output, exitCode) = cmd - - check exitCode == 0 - - const Str = "abc " - if p == Platforms.linux: - check output[0 .. output.high - 1] == Str - else: - # On the WSL - check output[0 .. output.high - 2] == Str + let r = execCmdEx("xsel -o") + check r.exitCode == 0 + + check r.output[0 .. r.output.high - 1] == "abc " suite "Editor: Modify the number string under the cursor": test "Increment the number string": diff --git a/tests/tregisters.nim b/tests/tregisters.nim index 66421f15c..0883a4c77 100644 --- a/tests/tregisters.nim +++ b/tests/tregisters.nim @@ -20,43 +20,12 @@ import std/[unittest, options, tables, importutils, osproc, os] import pkg/results import moepkg/[unicodeext, settings, independentutils] +import utils import moepkg/registers {.all.} -proc isXAvailable(): bool {.inline.} = - execCmdExNoOutput("xset q") == 0 - -template isXselAvailable(): bool = - isXAvailable() and execCmdExNoOutput("xsel --version") == 0 - -template isXclipAvailable(): bool = - isXAvailable() and execCmdExNoOutput("xclip -version") == 0 - -template isWlClipboardAvailable(): bool = - isXAvailable() and execCmdExNoOutput("wl-paste --version") == 0 - -template setBufferToXsel(buf: string): bool = - execShellCmd("printf '" & buf & "' | xsel -pi") == 0 - -template setBufferToXclip(buf: string): bool = - execShellCmd("printf '" & buf & "' | xclip") == 0 - -template setBufferToWlClipboard(buf: string): bool = - execShellCmd("printf '" & buf & "' | wl-copy") == 0 - -template clearXsel(): bool = - execShellCmd("printf '' | xsel") == 0 - -template clearXclip(): bool = - execShellCmd("printf '' | xclip") == 0 - -template clearWlClipboard(): bool = - execShellCmd("printf '' | wl-copy") == 0 - proc getClipboardBuffer(tool: ClipboardTool): string = case tool: - of none: - discard of xsel: let r = execCmdEx("xsel -o") return r.output[0 .. r.output.high - 1] diff --git a/tests/tsettings.nim b/tests/tsettings.nim index d5d8ce850..1ddffc5b0 100644 --- a/tests/tsettings.nim +++ b/tests/tsettings.nim @@ -50,7 +50,7 @@ const TomlStr = """ [Clipboard] enable = false - toolOnLinux = "xclip" + tool = "xclip" [BuildOnSave] enable = true @@ -404,7 +404,7 @@ suite "Parse configuration file": check settings.standard.colorMode == ColorMode.none check not settings.clipboard.enable - check settings.clipboard.toolOnLinux == ClipboardTool.xclip + check settings.clipboard.tool == ClipboardTool.xclip check settings.buildOnSave.enable check settings.buildOnSave.workspaceRoot == ru"/home/fox/git/moe" @@ -546,37 +546,61 @@ suite "Parse configuration file": const Str = """ [Clipboard] enable = true - toolOnLinux = "xclip"""" + tool = "xclip"""" let toml = parsetoml.parseString(Str) let settings = parseTomlConfigs(toml) check settings.clipboard.enable - check settings.clipboard.toolOnLinux == ClipboardTool.xclip + check settings.clipboard.tool == ClipboardTool.xclip test "Parse Clipboard setting 2": const Str = """ [Clipboard] enable = true - toolOnLinux = "xsel"""" + tool = "xsel"""" let toml = parsetoml.parseString(Str) let settings = parseTomlConfigs(toml) check settings.clipboard.enable - check settings.clipboard.toolOnLinux == ClipboardTool.xsel + check settings.clipboard.tool == ClipboardTool.xsel test "Parse Clipboard setting 3": const Str = """ [Clipboard] enable = true - toolOnLinux = "wl-clipboard"""" + tool = "wl-clipboard"""" let toml = parsetoml.parseString(Str) let settings = parseTomlConfigs(toml) check settings.clipboard.enable - check settings.clipboard.toolOnLinux == ClipboardTool.wlClipboard + check settings.clipboard.tool == ClipboardTool.wlClipboard + + test "Parse Clipboard setting 4": + const Str = """ + [Clipboard] + enable = true + tool = "wsl-default"""" + + let toml = parsetoml.parseString(Str) + let settings = parseTomlConfigs(toml) + + check settings.clipboard.enable + check settings.clipboard.tool == ClipboardTool.wslDefault + + test "Parse Clipboard setting 5": + const Str = """ + [Clipboard] + enable = true + tool = "macOS-default"""" + + let toml = parsetoml.parseString(Str) + let settings = parseTomlConfigs(toml) + + check settings.clipboard.enable + check settings.clipboard.tool == ClipboardTool.macOsDefault test "Parse color Mode setting 1": const Str = """ diff --git a/tests/utils.nim b/tests/utils.nim new file mode 100644 index 000000000..0838dac04 --- /dev/null +++ b/tests/utils.nim @@ -0,0 +1,95 @@ +#[###################### GNU General Public License 3.0 ######################]# +# # +# Copyright (C) 2017─2023 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 # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#[############################################################################]# + +import std/[options, os, strutils] +import moepkg/[independentutils, platform] + +proc removeLineEnd*(buf: string): string = + result = buf + result.stripLineEnd + +template isXAvailable*(): bool = + execCmdExNoOutput("xset q") == 0 + +template isWaylandAvailable*(): bool = + let r = execCmdEx("echo $XDG_SESSION_TYPE") + if r.exitCode != 0: assert false + + r.output.contains("wayland") + +template isXselAvailable*(): bool = + isXAvailable() and execCmdExNoOutput("xsel --version") == 0 + +template isXclipAvailable*(): bool = + isXAvailable() and execCmdExNoOutput("xclip -version") == 0 + +template isWlClipboardAvailable*(): bool = + isWaylandAvailable() and execCmdExNoOutput("wl-paste --version") == 0 + +template setBufferToXsel*(buf: string): bool = + execShellCmd("printf '" & buf & "' | xsel -pi") == 0 + +template setBufferToXclip*(buf: string): bool = + execShellCmd("printf '" & buf & "' | xclip") == 0 + +template setBufferToWlClipboard*(buf: string): bool = + execShellCmd("printf '" & buf & "' | wl-copy") == 0 + +template setBufferToWslDefaultClipboard*(buf: string): bool = + execShellCmd( + "printf '" & buf & "' | powershell.exe -Command Get-Clipboard") == 0 + +template getXselBuffer*(): string = + let r = execCmdEx("xsel -o") + if r.exitCode != 0: assert false + + r.output + +template getXclipBuffer*(): string = + let r = execCmdEx("xclip -o") + if r.exitCode != 0: assert false + + r.output + +template getWlClipboardBuffer*(): string = + let r = execCmdEx("wl-paste") + if r.exitCode != 0: assert false + + r.output + +template getWslDefaultBuffer*(): string = + let r = execCmdEx("powershell.exe -Command Get-Clipboard") + if r.exitCode != 0: assert false + + r.output + +template clearXsel*(): bool = + execShellCmd("printf '' | xsel") == 0 + +template clearXclip*(): bool = + execShellCmd("printf '' | xclip") == 0 + +template clearWlClipboard*(): bool = + execShellCmd("printf '' | wl-copy") == 0 + +template clearWslDefaultClipboard*(): bool = + execShellCmd("printf '' | clip.exe") == 0 + +template isWsl*(): bool = + platform.currentPlatform == Platforms.wsl