Add ScrollUp and ScrollDown commands for viewport scrolling, refine mouse wheel handling in GUI and terminal, and bump version to 1.2.2.
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
Release / Build Linux amd64 (push) Has been cancelled
Release / Build Linux arm64 (push) Has been cancelled
Release / Build macOS arm64 (.app) (push) Has been cancelled
Release / Create GitHub Release (push) Has been cancelled
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
Release / Build Linux amd64 (push) Has been cancelled
Release / Build Linux arm64 (push) Has been cancelled
Release / Build macOS arm64 (.app) (push) Has been cancelled
Release / Create GitHub Release (push) Has been cancelled
This commit is contained in:
408
CMakeLists.txt
408
CMakeLists.txt
@@ -4,7 +4,7 @@ project(kte)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(KTE_VERSION "1.2.1")
|
||||
set(KTE_VERSION "1.2.2")
|
||||
|
||||
# Default to terminal-only build to avoid SDL/OpenGL dependency by default.
|
||||
# Enable with -DBUILD_GUI=ON when SDL2/OpenGL/Freetype are available.
|
||||
@@ -16,36 +16,36 @@ option(KTE_UNDO_DEBUG "Enable undo instrumentation logs" OFF)
|
||||
option(KTE_ENABLE_TREESITTER "Enable optional Tree-sitter highlighter adapter" OFF)
|
||||
|
||||
if (CMAKE_HOST_UNIX)
|
||||
message(STATUS "Build system is POSIX.")
|
||||
message(STATUS "Build system is POSIX.")
|
||||
else ()
|
||||
message(STATUS "Build system is NOT POSIX.")
|
||||
message(STATUS "Build system is NOT POSIX.")
|
||||
endif ()
|
||||
|
||||
if (MSVC)
|
||||
add_compile_options("/W4" "$<$<CONFIG:RELEASE>:/O2>")
|
||||
add_compile_options("/W4" "$<$<CONFIG:RELEASE>:/O2>")
|
||||
else ()
|
||||
add_compile_options(
|
||||
"-Wall"
|
||||
"-Wextra"
|
||||
"-Werror"
|
||||
"$<$<CONFIG:DEBUG>:-g>"
|
||||
"$<$<CONFIG:RELEASE>:-O2>")
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
add_compile_options("-stdlib=libc++")
|
||||
else ()
|
||||
# nothing special for gcc at the moment
|
||||
endif ()
|
||||
add_compile_options(
|
||||
"-Wall"
|
||||
"-Wextra"
|
||||
"-Werror"
|
||||
"$<$<CONFIG:DEBUG>:-g>"
|
||||
"$<$<CONFIG:RELEASE>:-O2>")
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
add_compile_options("-stdlib=libc++")
|
||||
else ()
|
||||
# nothing special for gcc at the moment
|
||||
endif ()
|
||||
endif ()
|
||||
add_compile_definitions(KGE_PLATFORM=${CMAKE_HOST_SYSTEM_NAME})
|
||||
add_compile_definitions(KTE_VERSION_STR="v${KTE_VERSION}")
|
||||
if (KTE_ENABLE_TREESITTER)
|
||||
add_compile_definitions(KTE_ENABLE_TREESITTER)
|
||||
add_compile_definitions(KTE_ENABLE_TREESITTER)
|
||||
endif ()
|
||||
|
||||
message(STATUS "Build system: ${CMAKE_HOST_SYSTEM_NAME}")
|
||||
|
||||
if (${BUILD_GUI})
|
||||
include(cmake/imgui.cmake)
|
||||
include(cmake/imgui.cmake)
|
||||
endif ()
|
||||
|
||||
# NCurses for terminal mode
|
||||
@@ -55,250 +55,250 @@ find_package(Curses REQUIRED)
|
||||
include_directories(${CURSES_INCLUDE_DIR})
|
||||
|
||||
set(SYNTAX_SOURCES
|
||||
syntax/GoHighlighter.cc
|
||||
syntax/CppHighlighter.cc
|
||||
syntax/JsonHighlighter.cc
|
||||
syntax/ErlangHighlighter.cc
|
||||
syntax/MarkdownHighlighter.cc
|
||||
syntax/TreeSitterHighlighter.cc
|
||||
syntax/LispHighlighter.cc
|
||||
syntax/HighlighterEngine.cc
|
||||
syntax/RustHighlighter.cc
|
||||
syntax/HighlighterRegistry.cc
|
||||
syntax/SqlHighlighter.cc
|
||||
syntax/NullHighlighter.cc
|
||||
syntax/ForthHighlighter.cc
|
||||
syntax/PythonHighlighter.cc
|
||||
syntax/ShellHighlighter.cc
|
||||
syntax/GoHighlighter.cc
|
||||
syntax/CppHighlighter.cc
|
||||
syntax/JsonHighlighter.cc
|
||||
syntax/ErlangHighlighter.cc
|
||||
syntax/MarkdownHighlighter.cc
|
||||
syntax/TreeSitterHighlighter.cc
|
||||
syntax/LispHighlighter.cc
|
||||
syntax/HighlighterEngine.cc
|
||||
syntax/RustHighlighter.cc
|
||||
syntax/HighlighterRegistry.cc
|
||||
syntax/SqlHighlighter.cc
|
||||
syntax/NullHighlighter.cc
|
||||
syntax/ForthHighlighter.cc
|
||||
syntax/PythonHighlighter.cc
|
||||
syntax/ShellHighlighter.cc
|
||||
)
|
||||
|
||||
if (KTE_ENABLE_TREESITTER)
|
||||
list(APPEND SYNTAX_SOURCES
|
||||
TreeSitterHighlighter.cc)
|
||||
list(APPEND SYNTAX_SOURCES
|
||||
TreeSitterHighlighter.cc)
|
||||
endif ()
|
||||
|
||||
set(COMMON_SOURCES
|
||||
GapBuffer.cc
|
||||
PieceTable.cc
|
||||
Buffer.cc
|
||||
Editor.cc
|
||||
Command.cc
|
||||
HelpText.cc
|
||||
KKeymap.cc
|
||||
TerminalInputHandler.cc
|
||||
TerminalRenderer.cc
|
||||
TerminalFrontend.cc
|
||||
TestInputHandler.cc
|
||||
TestRenderer.cc
|
||||
TestFrontend.cc
|
||||
UndoNode.cc
|
||||
UndoTree.cc
|
||||
UndoSystem.cc
|
||||
GapBuffer.cc
|
||||
PieceTable.cc
|
||||
Buffer.cc
|
||||
Editor.cc
|
||||
Command.cc
|
||||
HelpText.cc
|
||||
KKeymap.cc
|
||||
TerminalInputHandler.cc
|
||||
TerminalRenderer.cc
|
||||
TerminalFrontend.cc
|
||||
TestInputHandler.cc
|
||||
TestRenderer.cc
|
||||
TestFrontend.cc
|
||||
UndoNode.cc
|
||||
UndoTree.cc
|
||||
UndoSystem.cc
|
||||
|
||||
${SYNTAX_SOURCES}
|
||||
${SYNTAX_SOURCES}
|
||||
)
|
||||
|
||||
|
||||
set(SYNTAX_HEADERS
|
||||
syntax/GoHighlighter.h
|
||||
syntax/HighlighterEngine.h
|
||||
syntax/ShellHighlighter.h
|
||||
syntax/MarkdownHighlighter.h
|
||||
syntax/LispHighlighter.h
|
||||
syntax/SqlHighlighter.h
|
||||
syntax/ForthHighlighter.h
|
||||
syntax/JsonHighlighter.h
|
||||
syntax/TreeSitterHighlighter.h
|
||||
syntax/NullHighlighter.h
|
||||
syntax/CppHighlighter.h
|
||||
syntax/ErlangHighlighter.h
|
||||
syntax/LanguageHighlighter.h
|
||||
syntax/RustHighlighter.h
|
||||
syntax/PythonHighlighter.h
|
||||
syntax/GoHighlighter.h
|
||||
syntax/HighlighterEngine.h
|
||||
syntax/ShellHighlighter.h
|
||||
syntax/MarkdownHighlighter.h
|
||||
syntax/LispHighlighter.h
|
||||
syntax/SqlHighlighter.h
|
||||
syntax/ForthHighlighter.h
|
||||
syntax/JsonHighlighter.h
|
||||
syntax/TreeSitterHighlighter.h
|
||||
syntax/NullHighlighter.h
|
||||
syntax/CppHighlighter.h
|
||||
syntax/ErlangHighlighter.h
|
||||
syntax/LanguageHighlighter.h
|
||||
syntax/RustHighlighter.h
|
||||
syntax/PythonHighlighter.h
|
||||
)
|
||||
|
||||
if (KTE_ENABLE_TREESITTER)
|
||||
list(APPEND THEME_HEADERS
|
||||
TreeSitterHighlighter.h)
|
||||
list(APPEND THEME_HEADERS
|
||||
TreeSitterHighlighter.h)
|
||||
endif ()
|
||||
|
||||
set(THEME_HEADERS
|
||||
themes/ThemeHelpers.h
|
||||
themes/EInk.h
|
||||
themes/Gruvbox.h
|
||||
themes/Solarized.h
|
||||
themes/Plan9.h
|
||||
themes/Nord.h
|
||||
themes/ThemeHelpers.h
|
||||
themes/EInk.h
|
||||
themes/Gruvbox.h
|
||||
themes/Solarized.h
|
||||
themes/Plan9.h
|
||||
themes/Nord.h
|
||||
)
|
||||
|
||||
set(COMMON_HEADERS
|
||||
GapBuffer.h
|
||||
PieceTable.h
|
||||
Buffer.h
|
||||
Editor.h
|
||||
AppendBuffer.h
|
||||
Command.h
|
||||
HelpText.h
|
||||
KKeymap.h
|
||||
InputHandler.h
|
||||
TerminalInputHandler.h
|
||||
Renderer.h
|
||||
TerminalRenderer.h
|
||||
Frontend.h
|
||||
TerminalFrontend.h
|
||||
TestInputHandler.h
|
||||
TestRenderer.h
|
||||
TestFrontend.h
|
||||
UndoNode.h
|
||||
UndoTree.h
|
||||
UndoSystem.h
|
||||
Highlight.h
|
||||
GapBuffer.h
|
||||
PieceTable.h
|
||||
Buffer.h
|
||||
Editor.h
|
||||
AppendBuffer.h
|
||||
Command.h
|
||||
HelpText.h
|
||||
KKeymap.h
|
||||
InputHandler.h
|
||||
TerminalInputHandler.h
|
||||
Renderer.h
|
||||
TerminalRenderer.h
|
||||
Frontend.h
|
||||
TerminalFrontend.h
|
||||
TestInputHandler.h
|
||||
TestRenderer.h
|
||||
TestFrontend.h
|
||||
UndoNode.h
|
||||
UndoTree.h
|
||||
UndoSystem.h
|
||||
Highlight.h
|
||||
|
||||
${SYNTAX_HEADERS}
|
||||
${THEME_HEADERS}
|
||||
${SYNTAX_HEADERS}
|
||||
${THEME_HEADERS}
|
||||
)
|
||||
|
||||
# kte (terminal-first) executable
|
||||
add_executable(kte
|
||||
main.cc
|
||||
${COMMON_SOURCES}
|
||||
${COMMON_HEADERS}
|
||||
main.cc
|
||||
${COMMON_SOURCES}
|
||||
${COMMON_HEADERS}
|
||||
)
|
||||
|
||||
if (KTE_USE_PIECE_TABLE)
|
||||
target_compile_definitions(kte PRIVATE KTE_USE_PIECE_TABLE=1)
|
||||
target_compile_definitions(kte PRIVATE KTE_USE_PIECE_TABLE=1)
|
||||
endif ()
|
||||
if (KTE_UNDO_DEBUG)
|
||||
target_compile_definitions(kte PRIVATE KTE_UNDO_DEBUG=1)
|
||||
target_compile_definitions(kte PRIVATE KTE_UNDO_DEBUG=1)
|
||||
endif ()
|
||||
|
||||
target_link_libraries(kte ${CURSES_LIBRARIES})
|
||||
|
||||
if (KTE_ENABLE_TREESITTER)
|
||||
# Users can provide their own tree-sitter include/lib via cache variables
|
||||
set(TREESITTER_INCLUDE_DIR "" CACHE PATH "Path to tree-sitter include directory")
|
||||
set(TREESITTER_LIBRARY "" CACHE FILEPATH "Path to tree-sitter library (.a/.dylib)")
|
||||
if (TREESITTER_INCLUDE_DIR)
|
||||
target_include_directories(kte PRIVATE ${TREESITTER_INCLUDE_DIR})
|
||||
endif ()
|
||||
if (TREESITTER_LIBRARY)
|
||||
target_link_libraries(kte ${TREESITTER_LIBRARY})
|
||||
endif ()
|
||||
# Users can provide their own tree-sitter include/lib via cache variables
|
||||
set(TREESITTER_INCLUDE_DIR "" CACHE PATH "Path to tree-sitter include directory")
|
||||
set(TREESITTER_LIBRARY "" CACHE FILEPATH "Path to tree-sitter library (.a/.dylib)")
|
||||
if (TREESITTER_INCLUDE_DIR)
|
||||
target_include_directories(kte PRIVATE ${TREESITTER_INCLUDE_DIR})
|
||||
endif ()
|
||||
if (TREESITTER_LIBRARY)
|
||||
target_link_libraries(kte ${TREESITTER_LIBRARY})
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
install(TARGETS kte
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
# Man pages
|
||||
install(FILES docs/kte.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
|
||||
|
||||
if (BUILD_TESTS)
|
||||
# test_undo executable for testing undo/redo system
|
||||
add_executable(test_undo
|
||||
test_undo.cc
|
||||
${COMMON_SOURCES}
|
||||
${COMMON_HEADERS}
|
||||
)
|
||||
# test_undo executable for testing undo/redo system
|
||||
add_executable(test_undo
|
||||
test_undo.cc
|
||||
${COMMON_SOURCES}
|
||||
${COMMON_HEADERS}
|
||||
)
|
||||
|
||||
if (KTE_USE_PIECE_TABLE)
|
||||
target_compile_definitions(test_undo PRIVATE KTE_USE_PIECE_TABLE=1)
|
||||
endif ()
|
||||
if (KTE_USE_PIECE_TABLE)
|
||||
target_compile_definitions(test_undo PRIVATE KTE_USE_PIECE_TABLE=1)
|
||||
endif ()
|
||||
|
||||
if (KTE_UNDO_DEBUG)
|
||||
target_compile_definitions(test_undo PRIVATE KTE_UNDO_DEBUG=1)
|
||||
endif ()
|
||||
if (KTE_UNDO_DEBUG)
|
||||
target_compile_definitions(test_undo PRIVATE KTE_UNDO_DEBUG=1)
|
||||
endif ()
|
||||
|
||||
|
||||
target_link_libraries(test_undo ${CURSES_LIBRARIES})
|
||||
if (KTE_ENABLE_TREESITTER)
|
||||
if (TREESITTER_INCLUDE_DIR)
|
||||
target_include_directories(test_undo PRIVATE ${TREESITTER_INCLUDE_DIR})
|
||||
endif ()
|
||||
if (TREESITTER_LIBRARY)
|
||||
target_link_libraries(test_undo ${TREESITTER_LIBRARY})
|
||||
endif ()
|
||||
endif ()
|
||||
target_link_libraries(test_undo ${CURSES_LIBRARIES})
|
||||
if (KTE_ENABLE_TREESITTER)
|
||||
if (TREESITTER_INCLUDE_DIR)
|
||||
target_include_directories(test_undo PRIVATE ${TREESITTER_INCLUDE_DIR})
|
||||
endif ()
|
||||
if (TREESITTER_LIBRARY)
|
||||
target_link_libraries(test_undo ${TREESITTER_LIBRARY})
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (${BUILD_GUI})
|
||||
target_sources(kte PRIVATE
|
||||
Font.h
|
||||
GUIConfig.cc
|
||||
GUIConfig.h
|
||||
GUIRenderer.cc
|
||||
GUIRenderer.h
|
||||
GUIInputHandler.cc
|
||||
GUIInputHandler.h
|
||||
GUIFrontend.cc
|
||||
GUIFrontend.h)
|
||||
target_compile_definitions(kte PRIVATE KTE_BUILD_GUI=1)
|
||||
target_link_libraries(kte imgui)
|
||||
target_sources(kte PRIVATE
|
||||
Font.h
|
||||
GUIConfig.cc
|
||||
GUIConfig.h
|
||||
GUIRenderer.cc
|
||||
GUIRenderer.h
|
||||
GUIInputHandler.cc
|
||||
GUIInputHandler.h
|
||||
GUIFrontend.cc
|
||||
GUIFrontend.h)
|
||||
target_compile_definitions(kte PRIVATE KTE_BUILD_GUI=1)
|
||||
target_link_libraries(kte imgui)
|
||||
|
||||
# kge (GUI-first) executable
|
||||
add_executable(kge
|
||||
main.cc
|
||||
${COMMON_SOURCES}
|
||||
${COMMON_HEADERS}
|
||||
GUIConfig.cc
|
||||
GUIConfig.h
|
||||
GUIRenderer.cc
|
||||
GUIRenderer.h
|
||||
GUIInputHandler.cc
|
||||
GUIInputHandler.h
|
||||
GUIFrontend.cc
|
||||
GUIFrontend.h)
|
||||
target_compile_definitions(kge PRIVATE KTE_BUILD_GUI=1 KTE_DEFAULT_GUI=1 KTE_FONT_SIZE=${KTE_FONT_SIZE})
|
||||
if (KTE_UNDO_DEBUG)
|
||||
target_compile_definitions(kge PRIVATE KTE_UNDO_DEBUG=1)
|
||||
endif ()
|
||||
target_link_libraries(kge ${CURSES_LIBRARIES} imgui)
|
||||
# kge (GUI-first) executable
|
||||
add_executable(kge
|
||||
main.cc
|
||||
${COMMON_SOURCES}
|
||||
${COMMON_HEADERS}
|
||||
GUIConfig.cc
|
||||
GUIConfig.h
|
||||
GUIRenderer.cc
|
||||
GUIRenderer.h
|
||||
GUIInputHandler.cc
|
||||
GUIInputHandler.h
|
||||
GUIFrontend.cc
|
||||
GUIFrontend.h)
|
||||
target_compile_definitions(kge PRIVATE KTE_BUILD_GUI=1 KTE_DEFAULT_GUI=1 KTE_FONT_SIZE=${KTE_FONT_SIZE})
|
||||
if (KTE_UNDO_DEBUG)
|
||||
target_compile_definitions(kge PRIVATE KTE_UNDO_DEBUG=1)
|
||||
endif ()
|
||||
target_link_libraries(kge ${CURSES_LIBRARIES} imgui)
|
||||
|
||||
# On macOS, build kge as a proper .app bundle
|
||||
if (APPLE)
|
||||
# Define the icon file
|
||||
set(MACOSX_BUNDLE_ICON_FILE kge.icns)
|
||||
set(kge_ICON "${CMAKE_CURRENT_SOURCE_DIR}/${MACOSX_BUNDLE_ICON_FILE}")
|
||||
# On macOS, build kge as a proper .app bundle
|
||||
if (APPLE)
|
||||
# Define the icon file
|
||||
set(MACOSX_BUNDLE_ICON_FILE kge.icns)
|
||||
set(kge_ICON "${CMAKE_CURRENT_SOURCE_DIR}/${MACOSX_BUNDLE_ICON_FILE}")
|
||||
|
||||
# Add icon to the target sources and mark it as a resource
|
||||
target_sources(kge PRIVATE ${kge_ICON})
|
||||
set_source_files_properties(${kge_ICON} PROPERTIES
|
||||
MACOSX_PACKAGE_LOCATION Resources)
|
||||
# Add icon to the target sources and mark it as a resource
|
||||
target_sources(kge PRIVATE ${kge_ICON})
|
||||
set_source_files_properties(${kge_ICON} PROPERTIES
|
||||
MACOSX_PACKAGE_LOCATION Resources)
|
||||
|
||||
# Configure Info.plist with version and identifiers
|
||||
set(KGE_BUNDLE_ID "dev.wntrmute.kge")
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_LIST_DIR}/cmake/Info.plist.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/kge-Info.plist
|
||||
@ONLY)
|
||||
# Configure Info.plist with version and identifiers
|
||||
set(KGE_BUNDLE_ID "dev.wntrmute.kge")
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_LIST_DIR}/cmake/Info.plist.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/kge-Info.plist
|
||||
@ONLY)
|
||||
|
||||
set_target_properties(kge PROPERTIES
|
||||
MACOSX_BUNDLE TRUE
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER ${KGE_BUNDLE_ID}
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "kge"
|
||||
MACOSX_BUNDLE_ICON_FILE ${MACOSX_BUNDLE_ICON_FILE}
|
||||
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_BINARY_DIR}/kge-Info.plist")
|
||||
set_target_properties(kge PROPERTIES
|
||||
MACOSX_BUNDLE TRUE
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER ${KGE_BUNDLE_ID}
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "kge"
|
||||
MACOSX_BUNDLE_ICON_FILE ${MACOSX_BUNDLE_ICON_FILE}
|
||||
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_BINARY_DIR}/kge-Info.plist")
|
||||
|
||||
add_dependencies(kge kte)
|
||||
add_custom_command(TARGET kge POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
$<TARGET_FILE:kte>
|
||||
$<TARGET_FILE_DIR:kge>/kte
|
||||
COMMENT "Copying kte binary into kge.app bundle")
|
||||
add_dependencies(kge kte)
|
||||
add_custom_command(TARGET kge POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
$<TARGET_FILE:kte>
|
||||
$<TARGET_FILE_DIR:kge>/kte
|
||||
COMMENT "Copying kte binary into kge.app bundle")
|
||||
|
||||
install(TARGETS kge
|
||||
BUNDLE DESTINATION .
|
||||
)
|
||||
install(TARGETS kge
|
||||
BUNDLE DESTINATION .
|
||||
)
|
||||
|
||||
install(TARGETS kte
|
||||
RUNTIME DESTINATION kge.app/Contents/MacOS
|
||||
)
|
||||
else ()
|
||||
install(TARGETS kge
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
endif ()
|
||||
# Install kge man page only when GUI is built
|
||||
install(FILES docs/kge.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
|
||||
install(FILES kge.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons)
|
||||
install(TARGETS kte
|
||||
RUNTIME DESTINATION kge.app/Contents/MacOS
|
||||
)
|
||||
else ()
|
||||
install(TARGETS kge
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
endif ()
|
||||
# Install kge man page only when GUI is built
|
||||
install(FILES docs/kge.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
|
||||
install(FILES kge.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons)
|
||||
endif ()
|
||||
|
||||
70
Command.cc
70
Command.cc
@@ -3067,6 +3067,74 @@ cmd_page_down(CommandContext &ctx)
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
cmd_scroll_up(CommandContext &ctx)
|
||||
{
|
||||
Buffer *buf = ctx.editor.CurrentBuffer();
|
||||
if (!buf)
|
||||
return false;
|
||||
ensure_at_least_one_line(*buf);
|
||||
const auto &rows = buf->Rows();
|
||||
std::size_t content_rows = std::max<std::size_t>(1, ctx.editor.ContentRows());
|
||||
std::size_t rowoffs = buf->Rowoffs();
|
||||
|
||||
// Scroll up by 3 lines (or count if specified), without moving cursor
|
||||
int scroll_amount = ctx.count > 0 ? ctx.count : 3;
|
||||
if (rowoffs >= static_cast<std::size_t>(scroll_amount))
|
||||
rowoffs -= static_cast<std::size_t>(scroll_amount);
|
||||
else
|
||||
rowoffs = 0;
|
||||
|
||||
buf->SetOffsets(rowoffs, buf->Coloffs());
|
||||
|
||||
// If cursor is now below the visible area, move it to the last visible line
|
||||
std::size_t cury = buf->Cury();
|
||||
if (cury >= rowoffs + content_rows) {
|
||||
std::size_t new_y = rowoffs + content_rows - 1;
|
||||
if (new_y >= rows.size() && !rows.empty())
|
||||
new_y = rows.size() - 1;
|
||||
buf->SetCursor(buf->Curx(), new_y);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
cmd_scroll_down(CommandContext &ctx)
|
||||
{
|
||||
Buffer *buf = ctx.editor.CurrentBuffer();
|
||||
if (!buf)
|
||||
return false;
|
||||
ensure_at_least_one_line(*buf);
|
||||
const auto &rows = buf->Rows();
|
||||
std::size_t content_rows = std::max<std::size_t>(1, ctx.editor.ContentRows());
|
||||
std::size_t rowoffs = buf->Rowoffs();
|
||||
|
||||
// Scroll down by 3 lines (or count if specified), without moving cursor
|
||||
int scroll_amount = ctx.count > 0 ? ctx.count : 3;
|
||||
|
||||
// Compute maximum top offset
|
||||
std::size_t max_top = 0;
|
||||
if (!rows.empty() && rows.size() > content_rows)
|
||||
max_top = rows.size() - content_rows;
|
||||
|
||||
rowoffs += static_cast<std::size_t>(scroll_amount);
|
||||
if (rowoffs > max_top)
|
||||
rowoffs = max_top;
|
||||
|
||||
buf->SetOffsets(rowoffs, buf->Coloffs());
|
||||
|
||||
// If cursor is now above the visible area, move it to the first visible line
|
||||
std::size_t cury = buf->Cury();
|
||||
if (cury < rowoffs) {
|
||||
buf->SetCursor(buf->Curx(), rowoffs);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static inline bool
|
||||
is_word_char(unsigned char c)
|
||||
{
|
||||
@@ -3675,6 +3743,8 @@ InstallDefaultCommands()
|
||||
CommandRegistry::Register({CommandId::MoveEnd, "end", "Move to end of line", cmd_move_end});
|
||||
CommandRegistry::Register({CommandId::PageUp, "page-up", "Page up", cmd_page_up});
|
||||
CommandRegistry::Register({CommandId::PageDown, "page-down", "Page down", cmd_page_down});
|
||||
CommandRegistry::Register({CommandId::ScrollUp, "scroll-up", "Scroll viewport up", cmd_scroll_up});
|
||||
CommandRegistry::Register({CommandId::ScrollDown, "scroll-down", "Scroll viewport down", cmd_scroll_down});
|
||||
CommandRegistry::Register({CommandId::WordPrev, "word-prev", "Move to previous word", cmd_word_prev});
|
||||
CommandRegistry::Register({CommandId::WordNext, "word-next", "Move to next word", cmd_word_next});
|
||||
CommandRegistry::Register({
|
||||
|
||||
@@ -58,6 +58,8 @@ enum class CommandId {
|
||||
MoveEnd,
|
||||
PageUp,
|
||||
PageDown,
|
||||
ScrollUp, // scroll viewport up (towards beginning) without moving cursor
|
||||
ScrollDown, // scroll viewport down (towards end) without moving cursor
|
||||
WordPrev,
|
||||
WordNext,
|
||||
DeleteWordPrev, // delete previous word (ESC BACKSPACE)
|
||||
|
||||
@@ -285,15 +285,11 @@ GUIInputHandler::ProcessSDLEvent(const SDL_Event &e)
|
||||
bool produced = false;
|
||||
switch (e.type) {
|
||||
case SDL_MOUSEWHEEL: {
|
||||
// If ImGui wants to capture the mouse (e.g., hovering the File Picker list),
|
||||
// don't translate wheel events into editor scrolling.
|
||||
// This prevents background buffer scroll while using GUI widgets.
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
if (io.WantCaptureMouse) {
|
||||
return true; // consumed by GUI
|
||||
}
|
||||
|
||||
// Map vertical wheel to line-wise cursor movement (MoveUp/MoveDown)
|
||||
// Map vertical wheel to viewport scrolling (ScrollUp/ScrollDown)
|
||||
// Note: We don't check WantCaptureMouse here because ImGui sets it to true
|
||||
// whenever the mouse is over any ImGui window (including our editor content area).
|
||||
// The NoScrollWithMouse flag on the child window prevents ImGui from handling
|
||||
// scroll internally, so we can safely process wheel events ourselves.
|
||||
int dy = e.wheel.y;
|
||||
#ifdef SDL_MOUSEWHEEL_FLIPPED
|
||||
if (e.wheel.direction == SDL_MOUSEWHEEL_FLIPPED)
|
||||
@@ -301,7 +297,7 @@ GUIInputHandler::ProcessSDLEvent(const SDL_Event &e)
|
||||
#endif
|
||||
if (dy != 0) {
|
||||
int repeat = dy > 0 ? dy : -dy;
|
||||
CommandId id = dy > 0 ? CommandId::MoveUp : CommandId::MoveDown;
|
||||
CommandId id = dy > 0 ? CommandId::ScrollUp : CommandId::ScrollDown;
|
||||
std::lock_guard<std::mutex> lk(mu_);
|
||||
for (int i = 0; i < repeat; ++i) {
|
||||
q_.push(MappedInput{true, id, std::string(), 0});
|
||||
@@ -372,7 +368,7 @@ GUIInputHandler::ProcessSDLEvent(const SDL_Event &e)
|
||||
// Digits without shift, or a plain '-'
|
||||
const bool is_digit_key = (key >= SDLK_0 && key <= SDLK_9) && !(mods & KMOD_SHIFT);
|
||||
const bool is_minus_key = (key == SDLK_MINUS);
|
||||
if (uarg_active_ && uarg_collecting_ && (is_digit_key || is_minus_key)) {
|
||||
if (uarg_active_ && uarg_collecting_ &&(is_digit_key || is_minus_key)) {
|
||||
suppress_text_input_once_ = true;
|
||||
}
|
||||
}
|
||||
@@ -564,7 +560,12 @@ GUIInputHandler::ProcessSDLEvent(const SDL_Event &e)
|
||||
|
||||
if (produced && mi.hasCommand) {
|
||||
// Attach universal-argument count if present, then clear the state
|
||||
if (uarg_active_ && mi.id != CommandId::UArgStatus) {
|
||||
if (uarg_active_ &&mi
|
||||
|
||||
.
|
||||
id != CommandId::UArgStatus
|
||||
)
|
||||
{
|
||||
int count = 0;
|
||||
if (!uarg_had_digits_ && !uarg_negative_) {
|
||||
count = (uarg_value_ > 0) ? uarg_value_ : 4;
|
||||
@@ -597,4 +598,4 @@ GUIInputHandler::Poll(MappedInput &out)
|
||||
out = q_.front();
|
||||
q_.pop();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -35,16 +35,16 @@ map_key_to_command(const int ch,
|
||||
case KEY_MOUSE: {
|
||||
MEVENT ev{};
|
||||
if (getmouse(&ev) == OK) {
|
||||
// Mouse wheel → map to MoveUp/MoveDown one line per wheel notch
|
||||
// Mouse wheel → scroll viewport without moving cursor
|
||||
#ifdef BUTTON4_PRESSED
|
||||
if (ev.bstate & (BUTTON4_PRESSED | BUTTON4_RELEASED | BUTTON4_CLICKED)) {
|
||||
out = {true, CommandId::MoveUp, "", 0};
|
||||
out = {true, CommandId::ScrollUp, "", 0};
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#ifdef BUTTON5_PRESSED
|
||||
if (ev.bstate & (BUTTON5_PRESSED | BUTTON5_RELEASED | BUTTON5_CLICKED)) {
|
||||
out = {true, CommandId::MoveDown, "", 0};
|
||||
out = {true, CommandId::ScrollDown, "", 0};
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@@ -320,4 +320,4 @@ TerminalInputHandler::Poll(MappedInput &out)
|
||||
{
|
||||
out = {};
|
||||
return decode_(out) && out.hasCommand;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user