CMake: enable C (Homebrew LLVM's config needs it); Kate: highlighting, language server setup, install script

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Nexoniarz 2026-10-09 00:36:44 +02:00
commit fd86eb885c
6 changed files with 272 additions and 1 deletions

View file

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.20) cmake_minimum_required(VERSION 3.20)
project(finch VERSION 2.3.0 LANGUAGES CXX) project(finch VERSION 2.3.0 LANGUAGES C CXX) # C: LLVM's CMake config checks C headers on some systems
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)

41
editors/kate/README.md Normal file
View file

@ -0,0 +1,41 @@
# Finch in Kate
Syntax highlighting and the Finch language server for **Kate** (and KWrite / KDevelop, which share
Kate's highlighting engine).
## Install
```sh
editors/kate/install.sh
```
It copies `finch.xml` to `~/.local/share/org.kde.syntax-highlighting/syntax/` and adds a `finch` entry
to `~/.config/kate/lspclient/settings.json` (your other servers are kept). Then:
1. Restart Kate.
2. **Settings → Configure Kate → Plugins**: enable **LSP Client** (and **Build & Run** for the next part).
3. Make sure `finch` is on your PATH (`finch version` in a terminal).
Open a `.fch` file: errors appear as you type, hovering shows types and docs, `Ctrl+Space` completes
(fields and methods after `.`), **Go to Definition** and the **Symbols** outline work, and parameter hints
pop up inside `(…)`.
## Running and building
**Build & Run** plugin → **Add target set**, then add targets with these commands (the working folder
can be `%d`, the folder of the current file):
| Target | Command |
|---|---|
| Run | `finch run %f` |
| Build | `finch build %f` |
Give one of them a shortcut in **Settings → Configure Keyboard Shortcuts** (search for "Build"). Finch's
errors have the `file:line:column: error:` form, so Kate lists them and jumps to the line on click.
## By hand
- Highlighting: copy `finch.xml` into `~/.local/share/org.kde.syntax-highlighting/syntax/`
(Windows: `%LOCALAPPDATA%\org.kde.syntax-highlighting\syntax\`).
- Language server: **Settings → Configure Kate → LSP Client → User Server Settings**, and add the
`finch` entry from `lspclient.json` inside `"servers"`.

165
editors/kate/finch.xml Normal file
View file

@ -0,0 +1,165 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language>
<!--
Finch syntax highlighting for Kate, KWrite and KDevelop (KSyntaxHighlighting).
Install: copy to ~/.local/share/org.kde.syntax-highlighting/syntax/finch.xml
(or run editors/kate/install.sh), then restart Kate.
-->
<language name="Finch" version="1" kateversion="5.0" section="Sources" extensions="*.fch"
mimetype="text/x-finch" indenter="cstyle" author="The Finch authors" license="Apache-2.0">
<highlighting>
<list name="keywords">
<item>fn</item>
<item>struct</item>
</list>
<list name="control">
<item>if</item>
<item>else</item>
<item>while</item>
<item>for</item>
<item>in</item>
<item>break</item>
<item>continue</item>
<item>return</item>
<item>defer</item>
</list>
<list name="imports">
<item>import</item>
<item>link</item>
</list>
<list name="constants">
<item>true</item>
<item>false</item>
<item>null</item>
</list>
<list name="types">
<item>int</item>
<item>float</item>
<item>bool</item>
<item>char</item>
<item>str</item>
<item>ptr</item>
<item>i8</item>
<item>i16</item>
<item>i32</item>
<item>i64</item>
<item>u8</item>
<item>u16</item>
<item>u32</item>
<item>u64</item>
<item>f32</item>
<item>f64</item>
</list>
<list name="builtins">
<item>print</item>
<item>input</item>
<item>read_file</item>
<item>write_file</item>
<item>file_exists</item>
<item>delete_file</item>
<item>shell</item>
<item>exit</item>
<item>addr</item>
<item>new</item>
<item>free</item>
</list>
<contexts>
<context name="Normal" attribute="Normal Text" lineEndContext="#stay">
<DetectSpaces/>
<Detect2Chars char="/" char1="/" attribute="Comment" context="LineComment"/>
<Detect2Chars char="/" char1="*" attribute="Comment" context="BlockComment" beginRegion="Comment"/>
<DetectChar char="{" attribute="Symbol" beginRegion="Brace"/>
<DetectChar char="}" attribute="Symbol" endRegion="Brace"/>
<DetectChar char="&quot;" attribute="String" context="String"/>
<DetectChar char="'" attribute="Char" context="Char"/>
<WordDetect String="fn" attribute="Keyword" context="FunctionName"/>
<WordDetect String="struct" attribute="Keyword" context="StructName"/>
<keyword String="control" attribute="Control Flow"/>
<keyword String="imports" attribute="Import"/>
<keyword String="constants" attribute="Constant"/>
<keyword String="types" attribute="Data Type"/>
<keyword String="builtins" attribute="Built-in"/>
<RegExpr String="\b0[xX][0-9a-fA-F_]+\b" attribute="Hex"/>
<RegExpr String="\b[0-9][0-9_]*\.[0-9][0-9_]*([eE][+-]?[0-9]+)?\b" attribute="Float"/>
<RegExpr String="\b[0-9][0-9_]*\b" attribute="Decimal"/>
<!-- a call: name( ; method or field after a dot -->
<RegExpr String="\b[A-Za-z_][A-Za-z0-9_]*(?=\s*\()" attribute="Function"/>
<!-- struct names are written with a capital letter by convention -->
<RegExpr String="\b[A-Z][A-Za-z0-9_]*\b" attribute="Data Type"/>
<DetectIdentifier/>
<Detect2Chars char=":" char1="=" attribute="Operator"/>
<Detect2Chars char="-" char1="&gt;" attribute="Operator"/>
<Detect2Chars char="." char1="." attribute="Operator"/>
<AnyChar String="+-*/%=&lt;&gt;!&amp;|^~" attribute="Operator"/>
<AnyChar String="()[],.:" attribute="Symbol"/>
</context>
<context name="FunctionName" attribute="Normal Text" lineEndContext="#pop" fallthroughContext="#pop">
<DetectSpaces/>
<RegExpr String="[A-Za-z_][A-Za-z0-9_]*" attribute="Function Definition" context="#pop"/>
</context>
<context name="StructName" attribute="Normal Text" lineEndContext="#pop" fallthroughContext="#pop">
<DetectSpaces/>
<RegExpr String="[A-Za-z_][A-Za-z0-9_]*" attribute="Data Type" context="#pop"/>
</context>
<context name="LineComment" attribute="Comment" lineEndContext="#pop">
<DetectSpaces/>
<IncludeRules context="##Comments"/>
</context>
<context name="BlockComment" attribute="Comment" lineEndContext="#stay">
<Detect2Chars char="*" char1="/" attribute="Comment" context="#pop" endRegion="Comment"/>
<IncludeRules context="##Comments"/>
</context>
<context name="String" attribute="String" lineEndContext="#pop">
<RegExpr String="\\[ntr0\\&quot;']" attribute="Escape"/>
<RegExpr String="\\." attribute="Error"/>
<DetectChar char="&quot;" attribute="String" context="#pop"/>
</context>
<context name="Char" attribute="Char" lineEndContext="#pop">
<RegExpr String="\\[ntr0\\&quot;']" attribute="Escape"/>
<DetectChar char="'" attribute="Char" context="#pop"/>
</context>
</contexts>
<itemDatas>
<itemData name="Normal Text" defStyleNum="dsNormal" spellChecking="false"/>
<itemData name="Keyword" defStyleNum="dsKeyword" spellChecking="false"/>
<itemData name="Control Flow" defStyleNum="dsControlFlow" spellChecking="false"/>
<itemData name="Import" defStyleNum="dsImport" spellChecking="false"/>
<itemData name="Constant" defStyleNum="dsConstant" spellChecking="false"/>
<itemData name="Data Type" defStyleNum="dsDataType" spellChecking="false"/>
<itemData name="Built-in" defStyleNum="dsBuiltIn" spellChecking="false"/>
<itemData name="Function" defStyleNum="dsFunction" spellChecking="false"/>
<itemData name="Function Definition" defStyleNum="dsFunction" bold="true" spellChecking="false"/>
<itemData name="Decimal" defStyleNum="dsDecVal" spellChecking="false"/>
<itemData name="Hex" defStyleNum="dsBaseN" spellChecking="false"/>
<itemData name="Float" defStyleNum="dsFloat" spellChecking="false"/>
<itemData name="String" defStyleNum="dsString"/>
<itemData name="Char" defStyleNum="dsChar" spellChecking="false"/>
<itemData name="Escape" defStyleNum="dsSpecialChar" spellChecking="false"/>
<itemData name="Operator" defStyleNum="dsOperator" spellChecking="false"/>
<itemData name="Symbol" defStyleNum="dsNormal" spellChecking="false"/>
<itemData name="Comment" defStyleNum="dsComment"/>
<itemData name="Error" defStyleNum="dsError" spellChecking="false"/>
</itemDatas>
</highlighting>
<general>
<comments>
<comment name="singleLine" start="//"/>
<comment name="multiLine" start="/*" end="*/" region="Comment"/>
</comments>
<keywords casesensitive="1"/>
<folding indentationsensitive="0"/>
</general>
</language>

27
editors/kate/install.sh Executable file
View file

@ -0,0 +1,27 @@
#!/usr/bin/env bash
# Installs Finch support for Kate (also KWrite and KDevelop):
# - syntax highlighting: ~/.local/share/org.kde.syntax-highlighting/syntax/finch.xml
# - the language server: adds "finch" to ~/.config/kate/lspclient/settings.json
# Then restart Kate and enable Settings → Configure Kate → Plugins → "LSP Client".
set -eu
here="$(cd "$(dirname "$0")" && pwd)"
data="${XDG_DATA_HOME:-$HOME/.local/share}/org.kde.syntax-highlighting/syntax"
conf="${XDG_CONFIG_HOME:-$HOME/.config}/kate/lspclient"
mkdir -p "$data" "$conf"
cp "$here/finch.xml" "$data/finch.xml"
echo "highlighting: $data/finch.xml"
# merge into the user's LSP settings instead of replacing them
python3 - "$conf/settings.json" "$here/lspclient.json" <<'PY'
import json, os, sys
path, ours = sys.argv[1], json.load(open(sys.argv[2]))
cur = {}
if os.path.exists(path) and os.path.getsize(path) > 0:
cur = json.load(open(path))
cur.setdefault("servers", {}).update(ours["servers"])
with open(path, "w") as f:
json.dump(cur, f, indent=4)
f.write("\n")
print("language server: " + path)
PY
command -v finch > /dev/null || echo "note: 'finch' isn't on your PATH yet; Kate starts the language server with 'finch lsp'"

View file

@ -0,0 +1,9 @@
{
"servers": {
"finch": {
"command": ["finch", "lsp"],
"url": "https://github.com/Nexoniarz/Finch",
"highlightingModeRegex": "^Finch$"
}
}
}

29
examples/OpenGL.fn Normal file
View file

@ -0,0 +1,29 @@
import "GLFW/glfw3.h"
fn main() {
if glfwInit() == 0 {
print("Błąd: Nie udało się zainicjalizować GLFW!")
return
}
win := glfwCreateWindow(800, 600, "lukas", null, null)
if win == null {
print("Błąd: Nie udało się stworzyć okna!")
glfwTerminate()
return
}
glfwMakeContextCurrent(win)
while glfwWindowShouldClose(win) == 0 {
// 1. Obsługa klawiatury/myszki
glfwPollEvents()
// 2. Podmiana bufora (wyświetlenie narysowanej klatki)
glfwSwapBuffers(win)
}
glfwDestroyWindow(win)
glfwTerminate()
}