Skip to content

gui: support text input scrolling and rich text rise #464

gui: support text input scrolling and rich text rise

gui: support text input scrolling and rich text rise #464

Workflow file for this run

name: CI Checks
on:
push:
paths:
- "**.v"
- "**.vsh"
- "**.c"
- "**.h"
- "**.m"
- "**.md"
- "**/ci.yml"
- ".github/workflows/*.yml"
pull_request:
paths:
- "**.v"
- "**.vsh"
- "**.c"
- "**.h"
- "**.m"
- "**.md"
- "**/ci.yml"
- ".github/workflows/*.yml"
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
jobs:
linting:
runs-on: ubuntu-latest
timeout-minutes: 25
env:
VFLAGS: -no-parallel
steps:
- name: Install V
id: install-v
uses: vlang/setup-v@v1.4
with:
check-latest: true
- name: Install vglyph
run: v install vglyph
- name: Install C development dependencies (headers and libs)
if: runner.os == 'Linux'
run: v retry -- sudo apt -qq update && v retry -- sudo apt install libpango1.0-dev libfontconfig1-dev libfribidi-dev libharfbuzz-dev libfreetype-dev libgl1-mesa-dri xvfb libxcursor-dev libxi-dev libxrandr-dev freeglut3-dev dbus libdbus-1-dev libdbus-glib-1-2 libdbus-glib-1-dev
- name: Install development dependencies on macos (headers and libs)
if: runner.os == 'macOS'
run: v retry -- brew install pango harfbuzz freetype2
- name: Checkout the gui module
uses: actions/checkout@v6
with:
path: gui
fetch-depth: 0
- name: Verify formatting of changed V files
if: github.event_name == 'pull_request'
working-directory: gui
run: |
base_ref="${{ github.base_ref }}"
git fetch --no-tags origin "$base_ref:refs/remotes/origin/$base_ref"
git diff --name-only -z --diff-filter=ACMRT "origin/${base_ref}...HEAD" -- '*.v' '*.vsh' > /tmp/vfmt-files
if [ ! -s /tmp/vfmt-files ]; then
echo "No changed V/VSH files to format-check."
exit 0
fi
xargs -0 v fmt -verify -inprocess < /tmp/vfmt-files
- name: Verify formatting
if: github.event_name != 'pull_request'
run: v fmt -verify -inprocess gui/
- name: Check formatting of MD files
run: v check-md gui/
- name: Check syntax of changed example scripts
if: github.event_name == 'pull_request'
working-directory: gui
run: |
base_ref="${{ github.base_ref }}"
files_list="${RUNNER_TEMP}/gui-example-syntax-files"
git fetch --no-tags origin "$base_ref:refs/remotes/origin/$base_ref"
git diff --name-only -z --diff-filter=ACMRT "origin/${base_ref}...HEAD" -- 'examples/*.vsh' > "$files_list"
if [ ! -s "$files_list" ]; then
echo "No changed example VSH scripts to syntax-check."
exit 0
fi
while IFS= read -r -d '' file; do
v -check -W "$file"
done < "$files_list"
- name: Skip full examples syntax lint
if: github.event_name != 'pull_request'
run: echo "Skipping full examples syntax lint; example .v files are covered by compilation checks."
compiling:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
fail-fast: true
runs-on: ${{ matrix.os }}
timeout-minutes: 25
env:
VFLAGS: -no-parallel
steps:
- name: Install V
id: install-v
uses: vlang/setup-v@v1.4
with:
check-latest: true
- name: Install vglyph
run: v install vglyph
- name: Install X11/GL development dependencies (headers and libs)
if: runner.os == 'Linux'
run: v retry -- sudo apt -qq update && v retry -- sudo apt install libpango1.0-dev libfontconfig1-dev libfribidi-dev libharfbuzz-dev libfreetype-dev libgl1-mesa-dri xvfb libxcursor-dev libxi-dev libxrandr-dev freeglut3-dev dbus libdbus-1-dev libdbus-glib-1-2 libdbus-glib-1-dev
- name: Install development dependencies on macos (headers and libs)
if: runner.os == 'macOS'
run: v retry -- brew install pango harfbuzz freetype2
- name: Checkout the gui module
uses: actions/checkout@v6
with:
path: gui
fetch-depth: 0
- name: Run tests
env:
VFLAGS: -no-parallel -cc clang
run: |
test_manifest="${RUNNER_TEMP}/gui-test-files"
git -C gui ls-files '*_test.v' | LC_ALL=C sort > "$test_manifest"
test_count="$(wc -l < "$test_manifest" | tr -d ' ')"
echo "Test files: $test_count"
i=0
while IFS= read -r file; do
i=$((i + 1))
echo "[$i/$test_count] gui/$file"
done < "$test_manifest"
v test gui/
- name: Check compilation of examples
if: github.event_name == 'pull_request'
env:
VFLAGS: -no-parallel -cc clang
run: v should-compile-all gui/examples/
- name: Check compilation of changed examples with -W
if: github.event_name == 'pull_request'
env:
VFLAGS: -no-parallel -cc clang
working-directory: gui
run: |
base_ref="${{ github.base_ref }}"
files_list="${RUNNER_TEMP}/gui-example-compile-files"
git fetch --no-tags origin "$base_ref:refs/remotes/origin/$base_ref"
git diff --name-only -z --diff-filter=ACMRT "origin/${base_ref}...HEAD" -- 'examples/*.v' > "$files_list"
if [ ! -s "$files_list" ]; then
echo "No changed example .v files to compile with -W."
exit 0
fi
mkdir -p examples/bin
while IFS= read -r -d '' file; do
output_file="examples/bin/$(basename "${file%.v}")"
if [ "$file" = "examples/showcase.v" ]; then
v -no-parallel -o "$output_file" "$file"
else
v -no-parallel -W -o "$output_file" "$file"
fi
done < "$files_list"
- name: Check compilation of examples without warning-fatal mode
if: github.event_name != 'pull_request'
env:
VFLAGS: -no-parallel -cc clang
run: v gui/examples/_build.vsh --no-warnings
compiling-on-windows:
runs-on: windows-latest
timeout-minutes: 70
env:
VFLAGS: -no-parallel
VCPKG_BINARY_CACHE: ${{ github.workspace }}\vcpkg-binary-cache
VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}\vcpkg-binary-cache,readwrite
steps:
- name: Resolve V revision
id: v
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
$revision = (git ls-remote https://github.com/vlang/v HEAD).Split()[0]
"revision=$revision" | Add-Content -Path $env:GITHUB_OUTPUT
- name: Restore V compiler cache
id: restore-v-cache
uses: actions/cache/restore@v4
with:
path: v
key: windows-v-compiler-${{ steps.v.outputs.revision }}-v1
- name: Install V
id: install-v
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
function Assert-NativeCommand($Message) {
if ($LASTEXITCODE -ne 0) {
throw $Message
}
}
$expectedRevision = '${{ steps.v.outputs.revision }}'
if (Test-Path .\v\v.exe) {
$cachedRevision = (& git -C v rev-parse HEAD).Trim()
Assert-NativeCommand "Could not inspect cached V revision"
if ($cachedRevision -ne $expectedRevision) {
Write-Host "Cached V revision $cachedRevision does not match expected $expectedRevision; rebuilding."
Remove-Item -Recurse -Force .\v
}
}
if (-not (Test-Path .\v\v.exe)) {
if (Test-Path .\v) {
Remove-Item -Recurse -Force .\v
}
git init v
Assert-NativeCommand "git init failed"
git -C v remote add origin https://github.com/vlang/v
Assert-NativeCommand "git remote add failed"
git -C v fetch --depth 1 origin $expectedRevision
Assert-NativeCommand "git fetch failed"
git -C v checkout --detach FETCH_HEAD
Assert-NativeCommand "git checkout failed"
Push-Location v
cmd /c makev.bat
if ($LASTEXITCODE -ne 0) {
throw "makev.bat failed"
}
Pop-Location
}
$vPath = (Resolve-Path .\v).Path
Add-Content -Path $env:GITHUB_PATH -Value $vPath
$version = (& .\v\v.exe version).Trim()
$revision = (& git -C v rev-parse HEAD).Trim()
Assert-NativeCommand "Could not inspect V revision"
"version=$version" | Add-Content -Path $env:GITHUB_OUTPUT
"revision=$revision" | Add-Content -Path $env:GITHUB_OUTPUT
- name: Log V version
run: v version
- name: Save V compiler cache
if: ${{ steps.restore-v-cache.outputs.cache-hit != 'true' }}
uses: actions/cache/save@v4
with:
path: v
key: ${{ steps.restore-v-cache.outputs.cache-primary-key }}
- name: Resolve vglyph revision
id: vglyph
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
$revision = (git ls-remote https://github.com/vlang/vglyph HEAD).Split()[0]
if ($LASTEXITCODE -ne 0) {
throw "Could not resolve vglyph revision"
}
"revision=$revision" | Add-Content -Path $env:GITHUB_OUTPUT
- name: Restore vcpkg binary cache
id: restore-vcpkg-cache
uses: actions/cache/restore@v4
with:
path: ${{ env.VCPKG_BINARY_CACHE }}
key: windows-vcpkg-x64-windows-pango-freetype-${{ steps.install-v.outputs.revision }}-v2
restore-keys: |
windows-vcpkg-x64-windows-pango-freetype-
- name: Restore V module cache
id: restore-vglyph-cache
uses: actions/cache/restore@v4
with:
path: ~/.vmodules/vglyph
key: windows-vmodules-vglyph-${{ steps.install-v.outputs.revision }}-${{ steps.vglyph.outputs.revision }}-v2
- name: Install pango and freetype
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path "$env:VCPKG_BINARY_CACHE" | Out-Null
vcpkg install pango freetype
- name: Save vcpkg binary cache
if: ${{ steps.restore-vcpkg-cache.outputs.cache-hit != 'true' }}
uses: actions/cache/save@v4
with:
path: ${{ env.VCPKG_BINARY_CACHE }}
key: ${{ steps.restore-vcpkg-cache.outputs.cache-primary-key }}
- name: Expose vcpkg pkg-config paths
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
$triplet = 'x64-windows'
$vcpkgExe = (Get-Command vcpkg -ErrorAction Stop).Source
$roots = @()
if ($vcpkgExe) {
$roots += Split-Path -Parent $vcpkgExe
}
if ($env:VCPKG_ROOT) {
$roots += $env:VCPKG_ROOT
}
$vcpkgRoot = $null
foreach ($root in ($roots | Select-Object -Unique)) {
if (Test-Path (Join-Path $root "installed\$triplet")) {
$vcpkgRoot = $root
break
}
}
if (-not $vcpkgRoot) {
throw "Could not find vcpkg installed\$triplet from vcpkg.exe or VCPKG_ROOT"
}
$tripletRoot = Join-Path $vcpkgRoot "installed\$triplet"
$pkgConfigDirs = @(
(Join-Path $tripletRoot 'lib\pkgconfig'),
(Join-Path $tripletRoot 'share\pkgconfig')
) | Where-Object { Test-Path $_ }
if ($pkgConfigDirs.Count -eq 0) {
throw "No pkgconfig directories found under $tripletRoot"
}
$pkgConfigPath = $pkgConfigDirs -join ';'
"PKG_CONFIG_PATH=$pkgConfigPath" | Add-Content -Path $env:GITHUB_ENV
$env:PKG_CONFIG_PATH = $pkgConfigPath
$pathEntries = @()
$binDir = Join-Path $tripletRoot 'bin'
if (Test-Path $binDir) {
$pathEntries += $binDir
}
$pkgconfDir = Join-Path $tripletRoot 'tools\pkgconf'
if (Test-Path $pkgconfDir) {
$pathEntries += $pkgconfDir
}
foreach ($entry in $pathEntries) {
$entry | Add-Content -Path $env:GITHUB_PATH
}
if ($pathEntries.Count -gt 0) {
$env:PATH = ($pathEntries + $env:PATH) -join ';'
}
if (-not (Get-Command pkg-config -ErrorAction SilentlyContinue)) {
$pkgconf = Get-Command pkgconf -ErrorAction SilentlyContinue
if ($pkgconf) {
$shimDir = Join-Path $env:RUNNER_TEMP 'pkg-config-shim'
New-Item -ItemType Directory -Force -Path $shimDir | Out-Null
Set-Content -Path (Join-Path $shimDir 'pkg-config.cmd') -Encoding ascii -Value @(
'@echo off',
'"' + $pkgconf.Source + '" %*'
)
$shimDir | Add-Content -Path $env:GITHUB_PATH
$env:PATH = "$shimDir;$env:PATH"
}
}
$pkgConfig = Get-Command pkg-config -ErrorAction Stop
& $pkgConfig.Source --exists freetype2 pango pangoft2
if ($LASTEXITCODE -ne 0) {
throw "pkg-config could not resolve freetype2 pango pangoft2"
}
- name: Ensure vglyph revision
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
function Assert-NativeCommand($Message) {
if ($LASTEXITCODE -ne 0) {
throw $Message
}
}
$expectedRevision = '${{ steps.vglyph.outputs.revision }}'
$vglyphPath = Join-Path $HOME '.vmodules\vglyph'
if (Test-Path (Join-Path $vglyphPath '.git')) {
$cachedRevision = (& git -C $vglyphPath rev-parse HEAD).Trim()
Assert-NativeCommand "Could not inspect cached vglyph revision"
if ($cachedRevision -ne $expectedRevision) {
Write-Host "Cached vglyph revision $cachedRevision does not match expected $expectedRevision; rebuilding."
Remove-Item -Recurse -Force $vglyphPath
}
} elseif (Test-Path $vglyphPath) {
Remove-Item -Recurse -Force $vglyphPath
}
if (-not (Test-Path $vglyphPath)) {
$vmodulesPath = Split-Path -Parent $vglyphPath
New-Item -ItemType Directory -Force -Path $vmodulesPath | Out-Null
git init $vglyphPath
Assert-NativeCommand "git init vglyph failed"
git -C $vglyphPath remote add origin https://github.com/vlang/vglyph
Assert-NativeCommand "git remote add vglyph failed"
git -C $vglyphPath fetch --depth 1 origin $expectedRevision
Assert-NativeCommand "git fetch vglyph failed"
git -C $vglyphPath checkout --detach FETCH_HEAD
Assert-NativeCommand "git checkout vglyph failed"
}
- name: Save V module cache
if: ${{ steps.restore-vglyph-cache.outputs.cache-hit != 'true' }}
uses: actions/cache/save@v4
with:
path: ~/.vmodules/vglyph
key: ${{ steps.restore-vglyph-cache.outputs.cache-primary-key }}
- name: Checkout the gui module
uses: actions/checkout@v6
with:
path: gui
fetch-depth: 0
- name: Configure MSVC developer environment
uses: ilammy/msvc-dev-cmd@v1
- name: Run Windows setup preflight
env:
GUI_WINDOWS_PREFLIGHT_CC: msvc
run: v -cc msvc run gui/_windows_preflight.vsh
- name: Run tests
env:
VFLAGS: -no-parallel -cc msvc
VJOBS: 1
VTEST_ONLY_FN: test_*
run: |
$testFiles = @(git -C gui ls-files '*_test.v' | Sort-Object)
Write-Host "Test files: $($testFiles.Count)"
for ($i = 0; $i -lt $testFiles.Count; $i++) {
Write-Host ("[{0}/{1}] gui/{2}" -f ($i + 1), $testFiles.Count, $testFiles[$i])
}
v test gui/
- name: Check compilation of examples
if: github.event_name == 'pull_request'
env:
VFLAGS: -no-parallel -cc msvc
run: v gui/examples/_build.vsh --no-warnings --skip-missing-sqlite
- name: Check compilation of changed examples with -W
if: github.event_name == 'pull_request'
env:
VFLAGS: -no-parallel -cc msvc
shell: pwsh
working-directory: gui
run: |
$baseRef = '${{ github.base_ref }}'
git fetch --no-tags origin "${baseRef}:refs/remotes/origin/${baseRef}"
if ($LASTEXITCODE -ne 0) {
exit $LASTEXITCODE
}
$files = @(git diff --name-only --diff-filter=ACMRT "origin/${baseRef}...HEAD" -- 'examples/*.v')
if ($LASTEXITCODE -ne 0) {
exit $LASTEXITCODE
}
if ($files.Count -eq 0) {
Write-Host 'No changed example .v files to compile with -W.'
exit 0
}
v examples/_build.vsh --skip-missing-sqlite @files
if ($LASTEXITCODE -ne 0) {
exit $LASTEXITCODE
}
- name: Check compilation of examples without warning-fatal mode
if: github.event_name != 'pull_request'
env:
VFLAGS: -no-parallel -cc msvc
run: v gui/examples/_build.vsh --no-warnings --skip-missing-sqlite