Files
z-bar-qt/Plugins/ZShell/Llm/CMakeLists.txt
T
zach 9ea1f846ae
C++ / fmt (pull_request) Failing after 5s
C++ / build (pull_request) Failing after 10s
C++ / clang-tidy (pull_request) Failing after 11s
JS/TS / fmt (pull_request) Successful in 9s
JS/TS / lint (pull_request) Successful in 10s
Python / static (pull_request) Successful in 34s
Rust / build (pull_request) Successful in 59s
Python / verify (pull_request) Successful in 1m48s
Rust / fmt (pull_request) Successful in 47s
Rust / clippy (pull_request) Successful in 1m6s
more unfinished changes, process tab for dashboard
2026-09-25 16:51:28 +02:00

263 lines
9.4 KiB
CMake

pkg_check_modules(CMARK_GFM REQUIRED IMPORTED_TARGET libcmark-gfm)
pkg_check_modules(TREE_SITTER REQUIRED IMPORTED_TARGET tree-sitter)
find_path(JKQTPlotter6_CMAKE_DIR
NAMES JKQTMathText6Config.cmake
HINTS /usr/lib/cmake/JKQTPlotter6 /usr/local/lib/cmake/JKQTPlotter6
DOC "Directory containing the JKQtPlotter cmake package files")
find_package(JKQTMathText6 REQUIRED PATHS "${JKQTPlotter6_CMAKE_DIR}")
function(_ts_entry_point out file)
get_filename_component(_ts_nm_base "${file}" NAME)
set(_ts_nm_file "${CMAKE_CURRENT_BINARY_DIR}/ts-entry-${_ts_nm_base}")
execute_process(
COMMAND nm -D --defined-only "${file}"
RESULT_VARIABLE _ts_nm_rc
OUTPUT_FILE "${_ts_nm_file}"
ERROR_FILE "${_ts_nm_file}.err")
set(_ts_sym "tree_sitter_missing")
if(_ts_nm_rc EQUAL 0 AND EXISTS "${_ts_nm_file}")
file(READ "${_ts_nm_file}" _ts_nm_out)
file(REMOVE "${_ts_nm_file}" "${_ts_nm_file}.err")
string(REGEX MATCHALL " T tree_sitter_[A-Za-z0-9_]+" _ts_syms "${_ts_nm_out}")
foreach(_ts_s IN LISTS _ts_syms)
string(REPLACE " T " "" _ts_s "${_ts_s}")
if(NOT _ts_s MATCHES "_external")
set(_ts_sym "${_ts_s}")
break()
endif()
endforeach()
endif()
set(${out} "${_ts_sym}" PARENT_SCOPE)
endfunction()
function(_ts_expand_inherits query_dir text outVar)
set(result "${text}")
set(_visited "")
set(_depth 0)
while(_depth LESS 8)
string(REGEX MATCHALL "inherits:[ \t]*[A-Za-z0-9_]+" _inh "${result}")
if(NOT _inh)
break()
endif()
set(_added FALSE)
foreach(_entry IN LISTS _inh)
string(REGEX REPLACE "^inherits:[ \t]*" "" _name "${_entry}")
set(_file "${query_dir}/${_name}/highlights.scm")
if(NOT EXISTS "${_file}" OR _file IN_LIST _visited)
continue()
endif()
list(APPEND _visited "${_file}")
file(READ "${_file}" _inh_text)
string(APPEND result "\n${_inh_text}")
set(_added TRUE)
endforeach()
if(NOT _added)
break()
endif()
math(EXPR _depth "${_depth} + 1")
endwhile()
set(${outVar} "${result}" PARENT_SCOPE)
endfunction()
function(_ts_add_query sid text filesVar hashesVar)
set(files "${${filesVar}}")
set(hashes "${${hashesVar}}")
string(SHA256 _ts_qh "${text}")
if(_ts_qh IN_LIST hashes)
return()
endif()
list(APPEND hashes "${_ts_qh}")
list(LENGTH files _ts_qi)
set(_ts_qfile "${CMAKE_CURRENT_BINARY_DIR}/ts-queries/${sid}_${_ts_qi}.scm")
file(WRITE "${_ts_qfile}" "${text}")
list(APPEND files "${_ts_qfile}")
set(${filesVar} "${files}" PARENT_SCOPE)
set(${hashesVar} "${hashes}" PARENT_SCOPE)
endfunction()
set(_ts_candidates "") # entries: <id>|<cmake-safe id>|<lib>|<symbol>
file(GLOB _ts_sys_files
"/usr/lib/libtree-sitter-*.so" "/usr/local/lib/libtree-sitter-*.so")
foreach(_ts_file IN LISTS _ts_sys_files)
get_filename_component(_ts_name "${_ts_file}" NAME)
string(REGEX REPLACE "^libtree-sitter-(.+)\.so$" "\\1" _ts_id "${_ts_name}")
string(REPLACE "-" "_" _ts_sid "${_ts_id}")
_ts_entry_point(_ts_sym "${_ts_file}")
list(APPEND _ts_candidates
"${_ts_id}|${_ts_sid}|libtree-sitter-${_ts_id}.so|${_ts_sym}")
endforeach()
set(_ts_nvim_parser_dirs
"$ENV{HOME}/.local/share/nvim/site/parser"
"$ENV{HOME}/.local/share/nvim/runtime/parser"
"$ENV{HOME}/.local/share/nvim/lazy/nvim-treesitter/parser")
set(_ts_nvim_query_dirs
"$ENV{HOME}/.local/share/nvim/site/queries"
"$ENV{HOME}/.local/share/nvim/lazy/nvim-treesitter/runtime/queries")
foreach(_ts_dir IN LISTS _ts_nvim_parser_dirs)
file(GLOB _ts_dir_files "${_ts_dir}/*.so")
foreach(_ts_file IN LISTS _ts_dir_files)
get_filename_component(_ts_name "${_ts_file}" NAME)
string(REGEX REPLACE "\\.so$" "" _ts_id "${_ts_name}")
string(REPLACE "-" "_" _ts_sid "${_ts_id}")
_ts_entry_point(_ts_sym "${_ts_file}")
list(APPEND _ts_candidates
"${_ts_id}|${_ts_sid}|${_ts_file}|${_ts_sym}")
endforeach()
endforeach()
set(_ts_ids "")
foreach(_ts_c IN LISTS _ts_candidates)
string(REPLACE "|" ";" _ts_parts "${_ts_c}")
list(GET _ts_parts 0 _ts_id)
if(NOT _ts_id IN_LIST _ts_ids)
list(APPEND _ts_ids "${_ts_id}")
endif()
endforeach()
list(SORT _ts_ids)
set(HIGHLIGHT_QUERIES_HPP "${CMAKE_CURRENT_BINARY_DIR}/highlight-queries.hpp")
set(_hl_header
"#pragma once\n\n// Generated by CMake. Discoverd tree-sitter grammars and their\n// highlight queries: vendored highlight-queries/*.scm (MIT), Neovim\n// nvim-treesitter queries, and tree-sitter/highlighting (MIT).\nnamespace ZShell::llm::hq {\nstruct Candidate { const char* lib; const char* symbol; };\nstruct Grammar { const char* id; int nCandidates; const Candidate* candidates; int nQueries; const char* const* queries; };\n")
set(_ts_grammar_rows "")
set(_ts_vendored
c cpp python javascript typescript tsx bash json rust go yaml toml sql)
foreach(_ts_id IN LISTS _ts_ids)
string(REPLACE "-" "_" _ts_sid "${_ts_id}")
set(_ts_qfiles "")
set(_ts_qhashes "")
if(_ts_id STREQUAL "cpp")
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/highlight-queries/c.scm" _ts_qa)
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/highlight-queries/cpp.scm" _ts_qb)
_ts_add_query(${_ts_sid} "${_ts_qa}\n${_ts_qb}" _ts_qfiles _ts_qhashes)
elseif(_ts_id STREQUAL "typescript" OR _ts_id STREQUAL "tsx")
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/highlight-queries/javascript.scm" _ts_qa)
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/highlight-queries/typescript.scm" _ts_qb)
_ts_add_query(${_ts_sid} "${_ts_qa}\n${_ts_qb}" _ts_qfiles _ts_qhashes)
_ts_add_query(${_ts_sid} "${_ts_qb}" _ts_qfiles _ts_qhashes)
elseif(_ts_id IN_LIST _ts_vendored)
file(READ
"${CMAKE_CURRENT_SOURCE_DIR}/highlight-queries/${_ts_id}.scm" _ts_q)
_ts_add_query(${_ts_sid} "${_ts_q}" _ts_qfiles _ts_qhashes)
endif()
foreach(_ts_qd IN LISTS _ts_nvim_query_dirs)
if(EXISTS "${_ts_qd}/${_ts_id}/highlights.scm")
file(READ "${_ts_qd}/${_ts_id}/highlights.scm" _ts_q)
_ts_expand_inherits("${_ts_qd}" "${_ts_q}" _ts_q)
_ts_add_query(${_ts_sid} "${_ts_q}" _ts_qfiles _ts_qhashes)
endif()
endforeach()
if(NOT _ts_qfiles)
set(_ts_dl "${CMAKE_CURRENT_BINARY_DIR}/ts-query-downloads/${_ts_sid}.scm")
if(NOT EXISTS "${_ts_dl}")
file(DOWNLOAD
"https://raw.githubusercontent.com/tree-sitter/highlighting/main/queries/${_ts_id}/highlight.scm"
"${_ts_dl}" STATUS _ts_dl_status TIMEOUT 30)
list(GET _ts_dl_status 0 _ts_dl_rc)
if(NOT _ts_dl_rc EQUAL 0)
file(REMOVE "${_ts_dl}")
endif()
endif()
if(EXISTS "${_ts_dl}")
file(READ "${_ts_dl}" _ts_q)
_ts_add_query(${_ts_sid} "${_ts_q}" _ts_qfiles _ts_qhashes)
endif()
endif()
list(LENGTH _ts_qfiles _ts_nq)
if(_ts_nq EQUAL 0)
continue()
endif()
set(_ts_qn 0)
set(_ts_q_ptrs "")
foreach(_ts_qfile IN LISTS _ts_qfiles)
file(READ "${_ts_qfile}" _ts_q)
string(APPEND _hl_header
"inline constexpr const char* q_${_ts_sid}_${_ts_qn} = R\"ZSQUERY(${_ts_q})ZSQUERY\";\n")
string(APPEND _ts_q_ptrs "q_${_ts_sid}_${_ts_qn}, ")
math(EXPR _ts_qn "${_ts_qn} + 1")
endforeach()
string(APPEND _hl_header
"inline constexpr const char* const q_${_ts_sid}[] = { ${_ts_q_ptrs} };\n")
string(APPEND _hl_header "inline constexpr Candidate cand_${_ts_sid}[] = {\n")
set(_ts_nc 0)
foreach(_ts_c IN LISTS _ts_candidates)
string(REPLACE "|" ";" _ts_parts "${_ts_c}")
list(GET _ts_parts 0 _ts_cid)
if(_ts_cid STREQUAL _ts_id)
list(GET _ts_parts 2 _ts_lib)
list(GET _ts_parts 3 _ts_sym)
string(APPEND _hl_header
" { R\"ZSLIB(${_ts_lib})ZSLIB\", R\"ZSSYM(${_ts_sym})ZSSYM\" },\n")
math(EXPR _ts_nc "${_ts_nc} + 1")
endif()
endforeach()
string(APPEND _hl_header "};\n")
if(_ts_nc EQUAL 0)
string(APPEND _hl_header "") # (arrays stay; grammar row is skipped)
continue()
endif()
list(APPEND _ts_grammar_rows
"{ \"${_ts_id}\", ${_ts_nc}, cand_${_ts_sid}, ${_ts_nq}, q_${_ts_sid} },")
endforeach()
string(APPEND _hl_header "inline constexpr Grammar grammars[] = {\n")
foreach(_ts_row IN LISTS _ts_grammar_rows)
string(APPEND _hl_header " ${_ts_row}\n")
endforeach()
string(APPEND _hl_header "};\n}\n")
file(WRITE "${HIGHLIGHT_QUERIES_HPP}" "${_hl_header}")
set(LM_FONTS
lmroman10-regular
lmroman10-italic
lmroman10-bold
lmroman10-bolditalic
latinmodern-math)
set(LM_FONTS_HPP "${CMAKE_CURRENT_BINARY_DIR}/latinmodern-fonts.hpp")
set(_lm_header "#pragma once\n\n// Vendored Latin Modern fonts (GUST Font License; see\n// fonts/latinmodern/GUST-FONT-LICENSE.txt).\nnamespace ZShell::llm::lmfont {\n")
foreach(_lm_font IN LISTS LM_FONTS)
string(REPLACE "-" "_" _lm_sym "${_lm_font}")
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/fonts/latinmodern/${_lm_font}.otf" _lm_hex HEX)
string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," _lm_bytes "${_lm_hex}")
string(APPEND _lm_header "inline const unsigned char ${_lm_sym}[] = { ${_lm_bytes} };\n")
endforeach()
string(APPEND _lm_header "}\n")
file(WRITE "${LM_FONTS_HPP}" "${_lm_header}")
qml_module(ZShell-llm
URI ZShell.Llm
SOURCES
attachment.hpp attachment.cpp
chat.hpp chat.cpp
chatstore.hpp chatstore.cpp
codehighlighter.hpp codehighlighter.cpp
filetool.hpp filetool.cpp
generation.hpp generation.cpp
llmclient.hpp llmclient.cpp
markdownblock.hpp
markdownparser.hpp markdownparser.cpp
mathtext.hpp mathtext.cpp
message.hpp message.cpp
messagemodel.hpp messagemodel.cpp
segment.hpp segment.cpp
session.hpp session.cpp
shelltool.hpp shelltool.cpp
tool.hpp tool.cpp
webfetchtool.hpp webfetchtool.cpp
LIBRARIES
Qt::Network
Qt::Sql
Qt::Gui
Qt::Widgets
ZShell-config
ZShell-settings
JKQTPlotter::JKQTMathText
PkgConfig::CMARK_GFM
PkgConfig::TREE_SITTER
)
target_include_directories(ZShell-llm PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_include_directories(ZShell-llm PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../Config)